Ravi Katiyar

File Uploader

Component

About

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds File Uploader to your project and fits it to your theme.

Code

How File Uploader is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import * as React from "react";
import { useState } from "react";
import { FileUploader } from "@/components/ui/file-uploader"; // Adjust path as needed
import { Button } from "@/components/ui/button";
import Link from "next/link";

export default function FileUploaderDemo() {
  // --- Component State ---
  const [status, setStatus] = useState<
    "idle" | "uploading" | "success" | "error"
  >("idle");
  const [fileName, setFileName] = useState<string | undefined>();
  const [fileSize, setFileSize] = useState<number | undefined>();
  const [errorMessage, setErrorMessage] = useState<string | undefined>();

  // --- Constants ---
  const ACCEPTED_TYPES = "text/csv";
  const MAX_SIZE_MB = 20;
  const MAX_SIZE_BYTES = MAX_SIZE_MB * 1024 * 1024;

  // --- Event Handler ---
  const handleFileSelect = (file: File) => {
    if (!file) {
      // This is for the "Change" button
      setStatus("idle");
      setFileName(undefined);
      setFileSize(undefined);
      setErrorMessage(undefined);
      return;
    }

    // Set file details immediately
    setFileName(file.name);
    setFileSize(file.size);
    setStatus("uploading");
    setErrorMessage(undefined);

    // --- Simulate Upload and Validation ---
    setTimeout(() => {
      // 1. Validate Type
      if (file.type !== ACCEPTED_TYPES) {
        setStatus("error");
        setErrorMessage("Invalid file type. Please upload a CSV.");
        return;
      }

      // 2. Validate Size
      if (file.size > MAX_SIZE_BYTES) {
        setStatus("error");
        setErrorMessage(
          `File is too large. Maximum size is ${MAX_SIZE_MB}MB.`
        );
        return;
      }

      // 3. Simulate Success
      setStatus("success");
    }, 2000); // 2-second simulation
  };

  return (
    <div className="flex w-full max-w-xl flex-col items-center space-y-6 rounded-lg bg-background p-8">
      {/* Page Header from image */}
      <div className="text-center">
        <h1 className="text-3xl font-semibold text-foreground">
          Add multiple contractors
        </h1>
        <p className="mt-2 text-base text-muted-foreground">
          Utilize our{" "}
          <Link href="#" className="font-medium text-primary hover:underline">
            CSV template
          </Link>{" "}
          and simultaneously invite any
          <br />
          number of contractors to join Molecules Design.
        </p>
      </div>

      {/* The Reusable Component */}
      <FileUploader
        status={status}
        onFileSelect={handleFileSelect}
        acceptedFileTypes={ACCEPTED_TYPES}
        maxFileSizeMb={MAX_SIZE_MB}
        fileName={fileName}
        fileSize={fileSize}
        errorMessage={errorMessage}
        className="w-full"
      />

      {/* CTA Button from image */}
      <Button
        className="w-full max-w-xs"
        size="lg"
        disabled={status !== "success"}
      >
        See upload results
      </Button>
    </div>
  );
}

Dependencies

More by Ravi Katiyar

View all
  • Animated Shader Hero

    Animated Shader Hero

    3.7K
  • Hero

    Hero

    3.1K
  • Circular Gallery

    Circular Gallery

    2.7K
  • Minimalist Hero

    Minimalist Hero

    2.5K
  • Floating Icons Hero Section

    Floating Icons Hero Section

    1.9K
  • Glass Calendar

    Glass Calendar

    1.8K
  • Feature Carousel

    Feature Carousel

    1.7K
  • AI Image Generator Hero

    AI Image Generator Hero

    1.4K