86 lines
4.1 KiB
TypeScript
86 lines
4.1 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||
import { toast } from "sonner";
|
||
import { Button, Card, CardContent, Input, PageHeader } from "@/components/ds";
|
||
import { useCurrentHub } from "@/modules/workspace/hooks/useCurrentHub";
|
||
import { useWorkspaceCapabilities } from "@/modules/workspace/hooks/useWorkspaceCapabilities";
|
||
import { workspaceApi } from "@/modules/workspace/services/workspace-api";
|
||
import { WorkspaceEmptyState, WorkspacePageError, WorkspacePageLoader } from "@/modules/workspace/pages/shared";
|
||
|
||
export const WorkspaceAssets = function WorkspaceAssetsPage() {
|
||
const queryClient = useQueryClient();
|
||
const { tenantId, hubId, loading } = useCurrentHub();
|
||
const caps = useWorkspaceCapabilities();
|
||
const [fileRef, setFileRef] = useState("");
|
||
const [title, setTitle] = useState("");
|
||
const assets = useQuery({
|
||
queryKey: ["workspace", tenantId, "assets", hubId],
|
||
queryFn: () => workspaceApi.assets.list(tenantId!, { work_hub_id: hubId || undefined }),
|
||
enabled: !!tenantId && !!hubId,
|
||
});
|
||
const create = useMutation({
|
||
mutationFn: () =>
|
||
workspaceApi.assets.create(tenantId!, {
|
||
work_hub_id: hubId,
|
||
file_ref: fileRef,
|
||
title: title || fileRef,
|
||
}),
|
||
onSuccess: () => {
|
||
toast.success("ارجاع فایل ثبت شد");
|
||
setFileRef("");
|
||
setTitle("");
|
||
void queryClient.invalidateQueries({ queryKey: ["workspace", tenantId, "assets"] });
|
||
},
|
||
onError: (err) => toast.error(err instanceof Error ? err.message : "ثبت ارجاع ناموفق بود"),
|
||
});
|
||
|
||
if (!tenantId || loading || assets.isLoading) return <WorkspacePageLoader />;
|
||
if (!hubId) return <WorkspaceEmptyState title="مرکز کار لازم است" description="ابتدا مرکز کار را انتخاب کنید." />;
|
||
if (assets.error) return <WorkspacePageError error={assets.error} onRetry={() => assets.refetch()} />;
|
||
|
||
const storageReady = caps.data?.file_storage?.available;
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
<PageHeader title="داراییها" description="فقط ارجاع به فایلهای سامانه ذخیرهسازی. بارگذاری محلی جعلی وجود ندارد." />
|
||
{!storageReady ? (
|
||
<div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200">
|
||
سامانه ذخیرهسازی فایل در دسترس نیست. میتوانید ارجاع خارجی ثبت کنید؛ آپلود باینری در فضای کاری انجام نمیشود.
|
||
</div>
|
||
) : null}
|
||
<Card>
|
||
<CardContent className="grid gap-2 p-5 md:grid-cols-[1fr_1fr_auto]">
|
||
<Input value={fileRef} onChange={(event) => setFileRef(event.target.value)} placeholder="شناسه فایل خارجی" />
|
||
<Input value={title} onChange={(event) => setTitle(event.target.value)} placeholder="عنوان" />
|
||
<Button disabled={!fileRef.trim() || create.isPending} onClick={() => create.mutate()}>
|
||
ثبت ارجاع
|
||
</Button>
|
||
</CardContent>
|
||
</Card>
|
||
{(assets.data ?? []).length === 0 ? (
|
||
<WorkspaceEmptyState title="ارجاعی ثبت نشده" description="شناسه فایل را از سامانه ذخیرهسازی وارد کنید." />
|
||
) : (
|
||
<div className="space-y-2">
|
||
{(assets.data ?? []).map((asset) => (
|
||
<Card key={String(asset.id)}>
|
||
<CardContent className="flex items-center justify-between p-4">
|
||
<div>
|
||
<p className="font-medium text-secondary">{String(asset.title || "فایل")}</p>
|
||
<p className="text-xs text-[var(--muted)]">
|
||
{asset.role ? `نقش: ${String(asset.role)} · ` : ""}
|
||
فقط ارجاع
|
||
</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default WorkspaceAssets;
|