101 lines
3.6 KiB
TypeScript
101 lines
3.6 KiB
TypeScript
'use client';
|
|
|
|
|
|
|
|
import { useTranslation } from '../../../i18n/useTranslation';
|
|
type Props = {
|
|
fixableFiles: string[]
|
|
selectedFiles: string[]
|
|
isAutoFixing: boolean
|
|
forceConvertToClient: boolean
|
|
onToggleFile: (file: string) => void
|
|
onSelectAll: () => void
|
|
onClear: () => void
|
|
onToggleForceConvertToClient: () => void
|
|
onRunFixSelected: () => void
|
|
}
|
|
|
|
export default function ScanFixPanel({
|
|
fixableFiles,
|
|
selectedFiles,
|
|
isAutoFixing,
|
|
forceConvertToClient,
|
|
onToggleFile,
|
|
onSelectAll,
|
|
onClear,
|
|
onToggleForceConvertToClient,
|
|
onRunFixSelected,
|
|
}: Props) {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<div className="mb-5 rounded-xl border border-indigo-200 bg-indigo-50/40 p-4">
|
|
<div className="flex items-start justify-between gap-3 flex-wrap">
|
|
<div>
|
|
<h3 className="text-sm font-semibold text-indigo-800">{t('autofix.k43218db0')}</h3>
|
|
<p className="text-xs text-indigo-700/90 mt-1">{t('autofix.k34a0a2e4')}</p>
|
|
<label className="mt-2 inline-flex items-center gap-2 text-xs text-indigo-800">
|
|
<input
|
|
type="checkbox"
|
|
checked={forceConvertToClient}
|
|
onChange={onToggleForceConvertToClient}
|
|
className="h-3.5 w-3.5 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
|
/>{t('autofix.k68c88f41')}</label>
|
|
<p className="text-[11px] text-indigo-700/80 mt-1">{t('autofix.k6569783c')}</p>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
type="button"
|
|
onClick={onSelectAll}
|
|
className="rounded-md border border-indigo-200 bg-white px-2.5 py-1.5 text-xs font-medium text-indigo-700 hover:bg-indigo-50"
|
|
>{t('autofix.k4c6eb72c')}</button>
|
|
<button
|
|
type="button"
|
|
onClick={onClear}
|
|
className="rounded-md border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 hover:bg-gray-50"
|
|
>
|
|
Clear
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{fixableFiles.length === 0 ? (
|
|
<div className="mt-3 rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-2 text-xs text-emerald-700">{t('autofix.ke3480838')}</div>
|
|
) : (
|
|
<div className="mt-3 space-y-2 max-h-44 overflow-y-auto pr-1">
|
|
{fixableFiles.map((file) => {
|
|
const checked = selectedFiles.includes(file)
|
|
return (
|
|
<label
|
|
key={file}
|
|
className="flex items-center gap-2 rounded-md border border-indigo-100 bg-white px-3 py-2 text-xs text-indigo-900"
|
|
>
|
|
<input
|
|
type="checkbox"
|
|
checked={checked}
|
|
onChange={() => onToggleFile(file)}
|
|
className="h-3.5 w-3.5 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
|
/>
|
|
<span className="font-mono break-all">{file}</span>
|
|
</label>
|
|
)
|
|
})}
|
|
</div>
|
|
)}
|
|
|
|
<div className="mt-3 flex items-center justify-between gap-3 flex-wrap">
|
|
<p className="text-xs text-indigo-700">
|
|
Selected: {selectedFiles.length} / {fixableFiles.length}
|
|
</p>
|
|
<button
|
|
type="button"
|
|
disabled={isAutoFixing || selectedFiles.length === 0}
|
|
onClick={onRunFixSelected}
|
|
className="rounded-md bg-indigo-700 text-white px-3 py-1.5 text-xs font-semibold hover:bg-indigo-600 disabled:opacity-50"
|
|
>
|
|
{isAutoFixing ? 'Applying fix...' : `Fix selected files (${selectedFiles.length})`}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|