89 lines
4.1 KiB
TypeScript
89 lines
4.1 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import Link from "next/link";
|
||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||
import { toast } from "sonner";
|
||
import { Button, Card, CardContent, Dialog, Input, PageHeader, Textarea } from "@/components/ds";
|
||
import { useCurrentHub } from "@/modules/workspace/hooks/useCurrentHub";
|
||
import { workspaceApi } from "@/modules/workspace/services/workspace-api";
|
||
import { TEAM_STATUS, labelOf } from "@/modules/workspace/labels";
|
||
import { WorkspaceEmptyState, WorkspacePageError, WorkspacePageLoader } from "@/modules/workspace/pages/shared";
|
||
|
||
export const WorkspaceTeams = function WorkspaceTeamsPage() {
|
||
const queryClient = useQueryClient();
|
||
const { tenantId, hubId, loading: hubLoading } = useCurrentHub();
|
||
const [open, setOpen] = useState(false);
|
||
const [name, setName] = useState("");
|
||
const [description, setDescription] = useState("");
|
||
const teams = useQuery({
|
||
queryKey: ["workspace", tenantId, "teams", hubId],
|
||
queryFn: () => workspaceApi.teams.list(tenantId!, hubId || undefined),
|
||
enabled: !!tenantId,
|
||
});
|
||
const create = useMutation({
|
||
mutationFn: () => workspaceApi.teams.create(tenantId!, { work_hub_id: hubId, name, description }),
|
||
onSuccess: () => {
|
||
toast.success("تیم ایجاد شد");
|
||
setOpen(false);
|
||
setName("");
|
||
setDescription("");
|
||
void queryClient.invalidateQueries({ queryKey: ["workspace", tenantId, "teams"] });
|
||
},
|
||
onError: (err) => toast.error(err instanceof Error ? err.message : "ایجاد تیم ناموفق بود"),
|
||
});
|
||
|
||
if (!tenantId || hubLoading || teams.isLoading) return <WorkspacePageLoader />;
|
||
if (!hubId) {
|
||
return <WorkspaceEmptyState title="مرکز کار لازم است" description="ابتدا یک مرکز کار بسازید." />;
|
||
}
|
||
if (teams.error) return <WorkspacePageError error={teams.error} onRetry={() => teams.refetch()} />;
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
<PageHeader
|
||
title="تیمها"
|
||
description="اعضای تیم را با نقش مالک، مدیر، عضو یا ناظر مدیریت کنید."
|
||
actions={<Button onClick={() => setOpen(true)}>تیم جدید</Button>}
|
||
/>
|
||
{(teams.data ?? []).length === 0 ? (
|
||
<WorkspaceEmptyState
|
||
title="تیمی ثبت نشده"
|
||
description="برای واگذاری پروژه و محتوا، یک تیم بسازید."
|
||
action={<Button onClick={() => setOpen(true)}>ایجاد تیم</Button>}
|
||
/>
|
||
) : (
|
||
<div className="grid gap-4 md:grid-cols-2">
|
||
{(teams.data ?? []).map((team) => (
|
||
<Card key={String(team.id)}>
|
||
<CardContent className="space-y-2 p-5">
|
||
<div className="flex items-start justify-between">
|
||
<h2 className="font-semibold text-secondary">{String(team.name || "تیم")}</h2>
|
||
<span className="text-xs text-[var(--muted)]">{labelOf(TEAM_STATUS, String(team.status || ""))}</span>
|
||
</div>
|
||
<p className="text-sm text-[var(--muted)]">{String(team.description || "بدون توضیح")}</p>
|
||
<Link href={`/workspace/teams/${team.id}`}>
|
||
<Button variant="outline" className="w-full">
|
||
اعضای تیم
|
||
</Button>
|
||
</Link>
|
||
</CardContent>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
)}
|
||
<Dialog open={open} onClose={() => setOpen(false)} title="تیم جدید">
|
||
<div className="space-y-3">
|
||
<Input value={name} onChange={(event) => setName(event.target.value)} placeholder="نام تیم" />
|
||
<Textarea value={description} onChange={(event) => setDescription(event.target.value)} placeholder="توضیح" />
|
||
<Button className="w-full" disabled={!name.trim() || create.isPending} onClick={() => create.mutate()}>
|
||
ایجاد
|
||
</Button>
|
||
</div>
|
||
</Dialog>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default WorkspaceTeams;
|