"use client"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useState, useTransition, useEffect } from "react"; import { ArrowLeft, Save, AlertTriangle } from "lucide-react"; import { Button, Card, CardContent, Input, Label, Badge } from "poyraz-ui/atoms"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, toast } from "poyraz-ui/molecules"; import { useTranslations } from "@/components/i18n/i18n-provider"; import { upsertTranslationsAction } from "./actions"; type ReferenceKey = { key: string; namespace: string; translationKey: string; tr: string; en: string; parityOk: boolean; }; type LocaleDetail = { code: string; name: string; nativeName: string; }; export function TranslationEditor({ locale, namespaces, referenceKeys, overrides, }: { locale: LocaleDetail; namespaces: readonly string[]; referenceKeys: ReferenceKey[]; overrides: Record; }) { const t = useTranslations(); const router = useRouter(); const [pending, startTransition] = useTransition(); const [activeNamespace, setActiveNamespace] = useState("common"); const [filter, setFilter] = useState<"all" | "missing" | "dirty">("all"); const [edits, setEdits] = useState>({}); const isDirty = Object.keys(edits).length > 0; useEffect(() => { const handleBeforeUnload = (e: BeforeUnloadEvent) => { if (isDirty) { e.preventDefault(); e.returnValue = ""; } }; window.addEventListener("beforeunload", handleBeforeUnload); return () => window.removeEventListener("beforeunload", handleBeforeUnload); }, [isDirty]); const handleSave = () => { if (!isDirty) return; startTransition(async () => { const payload = Object.entries(edits).map(([fullKey, value]) => { const [namespace, ...rest] = fullKey.split("."); return { namespace, key: rest.join("."), value, }; }); const result = await upsertTranslationsAction(locale.code, payload); if (result.errorKey) { toast.error(t(result.errorKey)); } else { toast.success("Çeviriler başarıyla kaydedildi."); setEdits({}); router.refresh(); } }); }; const handleReset = (fullKey: string) => { setEdits(prev => { const next = { ...prev }; delete next[fullKey]; return next; }); }; const filteredKeys = referenceKeys.filter(k => { if (k.namespace !== activeNamespace && activeNamespace !== "all") return false; const isEdited = edits[k.key] !== undefined; const value = isEdited ? edits[k.key] : (overrides[k.key] || ""); const isMissing = value.trim() === ""; if (filter === "missing" && !isMissing) return false; if (filter === "dirty" && !isEdited) return false; return true; }); return (

{locale.nativeName} Çevirileri

{filteredKeys.length === 0 ? ( Gösterilecek çeviri anahtarı bulunamadı. ) : ( filteredKeys.map((item) => { const isEdited = edits[item.key] !== undefined; const currentValue = isEdited ? edits[item.key] : (overrides[item.key] || ""); const trVars = item.tr.match(/\{[^}]+\}/g) || []; const targetVars: string[] = currentValue.match(/\{[^}]+\}/g) || []; const missingVars = trVars.filter(v => !targetVars.includes(v)); return (
{item.key} {isEdited && Değiştirildi}
TR Referans: {item.tr}
EN Referans: {item.en}
setEdits(prev => ({ ...prev, [item.key]: e.target.value }))} className={missingVars.length > 0 ? "border-destructive focus-visible:ring-destructive" : ""} /> {missingVars.length > 0 && (

Eksik değişkenler: {missingVars.join(", ")}

)} {isEdited && (
)}
); }) )}
{isDirty && (
)}
); }