mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 01:40:01 +00:00
183fe0a93c
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
149 lines
5.4 KiB
React
149 lines
5.4 KiB
React
import React, { useState, useEffect } from 'react';
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
|
|
import { Button } from '@/components/ui/button';
|
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
import { Loader2, AlertTriangle, CheckCircle, RotateCcw } from 'lucide-react';
|
|
import { useAuth } from '@/contexts/AuthContext';
|
|
import { useToast } from '@/hooks/use-toast';
|
|
|
|
export function CallLogRestoreDialog({ open, onOpenChange, onSuccess }) {
|
|
const { user } = useAuth();
|
|
const { toast } = useToast();
|
|
|
|
const [step, setStep] = useState('analyze');
|
|
const [analysis, setAnalysis] = useState(null);
|
|
const [loading, setLoading] = useState(false);
|
|
const [result, setResult] = useState(null);
|
|
|
|
useEffect(() => {
|
|
if (open && step === 'analyze') {
|
|
performAnalysis();
|
|
}
|
|
}, [open]);
|
|
|
|
const performAnalysis = async () => {
|
|
setLoading(true);
|
|
try {
|
|
// Placeholder: In production, use fetchCallLogsForRestoration
|
|
setAnalysis({ count: 0, records: [], issues: [] });
|
|
setStep('review');
|
|
} catch (err) {
|
|
toast({ variant: "destructive", title: "Analysis Failed", description: err.message });
|
|
onOpenChange(false);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleRestore = async () => {
|
|
if (!analysis) return;
|
|
setStep('restoring');
|
|
|
|
try {
|
|
// Placeholder: In production, use restoreCallLogs
|
|
const res = { successCount: analysis.records.length, errors: [] };
|
|
setResult(res);
|
|
setStep('result');
|
|
if (onSuccess) onSuccess();
|
|
} catch (err) {
|
|
toast({ variant: "destructive", title: "Restoration Failed", description: err.message });
|
|
setStep('review');
|
|
}
|
|
};
|
|
|
|
const handleClose = () => {
|
|
setStep('analyze');
|
|
setAnalysis(null);
|
|
setResult(null);
|
|
onOpenChange(false);
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={handleClose}>
|
|
<DialogContent className="sm:max-w-[600px]">
|
|
<DialogHeader>
|
|
<DialogTitle className="flex items-center gap-2">
|
|
<RotateCcw className="w-5 h-5 text-amber-600" />
|
|
Call Log Restoration
|
|
</DialogTitle>
|
|
<DialogDescription>
|
|
Scan and verify integrity of recent call logs.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="py-4">
|
|
{step === 'analyze' && (
|
|
<div className="flex flex-col items-center justify-center py-8">
|
|
<Loader2 className="w-8 h-8 animate-spin text-blue-600 mb-4" />
|
|
<p className="text-sm text-slate-500">Scanning call logs...</p>
|
|
</div>
|
|
)}
|
|
|
|
{step === 'review' && analysis && (
|
|
<div className="space-y-4">
|
|
<div className="bg-amber-50 border border-amber-200 rounded-lg p-4 flex items-start gap-3">
|
|
<AlertTriangle className="w-5 h-5 text-amber-600 shrink-0 mt-0.5" />
|
|
<div>
|
|
<h4 className="font-medium text-amber-900 text-sm">Review Findings</h4>
|
|
<p className="text-sm text-amber-800 mt-1">
|
|
Found <strong>{analysis.count}</strong> recent call logs.
|
|
{analysis.issues.length > 0
|
|
? ` Detected ${analysis.issues.length} potential integrity issues.`
|
|
: " No critical issues detected."}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="text-sm text-slate-600">
|
|
Proceeding will attempt to correct any metadata issues and verify record consistency.
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{step === 'restoring' && (
|
|
<div className="flex flex-col items-center justify-center py-8">
|
|
<Loader2 className="w-8 h-8 animate-spin text-green-600 mb-4" />
|
|
<p className="text-sm text-slate-500">Processing records...</p>
|
|
</div>
|
|
)}
|
|
|
|
{step === 'result' && result && (
|
|
<div className="space-y-4">
|
|
<div className="bg-green-50 border border-green-200 rounded-lg p-4 flex items-start gap-3">
|
|
<CheckCircle className="w-5 h-5 text-green-600 shrink-0 mt-0.5" />
|
|
<div>
|
|
<h4 className="font-medium text-green-900 text-sm">Process Complete</h4>
|
|
<p className="text-sm text-green-800 mt-1">
|
|
Successfully processed {result.successCount} records.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{result.errors.length > 0 && (
|
|
<ScrollArea className="h-[100px] w-full border rounded-md p-2 bg-red-50 text-xs text-red-700">
|
|
{result.errors.map((e, i) => (
|
|
<div key={i} className="mb-1">Error with ID {e.id}: {e.message}</div>
|
|
))}
|
|
</ScrollArea>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
{step === 'review' && (
|
|
<>
|
|
<Button variant="outline" onClick={handleClose}>Cancel</Button>
|
|
<Button onClick={handleRestore} className="bg-amber-600 hover:bg-amber-700 text-white">
|
|
Proceed
|
|
</Button>
|
|
</>
|
|
)}
|
|
{step === 'result' && (
|
|
<Button onClick={handleClose}>Close</Button>
|
|
)}
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
} |