'use client' import { Download, Globe, Save } from 'lucide-react' import { useMemo, useState } from 'react' import { saveTranslations } from '@/actions/translations' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { useServerAction } from '@/hooks/use-server-action' import { flattenObject, unflattenObject } from '@/lib/translations-utils' interface Props { enJson: string itJson: string } export function TranslationsClient({ enJson, itJson }: Props) { const [en, setEn] = useState(() => flattenObject(JSON.parse(enJson))) const [it, setIt] = useState(() => flattenObject(JSON.parse(itJson))) const [search, setSearch] = useState('') const [group, setGroup] = useState('') const [activeLang, setActiveLang] = useState<'en' | 'it'>('en') const { run, isPending } = useServerAction() const PER_PAGE = 30 const [page, setPage] = useState(1) const activeData = activeLang === 'en' ? en : it const setActiveData = activeLang === 'en' ? setEn : setIt const groups = useMemo(() => { const g = new Set() Object.keys(en).forEach((k) => { const parts = k.split('.') if (parts.length > 1) g.add(parts[0]) }) return Array.from(g).sort() }, [en]) const filteredKeys = useMemo(() => { return Object.keys(activeData).filter((key) => { const matchSearch = !search || key.toLowerCase().includes(search.toLowerCase()) || activeData[key].toLowerCase().includes(search.toLowerCase()) const matchGroup = !group || key.startsWith(`${group}.`) return matchSearch && matchGroup }) }, [activeData, search, group]) const totalPages = Math.ceil(filteredKeys.length / PER_PAGE) const pageKeys = filteredKeys.slice((page - 1) * PER_PAGE, page * PER_PAGE) function updateValue(key: string, value: string) { setActiveData({ ...activeData, [key]: value }) } function handleSave() { run(() => saveTranslations({ locale: activeLang, data: unflattenObject(activeData) }), { successMessage: 'Translations saved!', }) } function handleExport() { const blob = new Blob([JSON.stringify(unflattenObject(activeData), null, 2)], { type: 'application/json', }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `${activeLang}.json` a.click() URL.revokeObjectURL(url) } return (

CMS

{ setSearch(e.target.value) setPage(1) }} className="max-w-xs" /> {filteredKeys.length} keys
{pageKeys.map((key) => (
{key} updateValue(key, e.target.value)} className="flex-1 h-8 text-sm" />
))}
{totalPages > 1 && (
Page {page} of {totalPages}
)}
) }