|
@@ -8,6 +8,7 @@ import { Label } from '@/components/ui/label';
|
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
|
|
import { useToast } from '@/hooks/use-toast';
|
|
import { useToast } from '@/hooks/use-toast';
|
|
|
import { createImport, getLayoutConfigurations } from '@/app/actions/imports';
|
|
import { createImport, getLayoutConfigurations } from '@/app/actions/imports';
|
|
|
|
|
+import { uploadFile } from '@/app/actions/file-upload';
|
|
|
|
|
|
|
|
interface LayoutConfiguration {
|
|
interface LayoutConfiguration {
|
|
|
id: number;
|
|
id: number;
|
|
@@ -23,6 +24,7 @@ interface CreateImportDialogProps {
|
|
|
export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImportDialogProps) {
|
|
export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImportDialogProps) {
|
|
|
const [name, setName] = useState('');
|
|
const [name, setName] = useState('');
|
|
|
const [layoutId, setLayoutId] = useState<string>('');
|
|
const [layoutId, setLayoutId] = useState<string>('');
|
|
|
|
|
+ const [selectedFile, setSelectedFile] = useState<File | null>(null);
|
|
|
const [loading, setLoading] = useState(false);
|
|
const [loading, setLoading] = useState(false);
|
|
|
const [layouts, setLayouts] = useState<LayoutConfiguration[]>([]);
|
|
const [layouts, setLayouts] = useState<LayoutConfiguration[]>([]);
|
|
|
const [loadingLayouts, setLoadingLayouts] = useState(true);
|
|
const [loadingLayouts, setLoadingLayouts] = useState(true);
|
|
@@ -51,9 +53,29 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
|
|
|
}
|
|
}
|
|
|
}, [open, toast]);
|
|
}, [open, toast]);
|
|
|
|
|
|
|
|
|
|
+ const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
+ const file = e.target.files?.[0];
|
|
|
|
|
+ if (file) {
|
|
|
|
|
+ setSelectedFile(file);
|
|
|
|
|
+ // Auto-fill name from filename if empty
|
|
|
|
|
+ if (!name.trim()) {
|
|
|
|
|
+ setName(file.name.replace(/\.[^/.]+$/, ''));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
async function handleSubmit(e: React.FormEvent) {
|
|
async function handleSubmit(e: React.FormEvent) {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
|
|
+ if (!selectedFile) {
|
|
|
|
|
+ toast({
|
|
|
|
|
+ title: 'Error',
|
|
|
|
|
+ description: 'Please select a file to upload',
|
|
|
|
|
+ variant: 'destructive',
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (!name.trim()) {
|
|
if (!name.trim()) {
|
|
|
toast({
|
|
toast({
|
|
|
title: 'Error',
|
|
title: 'Error',
|
|
@@ -75,9 +97,22 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
|
|
|
setLoading(true);
|
|
setLoading(true);
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
|
|
+ // First, upload the file
|
|
|
|
|
+ const uploadResult = await uploadFile(selectedFile);
|
|
|
|
|
+ if (!uploadResult.success) {
|
|
|
|
|
+ toast({
|
|
|
|
|
+ title: 'Error',
|
|
|
|
|
+ description: uploadResult.error || 'Failed to upload file',
|
|
|
|
|
+ variant: 'destructive',
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Then create the import with the file reference
|
|
|
const result = await createImport({
|
|
const result = await createImport({
|
|
|
name: name.trim(),
|
|
name: name.trim(),
|
|
|
layoutId: parseInt(layoutId),
|
|
layoutId: parseInt(layoutId),
|
|
|
|
|
+ fileId: uploadResult.data?.id,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
if (result.success) {
|
|
if (result.success) {
|
|
@@ -87,6 +122,7 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
|
|
|
});
|
|
});
|
|
|
setName('');
|
|
setName('');
|
|
|
setLayoutId('');
|
|
setLayoutId('');
|
|
|
|
|
+ setSelectedFile(null);
|
|
|
onOpenChange(false);
|
|
onOpenChange(false);
|
|
|
onSuccess?.();
|
|
onSuccess?.();
|
|
|
} else {
|
|
} else {
|
|
@@ -109,15 +145,30 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
|
- <DialogContent className="sm:max-w-[425px]">
|
|
|
|
|
|
|
+ <DialogContent className="sm:max-w-[500px]">
|
|
|
<DialogHeader>
|
|
<DialogHeader>
|
|
|
<DialogTitle>Create New Import</DialogTitle>
|
|
<DialogTitle>Create New Import</DialogTitle>
|
|
|
<DialogDescription>
|
|
<DialogDescription>
|
|
|
- Create a new import with a layout configuration and file name.
|
|
|
|
|
|
|
+ Upload a file and create a new import with a layout configuration.
|
|
|
</DialogDescription>
|
|
</DialogDescription>
|
|
|
</DialogHeader>
|
|
</DialogHeader>
|
|
|
<form onSubmit={handleSubmit}>
|
|
<form onSubmit={handleSubmit}>
|
|
|
<div className="grid gap-4 py-4">
|
|
<div className="grid gap-4 py-4">
|
|
|
|
|
+ <div className="grid gap-2">
|
|
|
|
|
+ <Label htmlFor="file">Upload File</Label>
|
|
|
|
|
+ <Input
|
|
|
|
|
+ id="file"
|
|
|
|
|
+ type="file"
|
|
|
|
|
+ onChange={handleFileChange}
|
|
|
|
|
+ accept=".csv,.xlsx,.xls"
|
|
|
|
|
+ disabled={loading}
|
|
|
|
|
+ />
|
|
|
|
|
+ {selectedFile && (
|
|
|
|
|
+ <p className="text-sm text-muted-foreground">
|
|
|
|
|
+ Selected: {selectedFile.name} ({(selectedFile.size / 1024 / 1024).toFixed(2)} MB)
|
|
|
|
|
+ </p>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
<div className="grid gap-2">
|
|
<div className="grid gap-2">
|
|
|
<Label htmlFor="name">Import Name</Label>
|
|
<Label htmlFor="name">Import Name</Label>
|
|
|
<Input
|
|
<Input
|
|
@@ -148,7 +199,10 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
|
|
|
<Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={loading}>
|
|
<Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={loading}>
|
|
|
Cancel
|
|
Cancel
|
|
|
</Button>
|
|
</Button>
|
|
|
- <Button type="submit" disabled={loading || !name || !layoutId}>
|
|
|
|
|
|
|
+ <Button
|
|
|
|
|
+ type="submit"
|
|
|
|
|
+ disabled={loading || !selectedFile || !name || !layoutId}
|
|
|
|
|
+ >
|
|
|
{loading ? 'Creating...' : 'Create Import'}
|
|
{loading ? 'Creating...' : 'Create Import'}
|
|
|
</Button>
|
|
</Button>
|
|
|
</DialogFooter>
|
|
</DialogFooter>
|