feat(admin): full Persian (fa) localization + RTL polish
- admin-resources: all config titles/descriptions/columns/fields → Persian - AdminResource: generic UI strings (new/edit/delete/save/cancel/loading/empty/ actions/confirm) → Persian; text-left/right → logical text-start/end - TemplatesAdmin: all labels, table, modal, statuses, errors → Persian - FileUploadField, WebsiteSettingsAdmin, FileManager → Persian - layout: ms-auto logical prop (NodesTable/RenderQueue/AiContentStudio already i18n with Persian values) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -119,7 +119,7 @@ export function AdminResource({ config }: { config: ResourceConfig }) {
|
||||
};
|
||||
|
||||
const remove = async (row: Record<string, unknown>) => {
|
||||
if (!confirm(`Delete this ${config.title.replace(/s$/, "").toLowerCase()}?`)) return;
|
||||
if (!confirm("حذف این مورد؟")) return;
|
||||
const res = await fetch(url(`/${row[idKey]}`), { method: "DELETE" });
|
||||
if (res.ok) reload();
|
||||
else {
|
||||
@@ -136,7 +136,7 @@ export function AdminResource({ config }: { config: ResourceConfig }) {
|
||||
{config.description && <p className="mt-1 text-sm text-gray-400">{config.description}</p>}
|
||||
</div>
|
||||
{config.canCreate && config.fields && (
|
||||
<button className={btn} onClick={openCreate}>+ New</button>
|
||||
<button className={btn} onClick={openCreate}>+ مورد جدید</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -145,20 +145,20 @@ export function AdminResource({ config }: { config: ResourceConfig }) {
|
||||
<div className={`${card} overflow-hidden`}>
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-[#1e2235] text-left text-xs text-gray-500">
|
||||
<tr className="border-b border-[#1e2235] text-start text-xs text-gray-500">
|
||||
{config.columns.map((c) => (
|
||||
<th key={c.key} className="px-4 py-3 font-medium">{c.label}</th>
|
||||
))}
|
||||
{(config.canEdit || config.canDelete || config.rowActions) && (
|
||||
<th className="px-4 py-3 text-right font-medium">Actions</th>
|
||||
<th className="px-4 py-3 text-end font-medium">عملیات</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{loading ? (
|
||||
<tr><td className="px-4 py-8 text-center text-gray-500" colSpan={99}>Loading…</td></tr>
|
||||
<tr><td className="px-4 py-8 text-center text-gray-500" colSpan={99}>در حال بارگذاری…</td></tr>
|
||||
) : rows.length === 0 ? (
|
||||
<tr><td className="px-4 py-8 text-center text-gray-500" colSpan={99}>No records.</td></tr>
|
||||
<tr><td className="px-4 py-8 text-center text-gray-500" colSpan={99}>رکوردی یافت نشد.</td></tr>
|
||||
) : (
|
||||
rows.map((row, i) => (
|
||||
<tr key={String(row[idKey] ?? i)} className="border-b border-[#161a2e] hover:bg-[#12152a]">
|
||||
@@ -172,14 +172,14 @@ export function AdminResource({ config }: { config: ResourceConfig }) {
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
{config.rowActions?.(row, reload)}
|
||||
{config.canEdit && config.fields && (
|
||||
<button className={btnGhost} onClick={() => openEdit(row)}>Edit</button>
|
||||
<button className={btnGhost} onClick={() => openEdit(row)}>ویرایش</button>
|
||||
)}
|
||||
{config.canDelete && (
|
||||
<button
|
||||
className="rounded-lg border border-red-500/30 px-3 py-1.5 text-xs text-red-300 hover:bg-red-500/10"
|
||||
onClick={() => remove(row)}
|
||||
>
|
||||
Delete
|
||||
حذف
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -196,7 +196,7 @@ export function AdminResource({ config }: { config: ResourceConfig }) {
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4" onClick={closeForm}>
|
||||
<div className={`${card} w-full max-w-lg p-5`} onClick={(e) => e.stopPropagation()}>
|
||||
<h2 className="text-sm font-semibold text-white">
|
||||
{editing ? "Edit" : "New"} {config.title.replace(/s$/, "")}
|
||||
{editing ? "ویرایش" : "افزودن"} — {config.title}
|
||||
</h2>
|
||||
<div className="mt-4 grid max-h-[60vh] gap-3 overflow-y-auto pr-1">
|
||||
{config.fields.map((f) => (
|
||||
@@ -235,8 +235,8 @@ export function AdminResource({ config }: { config: ResourceConfig }) {
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-5 flex items-center justify-end gap-2">
|
||||
<button className={btnGhost} onClick={closeForm}>Cancel</button>
|
||||
<button className={btn} onClick={submit} disabled={saving}>{saving ? "Saving…" : "Save"}</button>
|
||||
<button className={btnGhost} onClick={closeForm}>انصراف</button>
|
||||
<button className={btn} onClick={submit} disabled={saving}>{saving ? "در حال ذخیره…" : "ذخیره"}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user