'use client'; // src/app/update/[id]/update-view.tsx import { useState } from "react"; import { Box, Button, Typography, Paper, Stack, TextField, MenuItem, IconButton, Grid, Checkbox, CircularProgress, Tooltip } from "@mui/material"; import SaveIcon from "@mui/icons-material/Save"; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import AssignmentIcon from '@mui/icons-material/Assignment'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh'; import MapIcon from '@mui/icons-material/Map'; import { useRouter } from "next/navigation"; import { updateFileAction } from "./_actions"; import { getMetadataPreviewAction } from "@/app/dashboard/actions"; interface MetadataPair { key: string; value: string; selected: boolean; isPending?: boolean; } /** * Utility to turn nested objects into flat key-value pairs for the UI */ const flattenObject = (obj: any, prefix = ''): Record => { let results: Record = {}; for (const key in obj) { const value = obj[key]; const newKey = prefix ? `${prefix}.${key}` : key; if (value && typeof value === 'object' && !Array.isArray(value)) { Object.assign(results, flattenObject(value, newKey)); } else { results[newKey] = String(value); } } return results; }; export default function UpdateView({ fileNode, folders: availablefolders }: { fileNode: any; folders: any[]; }) { const router = useRouter(); const [loading, setLoading] = useState(false); const [isExtracting, setIsExtracting] = useState(false); const [name, setName] = useState(fileNode.name); const [description, setDescription] = useState(fileNode.description || ""); const [parentId, setParentId] = useState(fileNode.parentId || ""); const initialMetadata: MetadataPair[] = Object.entries(fileNode.metadata || {}) .filter(([key]) => !['type', 'mimeType', 'magicFilled', 'details'].includes(key)) .map(([key, value]) => ({ key, value: String(value), selected: true, isPending: false })); const [customMetadata, setCustomMetadata] = useState(initialMetadata); const handleMagicEnhance = async () => { setIsExtracting(true); try { const result = await getMetadataPreviewAction(fileNode.id); if (result.success) { // Flatten the nested 'details' and top level props const flatData = flattenObject(result.data); const extractedRows: MetadataPair[] = Object.entries(flatData) .filter(([key]) => !['type', 'mimeType', 'title'].includes(key) && !key.includes('Binary Data')) .map(([key, value]) => ({ key, value: String(value), selected: true, isPending: true })); setCustomMetadata(prev => { const existingKeys = new Set(prev.map(r => r.key)); const filteredNew = extractedRows.filter(r => !existingKeys.has(r.key)); return [...prev, ...filteredNew]; }); } } catch (err) { alert("Failed to extract metadata."); } finally { setIsExtracting(false); } }; const handleUpdate = async () => { setLoading(true); const formData = new FormData(); formData.append("id", fileNode.id); formData.append("name", name); formData.append("description", description); formData.append("parentId", parentId); const metadataObj = customMetadata.reduce((acc, curr) => { if (curr.selected && curr.key.trim()) { acc[curr.key.trim()] = curr.value; } return acc; }, {} as Record); formData.append("customMetadata", JSON.stringify(metadataObj)); const res = await updateFileAction(formData); if (res.success) { router.push("/dashboard"); router.refresh(); } else { alert("Update failed"); setLoading(false); } }; return ( Edit File Details Enrich Metadata Extract GPS, Camera Specs, and Dimensions. setName(e.target.value)} slotProps={{ inputLabel: { shrink: true } }} /> setParentId(e.target.value)}> -- Root -- {availablefolders?.map((f: any) => ({f.name}))} Attributes {customMetadata.map((row, index) => ( { const updated = [...customMetadata]; updated[index].selected = e.target.checked; setCustomMetadata(updated); }} /> { const updated = [...customMetadata]; updated[index].key = e.target.value; setCustomMetadata(updated); }} /> { const updated = [...customMetadata]; updated[index].value = e.target.value; setCustomMetadata(updated); }} /> setCustomMetadata(customMetadata.filter((_, i) => i !== index))}> {row.key.toLowerCase().includes('latitude') && row.value && ( )} ))} setDescription(e.target.value)} /> ); }