Integration Recipes

React Dropzone Integration

Create an intuitive drag-and-drop file upload zone with animated progress indicators using react-dropzone and `@cloudizero/sdk`.

Installation

bash
pnpm add react-dropzone @cloudizero/sdk

Component Implementation

The code snippet below combines drop events with `@cloudizero/sdk`'s real-time onProgress callback:

components/dropzone-uploader.tsx
"use client";

import { useState } from "react";
import { useDropzone } from "react-dropzone";
import { Cloudizero } from "@cloudizero/sdk";

const cz = new Cloudizero({
  apiKey: process.env.NEXT_PUBLIC_CLOUDIZERO_KEY!,
});

export function DropzoneUploader({ projectId }: { projectId: string }) {
  const [uploading, setUploading] = useState(false);
  const [progress, setProgress] = useState(0);

  const onDrop = async (acceptedFiles: File[]) => {
    const file = acceptedFiles[0];
    if (!file) return;

    setUploading(true);
    setProgress(0);

    try {
      const asset = await cz.storage.upload({
        file,
        fileName: file.name,
        projectId,
        mimeType: file.type,
        onProgress: ({ percent }) => setProgress(percent),
      });

      console.log("Uploaded successfully:", asset.url);
    } catch (err) {
      console.error("Dropzone upload failed:", err);
    } finally {
      setUploading(false);
    }
  };

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    multiple: false,
  });

  return (
    <div
      {...getRootProps()}
      className={`border-2 border-dashed rounded-2xl p-10 text-center cursor-pointer transition-colors ${
        isDragActive ? "border-blue-500 bg-blue-500/10" : "border-border hover:border-blue-500/40"
      }`}
    >
      <input {...getInputProps()} />
      {uploading ? (
        <div className="space-y-2">
          <p className="text-sm font-medium">Uploading: {progress}%</p>
          <div className="w-48 mx-auto bg-muted h-2 rounded-full overflow-hidden">
            <div className="bg-blue-600 h-full transition-all" style={{ width: `${progress}%` }} />
          </div>
        </div>
      ) : isDragActive ? (
        <p className="text-sm font-medium text-blue-600">Drop files here to upload...</p>
      ) : (
        <p className="text-sm text-muted-foreground">
          Drag & drop media here, or <span className="text-blue-600 font-medium">browse files</span>
        </p>
      )}
    </div>
  );
}