105 lines
5.1 KiB
TypeScript
105 lines
5.1 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { AlertTriangle, X, Check, ArrowRight } from 'lucide-react';
|
|
import { formatBytes } from '../utils/formatters';
|
|
|
|
interface ConflictModalProps {
|
|
isOpen: boolean;
|
|
sourceFile: { name: string; size: number; date: string };
|
|
targetFile: { name: string; size: number; date: string };
|
|
onOverwrite: (applyToAll: boolean) => void;
|
|
onSkip: (applyToAll: boolean) => void;
|
|
onClose: () => void; // Usually acts as cancel/skip logic if forced closed
|
|
}
|
|
|
|
const ConflictModal: React.FC<ConflictModalProps> = ({
|
|
isOpen,
|
|
sourceFile,
|
|
targetFile,
|
|
onOverwrite,
|
|
onSkip,
|
|
onClose
|
|
}) => {
|
|
const [applyToAll, setApplyToAll] = useState(false);
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
|
|
<div className="bg-white rounded-lg shadow-xl w-[500px] max-w-full m-4 flex flex-col overflow-hidden">
|
|
{/* Header */}
|
|
<div className="bg-yellow-50 px-4 py-3 border-b border-yellow-100 flex justify-between items-center">
|
|
<div className="flex items-center gap-2 text-yellow-700">
|
|
<AlertTriangle size={20} />
|
|
<h3 className="font-bold text-sm">파일 중복 확인 (File Conflict)</h3>
|
|
</div>
|
|
<button onClick={onClose} className="text-slate-400 hover:text-slate-600">
|
|
<X size={18} />
|
|
</button>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="p-6 flex flex-col gap-4">
|
|
<p className="text-slate-700 text-sm">
|
|
대상 위치에 동일한 이름의 파일이 이미 존재합니다. 어떻게 처리하시겠습니까?
|
|
</p>
|
|
|
|
<div className="bg-slate-50 border border-slate-200 rounded p-4 text-xs flex flex-col gap-3">
|
|
{/* Target (Existing) */}
|
|
<div className="flex justify-between items-center">
|
|
<div className="flex flex-col gap-1 w-1/2 pr-2 border-r border-slate-200">
|
|
<span className="font-semibold text-slate-500">기존 파일 (Target)</span>
|
|
<span className="font-medium text-slate-800 truncate" title={targetFile.name}>{targetFile.name}</span>
|
|
<div className="flex gap-2 text-slate-500">
|
|
<span>{formatBytes(targetFile.size)}</span>
|
|
<span>{new Date(targetFile.date).toLocaleString()}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Source (New) */}
|
|
<div className="flex flex-col gap-1 w-1/2 pl-2 text-right">
|
|
<span className="font-semibold text-blue-600">새 파일 (Source)</span>
|
|
<span className="font-medium text-slate-800 truncate" title={sourceFile.name}>{sourceFile.name}</span>
|
|
<div className="flex gap-2 justify-end text-slate-500">
|
|
<span>{formatBytes(sourceFile.size)}</span>
|
|
<span>{new Date(sourceFile.date).toLocaleString()}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2 mt-2">
|
|
<input
|
|
type="checkbox"
|
|
id="applyToAll"
|
|
checked={applyToAll}
|
|
onChange={(e) => setApplyToAll(e.target.checked)}
|
|
className="rounded border-slate-300 text-blue-600 focus:ring-blue-500"
|
|
/>
|
|
<label htmlFor="applyToAll" className="text-sm text-slate-600 cursor-pointer select-none">
|
|
이후 모든 중복 파일에 대해 동일하게 적용
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="bg-slate-50 px-4 py-3 border-t border-slate-200 flex justify-end gap-2">
|
|
<button
|
|
onClick={() => onSkip(applyToAll)}
|
|
className="px-4 py-2 bg-white border border-slate-300 rounded text-sm font-medium text-slate-700 hover:bg-slate-50 transition-colors"
|
|
>
|
|
건너뛰기 (Skip)
|
|
</button>
|
|
<button
|
|
onClick={() => onOverwrite(applyToAll)}
|
|
className="px-4 py-2 bg-blue-600 text-white rounded text-sm font-medium hover:bg-blue-700 transition-colors shadow-sm"
|
|
>
|
|
덮어쓰기 (Overwrite)
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ConflictModal;
|