feat: implement Files page with persistent storage and version tracking

Three-panel file manager (nav, list, details) modeled after Stirling-PDF.
- Backend: user_files table, /api/v1/files/* CRUD routes, file storage
  helpers, thumbnail generation via Sharp, recursive CTE version chains
- Frontend: FilesNav, FileList, FileDetails, FileUploadArea components,
  Zustand store, mobile layout with bottom sheet
- Integration: tool-factory auto-saves results as new versions when
  fileId is provided, "Open File" loads file into tool processing flow
- Search, bulk select/delete/download, version badges, tool chain tags
This commit is contained in:
Siddharth Kumar Sah
2026-03-26 01:10:51 +08:00
parent 926b52d330
commit 62fbb5484c
24 changed files with 771 additions and 470 deletions
+2 -4
View File
@@ -87,8 +87,7 @@ function deriveCompat(entries: FileEntry[], selectedIndex: number) {
files: entries.map((e) => e.file),
currentEntry: entry,
hasFiles: entries.length > 0,
allProcessed:
entries.length > 0 && entries.every((e) => e.status === "completed"),
allProcessed: entries.length > 0 && entries.every((e) => e.status === "completed"),
selectedFileName: entry ? entry.file.name : null,
selectedFileSize: entry ? entry.file.size : null,
originalBlobUrl: entry ? entry.blobUrl : null,
@@ -183,8 +182,7 @@ export const useFileStore = create<FileState>((set, get) => ({
set({ entries, ...deriveCompat(entries, idx) });
},
setBatchZip: (blob, filename) =>
set({ batchZipBlob: blob, batchZipFilename: filename }),
setBatchZip: (blob, filename) => set({ batchZipBlob: blob, batchZipFilename: filename }),
setProcessing: (v) => set({ processing: v }),