revert fb8e77bb68
Local Build and Deploy / deploy (push) Successful in 1m11s
Local Build and Deploy / deploy (push) Successful in 1m11s
revert style: clean up code with prettier and eslint
This commit is contained in:
1 parent
27de078f54
commit
e85e4d74ea
378 files changed
+20710
-22428
No files matched your search
@@ -1,74 +1,74 @@
|
||||
"use client";
|
||||
'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";
|
||||
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;
|
||||
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 [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 activeData = activeLang === 'en' ? en : it
|
||||
const setActiveData = activeLang === 'en' ? setEn : setIt
|
||||
|
||||
const groups = useMemo(() => {
|
||||
const g = new Set<string>();
|
||||
const g = new Set<string>()
|
||||
Object.keys(en).forEach((k) => {
|
||||
const parts = k.split(".");
|
||||
if (parts.length > 1) g.add(parts[0]);
|
||||
});
|
||||
return Array.from(g).sort();
|
||||
}, [en]);
|
||||
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]);
|
||||
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);
|
||||
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 });
|
||||
setActiveData({ ...activeData, [key]: value })
|
||||
}
|
||||
|
||||
function handleSave() {
|
||||
run(() => saveTranslations({ locale: activeLang, data: unflattenObject(activeData) }), {
|
||||
successMessage: "Translations saved!",
|
||||
});
|
||||
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);
|
||||
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 (
|
||||
@@ -83,7 +83,7 @@ export function TranslationsClient({ enJson, itJson }: Props) {
|
||||
<Download className="w-4 h-4 mr-1" /> Export
|
||||
</Button>
|
||||
<Button size="sm" onClick={handleSave} disabled={isPending}>
|
||||
<Save className="w-4 h-4 mr-1" /> {isPending ? "Saving..." : "Save"}
|
||||
<Save className="w-4 h-4 mr-1" /> {isPending ? 'Saving...' : 'Save'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,16 +91,16 @@ export function TranslationsClient({ enJson, itJson }: Props) {
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<div className="flex gap-1">
|
||||
<Button
|
||||
variant={activeLang === "en" ? "default" : "outline"}
|
||||
variant={activeLang === 'en' ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
onClick={() => setActiveLang("en")}
|
||||
onClick={() => setActiveLang('en')}
|
||||
>
|
||||
EN
|
||||
</Button>
|
||||
<Button
|
||||
variant={activeLang === "it" ? "default" : "outline"}
|
||||
variant={activeLang === 'it' ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
onClick={() => setActiveLang("it")}
|
||||
onClick={() => setActiveLang('it')}
|
||||
>
|
||||
IT
|
||||
</Button>
|
||||
@@ -109,8 +109,8 @@ export function TranslationsClient({ enJson, itJson }: Props) {
|
||||
placeholder="Filter by key or value..."
|
||||
value={search}
|
||||
onChange={(e) => {
|
||||
setSearch(e.target.value);
|
||||
setPage(1);
|
||||
setSearch(e.target.value)
|
||||
setPage(1)
|
||||
}}
|
||||
className="max-w-xs"
|
||||
/>
|
||||
@@ -118,8 +118,8 @@ export function TranslationsClient({ enJson, itJson }: Props) {
|
||||
className="rounded-md border bg-background px-3 py-1 text-sm"
|
||||
value={group}
|
||||
onChange={(e) => {
|
||||
setGroup(e.target.value);
|
||||
setPage(1);
|
||||
setGroup(e.target.value)
|
||||
setPage(1)
|
||||
}}
|
||||
>
|
||||
<option value="">All groups</option>
|
||||
@@ -129,13 +129,17 @@ export function TranslationsClient({ enJson, itJson }: Props) {
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<span className="text-sm text-muted-foreground self-center">{filteredKeys.length} keys</span>
|
||||
<span className="text-sm text-muted-foreground self-center">
|
||||
{filteredKeys.length} keys
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border bg-card divide-y">
|
||||
{pageKeys.map((key) => (
|
||||
<div key={key} className="flex items-center gap-3 px-4 py-2">
|
||||
<span className="text-xs font-mono text-muted-foreground w-64 truncate flex-shrink-0">{key}</span>
|
||||
<span className="text-xs font-mono text-muted-foreground w-64 truncate flex-shrink-0">
|
||||
{key}
|
||||
</span>
|
||||
<Input
|
||||
value={activeData[key]}
|
||||
onChange={(e) => updateValue(key, e.target.value)}
|
||||
@@ -151,7 +155,12 @@ export function TranslationsClient({ enJson, itJson }: Props) {
|
||||
Page {page} of {totalPages}
|
||||
</span>
|
||||
<div className="flex gap-1">
|
||||
<Button variant="outline" size="sm" disabled={page <= 1} onClick={() => setPage(page - 1)}>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={page <= 1}
|
||||
onClick={() => setPage(page - 1)}
|
||||
>
|
||||
Prev
|
||||
</Button>
|
||||
<Button
|
||||
@@ -166,5 +175,5 @@ export function TranslationsClient({ enJson, itJson }: Props) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user