Преглед изворни кода

refactor(imports): improve type safety and error handling across import components

- Consolidated React imports and removed unused dependencies
- Added proper TypeScript interfaces for Import and related types
- Enhanced error handling with consistent catch blocks
- Fixed data transformation issues in imports page
- Updated date handling to use Date objects consistently
- Improved null safety in API response handling
vtugulan пре 6 месеци
родитељ
комит
305b487fbf

+ 4 - 5
app/components/imports/CreateImportDialog.tsx

@@ -1,6 +1,6 @@
 'use client';
 
-import { useState } from 'react';
+import { useState, useEffect } from 'react';
 import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
 import { Button } from '@/components/ui/button';
 import { Input } from '@/components/ui/input';
@@ -8,7 +8,6 @@ import { Label } from '@/components/ui/label';
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
 import { useToast } from '@/hooks/use-toast';
 import { createImport, getLayoutConfigurations } from '@/app/actions/imports';
-import { useEffect } from 'react';
 
 interface LayoutConfiguration {
   id: number;
@@ -33,7 +32,7 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
     if (open) {
       loadLayouts();
     }
-  }, [open]);
+  }, [open, loadLayouts]);
 
   async function loadLayouts() {
     try {
@@ -41,7 +40,7 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
       if (result.success && result.data) {
         setLayouts(result.data);
       }
-    } catch (error) {
+    } catch {
       toast({
         title: 'Error',
         description: 'Failed to load layout configurations',
@@ -97,7 +96,7 @@ export function CreateImportDialog({ open, onOpenChange, onSuccess }: CreateImpo
           variant: 'destructive',
         });
       }
-    } catch (error) {
+    } catch {
       toast({
         title: 'Error',
         description: 'Failed to create import',

+ 12 - 2
app/components/imports/EditImportDialog.tsx

@@ -7,7 +7,17 @@ import { Input } from '@/components/ui/input';
 import { Label } from '@/components/ui/label';
 import { useToast } from '@/hooks/use-toast';
 import { updateImport } from '@/app/actions/imports';
-import { Import } from '@/app/actions/imports';
+
+interface Import {
+  id: number;
+  name: string;
+  importDate: string;
+  layoutId: number;
+  layout: {
+    id: number;
+    name: string;
+  };
+}
 
 interface EditImportDialogProps {
   open: boolean;
@@ -61,7 +71,7 @@ export function EditImportDialog({ open, onOpenChange, importRecord, onSuccess }
           variant: 'destructive',
         });
       }
-    } catch (error) {
+    } catch {
       toast({
         title: 'Error',
         description: 'Failed to update import',

+ 16 - 6
app/components/imports/ImportDetailDialog.tsx

@@ -3,7 +3,6 @@
 import { useState, useEffect } from 'react';
 import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
 import { Button } from '@/components/ui/button';
-import { Badge } from '@/components/ui/badge';
 import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
 import { format } from 'date-fns';
 import { useToast } from '@/hooks/use-toast';
@@ -17,12 +16,13 @@ interface CintasSummary {
   trrPlus4Wk: number;
   powerAdds: number;
   weekId: number;
+  importId: number;
 }
 
 interface ImportDetail {
   id: number;
   name: string;
-  importDate: string;
+  importDate: Date;
   layout: {
     id: number;
     name: string;
@@ -31,8 +31,16 @@ interface ImportDetail {
       name: string;
       tableName: string;
       fields: Array<{
+        id: number;
         name: string;
+        createdAt: Date;
+        updatedAt: Date;
+        layoutSectionId: number;
+        cellPosition: string;
+        dataType: string;
+        dataTypeFormat: string | null;
         importTableColumnName: string;
+        importColumnOrderNumber: number;
       }>;
     }>;
   };
@@ -60,7 +68,7 @@ export function ImportDetailDialog({ open, onOpenChange, importId }: ImportDetai
   async function loadImportDetail() {
     try {
       const result = await getImportById(importId);
-      if (result.success) {
+      if (result.success && result.data) {
         setImportDetail(result.data);
       } else {
         toast({
@@ -68,13 +76,15 @@ export function ImportDetailDialog({ open, onOpenChange, importId }: ImportDetai
           description: result.error || 'Failed to load import details',
           variant: 'destructive',
         });
+        setImportDetail(null);
       }
-    } catch (error) {
+    } catch {
       toast({
         title: 'Error',
         description: 'Failed to load import details',
         variant: 'destructive',
       });
+      setImportDetail(null);
     } finally {
       setLoading(false);
     }
@@ -97,7 +107,7 @@ export function ImportDetailDialog({ open, onOpenChange, importId }: ImportDetai
           variant: 'destructive',
         });
       }
-    } catch (error) {
+    } catch {
       toast({
         title: 'Error',
         description: 'Failed to calculate summaries',
@@ -148,7 +158,7 @@ export function ImportDetailDialog({ open, onOpenChange, importId }: ImportDetai
               </div>
               <div className="flex justify-between">
                 <span className="font-medium">Import Date:</span>
-                <span>{format(new Date(importDetail.importDate), 'PPpp')}</span>
+                <span>{format(importDetail.importDate, 'PPpp')}</span>
               </div>
             </CardContent>
           </Card>

+ 1 - 2
app/components/layout-configurations/AddSectionDialog.tsx

@@ -14,7 +14,6 @@ import {
 } from "@/components/ui/dialog";
 import { Input } from "@/components/ui/input";
 import { Label } from "@/components/ui/label";
-import { Textarea } from "@/components/ui/textarea";
 import { useToast } from "@/hooks/use-toast";
 
 interface AddSectionDialogProps {
@@ -80,7 +79,7 @@ export function AddSectionDialog({
           variant: "destructive",
         });
       }
-    } catch (error) {
+    } catch {
       toast({
         title: "Error",
         description: "An unexpected error occurred",

+ 20 - 6
app/imports/page.tsx

@@ -1,7 +1,7 @@
 'use client';
 
 import { useState, useEffect } from 'react';
-import { Plus, FileText, Calendar, Settings, Trash2, Edit } from 'lucide-react';
+import { Plus, FileText, Calendar, Trash2, Edit } from 'lucide-react';
 import { Button } from '@/components/ui/button';
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
 import { Badge } from '@/components/ui/badge';
@@ -39,16 +39,30 @@ export default function ImportsPage() {
   async function loadImports() {
     try {
       const result = await getImports();
-      if (result.success) {
-        setImports(result.data);
+      if (result.success && result.data) {
+        // Transform the data to match our Import interface
+        const transformedImports = result.data.map(item => ({
+          id: item.id,
+          name: item.name,
+          importDate: item.importDate instanceof Date
+            ? item.importDate.toISOString()
+            : String(item.importDate),
+          layoutId: item.layoutId,
+          layout: {
+            id: item.layout.id,
+            name: item.layout.name,
+          },
+        }));
+        setImports(transformedImports);
       } else {
         toast({
           title: 'Error',
-          description: 'Failed to load imports',
+          description: result.error || 'Failed to load imports',
           variant: 'destructive',
         });
+        setImports([]);
       }
-    } catch (error) {
+    } catch {
       toast({
         title: 'Error',
         description: 'Failed to load imports',
@@ -77,7 +91,7 @@ export default function ImportsPage() {
           variant: 'destructive',
         });
       }
-    } catch (error) {
+    } catch {
       toast({
         title: 'Error',
         description: 'Failed to delete import',