You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<FileUpload /> is a production-ready dropzone component that other features can drop into any form. The demo page at /uploads-demo proves it works end-to-end against mocked endpoints.
Tasks
FileUpload component
Real drag-and-drop dropzone using a library like react-dropzone or a hand-rolled equivalent.
What this accomplishes: Users can drag files in, or click to open the OS file picker. Modern, expected UX.
Client-side validation: MIME type check, size check, friendly error messages.
What this accomplishes: Users get instant feedback when they try to drop a 10 GB video or a .exe, instead of a confusing server error.
On file accept, call POST /api/v1/uploads/sign (mocked to return a fake signed URL).
What this accomplishes: The upload flow is wired up. When the backend ships, no frontend changes needed.
Simulated upload: if the response is a mock, skip the actual PUT to GCS and just show a fake progress animation. If the response looks real, do the PUT.
What this accomplishes: The demo works without a working GCS bucket, but the real flow is also exercised when both halves are deployed.
After upload completes, call back to the parent with the uploadId so it can be stored in form state.
What this accomplishes: The parent component (like an application form) knows which file the user uploaded and can reference it later.
FilePreview component
Shows filename, file size (formatted), MIME type icon.
"Replace" button reopens the dropzone.
"Remove" button clears the upload from form state.
What this accomplishes: Users can see what they uploaded and easily change their mind.
UploadProgress component
Real progress bar driven by upload progress events (or fake-timed for the mock).
Shows percentage, transferred bytes / total bytes.
What this accomplishes: Long uploads (resumes can be a few MB) don't feel frozen.
Demo page
/uploads-demo mounts <FileUpload /> with a state display showing the current uploadId, filename, and a button to fetch a download URL.
What this accomplishes: Self-contained proof the component works without needing the application form to be done. Doubles as docs for other devs.
Styling
shadcn-themed dropzone with hover/active states.
Error states are visually distinct (red border, error icon).
Works on desktop
Definition of done
/uploads-demo accepts a file, shows progress, shows the preview, and lets the user replace or remove.
Validation errors render correctly for bad MIME and oversize files.
Other tickets (Ticket 2's FileUploadField) can import <FileUpload /> and consume it via documented props.
Goal
<FileUpload />is a production-ready dropzone component that other features can drop into any form. The demo page at/uploads-demoproves it works end-to-end against mocked endpoints.Tasks
FileUpload component
react-dropzoneor a hand-rolled equivalent.POST /api/v1/uploads/sign(mocked to return a fake signed URL).uploadIdso it can be stored in form state.FilePreview component
UploadProgress component
Demo page
/uploads-demomounts<FileUpload />with a state display showing the currentuploadId, filename, and a button to fetch a download URL.Styling
Definition of done
/uploads-demoaccepts a file, shows progress, shows the preview, and lets the user replace or remove.FileUploadField) can import<FileUpload />and consume it via documented props.