"use client"; import { archiveClientRecord, createClientRecord, updateClientRecord, } from "@/app/(dashboard)/clients/actions"; import { Badge, Button, Card, CardContent, Input, Label, Textarea } from "poyraz-ui/atoms"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "poyraz-ui/molecules"; import { Archive, ExternalLink, Mail, PauseCircle, Pencil, Phone, Plus, UserCheck, Users, Wallet, type LucideIcon, } from "lucide-react"; import Link from "next/link"; import { useState } from "react"; export type ClientListItem = { id: string; name: string; company_name: string | null; email: string | null; phone: string | null; website: string | null; status: "active" | "paused" | "archived"; notes: string | null; created_at: string; projectCount: number; revenueTotal: number; }; const statusLabels = { active: "Aktif", paused: "Duraklatıldı", archived: "Arşivlendi", }; const statusClasses = { active: "border-emerald-200 bg-emerald-50 text-emerald-700", paused: "border-amber-200 bg-amber-50 text-amber-700", archived: "border-zinc-200 bg-zinc-50 text-zinc-600", }; type ClientsClientProps = { clients: ClientListItem[]; totalRevenue: number; activeCount: number; pausedCount: number; archivedCount: number; }; export function ClientsClient({ clients, totalRevenue, activeCount, pausedCount, archivedCount, }: ClientsClientProps) { const [query, setQuery] = useState(""); const normalizedQuery = query.trim().toLowerCase(); const filteredClients = normalizedQuery ? clients.filter((client) => [ client.name, client.company_name, client.email, client.phone, client.website, client.notes, ] .filter(Boolean) .some((value) => value!.toLowerCase().includes(normalizedQuery)), ) : clients; return (
Freelancer operasyonu

Müşteriler

Çalıştığın müşterileri, iletişim bilgilerini ve temel iş durumunu tek ekrandan yönet.

Müşteri listesi

{filteredClients.length} kayıt görüntüleniyor.

setQuery(event.target.value)} placeholder="Müşteri, firma, e-posta veya not ara" className="md:max-w-sm" />
{filteredClients.length > 0 ? (
Müşteri İletişim Durum Projeler İşlem
{filteredClients.map((client) => ( ))}
) : ( )}
); } function ClientRow({ client }: { client: ClientListItem }) { return (
{getInitials(client.name)}
{client.name}
{client.company_name || "Firma bilgisi yok"}
{client.email ? ( {client.email} ) : null} {client.phone ? ( {client.phone} ) : null} {client.website ? ( {client.website.replace(/^https?:\/\//, "")} ) : null} {!client.email && !client.phone && !client.website ? ( İletişim bilgisi yok ) : null}
{statusLabels[client.status]}
{client.projectCount}
{formatCurrency(client.revenueTotal)}
{client.status !== "archived" ? (
) : null}
); } function ClientDialog({ mode, client, }: { mode: "create" | "edit"; client?: ClientListItem; }) { const [open, setOpen] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const action = mode === "create" ? createClientRecord : updateClientRecord; async function handleSubmit(formData: FormData) { setIsSubmitting(true); try { await action(formData); setOpen(false); } finally { setIsSubmitting(false); } } return (
{client ? : null} {mode === "create" ? "Yeni müşteri" : "Müşteriyi düzenle"} Müşteri bilgilerini sade tut; proje ve finans bağlantıları sonraki modüllerden otomatik görünecek.
); } function ClientFormFields({ client }: { client?: ClientListItem }) { return (