"use client"; import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ScrollArea } from "@/components/ui/scroll-area"; import { AlertTriangle, ArrowRight, Check, X } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { RenameProposal, ProposeRenameResponse, BatchRenameResponse } from "@/types"; interface RenameDialogProps { open: boolean; onOpenChange: (open: boolean) => void; albumPath: string; onRenameComplete: () => void; } export function RenameDialog({ open, onOpenChange, albumPath, onRenameComplete }: RenameDialogProps) { const [loading, setLoading] = useState(false); const [proposals, setProposals] = useState([]); const [allFiles, setAllFiles] = useState([]); const [applyToAll, setApplyToAll] = useState(true); const [maxFileLength, setMaxFileLength] = useState(0); const [selectedStrategy, setSelectedStrategy] = useState<"remove_brackets" | "remove_parens" | "remove_both" | "truncate">("remove_both"); const [renaming, setRenaming] = useState(false); useEffect(() => { if (open && albumPath) { fetchProposals(); } }, [open, albumPath]); const fetchProposals = async () => { setLoading(true); try { const res = await fetch("/api/propose-rename", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ albumPath }), }); const data = await res.json() as ProposeRenameResponse; if (data.success) { setProposals(data.problematicFiles); setAllFiles(data.allFiles || []); setMaxFileLength(data.maxFileLength); } } catch (e) { console.error("Failed to fetch proposals", e); } finally { setLoading(false); } }; const handleRename = async () => { setRenaming(true); try { const activeProposals = applyToAll ? allFiles : proposals; const renames = activeProposals.map(p => ({ original: p.original, newName: p.strategies[selectedStrategy] || p.strategies.truncate // Fallback to truncate if strategy returns null (shouldn't happen for truncate) })); const res = await fetch("/api/batch-rename", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ albumPath, renames }), }); const result = await res.json() as BatchRenameResponse; if (result.success) { onRenameComplete(); onOpenChange(false); } else { alert(`Rename failed: ${result.errors?.join(', ')}`); } } catch (e) { alert("Rename request failed"); } finally { setRenaming(false); } }; const getPreview = (proposal: RenameProposal) => { const newName = proposal.strategies[selectedStrategy]; if (!newName) return Strategy not applicable (still too long); return {newName}; }; return ( Long Filenames Detected The following files exceed the maximum allowed length ({maxFileLength} characters). Please select a renaming strategy to fix them.
setSelectedStrategy(v as "remove_brackets" | "remove_parens" | "remove_both" | "truncate")} className="flex-1 flex flex-col min-h-0"> Remove [] Remove () Remove Both Smart Truncate
{(applyToAll ? allFiles : proposals).map((p, i) => (
{p.original} {p.original.length}
{getPreview(p)} {p.strategies[selectedStrategy] && ( {p.strategies[selectedStrategy]!.length} )}
))}
); }