import { useEffect, useState } from "react" import { Plus, Building2, Loader2, Pencil, Trash2 } from "lucide-react" import { useWorkspace } from "../context/WorkspaceContext" import { useTranslation } from "../hooks/useTranslation" import { type Client } from "../types/client" import { getClients } from "../api/clients" import CreateClientModal from "../components/CreateClientModal" import EditClientModal from "../components/EditClientModal" import DeleteClientModal from "../components/DeleteClientModal" import FilterBar from "../components/FilterBar" import { Button } from "../components/ui/button" import { Card } from "../components/ui/card" import { Pagination } from "../components/Pagination" export default function Clients() { const { activeWorkspace } = useWorkspace() const [clients, setClients] = useState([]) const [isLoading, setIsLoading] = useState(true) // Pagination States const [currentPage, setCurrentPage] = useState(1) const [totalItems, setTotalItems] = useState(0) const [limit, setLimit] = useState(10) // Filter States const [searchQuery, setSearchQuery] = useState("") const [debouncedSearch, setDebouncedSearch] = useState("") const [ordering, setOrdering] = useState("-created_at") // Modal States const [isCreateModalOpen, setIsCreateModalOpen] = useState(false) const [editClient, setEditClient] = useState(null) const [deleteClient, setDeleteClient] = useState(null) const { t, lang } = useTranslation() const isFa = lang === "fa" const orderingOptions = [ { value: "-created_at", label: t.ordering?.createdAtDesc || "Newest First" }, { value: "created_at", label: t.ordering?.createdAt || "Oldest First" }, { value: "name", label: t.ordering?.name || "Name (A-Z)" }, { value: "-name", label: t.ordering?.nameDesc || "Name (Z-A)" }, { value: "-updated_at", label: t.ordering?.updatedAtDesc || "Recently Updated" }, ] useEffect(() => { setCurrentPage(1) }, [debouncedSearch, ordering]) // Debounce search input to avoid spamming the API useEffect(() => { const handler = setTimeout(() => { setDebouncedSearch(searchQuery) }, 500) return () => clearTimeout(handler) }, [searchQuery]) const fetchClientsList = async () => { if (!activeWorkspace?.id) { setIsLoading(false) return } setIsLoading(true) try { const offset = (currentPage - 1) * limit const data: any = await getClients(activeWorkspace.id, debouncedSearch, ordering, limit, offset) const items = data?.results || (Array.isArray(data) ? data : []) const count = data?.count !== undefined ? data.count : items.length setClients(items) setTotalItems(count) } catch (error) { console.error(t.clients.errors.fetchFailed, error) setClients([]) } finally { setIsLoading(false) } } const formatDate = (dateStr: string | undefined) => { if (!dateStr) return "-" try { const date = new Date(dateStr) return new Intl.DateTimeFormat(isFa ? "fa-IR" : "en-US", { dateStyle: "long", timeZone: "Asia/Tehran" }).format(date) } catch (e) { return dateStr } } useEffect(() => { fetchClientsList() }, [activeWorkspace?.id, debouncedSearch, ordering, currentPage, limit]) if (!activeWorkspace) { return (
{t.clients.selectWorkspace}
) } return (

{t.clients.title}

{t.clients.description(activeWorkspace.name)}

{isLoading ? (
) : clients.length === 0 ? (

{t.clients.noClients}

{searchQuery ? t.clients.noClientsSearch : t.clients.noClientsAdd}

) : (
    {clients.map((client) => (
  • {client.name}

    {client.notes && (

    {client.notes}

    )}
    {t.clients.addedOn}: {formatDate(client.created_at)}
  • ))}
)}
{!isLoading && clients.length > 0 && ( )} setIsCreateModalOpen(false)} onSuccess={fetchClientsList} workspaceId={activeWorkspace.id} /> setEditClient(null)} onSuccess={fetchClientsList} client={editClient} /> setDeleteClient(null)} onSuccess={fetchClientsList} client={deleteClient} />
) }