import React from 'react'; import { useTranslation } from 'react-i18next'; import { AlertCircle, CheckCircle2, Loader2 } from 'lucide-react'; import type { MigrationPair, MigrationPhase, MigrationResult, } from '../../utils/deviceSync/runDeviceSyncMigration'; interface Props { migrationPhase: MigrationPhase; migrationOldTemplate: string; migrationPairs: MigrationPair[]; migrationCollisions: MigrationPair[]; migrationUnchanged: number; migrationResult: MigrationResult | null; executeMigration: () => Promise; closeMigration: () => void; } export default function DeviceSyncMigrationModal({ migrationPhase, migrationOldTemplate, migrationPairs, migrationCollisions, migrationUnchanged, migrationResult, executeMigration, closeMigration, }: Props) { const { t } = useTranslation(); if (migrationPhase === 'closed') return null; return (
e.stopPropagation()}>

{t('deviceSync.migrateTitle', { defaultValue: 'Reorganize existing files' })}

{migrationPhase === 'loading' && (
{t('deviceSync.migrateLoading', { defaultValue: 'Analyzing existing files…' })}
)} {migrationPhase === 'nothing' && (
{migrationOldTemplate ? ( t('deviceSync.migrateNothingToDo', { defaultValue: 'All existing files already match the new scheme — nothing to do.' }) ) : ( t('deviceSync.migrateNoTemplate', { defaultValue: 'No legacy filename template found on the device. Migration only applies when the stick was synced with a Psysonic version that supported custom templates.' }) )}
)} {migrationPhase === 'preview' && ( <>
{migrationPairs.length}{' '} {t('deviceSync.migrateFilesToRename', { defaultValue: 'files will be renamed' })}
{migrationUnchanged > 0 && (
{t('deviceSync.migrateUnchanged', { defaultValue: '{{n}} files are already at the correct path', n: migrationUnchanged, })}
)} {migrationCollisions.length > 0 && (
{t('deviceSync.migrateCollisions', { defaultValue: '{{n}} files cannot be renamed automatically (multiple tracks map to the same target). They will be left untouched — the next sync re-downloads them into the correct location.', n: migrationCollisions.length, })}
)}
{t('deviceSync.migratePreviewNote', { defaultValue: 'Old template: {{tpl}}', tpl: migrationOldTemplate, })}
)} {migrationPhase === 'executing' && (
{t('deviceSync.migrateExecuting', { defaultValue: 'Renaming files…' })}
)} {migrationPhase === 'done' && migrationResult && (
{t('deviceSync.migrateSuccess', { defaultValue: '{{n}} files renamed successfully', n: migrationResult.ok, })}
{migrationResult.failed > 0 && (
{t('deviceSync.migrateFailed', { defaultValue: '{{n}} renames failed', n: migrationResult.failed, })}
)} {migrationResult.errors.length > 0 && (
{t('deviceSync.migrateShowErrors', { defaultValue: 'Show errors' })}
    {migrationResult.errors.slice(0, 50).map((err, i) => (
  • {err}
  • ))} {migrationResult.errors.length > 50 && (
  • … {migrationResult.errors.length - 50} more
  • )}
)}
)}
{migrationPhase === 'preview' && ( <> )} {(migrationPhase === 'done' || migrationPhase === 'nothing') && ( )}
); }