fixed file creation bug

This commit is contained in:
stephen 2026-02-07 12:33:43 +11:00
parent 552662cf16
commit 672408081d
3 changed files with 12401 additions and 39 deletions

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -6,7 +6,7 @@ import {
TextField, IconButton, Divider,
Grid,
CircularProgress, Checkbox, MenuItem,
InputAdornment, Collapse
Collapse
} from "@mui/material";
import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh';
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
@ -26,7 +26,7 @@ interface MetadataRow {
selected?: boolean;
}
export default function UploadView({ user, folders }: { user: any; folders: any[] }) {
export default function UploadView({ folders }: { user: any; folders: any[] }) {
const router = useRouter();
const fileInputRef = useRef<HTMLInputElement>(null);
@ -50,9 +50,10 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
const result = await getMetadataPreviewAction(selectedFile.name);
if (result.success) {
// Map data from the new extractor (PDF or Image)
const extractedRows: MetadataRow[] = Object.entries(result.data ?? {}).map(([k, v]) => ({
key: k,
value: String(v),
value: typeof v === 'object' ? JSON.stringify(v) : String(v),
isPending: true,
selected: true
}));
@ -74,6 +75,8 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
const file = e.target.files?.[0];
if (file) {
setSelectedFile(file);
// Optional: Auto-run magic enhance on file selection
// handleMagicEnhance();
}
};
@ -89,8 +92,10 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
if (newFolderName.trim()) {
const folderResult = await createFolderAction(newFolderName, targetFolderId || null);
if (folderResult.success) {
// If successful, we want the file to go inside this NEW folder
// If successful, the file goes inside this NEW folder
currentParentId = folderResult.node.id;
} else {
throw new Error(folderResult.error || "Failed to create folder");
}
}
@ -117,7 +122,6 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
}
}
console.log("✅ Process complete. Returning to dashboard.");
router.push("/dashboard");
router.refresh();
} catch (err: any) {
@ -129,7 +133,7 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
};
return (
<Paper sx={{ p: { xs: 3, md: 6 }, borderRadius: 4, maxWidth: 800, mx: 'auto' }} elevation={3}>
<Paper sx={{ p: { xs: 3, md: 6 }, borderRadius: 4, maxWidth: 800, mx: 'auto', mt: 4 }} elevation={3}>
<Typography variant="h4" fontWeight={900} color="primary" gutterBottom align="center">
Upload & Enrich
</Typography>
@ -141,12 +145,10 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
<TextField
select
fullWidth
label="Destination Folder"
label="Parent Destination"
value={targetFolderId}
onChange={(e) => {
setTargetFolderId(e.target.value);
if (e.target.value) setShowNewFolderInput(false);
}}
onChange={(e) => setTargetFolderId(e.target.value)}
helperText="Choose where your file (and new folder) will live"
>
<MenuItem value=""><em>-- Root Directory --</em></MenuItem>
{folders?.map((f) => (
@ -155,23 +157,23 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
</TextField>
<Button
variant={showNewFolderInput ? "contained" : "outlined"}
onClick={() => {
setShowNewFolderInput(!showNewFolderInput);
if (!showNewFolderInput) setTargetFolderId("");
}}
onClick={() => setShowNewFolderInput(!showNewFolderInput)}
sx={{ height: 56, minWidth: 56 }}
title="Create a new sub-folder"
>
<CreateNewFolderIcon />
</Button>
</Stack>
<Collapse in={showNewFolderInput}>
<Box sx={{ mt: 2, p: 2, bgcolor: 'grey.50', borderRadius: 2 }}>
<Box sx={{ mt: 2, p: 2, bgcolor: 'grey.50', borderRadius: 2, border: '1px solid', borderColor: 'divider' }}>
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 1 }}>
NEW SUB-FOLDER NAME
</Typography>
<TextField
fullWidth
size="small"
label="New Folder Name"
placeholder="Enter name to create folder..."
placeholder="e.g. Invoices 2026"
value={newFolderName}
onChange={(e) => setNewFolderName(e.target.value)}
/>
@ -194,17 +196,17 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
fullWidth
startIcon={<CloudUploadIcon />}
onClick={() => fileInputRef.current?.click()}
sx={{ py: 4, borderStyle: 'dashed', borderWidth: 2 }}
sx={{ py: 4, borderStyle: 'dashed', borderWidth: 2, borderRadius: 2 }}
>
Select File to Upload
</Button>
) : (
<Paper variant="outlined" sx={{ p: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between', bgcolor: 'primary.50' }}>
<Paper variant="outlined" sx={{ p: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between', bgcolor: 'primary.50', borderStyle: 'solid' }}>
<Stack direction="row" spacing={2} alignItems="center">
<CloudUploadIcon color="primary" />
<Typography variant="body1" fontWeight="500">{selectedFile.name}</Typography>
<Typography variant="body1" fontWeight="600">{selectedFile.name}</Typography>
</Stack>
<IconButton onClick={() => setSelectedFile(null)} color="error">
<IconButton onClick={() => setSelectedFile(null)} color="error" size="small">
<ClearIcon />
</IconButton>
</Paper>
@ -214,35 +216,48 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
<Divider sx={{ my: 4 }} />
{/* MAGIC EXTRACT */}
<Box sx={{ mb: 4, p: 2, bgcolor: '#f0f7ff', borderRadius: 2, border: '1px dashed #1976d2' }}>
<Stack direction="row" justifyContent="space-between" alignItems="center">
{/* MAGIC EXTRACT SECTION */}
<Box sx={{ mb: 4, p: 2.5, bgcolor: '#f0f7ff', borderRadius: 2, border: '1px dashed #1976d2' }}>
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
<Box>
<Typography variant="subtitle1" fontWeight="bold">Magic Extract</Typography>
<Typography variant="caption" color="text.secondary">Populate metadata automatically from file properties.</Typography>
<Typography variant="subtitle1" fontWeight="bold" color="primary.main">
Magic Extract
</Typography>
<Typography variant="caption" color="text.secondary">
Automatically pull Author, GPS, and Camera data from the file.
</Typography>
</Box>
<Button
variant="contained"
onClick={handleMagicEnhance}
disabled={!selectedFile || isExtracting}
startIcon={isExtracting ? <CircularProgress size={20} color="inherit" /> : <AutoFixHighIcon />}
sx={{ borderRadius: 20, px: 3 }}
>
{isExtracting ? "Running..." : "Run"}
{isExtracting ? "Extracting..." : "Run"}
</Button>
</Stack>
</Box>
{/* METADATA PREVIEW */}
{/* METADATA PREVIEW GRID */}
<Box sx={{ mb: 4 }}>
<Typography variant="h6" fontWeight="700" sx={{ mb: 2, display: 'flex', alignItems: 'center', gap: 1 }}>
<AssignmentIcon color="primary" /> Metadata Preview
<AssignmentIcon color="primary" /> Metadata Fields
</Typography>
{rows.length === 0 && (
<Typography variant="body2" color="text.secondary" sx={{ fontStyle: 'italic', textAlign: 'center', py: 2 }}>
No metadata added yet. Run Magic Extract or add manual fields below.
</Typography>
)}
<Stack spacing={2}>
{rows.map((row, index) => (
<Grid container spacing={1} key={index} alignItems="center">
<Grid size={1}>
<Grid item xs={1}>
<Checkbox
checked={row.selected}
size="small"
onChange={(e) => {
const updated = [...rows];
updated[index].selected = e.target.checked;
@ -250,9 +265,9 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
}}
/>
</Grid>
<Grid size={5}>
<Grid item xs={5}>
<TextField
fullWidth size="small" label="Key" value={row.key}
fullWidth size="small" label="Property Name" value={row.key}
onChange={(e) => {
const updated = [...rows];
updated[index].key = e.target.value;
@ -260,7 +275,7 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
}}
/>
</Grid>
<Grid size={5}>
<Grid item xs={5}>
<TextField
fullWidth size="small" label="Value" value={row.value}
onChange={(e) => {
@ -270,36 +285,43 @@ export default function UploadView({ user, folders }: { user: any; folders: any[
}}
/>
</Grid>
<Grid size={1}>
<IconButton onClick={() => setRows(rows.filter((_, i) => i !== index))} color="error">
<Grid item xs={1}>
<IconButton onClick={() => setRows(rows.filter((_, i) => i !== index))} color="error" size="small">
<DeleteOutlineIcon />
</IconButton>
</Grid>
</Grid>
))}
<Button
variant="text"
startIcon={<AddCircleOutlineIcon />}
onClick={() => setRows([...rows, {key: "", value: "", selected: true}])}
sx={{ alignSelf: 'flex-start', mt: 1 }}
>
Add Manual Field
</Button>
</Stack>
</Box>
{/* UPLOAD BUTTON */}
{/* ACTION BUTTON */}
<Button
variant="contained"
size="large"
fullWidth
onClick={handleSave}
disabled={!canSubmit || saveStatus === 'saving'}
sx={{ py: 2, fontWeight: 'bold' }}
sx={{
py: 2,
fontWeight: 'bold',
borderRadius: 2,
boxShadow: 4
}}
>
{saveStatus === 'saving' ? (
<Stack direction="row" spacing={2} alignItems="center">
<CircularProgress size={24} color="inherit" />
<Typography>Processing Upload...</Typography>
<Typography>Creating Folder & Uploading...</Typography>
</Stack>
) : (
"Complete Upload & Save"