This commit is contained in:
2026-09-02 12:06:20 +03:30
parent e248943f4c
commit 87aee8c46b
5 changed files with 46 additions and 39 deletions
+10 -7
View File
@@ -14,7 +14,6 @@ import {
Textarea,
Modal,
PageHeader,
Switch,
} from "@/components/ui";
import { EditIcon, EyeIcon, PlusIcon, TrashIcon } from "@/components/icons";
import { MediaPreview } from "@/components/MediaPreview";
@@ -148,7 +147,7 @@ export default function CategoriesPage() {
});
toast.success(
row.is_deeplink_only
? "به فهرست عادی بازگشت."
? "به فهرست عادی بازگردانده شد."
: "به لینک مستقیم تبدیل شد.",
);
reload();
@@ -237,11 +236,15 @@ export default function CategoriesPage() {
subtitle="مدیریت دسته‌بندی‌های عمومی رسانه، پلی‌لیست و قالب تنفس"
action={
<div className="flex items-center gap-3">
<Switch
checked={showDeepLinks}
onChange={setShowDeepLinks}
label="فقط لینک‌های مستقیم"
/>
<Select
value={showDeepLinks ? "deeplink" : "normal"}
onChange={(e) => setShowDeepLinks(e.target.value === "deeplink")}
aria-label="نمایش"
className="w-44"
>
<option value="normal">دسته‌بندی‌های عادی</option>
<option value="deeplink">لینک‌های مستقیم</option>
</Select>
<Select
value={typeFilter}
onChange={(e) => setTypeFilter(e.target.value as CategoryType)}
+11 -11
View File
@@ -117,7 +117,7 @@ export default function CategoryDeepLinksPage() {
method: "POST",
body: toFormData({ is_deeplink_only: 0 }),
});
toast.success("از لینک مستقیم خارج شد.");
toast.success("به فهرست عادی بازگردانده شد.");
reload();
} catch (err) {
toast.error(err instanceof ApiError ? err.message : "خطا در ذخیره‌سازی");
@@ -134,10 +134,10 @@ export default function CategoryDeepLinksPage() {
method: "POST",
body: toFormData({ name, type, order, description, icon }),
});
toast.success("لینک مستقیم بهروزرسانی شد.");
toast.success("لینک مستقیم به‌روزرسانی شد.");
} else if (source === "existing") {
if (!existingId) {
toast.error("دسته‌بندی را انتخاب کنید.");
toast.error("یک دسته‌بندی انتخاب کنید.");
return;
}
await apiFetch(`/categories/${existingId}`, {
@@ -233,8 +233,8 @@ export default function CategoryDeepLinksPage() {
return (
<div>
<PageHeader
title="لینکهای مستقیم دسته‌بندی"
subtitle="دسته‌بندیهایی که در فهرست نمایش داده نمیشوند اما از طریق لینک مستقیم قابل دسترسیاند"
title="لینک‌های مستقیم دسته‌بندی"
subtitle="دسته‌بندی‌هایی که در فهرست نمایش داده نمی‌شوند اما از طریق لینک مستقیم قابل دسترسی هستند"
action={
<Button icon={<PlusIcon className="h-4 w-4" />} onClick={openCreate}>
لینک مستقیم جدید
@@ -262,8 +262,8 @@ export default function CategoryDeepLinksPage() {
<Button
variant="ghost"
onClick={() => unhide(row)}
aria-label="نمایش در فهرست"
title="نمایش در فهرست"
aria-label="بازگرداندن به فهرست"
title="بازگرداندن به فهرست"
>
<EyeIcon className="h-4 w-4" />
</Button>
@@ -329,7 +329,7 @@ export default function CategoryDeepLinksPage() {
</Select>
) : (
<p className="text-xs text-muted">
{allLoading ? "در حال بارگذاری..." : "دسته‌بندی‌ای موجود نیست."}
{allLoading ? "در حال بارگذاری..." : "دسته‌بندی‌ای وجود ندارد."}
</p>
)}
</Field>
@@ -387,13 +387,13 @@ export default function CategoryDeepLinksPage() {
<p className="rounded-xl border border-border bg-surface-muted p-3 text-xs text-muted">
{editing ? (
<>
این دسته‌بندی در فهرست نمایش داده نمیشود و فقط با لینک مستقیم قابل
دسترسی است. برای بازگرداندن آن به فهرست، از دکمه «نمایش در فهرست»
این دسته‌بندی در فهرست نمایش داده نمی‌شود و فقط با لینک مستقیم قابل
دسترسی است. برای بازگرداندن آن به فهرست، از دکمه «بازگرداندن به فهرست»
استفاده کنید.
</>
) : (
<>
پس از ذخیره، این دسته‌بندی در فهرست نمایش داده نمیشود و فقط با لینک
پس از ذخیره، این دسته‌بندی در فهرست نمایش داده نمی‌شود و فقط با لینک
مستقیم قابل دسترسی است.
</>
)}
+12 -12
View File
@@ -151,7 +151,7 @@ export default function MediaDeepLinksPage() {
method: "POST",
body: toFormData({ is_deeplink_only: 0 }),
});
toast.success("از لینک مستقیم خارج شد.");
toast.success("به فهرست عادی بازگردانده شد.");
reload();
} catch (err) {
toast.error(err instanceof ApiError ? err.message : "خطا در ذخیره‌سازی");
@@ -175,11 +175,11 @@ export default function MediaDeepLinksPage() {
image: imageFile,
});
await apiFetch(`/media/${editing.id}`, { method: "POST", body });
toast.success("لینک مستقیم بهروزرسانی شد.");
toast.success("لینک مستقیم به‌روزرسانی شد.");
} else if (source === "existing") {
// Toggle the chosen existing media to deeplink-only.
if (!existingId) {
toast.error("رسانهای را انتخاب کنید.");
toast.error("یک رسانه انتخاب کنید.");
return;
}
await apiFetch(`/media/${existingId}`, {
@@ -263,8 +263,8 @@ export default function MediaDeepLinksPage() {
return (
<div>
<PageHeader
title="لینکهای مستقیم رسانه"
subtitle="رسانههایی که در فهرست نمایش داده نمیشوند اما از طریق لینک مستقیم (دیپلینک) قابل دسترسیاند"
title="لینک‌های مستقیم رسانه"
subtitle="رسانه‌هایی که در فهرست نمایش داده نمی‌شوند اما از طریق لینک مستقیم قابل دسترسی هستند"
action={
<Button icon={<PlusIcon className="h-4 w-4" />} onClick={openCreate}>
لینک مستقیم جدید
@@ -292,8 +292,8 @@ export default function MediaDeepLinksPage() {
<Button
variant="ghost"
onClick={() => unhide(row)}
aria-label="نمایش در فهرست"
title="نمایش در فهرست"
aria-label="بازگرداندن به فهرست"
title="بازگرداندن به فهرست"
>
<EyeIcon className="h-4 w-4" />
</Button>
@@ -354,7 +354,7 @@ export default function MediaDeepLinksPage() {
</Select>
) : (
<p className="text-xs text-muted">
{allLoading ? "در حال بارگذاری..." : "رسانهای موجود نیست."}
{allLoading ? "در حال بارگذاری..." : "رسانه‌ای وجود ندارد."}
</p>
)}
</Field>
@@ -410,7 +410,7 @@ export default function MediaDeepLinksPage() {
/>
</Field>
<Field label="لینک خارجی" hint="اگر فایل آپلود نمیکنید، آدرس مستقیم فایل.">
<Field label="لینک خارجی" hint="اگر فایلی بارگذاری نمی‌کنید، نشانی مستقیم فایل را وارد کنید.">
<Input
dir="ltr"
value={externalUrl}
@@ -434,13 +434,13 @@ export default function MediaDeepLinksPage() {
<p className="rounded-xl border border-border bg-surface-muted p-3 text-xs text-muted">
{editing ? (
<>
این رسانه در فهرست «رسانهها» نمایش داده نمیشود و فقط با لینک مستقیم
قابل دسترسی است. برای بازگرداندن آن به فهرست، از دکمه «نمایش در فهرست»
این رسانه در فهرست «رسانه‌ها» نمایش داده نمی‌شود و فقط با لینک مستقیم
قابل دسترسی است. برای بازگرداندن آن به فهرست، از دکمه «بازگرداندن به فهرست»
استفاده کنید.
</>
) : (
<>
پس از ذخیره، این رسانه در فهرست «رسانهها» نمایش داده نمیشود و فقط با
پس از ذخیره، این رسانه در فهرست «رسانه‌ها» نمایش داده نمی‌شود و فقط با
لینک مستقیم قابل دسترسی است.
</>
)}
+11 -7
View File
@@ -220,7 +220,7 @@ export default function MediaPage() {
});
toast.success(
row.is_deeplink_only
? "به فهرست عادی بازگشت."
? "به فهرست عادی بازگردانده شد."
: "به لینک مستقیم تبدیل شد.",
);
reload();
@@ -327,7 +327,7 @@ export default function MediaPage() {
}
/>
<div className="mb-4 flex items-center gap-4">
<div className="mb-4 flex items-center gap-3">
<div className="max-w-sm flex-1">
<Input
value={search}
@@ -336,11 +336,15 @@ export default function MediaPage() {
disabled={showDeepLinks}
/>
</div>
<Switch
checked={showDeepLinks}
onChange={setShowDeepLinks}
label="فقط لینک‌های مستقیم"
/>
<Select
value={showDeepLinks ? "deeplink" : "normal"}
onChange={(e) => setShowDeepLinks(e.target.value === "deeplink")}
aria-label="نمایش"
className="w-44"
>
<option value="normal">رسانه‌های عادی</option>
<option value="deeplink">لینک‌های مستقیم</option>
</Select>
</div>
<DataTable