Skip to content

Alemoretti/upload-widget

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

38 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Upload Widget

A modern, animated file upload widget with image compression, progress tracking, and cloud storage integration. Built with React, TypeScript, Node.js and Framer Motion.

upload-widget

✨ Features

  • 🎨 Beautiful UI - Modern design with smooth animations using Framer Motion
  • πŸ“ Drag & Drop - Intuitive file selection with React Dropzone
  • πŸ—œοΈ Image Compression - Automatic image optimization before upload
  • πŸ“Š Progress Tracking - Real-time upload progress with visual indicators
  • ☁️ Cloud Storage - Integration with Cloudflare R2 for file storage
  • ⏸️ Upload Control - Cancel, retry, and manage uploads
  • πŸ“± Responsive - Works on desktop and mobile devices
  • 🎯 TypeScript - Fully typed for better development experience

πŸ—οΈ Architecture

This project consists of two main parts:

  • Frontend (/web) - React application with Vite
  • Backend (/server) - Node.js API with Fastify

πŸš€ Quick Start

Prerequisites

  • Node.js 18+
  • pnpm (recommended) or npm
  • Cloudflare R2 account (for file storage)

1. Clone the repository

git clone <repository-url>
cd upload-widget

2. Install dependencies

# Install root dependencies
pnpm install

# Install frontend dependencies
cd web
pnpm install

# Install backend dependencies
cd ../server
pnpm install

3. Environment Setup

Create a .env file in the server directory:

CLOUDFLARE_ACCESS_KEY_ID=your_access_key
CLOUDFLARE_SECRET_ACCESS_KEY=your_secret_key
CLOUDFLARE_BUCKET=your_bucket_name
CLOUDFLARE_ACCOUNT_ID=your_account_id
CLOUDFLARE_PUBLIC_URL=https://your-bucket.your-domain.com

4. Start Development Servers

Terminal 1 - Backend:

cd server
pnpm dev

Terminal 2 - Frontend:

cd web
pnpm dev

The application will be available at http://localhost:5174 (or the next available port).

πŸ› οΈ Tech Stack

Frontend

  • React 19 - UI library
  • TypeScript - Type safety
  • Vite - Build tool and dev server
  • Tailwind CSS - Styling
  • Framer Motion - Animations
  • Zustand - State management
  • Immer - Immutable state updates
  • Radix UI - Accessible components
  • React Dropzone - File drag & drop
  • Axios - HTTP client

Backend

  • Node.js - Runtime
  • Fastify - Web framework
  • TypeScript - Type safety
  • Zod - Schema validation
  • AWS SDK - Cloudflare R2 integration

πŸ“ Project Structure

upload-widget/
β”œβ”€β”€ web/                          # Frontend React app
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/           # React components
β”‚   β”‚   β”‚   β”œβ”€β”€ ui/              # Reusable UI components
β”‚   β”‚   β”‚   └── upload-widget-*  # Widget-specific components
β”‚   β”‚   β”œβ”€β”€ store/               # Zustand state management
β”‚   β”‚   β”œβ”€β”€ http/                # API client functions
β”‚   β”‚   └── utils/               # Utility functions
β”‚   └── package.json
β”œβ”€β”€ server/                       # Backend API
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ routes/              # API routes
β”‚   β”‚   β”œβ”€β”€ functions/           # Business logic
β”‚   β”‚   └── storage/             # Storage providers
β”‚   └── package.json
└── README.md

🎯 Key Components

Upload Widget (upload-widget.tsx)

Main widget component with collapsible functionality and smooth animations.

Upload Item (upload-widget-upload-item.tsx)

Individual upload item with progress bar, status indicators, and action buttons.

Dropzone (upload-widget-dropzone.tsx)

File selection area with drag & drop support.

Store (store/uploads.ts)

Zustand store managing upload state with Immer for immutable updates.

πŸ”§ Configuration

Image Compression

Configure compression settings in web/src/utils/compress-image.ts:

const compressedFile = await compressImage({
  file: upload.file,
  maxWidth: 1000,    // Maximum width
  maxHeight: 1000,   // Maximum height
  quality: 0.8,      // Compression quality (0-1)
});

Storage Provider

The backend uses Cloudflare R2 for file storage. To use a different provider, modify server/src/storage/providers/r2-storage.ts.

πŸ“ API Endpoints

POST /upload-image

Uploads a compressed image file to cloud storage.

Request:

  • multipart/form-data with file field

Response:

{
  "url": "https://your-bucket.your-domain.com/path/to/file.jpg"
}

🎨 Styling

The project uses Tailwind CSS with custom configurations:

  • Colors: Zinc-based dark theme
  • Animations: Framer Motion for smooth transitions
  • Components: Radix UI for accessibility
  • Icons: Lucide React icon library

πŸš€ Deployment

Frontend (Vercel/Netlify)

cd web
pnpm build
# Deploy the dist/ folder

Backend (Railway/Render/Fly.io)

cd server
# Set environment variables
# Deploy the server

πŸ™ Acknowledgments

About

App to upload files with an upload server

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors