'use client'; import { useState, useEffect, useCallback } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { format } from 'date-fns'; import { useToast } from '@/hooks/use-toast'; import { getImportById, triggerImportProcess, getImportProgress } from '@/app/actions/imports'; interface ImportDetail { id: number; name: string; importDate: Date; layout: { id: number; name: string; sections: Array<{ id: number; 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; }>; }>; }; file?: { id: string; filename: string; mimetype: string; size: number; data: Uint8Array; userId: string | null; createdAt: Date; updatedAt: Date; } | null; } interface ImportDetailDialogProps { open: boolean; onOpenChange: (open: boolean) => void; importId: number; } export function ImportDetailDialog({ open, onOpenChange, importId }: ImportDetailDialogProps) { const [importDetail, setImportDetail] = useState(null); const [loading, setLoading] = useState(true); const [processing, setProcessing] = useState(false); const [importStatus, setImportStatus] = useState<'idle' | 'processing' | 'completed' | 'failed'>('idle'); const [progress, setProgress] = useState(0); const [processedRecords, setProcessedRecords] = useState(0); const [totalRecords, setTotalRecords] = useState(0); const { toast } = useToast(); const loadImportDetail = useCallback(async () => { try { const result = await getImportById(importId); if (result.success && result.data) { setImportDetail(result.data); } else { toast({ title: 'Error', description: result.error || 'Failed to load import details', variant: 'destructive', }); setImportDetail(null); } } catch { toast({ title: 'Error', description: 'Failed to load import details', variant: 'destructive', }); setImportDetail(null); } finally { setLoading(false); } }, [importId, toast]); useEffect(() => { if (open && importId) { loadImportDetail(); } }, [open, importId, loadImportDetail]); async function handleTriggerImport() { if (!importDetail?.file) { toast({ title: 'Error', description: 'No file attached to this import', variant: 'destructive', }); return; } setProcessing(true); setImportStatus('processing'); setProgress(0); setProcessedRecords(0); setTotalRecords(0); try { console.log('[IMPORT_DIALOG] 🚀 Starting import for ID:', importId); const result = await triggerImportProcess(importId); console.log('[IMPORT_DIALOG] 📊 triggerImportProcess result:', result); if (result.success) { toast({ title: 'Success', description: result.message || 'Import process started successfully', }); console.log('[IMPORT_DIALOG] 🔄 Starting poll for import progress...'); // Poll for import progress until completion const pollInterval = setInterval(async () => { try { const progressResult = await getImportProgress(importId); console.log('[IMPORT_DIALOG] 📈 Progress result:', progressResult); if (progressResult.success && progressResult.data) { const { status, progress: prog, processedRecords: procRecs, totalRecords: totRecs, errorMessage } = progressResult.data; // Update progress display setProgress(prog); setProcessedRecords(procRecs); setTotalRecords(totRecs); setImportStatus(status as 'idle' | 'processing' | 'completed' | 'failed'); if (status === 'completed') { console.log('[IMPORT_DIALOG] ✅ Import completed!'); clearInterval(pollInterval); setProcessing(false); setImportStatus('completed'); toast({ title: 'Import Complete', description: `Successfully imported ${totRecs} records`, }); loadImportDetail(); } else if (status === 'failed') { console.error('[IMPORT_DIALOG] ❌ Import failed:', errorMessage); clearInterval(pollInterval); setProcessing(false); setImportStatus('failed'); toast({ title: 'Import Failed', description: errorMessage || 'Import processing failed', variant: 'destructive', }); } else { console.log('[IMPORT_DIALOG] ⏳ Import status:', status, { procRecs, totRecs }); } } } catch (error) { console.error('[IMPORT_DIALOG] ❌ Error polling import progress:', error); clearInterval(pollInterval); setProcessing(false); setImportStatus('failed'); } }, 1000); // Poll every second } else { console.error('[IMPORT_DIALOG] ❌ triggerImportProcess failed:', result.error); toast({ title: 'Error', description: result.error || 'Failed to start import process', variant: 'destructive', }); setProcessing(false); setImportStatus('failed'); } } catch { console.error('[IMPORT_DIALOG] ❌ Exception in handleTriggerImport'); toast({ title: 'Error', description: 'Failed to trigger import process', variant: 'destructive', }); setProcessing(false); setImportStatus('failed'); } } if (loading) { return ( Loading Import Details Please wait while we load the import information...
); } if (!importDetail) return null; return ( Import Details View detailed information about this import
Import Information
Name: {importDetail.name}
Layout: {importDetail.layout.name}
Import Date: {format(importDetail.importDate, 'PPpp')}
{importDetail.file && (
File: {importDetail.file.filename}
)}
Layout Configuration
{importDetail.layout.sections.map((section) => (

{section.name}

Table: {section.tableName}

{section.fields.map((field) => (
{field.name}: {field.importTableColumnName}
))}
))}
Import Actions
{importStatus === 'processing' && (
Import is currently processing...
Progress: {processedRecords} / {totalRecords} records ({progress}%)
)} {importStatus === 'completed' && (
Import completed successfully!
)} {importStatus === 'failed' && (
Import failed. Please check the logs for details.
)} {!importDetail.file && (
No file attached. Please upload a file before starting import.
)}
); }