profit-planet-frontend/src/app/admin/language-management/components/TranslationWizardModal.tsx
DeathKaioken 4074ea4eee Bibelbumser
Co-authored-by: Copilot <copilot@github.com>
2026-05-04 23:48:09 +02:00

168 lines
6.3 KiB
TypeScript

'use client';
import { useTranslation } from '../../../i18n/useTranslation';
import type { LanguageEntry } from '../hooks/useLanguageManagementTranslations';
import { useModalAnimation } from '../hooks/useModalAnimation';
type Props = {
isOpen: boolean;
currentWizardKey: string | null;
wizardIndex: number;
wizardMissingCount: number;
activeLang: string;
allLanguages: LanguageEntry[];
wizardInput: string;
setWizardInput: (value: string) => void;
wizardMarkGlobal: boolean;
setWizardMarkGlobal: (value: boolean) => void;
wizardUseEnglishReference: boolean;
setWizardUseEnglishReference: (value: boolean) => void;
englishValue: string;
addGlobalKey: (key: string) => void;
removeGlobalKey: (key: string) => void;
onClose: () => void;
onPrevious: () => void;
onSkip: () => void;
onNext: () => void | Promise<void>;
isSavingStep?: boolean;
};
export default function TranslationWizardModal({
isOpen,
currentWizardKey,
wizardIndex,
wizardMissingCount,
activeLang,
allLanguages,
wizardInput,
setWizardInput,
wizardMarkGlobal,
setWizardMarkGlobal,
wizardUseEnglishReference,
setWizardUseEnglishReference,
englishValue,
addGlobalKey,
removeGlobalKey,
onClose,
onPrevious,
onSkip,
onNext,
isSavingStep = false,
}: Props) {
const { t } = useTranslation();
const { isRendered, isVisible } = useModalAnimation(isOpen && Boolean(currentWizardKey));
if (!isRendered || !currentWizardKey) return null;
return (
<div className={`fixed inset-0 z-[120] flex items-center justify-center bg-black/45 backdrop-blur-sm transition-opacity duration-200 ${
isVisible ? 'opacity-100' : 'opacity-0'
}`}>
<div className={`mx-4 w-full max-w-2xl rounded-2xl border border-slate-200 bg-white shadow-2xl overflow-hidden transform transition-all duration-200 ${
isVisible ? 'opacity-100 translate-y-0 scale-100' : 'opacity-0 translate-y-2 scale-[0.98]'
}`}>
<div className="px-6 py-4 border-b border-slate-200 bg-slate-50 flex items-start justify-between gap-4">
<div>
<h2 className="text-lg font-bold text-[#1C2B4A]">{t('autofix.kcd190bdd')}</h2>
<p className="text-xs text-slate-600 mt-1">
Step {wizardIndex + 1} of {wizardMissingCount} for {allLanguages.find((l) => l.code === activeLang)?.name ?? activeLang}
</p>
</div>
<button onClick={onClose} className="text-slate-400 hover:text-slate-700 text-xl leading-none">
</button>
</div>
<div className="px-6 py-5 space-y-4">
<div className="rounded-lg border border-slate-200 bg-slate-50 px-3 py-2">
<p className="text-[11px] uppercase tracking-wide text-slate-500">Key</p>
<p className="font-mono text-xs text-slate-700 mt-1 break-all">{currentWizardKey}</p>
</div>
<div className="rounded-lg border border-slate-200 bg-white px-3 py-2">
<p className="text-[11px] uppercase tracking-wide text-slate-500">{t('autofix.kc518ff5c')}</p>
<p className="text-sm text-slate-700 mt-1">{englishValue}</p>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 mb-1">Translation</label>
<textarea
value={wizardInput}
onChange={(e) => setWizardInput(e.target.value)}
placeholder={t('languageManagement.wizardInputPlaceholder')}
rows={4}
className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[#1C2B4A]"
/>
</div>
<label className="inline-flex items-center gap-2 text-sm text-slate-700">
<input
type="checkbox"
checked={wizardMarkGlobal}
onChange={(e) => {
const checked = e.target.checked;
setWizardMarkGlobal(checked);
if (!currentWizardKey) return;
if (checked) {
addGlobalKey(currentWizardKey);
return;
}
removeGlobalKey(currentWizardKey);
}}
className="h-4 w-4 rounded border-slate-300 text-[#1C2B4A] focus:ring-[#1C2B4A]"
/>
Counts as global key (same value as English)
</label>
{activeLang !== 'en' && (
<label className="inline-flex items-center gap-2 text-sm text-slate-700">
<input
type="checkbox"
checked={wizardUseEnglishReference}
onChange={(e) => {
const checked = e.target.checked;
setWizardUseEnglishReference(checked);
if (checked) {
setWizardInput(englishValue);
}
}}
className="h-4 w-4 rounded border-slate-300 text-[#1C2B4A] focus:ring-[#1C2B4A]"
/>
Use English value (this language only, not global)
</label>
)}
</div>
<div className="px-6 py-4 border-t border-slate-200 bg-white flex items-center justify-between gap-3">
<button
type="button"
onClick={onPrevious}
disabled={wizardIndex === 0 || isSavingStep}
className="rounded-md border border-slate-300 px-3 py-2 text-sm text-slate-700 hover:bg-slate-50 disabled:opacity-50"
>
Back
</button>
<div className="flex items-center gap-2">
<button
type="button"
onClick={onSkip}
disabled={isSavingStep}
className="rounded-md border border-slate-300 px-3 py-2 text-sm text-slate-700 hover:bg-slate-50"
>
Skip
</button>
<button
type="button"
onClick={onNext}
disabled={isSavingStep || (wizardInput.trim() === '' && !wizardMarkGlobal && !wizardUseEnglishReference)}
className="rounded-md bg-[#1C2B4A] text-white px-4 py-2 text-sm font-semibold hover:bg-[#1C2B4A]/90 disabled:opacity-50"
>{isSavingStep
? t('common.saving')
: (wizardIndex >= wizardMissingCount - 1 ? t('autofix.k230e2c3c') : t('autofix.kb270a988'))}</button>
</div>
</div>
</div>
</div>
);
}