|
@@ -123,109 +123,120 @@ export default function ImportsPage() {
|
|
|
|
|
|
|
|
if (loading) {
|
|
if (loading) {
|
|
|
return (
|
|
return (
|
|
|
- <div className="container mx-auto py-8">
|
|
|
|
|
- <div className="flex justify-center">
|
|
|
|
|
- <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
|
|
|
|
|
|
+ <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
|
|
|
|
|
+ <div className="container mx-auto px-4 py-8">
|
|
|
|
|
+ <div className="flex justify-center">
|
|
|
|
|
+ <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
- <div className="container mx-auto py-8">
|
|
|
|
|
- <div className="flex justify-between items-center mb-6">
|
|
|
|
|
- <div>
|
|
|
|
|
- <h1 className="text-3xl font-bold">Import Management</h1>
|
|
|
|
|
- <p className="text-muted-foreground">Manage your data imports and configurations</p>
|
|
|
|
|
|
|
+ <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
|
|
|
|
|
+ <div className="container mx-auto px-4 py-8">
|
|
|
|
|
+ <div className="flex justify-between items-center mb-8">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <h1 className="text-3xl font-bold text-gray-900 dark:text-white">
|
|
|
|
|
+ Import Management
|
|
|
|
|
+ </h1>
|
|
|
|
|
+ <p className="text-gray-600 dark:text-gray-300">
|
|
|
|
|
+ Manage your data imports and configurations
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <Button onClick={() => setCreateDialogOpen(true)}>
|
|
|
|
|
+ <Plus className="mr-2 h-4 w-4" />
|
|
|
|
|
+ Create Import
|
|
|
|
|
+ </Button>
|
|
|
</div>
|
|
</div>
|
|
|
- <Button onClick={() => setCreateDialogOpen(true)}>
|
|
|
|
|
- <Plus className="mr-2 h-4 w-4" />
|
|
|
|
|
- Create Import
|
|
|
|
|
- </Button>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
|
|
|
- {imports.length === 0 ? (
|
|
|
|
|
- <Card>
|
|
|
|
|
- <CardContent className="flex flex-col items-center justify-center py-12">
|
|
|
|
|
- <FileText className="h-12 w-12 text-muted-foreground mb-4" />
|
|
|
|
|
- <h3 className="text-lg font-semibold mb-2">No imports yet</h3>
|
|
|
|
|
- <p className="text-muted-foreground mb-4">
|
|
|
|
|
- Get started by creating your first import
|
|
|
|
|
- </p>
|
|
|
|
|
- <Button onClick={() => setCreateDialogOpen(true)}>
|
|
|
|
|
- <Plus className="mr-2 h-4 w-4" />
|
|
|
|
|
- Create Import
|
|
|
|
|
- </Button>
|
|
|
|
|
- </CardContent>
|
|
|
|
|
- </Card>
|
|
|
|
|
- ) : (
|
|
|
|
|
- <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
|
|
|
- {imports.map((importRecord) => (
|
|
|
|
|
- <Card key={importRecord.id} className="hover:shadow-lg transition-shadow">
|
|
|
|
|
- <CardHeader>
|
|
|
|
|
- <div className="flex justify-between items-start">
|
|
|
|
|
- <div>
|
|
|
|
|
- <CardTitle className="text-lg">{importRecord.name}</CardTitle>
|
|
|
|
|
- <CardDescription>
|
|
|
|
|
- Layout: {importRecord.layout.name}
|
|
|
|
|
- </CardDescription>
|
|
|
|
|
|
|
+ {imports.length === 0 ? (
|
|
|
|
|
+ <Card className="dark:bg-gray-800 dark:border-gray-700">
|
|
|
|
|
+ <CardContent className="flex flex-col items-center justify-center py-12">
|
|
|
|
|
+ <FileText className="h-12 w-12 text-muted-foreground mb-4" />
|
|
|
|
|
+ <h3 className="text-lg font-semibold mb-2 text-gray-900 dark:text-white">No imports yet</h3>
|
|
|
|
|
+ <p className="text-muted-foreground mb-4 dark:text-gray-300">
|
|
|
|
|
+ Get started by creating your first import
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <Button onClick={() => setCreateDialogOpen(true)}>
|
|
|
|
|
+ <Plus className="mr-2 h-4 w-4" />
|
|
|
|
|
+ Create Import
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </CardContent>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
|
|
|
+ {imports.map((importRecord) => (
|
|
|
|
|
+ <Card key={importRecord.id} className="hover:shadow-lg transition-shadow dark:bg-gray-800 dark:border-gray-700">
|
|
|
|
|
+ <CardHeader>
|
|
|
|
|
+ <div className="flex justify-between items-start">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <CardTitle className="text-lg text-gray-900 dark:text-white">{importRecord.name}</CardTitle>
|
|
|
|
|
+ <CardDescription className="dark:text-gray-300">
|
|
|
|
|
+ Layout: {importRecord.layout.name}
|
|
|
|
|
+ </CardDescription>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <Badge variant="outline" className="dark:border-gray-600 dark:text-gray-300">
|
|
|
|
|
+ <Calendar className="mr-1 h-3 w-3" />
|
|
|
|
|
+ {format(new Date(importRecord.importDate), 'MMM d, yyyy')}
|
|
|
|
|
+ </Badge>
|
|
|
</div>
|
|
</div>
|
|
|
- <Badge variant="outline">
|
|
|
|
|
- <Calendar className="mr-1 h-3 w-3" />
|
|
|
|
|
- {format(new Date(importRecord.importDate), 'MMM d, yyyy')}
|
|
|
|
|
- </Badge>
|
|
|
|
|
- </div>
|
|
|
|
|
- </CardHeader>
|
|
|
|
|
- <CardContent>
|
|
|
|
|
- <div className="flex justify-between items-center">
|
|
|
|
|
- <div className="flex gap-2">
|
|
|
|
|
- <Button
|
|
|
|
|
- variant="ghost"
|
|
|
|
|
- size="sm"
|
|
|
|
|
- onClick={() => handleViewImport(importRecord)}
|
|
|
|
|
- >
|
|
|
|
|
- <FileText className="h-4 w-4" />
|
|
|
|
|
- </Button>
|
|
|
|
|
- <Button
|
|
|
|
|
- variant="ghost"
|
|
|
|
|
- size="sm"
|
|
|
|
|
- onClick={() => handleEditImport(importRecord)}
|
|
|
|
|
- >
|
|
|
|
|
- <Edit className="h-4 w-4" />
|
|
|
|
|
- </Button>
|
|
|
|
|
- <Button
|
|
|
|
|
- variant="ghost"
|
|
|
|
|
- size="sm"
|
|
|
|
|
- onClick={() => handleDeleteImport(importRecord.id)}
|
|
|
|
|
- >
|
|
|
|
|
- <Trash2 className="h-4 w-4" />
|
|
|
|
|
- </Button>
|
|
|
|
|
|
|
+ </CardHeader>
|
|
|
|
|
+ <CardContent>
|
|
|
|
|
+ <div className="flex justify-between items-center">
|
|
|
|
|
+ <div className="flex gap-2">
|
|
|
|
|
+ <Button
|
|
|
|
|
+ variant="ghost"
|
|
|
|
|
+ size="sm"
|
|
|
|
|
+ onClick={() => handleViewImport(importRecord)}
|
|
|
|
|
+ className="dark:hover:bg-gray-700"
|
|
|
|
|
+ >
|
|
|
|
|
+ <FileText className="h-4 w-4" />
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ variant="ghost"
|
|
|
|
|
+ size="sm"
|
|
|
|
|
+ onClick={() => handleEditImport(importRecord)}
|
|
|
|
|
+ className="dark:hover:bg-gray-700"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Edit className="h-4 w-4" />
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ variant="ghost"
|
|
|
|
|
+ size="sm"
|
|
|
|
|
+ onClick={() => handleDeleteImport(importRecord.id)}
|
|
|
|
|
+ className="dark:hover:bg-gray-700"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Trash2 className="h-4 w-4" />
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
- </CardContent>
|
|
|
|
|
- </Card>
|
|
|
|
|
- ))}
|
|
|
|
|
- </div>
|
|
|
|
|
- )}
|
|
|
|
|
-
|
|
|
|
|
- <CreateImportDialog
|
|
|
|
|
- open={createDialogOpen}
|
|
|
|
|
- onOpenChange={setCreateDialogOpen}
|
|
|
|
|
- onSuccess={loadImports}
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <EditImportDialog
|
|
|
|
|
- open={editDialogOpen}
|
|
|
|
|
- onOpenChange={setEditDialogOpen}
|
|
|
|
|
- importRecord={selectedImport}
|
|
|
|
|
- onSuccess={loadImports}
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <ImportDetailDialog
|
|
|
|
|
- open={detailDialogOpen}
|
|
|
|
|
- onOpenChange={setDetailDialogOpen}
|
|
|
|
|
- importId={selectedImport?.id || 0}
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ </CardContent>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+
|
|
|
|
|
+ <CreateImportDialog
|
|
|
|
|
+ open={createDialogOpen}
|
|
|
|
|
+ onOpenChange={setCreateDialogOpen}
|
|
|
|
|
+ onSuccess={loadImports}
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <EditImportDialog
|
|
|
|
|
+ open={editDialogOpen}
|
|
|
|
|
+ onOpenChange={setEditDialogOpen}
|
|
|
|
|
+ importRecord={selectedImport}
|
|
|
|
|
+ onSuccess={loadImports}
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <ImportDetailDialog
|
|
|
|
|
+ open={detailDialogOpen}
|
|
|
|
|
+ onOpenChange={setDetailDialogOpen}
|
|
|
|
|
+ importId={selectedImport?.id || 0}
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|