Explorar el Código

feat(files): implement file upload functionality in FilesTable component

vtugulan hace 6 meses
padre
commit
d4fb79b02f
Se han modificado 3 ficheros con 59 adiciones y 35 borrados
  1. 0 1
      app/api-docs/page.tsx
  2. 57 7
      app/components/filesTable.tsx
  3. 2 27
      app/files/page.tsx

+ 0 - 1
app/api-docs/page.tsx

@@ -189,7 +189,6 @@ export default function ApiDocs() {
             </div>
             <ApiReferenceReact 
               configuration={{
-                // url: '/api/openapi.json',
                 content: openApiSpec,
                 theme: 'default',
                 layout: 'modern'

+ 57 - 7
app/components/filesTable.tsx

@@ -11,7 +11,7 @@ import {
   SortingState,
   RowSelectionState,
 } from "@tanstack/react-table";
-import { useQuery } from "@tanstack/react-query";
+import { useQuery, useQueryClient } from "@tanstack/react-query";
 import { Button } from "@/components/ui/button";
 import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
 import { Checkbox } from "@/components/ui/checkbox";
@@ -25,6 +25,7 @@ import {
 } from "@/components/ui/table";
 import { Skeleton } from "@/components/ui/skeleton";
 import { AlertCircle, Download, Trash2, RefreshCw } from "lucide-react";
+import { Input } from "@/components/ui/input";
 
 interface FileData {
   id: string;
@@ -35,14 +36,13 @@ interface FileData {
   updatedAt: string;
 }
 
-interface FilesTableProps {
-  onFileAdded?: (file: FileData) => void;
-}
-
-export function FilesTable({}: FilesTableProps) {
+export function FilesTable() {
   const [sorting, setSorting] = useState<SortingState>([]);
   const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
   const [files, setFiles] = useState<FileData[]>([]);
+  const [isUploading, setIsUploading] = useState(false);
+  const [uploadProgress, setUploadProgress] = useState(0);
+  const queryClient = useQueryClient();
 
   const { data, isLoading, isError, error, refetch } = useQuery({
     queryKey: ["files"],
@@ -184,6 +184,45 @@ export function FilesTable({}: FilesTableProps) {
     enableRowSelection: true,
   });
 
+  const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
+    const file = event.target.files?.[0];
+    if (!file) return;
+
+    setIsUploading(true);
+    setUploadProgress(0);
+
+    const formData = new FormData();
+    formData.append("file", file);
+
+    try {
+      const response = await fetch("/api/upload", {
+        method: "POST",
+        body: formData,
+      });
+
+      const result = await response.json();
+      
+      if (result.success) {
+        // Add new file to the beginning of the list
+        setFiles(prevFiles => [result.file, ...prevFiles]);
+        
+        // Invalidate and refetch to ensure consistency
+        await queryClient.invalidateQueries({ queryKey: ["files"] });
+        
+        // Reset file input
+        event.target.value = '';
+      } else {
+        alert(`Upload failed: ${result.error || 'Unknown error'}`);
+      }
+    } catch (error) {
+      console.error("Upload error:", error);
+      alert("Failed to upload file");
+    } finally {
+      setIsUploading(false);
+      setUploadProgress(0);
+    }
+  };
+
   const handleRefresh = () => {
     refetch();
   };
@@ -344,6 +383,17 @@ export function FilesTable({}: FilesTableProps) {
         <div className="flex justify-between items-center">
           <CardTitle>Files in Database</CardTitle>
           <div className="flex gap-2">
+            <div className="flex items-center gap-2">
+              <Input
+                type="file"
+                onChange={handleFileUpload}
+                disabled={isUploading}
+                className="w-64 text-sm"
+              />
+              {isUploading && (
+                <span className="text-sm text-muted-foreground">Uploading...</span>
+              )}
+            </div>
             <Button
               onClick={handleDownloadSelected}
               disabled={table.getSelectedRowModel().rows.length === 0 || isLoading}
@@ -419,7 +469,7 @@ export function FilesTable({}: FilesTableProps) {
 
         <div className="flex items-center justify-between mt-4">
           <div className="text-sm text-muted-foreground">
-            {table.getRowModel().rows.length} of {files.length} row(s) selected
+            {table.getSelectedRowModel().rows.length} of {files.length} row(s) selected
           </div>
           <div className="flex gap-2">
             <Button

+ 2 - 27
app/files/page.tsx

@@ -1,26 +1,6 @@
-"use client";
-
-import { UploadForm } from "../components/uploadForm";
 import { FilesTable } from "../components/filesTable";
-import { useState } from "react";
-
-interface FileData {
-  id: string;
-  filename: string;
-  mimetype: string;
-  size: number;
-  createdAt: string;
-  updatedAt: string;
-}
 
 export default function FilesPage() {
-  const [, setNewFile] = useState<FileData | null>(null);
-
-  const handleFileUploaded = (file: FileData) => {
-    // This will trigger the FilesTable to add the new file
-    setNewFile(file);
-  };
-
   return (
     <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
       <main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
@@ -30,17 +10,12 @@ export default function FilesPage() {
         </h1>
         
         <p className="text-sm text-center sm:text-left max-w-[600px]">
-          Upload and manage your media files here. Select files to upload them to the server.
+          Upload and manage your media files here. Use the upload button in the table header to add new files.
         </p>
 
-        <div className="flex flex-col gap-4 items-center sm:items-start">
-          <h2 className="text-xl font-semibold">Upload Files</h2>
-          <UploadForm onFileUploaded={handleFileUploaded} />
-        </div>
-
         <div className="w-full max-w-6xl">
           <h2 className="text-2xl font-semibold mb-4">Files in Database</h2>
-          <FilesTable onFileAdded={handleFileUploaded} />
+          <FilesTable />
         </div>
       </main>
     </div>