@snksergio/design-system 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -1
- package/dist-lib/chunks/{app-shell-BNTvOETJ.mjs → app-shell-BdVam01i.cjs} +55 -55
- package/dist-lib/chunks/app-shell-BdVam01i.cjs.map +1 -0
- package/dist-lib/chunks/{app-shell-CDy42aNI.mjs → app-shell-C_enrPD8.mjs} +86 -86
- package/dist-lib/chunks/app-shell-C_enrPD8.mjs.map +1 -0
- package/dist-lib/chunks/{app-shell-mocks-oO_IV3Gw.mjs → app-shell-mocks-oO_IV3Gw.cjs} +1 -1
- package/dist-lib/chunks/{app-shell-mocks-oO_IV3Gw.mjs.map → app-shell-mocks-oO_IV3Gw.cjs.map} +1 -1
- package/dist-lib/chunks/{badge-B_2Zt52o.mjs → badge-B0D_PRxn.mjs} +10 -10
- package/dist-lib/chunks/badge-B0D_PRxn.mjs.map +1 -0
- package/dist-lib/chunks/{badge-DKpXURa1.mjs → badge-CUttkO1X.cjs} +10 -10
- package/dist-lib/chunks/badge-CUttkO1X.cjs.map +1 -0
- package/dist-lib/chunks/{chat-v2-mocks-BV9Wha_Z.mjs → chat-v2-mocks-BV9Wha_Z.cjs} +1 -1
- package/dist-lib/chunks/{chat-v2-mocks-BV9Wha_Z.mjs.map → chat-v2-mocks-BV9Wha_Z.cjs.map} +1 -1
- package/dist-lib/chunks/{chip-group-CsKBBHW2.mjs → chip-group-2-f_Yo7Y.cjs} +31 -64
- package/dist-lib/chunks/chip-group-2-f_Yo7Y.cjs.map +1 -0
- package/dist-lib/chunks/{chip-group-D3D0i72q.mjs → chip-group-_e-yh1Zq.mjs} +31 -64
- package/dist-lib/chunks/chip-group-_e-yh1Zq.mjs.map +1 -0
- package/dist-lib/chunks/{clientes-showcase-mocks-BMfbNNJh.mjs → clientes-showcase-mocks-CPNOhx1G.cjs} +3 -3
- package/dist-lib/chunks/clientes-showcase-mocks-CPNOhx1G.cjs.map +1 -0
- package/dist-lib/chunks/{clientes-showcase-mocks-Cq9u3nGZ.mjs → clientes-showcase-mocks-DEHCKxMK.mjs} +3 -3
- package/dist-lib/chunks/clientes-showcase-mocks-DEHCKxMK.mjs.map +1 -0
- package/dist-lib/chunks/{input-374MpdBL.mjs → input-BWevV7up.cjs} +3 -3
- package/dist-lib/chunks/input-BWevV7up.cjs.map +1 -0
- package/dist-lib/chunks/{input-DF4XAWmr.mjs → input-C9eKSSEb.mjs} +3 -3
- package/dist-lib/chunks/input-C9eKSSEb.mjs.map +1 -0
- package/dist-lib/chunks/{page-header-mC1gGtOI.mjs → page-header-DM2G1mdi.mjs} +3 -3
- package/dist-lib/chunks/page-header-DM2G1mdi.mjs.map +1 -0
- package/dist-lib/chunks/{page-header-Dw-3wqAG.mjs → page-header-qOywgRWy.cjs} +3 -3
- package/dist-lib/chunks/page-header-qOywgRWy.cjs.map +1 -0
- package/dist-lib/chunks/{panel-bzNmFlEZ.mjs → panel-CjfnpA-4.cjs} +532 -244
- package/dist-lib/chunks/panel-CjfnpA-4.cjs.map +1 -0
- package/dist-lib/chunks/{panel-Ds15whqp.mjs → panel-DZ7X1NZV.mjs} +547 -259
- package/dist-lib/chunks/panel-DZ7X1NZV.mjs.map +1 -0
- package/dist-lib/chunks/{useTheme-Dee4mo-A.mjs → useTheme-Dee4mo-A.cjs} +1 -1
- package/dist-lib/chunks/{useTheme-Dee4mo-A.mjs.map → useTheme-Dee4mo-A.cjs.map} +1 -1
- package/dist-lib/index.cjs +23 -76
- package/dist-lib/index.cjs.map +1 -1
- package/dist-lib/index.mjs +89 -142
- package/dist-lib/index.mjs.map +1 -1
- package/dist-lib/preview/chat.cjs +38 -39
- package/dist-lib/preview/chat.cjs.map +1 -1
- package/dist-lib/preview/chat.mjs +35 -36
- package/dist-lib/preview/chat.mjs.map +1 -1
- package/dist-lib/preview/clientes.cjs +22 -22
- package/dist-lib/preview/clientes.cjs.map +1 -1
- package/dist-lib/preview/clientes.mjs +20 -20
- package/dist-lib/preview/clientes.mjs.map +1 -1
- package/dist-lib/preview/dashboard.cjs +40 -40
- package/dist-lib/preview/dashboard.cjs.map +1 -1
- package/dist-lib/preview/dashboard.mjs +38 -38
- package/dist-lib/preview/dashboard.mjs.map +1 -1
- package/dist-lib/preview/mocks.cjs +3 -3
- package/dist-lib/preview/mocks.mjs +1 -1
- package/dist-lib/theme.css +18 -122
- package/dist-lib/tokens.cjs +24 -160
- package/dist-lib/tokens.cjs.map +1 -1
- package/dist-lib/tokens.mjs +24 -160
- package/dist-lib/tokens.mjs.map +1 -1
- package/package.json +142 -142
- package/dist-lib/chunks/app-shell-BNTvOETJ.mjs.map +0 -1
- package/dist-lib/chunks/app-shell-CDy42aNI.mjs.map +0 -1
- package/dist-lib/chunks/badge-B_2Zt52o.mjs.map +0 -1
- package/dist-lib/chunks/badge-DKpXURa1.mjs.map +0 -1
- package/dist-lib/chunks/chip-group-CsKBBHW2.mjs.map +0 -1
- package/dist-lib/chunks/chip-group-D3D0i72q.mjs.map +0 -1
- package/dist-lib/chunks/clientes-showcase-mocks-BMfbNNJh.mjs.map +0 -1
- package/dist-lib/chunks/clientes-showcase-mocks-Cq9u3nGZ.mjs.map +0 -1
- package/dist-lib/chunks/input-374MpdBL.mjs.map +0 -1
- package/dist-lib/chunks/input-DF4XAWmr.mjs.map +0 -1
- package/dist-lib/chunks/page-header-Dw-3wqAG.mjs.map +0 -1
- package/dist-lib/chunks/page-header-mC1gGtOI.mjs.map +0 -1
- package/dist-lib/chunks/panel-Ds15whqp.mjs.map +0 -1
- package/dist-lib/chunks/panel-bzNmFlEZ.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientes.mjs","sources":["../../src/preview/pages/ClientesShowcase/clientes-showcase.styles.ts","../../src/preview/pages/ClientesShowcase/components/NovoClienteDrawer/novo-cliente-drawer.tsx","../../src/preview/pages/ClientesShowcase/components/DetailDrawer/detail-drawer.styles.ts","../../src/preview/pages/ClientesShowcase/components/DetailDrawer/detail-drawer.tsx","../../src/preview/pages/ClientesShowcase/ClientesShowcase.tsx"],"sourcesContent":["import { tv } from \"@/utils/tv\";\n\n/**\n * Layout em grid de 2 colunas usado dentro do drawer pra pares de campos\n * (Email + WhatsApp, Cidade + Valor).\n */\nexport const drawerFormStyles = tv({\n slots: {\n twoCols: \"grid grid-cols-2 gap-gp-xl\",\n fieldLabel:\n \"text-[12.5px] font-semibold tracking-[0.01em] leading-none text-fg-default dark:text-fg-muted select-none\",\n statusDot: \"inline-block size-[8px] rounded-radius-full mr-gp-xs shrink-0\",\n },\n});\n","import { useEffect, useState } from \"react\";\nimport { Panel } from \"@/components/ui/Panel\";\nimport { Button } from \"@/components/ui/Button/button\";\nimport {\n FormField,\n FormFieldInput,\n FormFieldSelect,\n FormFieldTextarea,\n} from \"@/components/ui/FormField\";\nimport { ChipGroup, ChipGroupItem } from \"@/components/ui/Chip\";\nimport { STATUSES, CATEGORIES } from \"../../../TableDoc\";\nimport { CITIES, STATUS_DOT } from \"../../clientes-showcase-mocks\";\nimport { drawerFormStyles } from \"../../clientes-showcase.styles\";\nimport type { NovoClienteFormData } from \"../../clientes-showcase.types\";\n\nconst INITIAL_FORM: NovoClienteFormData = {\n name: \"\",\n email: \"\",\n whatsapp: \"\",\n statusId: \"active\",\n categoryId: \"lead\",\n city: \"\",\n value: 0,\n notes: \"\",\n};\n\nexport type NovoClienteDrawerProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Disparado ao confirmar — drawer fecha automaticamente após o submit. */\n onSubmit?: (data: NovoClienteFormData) => void;\n};\n\n/**\n * Drawer \"Novo cliente\" — replica visual do TblClientFormDrawer\n * (sandbox /design-and-table-v2), recompilado em cima dos componentes do DS:\n * Panel + FormField (Input / Select / Textarea) + ChipGroup + Button.\n *\n * Layout (top → bottom):\n * 1. Nome* — full width\n * 2. Email + WhatsApp — 2 cols\n * 3. Status — ChipGroup com dot colorido\n * 4. Categoria — ChipGroup\n * 5. Cidade + Valor R$ — 2 cols\n * 6. Notas — textarea full width\n */\nexport function NovoClienteDrawer({\n open,\n onOpenChange,\n onSubmit,\n}: NovoClienteDrawerProps) {\n const s = drawerFormStyles();\n const [form, setForm] = useState<NovoClienteFormData>(INITIAL_FORM);\n\n // Reseta form sempre que abrir\n useEffect(() => {\n if (open) setForm(INITIAL_FORM);\n }, [open]);\n\n const canSubmit = form.name.trim().length > 0;\n\n const handleSubmit = () => {\n if (!canSubmit) return;\n onSubmit?.(form);\n onOpenChange(false);\n };\n\n return (\n <Panel\n open={open}\n onOpenChange={onOpenChange}\n title=\"Novo cliente\"\n side=\"right\"\n size=\"md\"\n footer={\n <>\n <Button\n variant=\"outline\"\n color=\"secondary\"\n size=\"md\"\n onClick={() => onOpenChange(false)}\n >\n Cancelar\n </Button>\n <Button\n variant=\"filled\"\n color=\"primary\"\n size=\"md\"\n disabled={!canSubmit}\n onClick={handleSubmit}\n >\n Criar cliente\n </Button>\n </>\n }\n >\n <FormFieldInput\n label=\"Nome\"\n required\n placeholder=\"Maria Silva\"\n value={form.name}\n onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}\n />\n\n <div className={s.twoCols()}>\n <FormFieldInput\n label=\"Email\"\n type=\"email\"\n placeholder=\"cliente@exemplo.com\"\n value={form.email}\n onChange={(e) => setForm((f) => ({ ...f, email: e.target.value }))}\n />\n <FormFieldInput\n label=\"WhatsApp\"\n type=\"tel\"\n placeholder=\"55 11 99999-9999\"\n value={form.whatsapp}\n onChange={(e) => setForm((f) => ({ ...f, whatsapp: e.target.value }))}\n />\n </div>\n\n <FormField label=\"Status\">\n {() => (\n <ChipGroup\n type=\"single\"\n value={form.statusId}\n onValueChange={(v) =>\n v &&\n setForm((f) => ({\n ...f,\n statusId: v as keyof typeof STATUSES,\n }))\n }\n size=\"md\"\n shape=\"pill\"\n ariaLabel=\"Status do cliente\"\n >\n {Object.entries(STATUSES).map(([id, st]) => (\n <ChipGroupItem key={id} value={id}>\n <span\n className={s.statusDot()}\n style={{ background: STATUS_DOT[id] ?? st.color }}\n aria-hidden\n />\n {st.label}\n </ChipGroupItem>\n ))}\n </ChipGroup>\n )}\n </FormField>\n\n <FormField label=\"Categoria\">\n {() => (\n <ChipGroup\n type=\"single\"\n value={form.categoryId}\n onValueChange={(v) =>\n v &&\n setForm((f) => ({\n ...f,\n categoryId: v as keyof typeof CATEGORIES,\n }))\n }\n size=\"md\"\n shape=\"pill\"\n ariaLabel=\"Categoria do cliente\"\n >\n {Object.entries(CATEGORIES).map(([id, cat]) => (\n <ChipGroupItem key={id} value={id}>\n {cat.label}\n </ChipGroupItem>\n ))}\n </ChipGroup>\n )}\n </FormField>\n\n <div className={s.twoCols()}>\n <FormFieldSelect\n label=\"Cidade\"\n placeholder=\"Selecionar...\"\n value={form.city || undefined}\n onValueChange={(v) => setForm((f) => ({ ...f, city: v }))}\n options={CITIES.map((c) => ({ value: c, label: c }))}\n />\n <FormFieldInput\n label=\"Valor (R$)\"\n type=\"number\"\n startAddon=\"R$\"\n value={String(form.value)}\n onChange={(e) =>\n setForm((f) => ({ ...f, value: Number(e.target.value) }))\n }\n min={0}\n step={0.01}\n />\n </div>\n\n <FormFieldTextarea\n label=\"Notas\"\n placeholder=\"Observações sobre o cliente...\"\n rows={4}\n value={form.notes}\n onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}\n />\n </Panel>\n );\n}\n","import { tv } from \"@/utils/tv\";\n\n/**\n * Styles do DetailDrawer — apenas as partes internas (sections collapsibles\n * + DetailField). O shell flutuante (aside, header com avatar+meta, footer\n * com botões) é delegado ao `<FloatingPanel>` do DS.\n */\nexport const detailDrawerStyles = tv({\n slots: {\n section: \"border-b border-border-default last:border-b-0\",\n sectionHead: [\n \"flex items-center justify-between w-full\",\n \"px-[18px] py-[14px]\",\n \"bg-transparent border-0 cursor-pointer text-left\",\n \"text-[13px] font-semibold text-fg-default\",\n \"transition-colors duration-150\",\n \"hover:bg-bg-muted\",\n \"focus-visible:outline-none focus-visible:bg-bg-muted\",\n ],\n sectionChev: \"size-[14px] text-fg-muted transition-transform duration-200\",\n sectionChevOpen: \"rotate-180\",\n sectionBody: \"flex flex-col gap-gp-md px-[18px] pb-pad-2xl\",\n\n field: \"flex items-baseline justify-between gap-gp-md text-[13px]\",\n fieldLabel: \"text-[12px] text-fg-muted shrink-0\",\n fieldValue: \"text-fg-default text-right break-words min-w-0\",\n },\n});\n","import { useState, type ReactNode } from \"react\";\nimport { ChevronDown, Pencil, Trash2 } from \"lucide-react\";\nimport { Avatar, AvatarFallback } from \"@/components/shadcn/avatar\";\nimport { Button } from \"@/components/ui/Button/button\";\nimport { Chip } from \"@/components/ui/Chip\";\nimport { FloatingPanel } from \"@/components/ui/FloatingPanel\";\nimport { STATUSES, CATEGORIES, AGENTS } from \"../../../TableDoc\";\nimport {\n CATEGORY_KIND,\n STATUS_DOT,\n formatBRL,\n formatShortDate,\n} from \"../../clientes-showcase-mocks\";\nimport { detailDrawerStyles } from \"./detail-drawer.styles\";\nimport type { DetailDrawerProps } from \"./detail-drawer.types\";\n\n/* ── Helpers internos ────────────────────────────────────────────── */\n\nfunction formatLongDate(ms: number): string {\n if (!ms) return \"—\";\n const d = new Date(ms);\n return d.toLocaleDateString(\"pt-BR\", {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n });\n}\n\ntype SectionId = \"contact\" | \"meta\" | \"notes\";\n\n/* ── DetailField (label : value) ────────────────────────────────── */\n\ntype DetailFieldProps = {\n label: string;\n value: ReactNode;\n s: ReturnType<typeof detailDrawerStyles>;\n};\n\nfunction DetailField({ label, value, s }: DetailFieldProps) {\n return (\n <div className={s.field()}>\n <span className={s.fieldLabel()}>{label}</span>\n <span className={s.fieldValue()}>{value || \"—\"}</span>\n </div>\n );\n}\n\n/* ── DetailSection (collapsible) ─────────────────────────────────── */\n\ntype DetailSectionProps = {\n id: SectionId;\n title: string;\n open: boolean;\n onToggle: (id: SectionId) => void;\n children: ReactNode;\n s: ReturnType<typeof detailDrawerStyles>;\n};\n\nfunction DetailSection({\n id,\n title,\n open,\n onToggle,\n children,\n s,\n}: DetailSectionProps) {\n return (\n <section className={s.section()}>\n <button\n type=\"button\"\n className={s.sectionHead()}\n onClick={() => onToggle(id)}\n aria-expanded={open}\n >\n <span>{title}</span>\n <ChevronDown\n className={[s.sectionChev(), open ? s.sectionChevOpen() : \"\"].join(\" \")}\n />\n </button>\n {open && <div className={s.sectionBody()}>{children}</div>}\n </section>\n );\n}\n\n/* ── DetailDrawer ────────────────────────────────────────────────── */\n\n/**\n * Drawer \"Detalhes do cliente\" — usa `<FloatingPanel>` do DS (non-modal,\n * resizable, maximizable, responsive). Replica visual do `TblDetailsPanel`\n * do sandbox /design-and-table-v2.\n */\nexport function DetailDrawer({\n row,\n onClose,\n onEdit,\n onDelete,\n onSave,\n}: DetailDrawerProps) {\n const s = detailDrawerStyles();\n const [openSections, setOpenSections] = useState<Set<SectionId>>(\n () => new Set([\"contact\", \"meta\", \"notes\"]),\n );\n\n const toggle = (id: SectionId) => {\n setOpenSections((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n // Mantém ordem dos hooks estável independente de `row` — depois do toggle.\n if (!row) return null;\n\n const status = STATUSES[row.statusId];\n const cat = CATEGORIES[row.categoryId as keyof typeof CATEGORIES];\n const agent = AGENTS[row.agentId as keyof typeof AGENTS];\n const agentInitials =\n agent?.name.split(\" \").map((p) => p[0]).join(\"\").slice(0, 2) ?? \"?\";\n\n return (\n <FloatingPanel\n open={row !== null}\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n side=\"right\"\n size=\"md\"\n resizable\n maximizable\n resizableStorageKey=\"clientes-showcase.detail-drawer.width\"\n titleSlot={\n <div className=\"flex items-center gap-gp-md min-w-0\">\n <Avatar\n className=\"size-[40px] shrink-0\"\n style={{ background: row.avatarColor }}\n >\n <AvatarFallback className=\"bg-transparent text-white text-[14px] font-bold\">\n {row.initials}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex flex-col min-w-0 flex-1\">\n <div className=\"text-[15px] font-semibold text-fg-default whitespace-nowrap overflow-hidden text-ellipsis\">\n {row.name}\n </div>\n <div className=\"flex items-center gap-[6px] mt-[2px] text-[12px] text-fg-muted\">\n <span>{row.id}</span>\n <span className=\"opacity-50\">·</span>\n <span className=\"inline-flex items-center gap-[6px]\">\n <span\n className=\"inline-block size-[8px] rounded-radius-full shrink-0\"\n style={{ background: STATUS_DOT[row.statusId] ?? status?.color }}\n aria-hidden\n />\n {status?.label}\n </span>\n </div>\n </div>\n </div>\n }\n headerActions={\n <>\n <Button\n variant=\"soft\"\n color=\"secondary\"\n size=\"icon-sm\"\n aria-label=\"Editar\"\n onClick={() => onEdit?.(row)}\n >\n <Pencil />\n </Button>\n <Button\n variant=\"soft\"\n color=\"critical\"\n size=\"icon-sm\"\n aria-label=\"Excluir\"\n onClick={() => onDelete?.(row)}\n >\n <Trash2 />\n </Button>\n </>\n }\n footer={\n <>\n <Button variant=\"outline\" color=\"secondary\" size=\"sm\" onClick={onClose}>\n Cancelar\n </Button>\n <Button\n variant=\"filled\"\n color=\"primary\"\n size=\"sm\"\n onClick={() => onSave?.(row)}\n >\n Salvar alterações\n </Button>\n </>\n }\n >\n <DetailSection\n id=\"contact\"\n title=\"Contato\"\n open={openSections.has(\"contact\")}\n onToggle={toggle}\n s={s}\n >\n <DetailField\n label=\"Email\"\n value={\n <a\n href={`mailto:${row.email}`}\n className=\"text-fg-brand hover:underline\"\n >\n {row.email}\n </a>\n }\n s={s}\n />\n <DetailField\n label=\"Telefone\"\n value={\n <a\n href={`tel:${row.phone.replace(/\\D/g, \"\")}`}\n className=\"text-fg-brand hover:underline\"\n >\n {row.phone}\n </a>\n }\n s={s}\n />\n <DetailField label=\"Localização\" value={row.location} s={s} />\n </DetailSection>\n\n <DetailSection\n id=\"meta\"\n title=\"Atendimento\"\n open={openSections.has(\"meta\")}\n onToggle={toggle}\n s={s}\n >\n <DetailField label=\"ID\" value={row.id} s={s} />\n <DetailField\n label=\"Categoria\"\n value={\n cat ? (\n <Chip\n color={CATEGORY_KIND[row.categoryId] ?? \"info\"}\n variant=\"soft\"\n size=\"sm\"\n shape=\"pill\"\n >\n {cat.label}\n </Chip>\n ) : (\n \"—\"\n )\n }\n s={s}\n />\n <DetailField\n label=\"Atribuído a\"\n value={\n agent ? (\n <span className=\"inline-flex items-center gap-gp-sm\">\n <Avatar\n className=\"size-[22px]\"\n style={{ background: agent.color }}\n >\n <AvatarFallback className=\"bg-transparent text-white text-[10px] font-bold\">\n {agentInitials}\n </AvatarFallback>\n </Avatar>\n {agent.name}\n </span>\n ) : (\n \"—\"\n )\n }\n s={s}\n />\n <DetailField label=\"Valor\" value={formatBRL(row.value)} s={s} />\n <DetailField label=\"Criado em\" value={formatLongDate(row.createdAt)} s={s} />\n <DetailField\n label=\"Último contato\"\n value={formatShortDate(row.lastContact)}\n s={s}\n />\n </DetailSection>\n\n <DetailSection\n id=\"notes\"\n title=\"Anotações\"\n open={openSections.has(\"notes\")}\n onToggle={toggle}\n s={s}\n >\n <p className=\"text-[12.5px] text-fg-muted\">Sem anotações.</p>\n </DetailSection>\n </FloatingPanel>\n );\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useTheme, type Theme } from \"@/hooks/useTheme\";\nimport {\n Archive,\n Clock,\n Copy,\n Download,\n Maximize2,\n MessageSquare,\n MoreHorizontal,\n Pencil,\n Plus,\n RotateCcw,\n Trash2,\n Upload,\n} from \"lucide-react\";\nimport {\n CATEGORIES,\n AGENTS,\n type ClientRow,\n} from \"../TableDoc\";\nimport {\n DataTable,\n presetView,\n type DataTableColumnDef,\n type DataTableKanbanConfig,\n type DataTablePresetView,\n type DataTableRef,\n type DataTableViewMode,\n type FilterModel,\n} from \"@/components/ui/DataTable\";\nimport { AppShell } from \"@/components/ui/AppShell\";\nimport { Button } from \"@/components/ui/Button/button\";\nimport { Chip } from \"@/components/ui/Chip\";\nimport { PageHeader } from \"@/components/ui/PageHeader\";\nimport { BulkActionButton } from \"@/components/ui/TableToolbar\";\nimport { Avatar, AvatarFallback } from \"@/components/shadcn/avatar\";\nimport {\n APP_SHELL_CONTEXTS,\n APP_SHELL_COMMANDS,\n APP_SHELL_NOTIFICATIONS,\n APP_SHELL_MESSAGES,\n APP_SHELL_THEME_OPTIONS,\n APP_SHELL_LAYOUT_OPTIONS,\n APP_SHELL_USER,\n} from \"../../mocks/app-shell-mocks\";\nimport {\n CLIENTS_87,\n STATUS_OPTIONS,\n CATEGORY_OPTIONS,\n AGENT_OPTIONS,\n AGENTS_LOOKUP,\n KANBAN_COLUMNS,\n CATEGORY_KIND,\n formatBRL,\n formatShortDate,\n} from \"./clientes-showcase-mocks\";\nimport { NovoClienteDrawer } from \"./components/NovoClienteDrawer\";\nimport { DetailDrawer } from \"./components/DetailDrawer\";\nimport { AlertModal } from \"@/components/ui/AlertModal\";\n\n/* ── Columns declarativas (type-based) ─────────────────────────── */\n\ntype ColumnHandlers = {\n /** Pede confirmação de exclusão (abre o AlertModal). */\n onAskDelete: (row: ClientRow) => void;\n};\n\nfunction buildColumns(handlers: ColumnHandlers): DataTableColumnDef<ClientRow>[] {\n return [\n { field: \"id\", headerName: \"ID\", type: \"text\", width: 130 },\n {\n field: \"name\",\n headerName: \"Nome\",\n type: \"user\",\n sortable: true,\n width: 220,\n typeOptions: {\n users: Object.fromEntries(\n CLIENTS_87.map((c) => [\n c.name,\n {\n name: c.name,\n initials: c.initials,\n color: c.avatarColor,\n },\n ]),\n ),\n },\n valueGetter: (row) => row.name,\n },\n {\n field: \"email\",\n headerName: \"Email\",\n type: \"email\",\n enableColumnFilter: true,\n filterType: \"text\",\n },\n {\n field: \"phone\",\n headerName: \"Telefone\",\n type: \"phone\",\n },\n {\n field: \"statusId\",\n headerName: \"Status\",\n type: \"status\",\n enableColumnFilter: true,\n filterType: \"multiSelect\",\n filterOptions: STATUS_OPTIONS,\n },\n {\n field: \"categoryId\",\n headerName: \"Categoria\",\n type: \"badge\",\n enableColumnFilter: true,\n filterType: \"multiSelect\",\n filterOptions: CATEGORY_OPTIONS,\n },\n {\n field: \"agentId\",\n headerName: \"Atribuído\",\n type: \"user\",\n enableColumnFilter: true,\n filterType: \"select\",\n filterOptions: AGENT_OPTIONS,\n typeOptions: { users: AGENTS_LOOKUP },\n },\n {\n field: \"value\",\n headerName: \"Valor\",\n type: \"currency\",\n sortable: true,\n enableColumnFilter: true,\n filterType: \"number\",\n aggregate: \"sum\",\n aggregateFormatter: (v) =>\n new Intl.NumberFormat(\"pt-BR\", { style: \"currency\", currency: \"BRL\" }).format(v),\n },\n {\n field: \"createdAt\",\n headerName: \"Criado em\",\n type: \"date\",\n sortable: true,\n enableColumnFilter: true,\n filterType: \"date\",\n width: 130,\n },\n {\n field: \"lastContact\",\n headerName: \"Último contato\",\n type: \"date\",\n sortable: true,\n width: 150,\n },\n {\n field: \"location\",\n headerName: \"Localização\",\n type: \"text\",\n minWidth: 150,\n },\n {\n field: \"_actions\",\n headerName: \"\",\n type: \"actions\",\n width: 64,\n pinned: \"right\",\n getActions: ({ row }) => [\n {\n id: \"edit\",\n label: \"Editar\",\n icon: <Pencil />,\n showInMenu: true,\n onClick: () => console.log(\"Editar\", row.id),\n },\n {\n id: \"whatsapp\",\n label: \"Abrir atendimento (WhatsApp)\",\n icon: <MessageSquare />,\n showInMenu: true,\n onClick: () => console.log(\"Atendimento\", row.id),\n },\n {\n id: \"archive\",\n label: \"Arquivar\",\n icon: <Archive />,\n showInMenu: true,\n onClick: () => console.log(\"Arquivar\", row.id),\n },\n {\n id: \"delete\",\n label: \"Excluir cliente\",\n icon: <Trash2 />,\n showInMenu: true,\n destructive: true,\n onClick: () => handlers.onAskDelete(row),\n },\n ],\n },\n ];\n}\n\n/* ── Saved views / Presets — tabs do toolbar ───────────────────── */\n\nconst DEFAULT_VIEWS: DataTablePresetView[] = [\n presetView({\n id: \"preset:meus\",\n name: \"Meus\",\n filters: [{ field: \"agentId\", value: \"you\" }],\n }),\n presetView({\n id: \"preset:ativos\",\n name: \"Ativos\",\n filters: [{ field: \"statusId\", value: \"active\" }],\n }),\n presetView({\n id: \"preset:royals\",\n name: \"Royals\",\n filters: [{ field: \"categoryId\", value: \"royal\" }],\n }),\n presetView({\n id: \"preset:ultimos-7-dias\",\n name: \"Últimos 7 dias\",\n sort: [{ field: \"createdAt\", direction: \"desc\" }],\n }),\n];\n\n/* ── Filtros iniciais (Status=Ativo + Categoria=Royal — print) ─── */\n\nconst INITIAL_FILTERS: FilterModel = {\n items: [\n { id: \"filter-status-ativo\", field: \"statusId\", operator: \"equals\", value: \"active\" },\n { id: \"filter-categoria-royal\", field: \"categoryId\", operator: \"equals\", value: \"royal\" },\n ],\n logicOperator: \"AND\",\n};\n\n/* ── Kanban config (renderCard com JSX) ────────────────────────── */\n\nconst KANBAN_CONFIG: DataTableKanbanConfig<ClientRow> = {\n groupByField: \"statusId\",\n columns: KANBAN_COLUMNS,\n renderCard: ({ row }) => {\n const cat = CATEGORIES[row.categoryId as keyof typeof CATEGORIES];\n const agent = AGENTS[row.agentId as keyof typeof AGENTS];\n const agentInitials = agent?.name.split(\" \").map((s) => s[0]).join(\"\").slice(0, 2) ?? \"?\";\n return {\n title: row.name,\n subtitle: row.id,\n avatar: (\n <Avatar className=\"size-[28px]\" style={{ background: row.avatarColor }}>\n <AvatarFallback className=\"bg-transparent text-white text-[11px] font-bold\">\n {row.initials}\n </AvatarFallback>\n </Avatar>\n ),\n chip: cat ? (\n <Chip\n color={CATEGORY_KIND[row.categoryId] ?? \"info\"}\n variant=\"soft\"\n size=\"sm\"\n shape=\"pill\"\n >\n {cat.label}\n </Chip>\n ) : null,\n value: formatBRL(row.value),\n footerLeft: agent ? (\n <span className=\"inline-flex items-center gap-gp-sm min-w-0 flex-1\">\n <Avatar className=\"size-[22px]\" style={{ background: agent.color }}>\n <AvatarFallback className=\"bg-transparent text-white text-[10px] font-bold\">\n {agentInitials}\n </AvatarFallback>\n </Avatar>\n <span className=\"text-[12px] text-fg-muted whitespace-nowrap overflow-hidden text-ellipsis\">\n {agent.name}\n </span>\n </span>\n ) : null,\n footerRight: (\n <span className=\"inline-flex items-center gap-[4px] text-[11.5px] text-fg-muted [font-variant-numeric:tabular-nums] shrink-0\">\n <Clock size={11} strokeWidth={1.8} aria-hidden />\n {formatShortDate(row.lastContact)}\n </span>\n ),\n };\n },\n};\n\n/* ═══════════════════════════════════════════════════════════════════════════\n Page — Clientes (showcase usando AppShell + DataTable real)\n ═══════════════════════════════════════════════════════════════════════════ */\n\ntype ConfirmDeleteState = {\n ids: string[];\n label: string;\n /** Callback opcional após confirmar — usado pelo bulk pra limpar seleção. */\n onAfter?: () => void;\n} | null;\n\nexport default function ClientesShowcase() {\n const { theme, setTheme } = useTheme();\n const [rows, setRows] = useState<ClientRow[]>(() => CLIENTS_87);\n const [layout, setLayout] = useState<string>(\"fluid\");\n const [filterModel, setFilterModel] = useState<FilterModel>(INITIAL_FILTERS);\n const [viewMode, setViewMode] = useState<DataTableViewMode>(\"table\");\n const [novoClienteOpen, setNovoClienteOpen] = useState(false);\n const [detailRowId, setDetailRowId] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState<ConfirmDeleteState>(null);\n const detailRow = detailRowId ? rows.find((r) => r.id === detailRowId) ?? null : null;\n const tableRef = useRef<DataTableRef>(null);\n\n const askDelete = useCallback(\n (row: ClientRow) =>\n setConfirmDelete({ ids: [row.id], label: row.name }),\n [],\n );\n\n const askBulkDelete = useCallback(\n (ids: string[], onAfter: () => void) =>\n setConfirmDelete({\n ids,\n label: `${ids.length} cliente${ids.length === 1 ? \"\" : \"s\"}`,\n onAfter,\n }),\n [],\n );\n\n const handleConfirmDelete = useCallback(() => {\n if (!confirmDelete) return;\n const ids = new Set(confirmDelete.ids);\n setRows((prev) => prev.filter((r) => !ids.has(r.id)));\n if (detailRowId && ids.has(detailRowId)) setDetailRowId(null);\n confirmDelete.onAfter?.();\n setConfirmDelete(null);\n }, [confirmDelete, detailRowId]);\n\n const columns = useMemo(\n () => buildColumns({ onAskDelete: askDelete }),\n [askDelete],\n );\n\n return (\n <AppShell\n contexts={APP_SHELL_CONTEXTS}\n defaultActiveContextId=\"inbox\"\n defaultActiveItemHref=\"#atendimentos\"\n breadcrumb={[{ label: \"Atendimentos\" }]}\n commandGroups={APP_SHELL_COMMANDS}\n notifications={{\n items: APP_SHELL_NOTIFICATIONS,\n onMarkAllRead: () => alert(\"Marcar todas como lidas\"),\n onMoreActions: () => alert(\"Mais ações\"),\n onViewAll: () => alert(\"Ver todas\"),\n }}\n messages={{\n items: APP_SHELL_MESSAGES,\n onNewMessage: () => alert(\"Nova mensagem\"),\n onExpand: () => alert(\"Expandir\"),\n onViewAll: () => alert(\"Ver todas\"),\n }}\n theme={theme}\n onThemeChange={(id) => setTheme(id as Theme)}\n themeOptions={APP_SHELL_THEME_OPTIONS}\n user={APP_SHELL_USER}\n layout={layout}\n onLayoutChange={setLayout}\n layoutOptions={APP_SHELL_LAYOUT_OPTIONS}\n onSettings={() => alert(\"Abrir Configurações\")}\n onLogout={() => alert(\"Sair (mock)\")}\n >\n <PageHeader\n title=\"Clientes\"\n description=\"Gerencie sua base de clientes, acompanhe status de cadastro e abra atendimentos diretos pelo WhatsApp.\"\n badge={\n <Chip color=\"primary\" variant=\"soft\" size=\"sm\" shape=\"rounded\">\n {rows.length.toLocaleString(\"pt-BR\")} registros\n </Chip>\n }\n actions={\n <>\n <Button\n variant=\"outline\"\n color=\"secondary\"\n size=\"icon-md\"\n aria-label=\"Mais ações\"\n onClick={() => alert(\"Mais ações\")}\n >\n <MoreHorizontal />\n </Button>\n <Button\n variant=\"filled\"\n color=\"primary\"\n size=\"md\"\n iconLeft={<Plus />}\n onClick={() => setNovoClienteOpen(true)}\n >\n Novo cliente\n </Button>\n </>\n }\n />\n\n {/* DataTable — ocupa o resto do body ──────────────────────── */}\n <DataTable<ClientRow>\n ref={tableRef}\n rows={rows}\n columns={columns}\n getRowId={(r) => r.id}\n persistId=\"showcase-clientes-crud\"\n defaultViews={DEFAULT_VIEWS}\n filterModel={filterModel}\n onFilterModelChange={setFilterModel}\n viewMode={viewMode}\n onViewModeChange={setViewMode}\n kanbanConfig={KANBAN_CONFIG}\n toolbar={{\n enableSearch: true,\n enableFilters: true,\n enableColumns: true,\n enableDensity: true,\n enableExport: true,\n moreMenu: {\n items: [\n {\n id: \"fullscreen\",\n label: \"Tela cheia\",\n icon: <Maximize2 />,\n onSelect: () => alert(\"Tela cheia\"),\n },\n {\n id: \"duplicate\",\n label: \"Duplicar visualização\",\n icon: <Copy />,\n onSelect: () => alert(\"Duplicar visualização\"),\n },\n {\n id: \"import\",\n label: \"Importar CSV\",\n icon: <Upload />,\n onSelect: () => alert(\"Importar CSV\"),\n },\n {\n id: \"reset\",\n label: \"Resetar visualização\",\n icon: <RotateCcw />,\n destructive: true,\n onSelect: () => tableRef.current?.resetPersistedState(),\n },\n ],\n },\n }}\n paginationConfig={{\n enabled: true,\n initialPageSize: 10,\n pageSizeOptions: [10, 25, 50, 100],\n }}\n selectionConfig={{\n enabled: true,\n enableGlobal: true,\n actions: (selectedIds, clearSelection) => (\n <>\n <BulkActionButton\n icon={<Download />}\n onClick={() => tableRef.current?.exportCsv(\"selected\")}\n >\n Exportar\n </BulkActionButton>\n <BulkActionButton\n icon={<Trash2 />}\n variant=\"danger\"\n onClick={() => askBulkDelete(selectedIds.map(String), clearSelection)}\n >\n Excluir\n </BulkActionButton>\n </>\n ),\n }}\n onCellEditCommit={async ({ id, field, value }) => {\n await new Promise((res) => setTimeout(res, 400));\n setRows((prev) =>\n prev.map((r) => (r.id === id ? { ...r, [field]: value } : r)),\n );\n }}\n onRowClick={(row) => setDetailRowId(row.id)}\n className=\"flex-1 min-h-0\"\n />\n\n {/* Drawer \"Novo cliente\" — controlado pelo botão do header */}\n <NovoClienteDrawer\n open={novoClienteOpen}\n onOpenChange={setNovoClienteOpen}\n onSubmit={(data) => {\n console.log(\"Novo cliente:\", data);\n alert(`Cliente \"${data.name}\" criado (mock)`);\n }}\n />\n\n {/* DetailDrawer — abre ao clicar numa row, slide-in da direita SEM\n backdrop modal (tabela continua interativa atrás). */}\n <DetailDrawer\n row={detailRow}\n onClose={() => setDetailRowId(null)}\n onEdit={(r) => console.log(\"Editar\", r.id)}\n onDelete={(r) => askDelete(r)}\n onSave={(r) => alert(`Salvar alterações em ${r.name} (mock)`)}\n />\n\n {/* AlertModal de confirmação de exclusão — compartilhado entre\n row action menu, bulk action e DetailDrawer.onDelete. */}\n <AlertModal\n open={confirmDelete !== null}\n onOpenChange={(open) => {\n if (!open) setConfirmDelete(null);\n }}\n tone=\"danger\"\n title={\n confirmDelete && confirmDelete.ids.length > 1\n ? `Excluir ${confirmDelete.label}?`\n : \"Excluir cliente?\"\n }\n description={\n confirmDelete\n ? confirmDelete.ids.length > 1\n ? `Esta ação não pode ser desfeita. ${confirmDelete.label} serão removidos permanentemente.`\n : `Esta ação não pode ser desfeita. \"${confirmDelete.label}\" será removido permanentemente.`\n : null\n }\n confirmLabel=\"Excluir\"\n cancelLabel=\"Cancelar\"\n onConfirm={handleConfirmDelete}\n />\n </AppShell>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"clientes.mjs","sources":["../../src/preview/pages/ClientesShowcase/clientes-showcase.styles.ts","../../src/preview/pages/ClientesShowcase/components/NovoClienteDrawer/novo-cliente-drawer.tsx","../../src/preview/pages/ClientesShowcase/components/DetailDrawer/detail-drawer.styles.ts","../../src/preview/pages/ClientesShowcase/components/DetailDrawer/detail-drawer.tsx","../../src/preview/pages/ClientesShowcase/ClientesShowcase.tsx"],"sourcesContent":["import { tv } from \"@/utils/tv\";\r\n\r\n/**\r\n * Layout em grid de 2 colunas usado dentro do drawer pra pares de campos\r\n * (Email + WhatsApp, Cidade + Valor).\r\n */\r\nexport const drawerFormStyles = tv({\r\n slots: {\r\n twoCols: \"grid grid-cols-2 gap-gp-xl\",\r\n fieldLabel:\r\n \"text-body-sm font-semibold tracking-[0.01em] leading-none text-fg-default dark:text-fg-muted select-none\",\r\n statusDot: \"inline-block size-[8px] rounded-radius-full mr-gp-xs shrink-0\",\r\n },\r\n});\r\n","import { useEffect, useState } from \"react\";\nimport { Panel } from \"@/components/ui/Panel\";\nimport { Button } from \"@/components/ui/Button/button\";\nimport {\n FormField,\n FormFieldInput,\n FormFieldSelect,\n FormFieldTextarea,\n} from \"@/components/ui/FormField\";\nimport { ChipGroup, ChipGroupItem } from \"@/components/ui/Chip\";\nimport { STATUSES, CATEGORIES } from \"../../../TableDoc\";\nimport { CITIES, STATUS_DOT } from \"../../clientes-showcase-mocks\";\nimport { drawerFormStyles } from \"../../clientes-showcase.styles\";\nimport type { NovoClienteFormData } from \"../../clientes-showcase.types\";\n\nconst INITIAL_FORM: NovoClienteFormData = {\n name: \"\",\n email: \"\",\n whatsapp: \"\",\n statusId: \"active\",\n categoryId: \"lead\",\n city: \"\",\n value: 0,\n notes: \"\",\n};\n\nexport type NovoClienteDrawerProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Disparado ao confirmar — drawer fecha automaticamente após o submit. */\n onSubmit?: (data: NovoClienteFormData) => void;\n};\n\n/**\n * Drawer \"Novo cliente\" — replica visual do TblClientFormDrawer\n * (sandbox /design-and-table-v2), recompilado em cima dos componentes do DS:\n * Panel + FormField (Input / Select / Textarea) + ChipGroup + Button.\n *\n * Layout (top → bottom):\n * 1. Nome* — full width\n * 2. Email + WhatsApp — 2 cols\n * 3. Status — ChipGroup com dot colorido\n * 4. Categoria — ChipGroup\n * 5. Cidade + Valor R$ — 2 cols\n * 6. Notas — textarea full width\n */\nexport function NovoClienteDrawer({\n open,\n onOpenChange,\n onSubmit,\n}: NovoClienteDrawerProps) {\n const s = drawerFormStyles();\n const [form, setForm] = useState<NovoClienteFormData>(INITIAL_FORM);\n\n // Reseta form sempre que abrir\n useEffect(() => {\n if (open) setForm(INITIAL_FORM);\n }, [open]);\n\n const canSubmit = form.name.trim().length > 0;\n\n const handleSubmit = () => {\n if (!canSubmit) return;\n onSubmit?.(form);\n onOpenChange(false);\n };\n\n return (\n <Panel\n open={open}\n onOpenChange={onOpenChange}\n title=\"Novo cliente\"\n side=\"right\"\n size=\"md\"\n footer={\n <>\n <Button\n variant=\"outline\"\n color=\"secondary\"\n size=\"md\"\n onClick={() => onOpenChange(false)}\n >\n Cancelar\n </Button>\n <Button\n variant=\"filled\"\n color=\"primary\"\n size=\"md\"\n disabled={!canSubmit}\n onClick={handleSubmit}\n >\n Criar cliente\n </Button>\n </>\n }\n >\n <FormFieldInput\n label=\"Nome\"\n required\n placeholder=\"Maria Silva\"\n value={form.name}\n onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}\n />\n\n <div className={s.twoCols()}>\n <FormFieldInput\n label=\"Email\"\n type=\"email\"\n placeholder=\"cliente@exemplo.com\"\n value={form.email}\n onChange={(e) => setForm((f) => ({ ...f, email: e.target.value }))}\n />\n <FormFieldInput\n label=\"WhatsApp\"\n type=\"tel\"\n placeholder=\"55 11 99999-9999\"\n value={form.whatsapp}\n onChange={(e) => setForm((f) => ({ ...f, whatsapp: e.target.value }))}\n />\n </div>\n\n <FormField label=\"Status\">\n {() => (\n <ChipGroup\n type=\"single\"\n value={form.statusId}\n onValueChange={(v) =>\n v &&\n setForm((f) => ({\n ...f,\n statusId: v as keyof typeof STATUSES,\n }))\n }\n size=\"md\"\n shape=\"pill\"\n ariaLabel=\"Status do cliente\"\n >\n {Object.entries(STATUSES).map(([id, st]) => (\n <ChipGroupItem key={id} value={id}>\n <span\n className={s.statusDot()}\n style={{ background: STATUS_DOT[id] ?? st.color }}\n aria-hidden\n />\n {st.label}\n </ChipGroupItem>\n ))}\n </ChipGroup>\n )}\n </FormField>\n\n <FormField label=\"Categoria\">\n {() => (\n <ChipGroup\n type=\"single\"\n value={form.categoryId}\n onValueChange={(v) =>\n v &&\n setForm((f) => ({\n ...f,\n categoryId: v as keyof typeof CATEGORIES,\n }))\n }\n size=\"md\"\n shape=\"pill\"\n ariaLabel=\"Categoria do cliente\"\n >\n {Object.entries(CATEGORIES).map(([id, cat]) => (\n <ChipGroupItem key={id} value={id}>\n {cat.label}\n </ChipGroupItem>\n ))}\n </ChipGroup>\n )}\n </FormField>\n\n <div className={s.twoCols()}>\n <FormFieldSelect\n label=\"Cidade\"\n placeholder=\"Selecionar...\"\n value={form.city || undefined}\n onValueChange={(v) => setForm((f) => ({ ...f, city: v }))}\n options={CITIES.map((c) => ({ value: c, label: c }))}\n />\n <FormFieldInput\n label=\"Valor (R$)\"\n type=\"number\"\n startAddon=\"R$\"\n value={String(form.value)}\n onChange={(e) =>\n setForm((f) => ({ ...f, value: Number(e.target.value) }))\n }\n min={0}\n step={0.01}\n />\n </div>\n\n <FormFieldTextarea\n label=\"Notas\"\n placeholder=\"Observações sobre o cliente...\"\n rows={4}\n value={form.notes}\n onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}\n />\n </Panel>\n );\n}\n","import { tv } from \"@/utils/tv\";\r\n\r\n/**\r\n * Styles do DetailDrawer — apenas as partes internas (sections collapsibles\r\n * + DetailField). O shell flutuante (aside, header com avatar+meta, footer\r\n * com botões) é delegado ao `<FloatingPanel>` do DS.\r\n */\r\nexport const detailDrawerStyles = tv({\r\n slots: {\r\n section: \"border-b border-border-default last:border-b-0\",\r\n sectionHead: [\r\n \"flex items-center justify-between w-full\",\r\n \"px-[18px] py-[14px]\",\r\n \"bg-transparent border-0 cursor-pointer text-left\",\r\n \"text-body-sm font-semibold text-fg-default\",\r\n \"transition-colors duration-150\",\r\n \"hover:bg-bg-muted\",\r\n \"focus-visible:outline-none focus-visible:bg-bg-muted\",\r\n ],\r\n sectionChev: \"size-[14px] text-fg-muted transition-transform duration-200\",\r\n sectionChevOpen: \"rotate-180\",\r\n sectionBody: \"flex flex-col gap-gp-md px-[18px] pb-pad-2xl\",\r\n\r\n field: \"flex items-baseline justify-between gap-gp-md text-body-sm font-normal\",\r\n fieldLabel: \"text-body-xs font-normal text-fg-muted shrink-0\",\r\n fieldValue: \"text-fg-default text-right break-words min-w-0\",\r\n },\r\n});\r\n","import { useState, type ReactNode } from \"react\";\r\nimport { ChevronDown, Pencil, Trash2 } from \"lucide-react\";\r\nimport { Avatar, AvatarFallback } from \"@/components/shadcn/avatar\";\r\nimport { Button } from \"@/components/ui/Button/button\";\r\nimport { Chip } from \"@/components/ui/Chip\";\r\nimport { FloatingPanel } from \"@/components/ui/FloatingPanel\";\r\nimport { STATUSES, CATEGORIES, AGENTS } from \"../../../TableDoc\";\r\nimport {\r\n CATEGORY_KIND,\r\n STATUS_DOT,\r\n formatBRL,\r\n formatShortDate,\r\n} from \"../../clientes-showcase-mocks\";\r\nimport { detailDrawerStyles } from \"./detail-drawer.styles\";\r\nimport type { DetailDrawerProps } from \"./detail-drawer.types\";\r\n\r\n/* ── Helpers internos ────────────────────────────────────────────── */\r\n\r\nfunction formatLongDate(ms: number): string {\r\n if (!ms) return \"—\";\r\n const d = new Date(ms);\r\n return d.toLocaleDateString(\"pt-BR\", {\r\n day: \"numeric\",\r\n month: \"long\",\r\n year: \"numeric\",\r\n });\r\n}\r\n\r\ntype SectionId = \"contact\" | \"meta\" | \"notes\";\r\n\r\n/* ── DetailField (label : value) ────────────────────────────────── */\r\n\r\ntype DetailFieldProps = {\r\n label: string;\r\n value: ReactNode;\r\n s: ReturnType<typeof detailDrawerStyles>;\r\n};\r\n\r\nfunction DetailField({ label, value, s }: DetailFieldProps) {\r\n return (\r\n <div className={s.field()}>\r\n <span className={s.fieldLabel()}>{label}</span>\r\n <span className={s.fieldValue()}>{value || \"—\"}</span>\r\n </div>\r\n );\r\n}\r\n\r\n/* ── DetailSection (collapsible) ─────────────────────────────────── */\r\n\r\ntype DetailSectionProps = {\r\n id: SectionId;\r\n title: string;\r\n open: boolean;\r\n onToggle: (id: SectionId) => void;\r\n children: ReactNode;\r\n s: ReturnType<typeof detailDrawerStyles>;\r\n};\r\n\r\nfunction DetailSection({\r\n id,\r\n title,\r\n open,\r\n onToggle,\r\n children,\r\n s,\r\n}: DetailSectionProps) {\r\n return (\r\n <section className={s.section()}>\r\n <button\r\n type=\"button\"\r\n className={s.sectionHead()}\r\n onClick={() => onToggle(id)}\r\n aria-expanded={open}\r\n >\r\n <span>{title}</span>\r\n <ChevronDown\r\n className={[s.sectionChev(), open ? s.sectionChevOpen() : \"\"].join(\" \")}\r\n />\r\n </button>\r\n {open && <div className={s.sectionBody()}>{children}</div>}\r\n </section>\r\n );\r\n}\r\n\r\n/* ── DetailDrawer ────────────────────────────────────────────────── */\r\n\r\n/**\r\n * Drawer \"Detalhes do cliente\" — usa `<FloatingPanel>` do DS (non-modal,\r\n * resizable, maximizable, responsive). Replica visual do `TblDetailsPanel`\r\n * do sandbox /design-and-table-v2.\r\n */\r\nexport function DetailDrawer({\r\n row,\r\n onClose,\r\n onEdit,\r\n onDelete,\r\n onSave,\r\n}: DetailDrawerProps) {\r\n const s = detailDrawerStyles();\r\n const [openSections, setOpenSections] = useState<Set<SectionId>>(\r\n () => new Set([\"contact\", \"meta\", \"notes\"]),\r\n );\r\n\r\n const toggle = (id: SectionId) => {\r\n setOpenSections((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(id)) next.delete(id);\r\n else next.add(id);\r\n return next;\r\n });\r\n };\r\n\r\n // Mantém ordem dos hooks estável independente de `row` — depois do toggle.\r\n if (!row) return null;\r\n\r\n const status = STATUSES[row.statusId];\r\n const cat = CATEGORIES[row.categoryId as keyof typeof CATEGORIES];\r\n const agent = AGENTS[row.agentId as keyof typeof AGENTS];\r\n const agentInitials =\r\n agent?.name.split(\" \").map((p) => p[0]).join(\"\").slice(0, 2) ?? \"?\";\r\n\r\n return (\r\n <FloatingPanel\r\n open={row !== null}\r\n onOpenChange={(open) => {\r\n if (!open) onClose();\r\n }}\r\n side=\"right\"\r\n size=\"md\"\r\n resizable\r\n maximizable\r\n resizableStorageKey=\"clientes-showcase.detail-drawer.width\"\r\n titleSlot={\r\n <div className=\"flex items-center gap-gp-md min-w-0\">\r\n <Avatar\r\n className=\"size-[40px] shrink-0\"\r\n style={{ background: row.avatarColor }}\r\n >\r\n <AvatarFallback className=\"bg-transparent text-white text-body-md font-bold\">\r\n {row.initials}\r\n </AvatarFallback>\r\n </Avatar>\r\n <div className=\"flex flex-col min-w-0 flex-1\">\r\n <div className=\"text-body-md font-semibold text-fg-default whitespace-nowrap overflow-hidden text-ellipsis\">\r\n {row.name}\r\n </div>\r\n <div className=\"flex items-center gap-[6px] mt-[2px] text-body-xs font-normal text-fg-muted\">\r\n <span>{row.id}</span>\r\n <span className=\"opacity-50\">·</span>\r\n <span className=\"inline-flex items-center gap-[6px]\">\r\n <span\r\n className=\"inline-block size-[8px] rounded-radius-full shrink-0\"\r\n style={{ background: STATUS_DOT[row.statusId] ?? status?.color }}\r\n aria-hidden\r\n />\r\n {status?.label}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n headerActions={\r\n <>\r\n <Button\r\n variant=\"soft\"\r\n color=\"secondary\"\r\n size=\"icon-sm\"\r\n aria-label=\"Editar\"\r\n onClick={() => onEdit?.(row)}\r\n >\r\n <Pencil />\r\n </Button>\r\n <Button\r\n variant=\"soft\"\r\n color=\"critical\"\r\n size=\"icon-sm\"\r\n aria-label=\"Excluir\"\r\n onClick={() => onDelete?.(row)}\r\n >\r\n <Trash2 />\r\n </Button>\r\n </>\r\n }\r\n footer={\r\n <>\r\n <Button variant=\"outline\" color=\"secondary\" size=\"sm\" onClick={onClose}>\r\n Cancelar\r\n </Button>\r\n <Button\r\n variant=\"filled\"\r\n color=\"primary\"\r\n size=\"sm\"\r\n onClick={() => onSave?.(row)}\r\n >\r\n Salvar alterações\r\n </Button>\r\n </>\r\n }\r\n >\r\n <DetailSection\r\n id=\"contact\"\r\n title=\"Contato\"\r\n open={openSections.has(\"contact\")}\r\n onToggle={toggle}\r\n s={s}\r\n >\r\n <DetailField\r\n label=\"Email\"\r\n value={\r\n <a\r\n href={`mailto:${row.email}`}\r\n className=\"text-fg-brand hover:underline\"\r\n >\r\n {row.email}\r\n </a>\r\n }\r\n s={s}\r\n />\r\n <DetailField\r\n label=\"Telefone\"\r\n value={\r\n <a\r\n href={`tel:${row.phone.replace(/\\D/g, \"\")}`}\r\n className=\"text-fg-brand hover:underline\"\r\n >\r\n {row.phone}\r\n </a>\r\n }\r\n s={s}\r\n />\r\n <DetailField label=\"Localização\" value={row.location} s={s} />\r\n </DetailSection>\r\n\r\n <DetailSection\r\n id=\"meta\"\r\n title=\"Atendimento\"\r\n open={openSections.has(\"meta\")}\r\n onToggle={toggle}\r\n s={s}\r\n >\r\n <DetailField label=\"ID\" value={row.id} s={s} />\r\n <DetailField\r\n label=\"Categoria\"\r\n value={\r\n cat ? (\r\n <Chip\r\n color={CATEGORY_KIND[row.categoryId] ?? \"info\"}\r\n variant=\"soft\"\r\n size=\"sm\"\r\n shape=\"pill\"\r\n >\r\n {cat.label}\r\n </Chip>\r\n ) : (\r\n \"—\"\r\n )\r\n }\r\n s={s}\r\n />\r\n <DetailField\r\n label=\"Atribuído a\"\r\n value={\r\n agent ? (\r\n <span className=\"inline-flex items-center gap-gp-sm\">\r\n <Avatar\r\n className=\"size-[22px]\"\r\n style={{ background: agent.color }}\r\n >\r\n <AvatarFallback className=\"bg-transparent text-white text-caption-xs font-bold\">\r\n {agentInitials}\r\n </AvatarFallback>\r\n </Avatar>\r\n {agent.name}\r\n </span>\r\n ) : (\r\n \"—\"\r\n )\r\n }\r\n s={s}\r\n />\r\n <DetailField label=\"Valor\" value={formatBRL(row.value)} s={s} />\r\n <DetailField label=\"Criado em\" value={formatLongDate(row.createdAt)} s={s} />\r\n <DetailField\r\n label=\"Último contato\"\r\n value={formatShortDate(row.lastContact)}\r\n s={s}\r\n />\r\n </DetailSection>\r\n\r\n <DetailSection\r\n id=\"notes\"\r\n title=\"Anotações\"\r\n open={openSections.has(\"notes\")}\r\n onToggle={toggle}\r\n s={s}\r\n >\r\n <p className=\"text-body-xs font-normal text-fg-muted\">Sem anotações.</p>\r\n </DetailSection>\r\n </FloatingPanel>\r\n );\r\n}\r\n","import { useCallback, useMemo, useRef, useState } from \"react\";\r\nimport { useTheme, type Theme } from \"@/hooks/useTheme\";\r\nimport {\r\n Archive,\r\n Clock,\r\n Copy,\r\n Download,\r\n Maximize2,\r\n MessageSquare,\r\n MoreHorizontal,\r\n Pencil,\r\n Plus,\r\n RotateCcw,\r\n Trash2,\r\n Upload,\r\n} from \"lucide-react\";\r\nimport {\r\n CATEGORIES,\r\n AGENTS,\r\n type ClientRow,\r\n} from \"../TableDoc\";\r\nimport {\r\n DataTable,\r\n presetView,\r\n type DataTableColumnDef,\r\n type DataTableKanbanConfig,\r\n type DataTablePresetView,\r\n type DataTableRef,\r\n type DataTableViewMode,\r\n type FilterModel,\r\n} from \"@/components/ui/DataTable\";\r\nimport { AppShell } from \"@/components/ui/AppShell\";\r\nimport { Button } from \"@/components/ui/Button/button\";\r\nimport { Chip } from \"@/components/ui/Chip\";\r\nimport { PageHeader } from \"@/components/ui/PageHeader\";\r\nimport { BulkActionButton } from \"@/components/ui/TableToolbar\";\r\nimport { Avatar, AvatarFallback } from \"@/components/shadcn/avatar\";\r\nimport {\r\n APP_SHELL_CONTEXTS,\r\n APP_SHELL_COMMANDS,\r\n APP_SHELL_NOTIFICATIONS,\r\n APP_SHELL_MESSAGES,\r\n APP_SHELL_THEME_OPTIONS,\r\n APP_SHELL_LAYOUT_OPTIONS,\r\n APP_SHELL_USER,\r\n} from \"../../mocks/app-shell-mocks\";\r\nimport {\r\n CLIENTS_87,\r\n STATUS_OPTIONS,\r\n CATEGORY_OPTIONS,\r\n AGENT_OPTIONS,\r\n AGENTS_LOOKUP,\r\n KANBAN_COLUMNS,\r\n CATEGORY_KIND,\r\n formatBRL,\r\n formatShortDate,\r\n} from \"./clientes-showcase-mocks\";\r\nimport { NovoClienteDrawer } from \"./components/NovoClienteDrawer\";\r\nimport { DetailDrawer } from \"./components/DetailDrawer\";\r\nimport { AlertModal } from \"@/components/ui/AlertModal\";\r\n\r\n/* ── Columns declarativas (type-based) ─────────────────────────── */\r\n\r\ntype ColumnHandlers = {\r\n /** Pede confirmação de exclusão (abre o AlertModal). */\r\n onAskDelete: (row: ClientRow) => void;\r\n};\r\n\r\nfunction buildColumns(handlers: ColumnHandlers): DataTableColumnDef<ClientRow>[] {\r\n return [\r\n { field: \"id\", headerName: \"ID\", type: \"text\", width: 130 },\r\n {\r\n field: \"name\",\r\n headerName: \"Nome\",\r\n type: \"user\",\r\n sortable: true,\r\n width: 220,\r\n typeOptions: {\r\n users: Object.fromEntries(\r\n CLIENTS_87.map((c) => [\r\n c.name,\r\n {\r\n name: c.name,\r\n initials: c.initials,\r\n color: c.avatarColor,\r\n },\r\n ]),\r\n ),\r\n },\r\n valueGetter: (row) => row.name,\r\n },\r\n {\r\n field: \"email\",\r\n headerName: \"Email\",\r\n type: \"email\",\r\n enableColumnFilter: true,\r\n filterType: \"text\",\r\n },\r\n {\r\n field: \"phone\",\r\n headerName: \"Telefone\",\r\n type: \"phone\",\r\n },\r\n {\r\n field: \"statusId\",\r\n headerName: \"Status\",\r\n type: \"status\",\r\n enableColumnFilter: true,\r\n filterType: \"multiSelect\",\r\n filterOptions: STATUS_OPTIONS,\r\n },\r\n {\r\n field: \"categoryId\",\r\n headerName: \"Categoria\",\r\n type: \"badge\",\r\n enableColumnFilter: true,\r\n filterType: \"multiSelect\",\r\n filterOptions: CATEGORY_OPTIONS,\r\n },\r\n {\r\n field: \"agentId\",\r\n headerName: \"Atribuído\",\r\n type: \"user\",\r\n enableColumnFilter: true,\r\n filterType: \"select\",\r\n filterOptions: AGENT_OPTIONS,\r\n typeOptions: { users: AGENTS_LOOKUP },\r\n },\r\n {\r\n field: \"value\",\r\n headerName: \"Valor\",\r\n type: \"currency\",\r\n sortable: true,\r\n enableColumnFilter: true,\r\n filterType: \"number\",\r\n aggregate: \"sum\",\r\n aggregateFormatter: (v) =>\r\n new Intl.NumberFormat(\"pt-BR\", { style: \"currency\", currency: \"BRL\" }).format(v),\r\n },\r\n {\r\n field: \"createdAt\",\r\n headerName: \"Criado em\",\r\n type: \"date\",\r\n sortable: true,\r\n enableColumnFilter: true,\r\n filterType: \"date\",\r\n width: 130,\r\n },\r\n {\r\n field: \"lastContact\",\r\n headerName: \"Último contato\",\r\n type: \"date\",\r\n sortable: true,\r\n width: 150,\r\n },\r\n {\r\n field: \"location\",\r\n headerName: \"Localização\",\r\n type: \"text\",\r\n minWidth: 150,\r\n },\r\n {\r\n field: \"_actions\",\r\n headerName: \"\",\r\n type: \"actions\",\r\n width: 64,\r\n pinned: \"right\",\r\n getActions: ({ row }) => [\r\n {\r\n id: \"edit\",\r\n label: \"Editar\",\r\n icon: <Pencil />,\r\n showInMenu: true,\r\n onClick: () => console.log(\"Editar\", row.id),\r\n },\r\n {\r\n id: \"whatsapp\",\r\n label: \"Abrir atendimento (WhatsApp)\",\r\n icon: <MessageSquare />,\r\n showInMenu: true,\r\n onClick: () => console.log(\"Atendimento\", row.id),\r\n },\r\n {\r\n id: \"archive\",\r\n label: \"Arquivar\",\r\n icon: <Archive />,\r\n showInMenu: true,\r\n onClick: () => console.log(\"Arquivar\", row.id),\r\n },\r\n {\r\n id: \"delete\",\r\n label: \"Excluir cliente\",\r\n icon: <Trash2 />,\r\n showInMenu: true,\r\n destructive: true,\r\n onClick: () => handlers.onAskDelete(row),\r\n },\r\n ],\r\n },\r\n ];\r\n}\r\n\r\n/* ── Saved views / Presets — tabs do toolbar ───────────────────── */\r\n\r\nconst DEFAULT_VIEWS: DataTablePresetView[] = [\r\n presetView({\r\n id: \"preset:meus\",\r\n name: \"Meus\",\r\n filters: [{ field: \"agentId\", value: \"you\" }],\r\n }),\r\n presetView({\r\n id: \"preset:ativos\",\r\n name: \"Ativos\",\r\n filters: [{ field: \"statusId\", value: \"active\" }],\r\n }),\r\n presetView({\r\n id: \"preset:royals\",\r\n name: \"Royals\",\r\n filters: [{ field: \"categoryId\", value: \"royal\" }],\r\n }),\r\n presetView({\r\n id: \"preset:ultimos-7-dias\",\r\n name: \"Últimos 7 dias\",\r\n sort: [{ field: \"createdAt\", direction: \"desc\" }],\r\n }),\r\n];\r\n\r\n/* ── Filtros iniciais (Status=Ativo + Categoria=Royal — print) ─── */\r\n\r\nconst INITIAL_FILTERS: FilterModel = {\r\n items: [\r\n { id: \"filter-status-ativo\", field: \"statusId\", operator: \"equals\", value: \"active\" },\r\n { id: \"filter-categoria-royal\", field: \"categoryId\", operator: \"equals\", value: \"royal\" },\r\n ],\r\n logicOperator: \"AND\",\r\n};\r\n\r\n/* ── Kanban config (renderCard com JSX) ────────────────────────── */\r\n\r\nconst KANBAN_CONFIG: DataTableKanbanConfig<ClientRow> = {\r\n groupByField: \"statusId\",\r\n columns: KANBAN_COLUMNS,\r\n renderCard: ({ row }) => {\r\n const cat = CATEGORIES[row.categoryId as keyof typeof CATEGORIES];\r\n const agent = AGENTS[row.agentId as keyof typeof AGENTS];\r\n const agentInitials = agent?.name.split(\" \").map((s) => s[0]).join(\"\").slice(0, 2) ?? \"?\";\r\n return {\r\n title: row.name,\r\n subtitle: row.id,\r\n avatar: (\r\n <Avatar className=\"size-[28px]\" style={{ background: row.avatarColor }}>\r\n <AvatarFallback className=\"bg-transparent text-white text-caption-sm font-bold\">\r\n {row.initials}\r\n </AvatarFallback>\r\n </Avatar>\r\n ),\r\n chip: cat ? (\r\n <Chip\r\n color={CATEGORY_KIND[row.categoryId] ?? \"info\"}\r\n variant=\"soft\"\r\n size=\"sm\"\r\n shape=\"pill\"\r\n >\r\n {cat.label}\r\n </Chip>\r\n ) : null,\r\n value: formatBRL(row.value),\r\n footerLeft: agent ? (\r\n <span className=\"inline-flex items-center gap-gp-sm min-w-0 flex-1\">\r\n <Avatar className=\"size-[22px]\" style={{ background: agent.color }}>\r\n <AvatarFallback className=\"bg-transparent text-white text-caption-xs font-bold\">\r\n {agentInitials}\r\n </AvatarFallback>\r\n </Avatar>\r\n <span className=\"text-body-xs font-normal text-fg-muted whitespace-nowrap overflow-hidden text-ellipsis\">\r\n {agent.name}\r\n </span>\r\n </span>\r\n ) : null,\r\n footerRight: (\r\n <span className=\"inline-flex items-center gap-[4px] text-caption-sm text-fg-muted [font-variant-numeric:tabular-nums] shrink-0\">\r\n <Clock size={11} strokeWidth={1.8} aria-hidden />\r\n {formatShortDate(row.lastContact)}\r\n </span>\r\n ),\r\n };\r\n },\r\n};\r\n\r\n/* ═══════════════════════════════════════════════════════════════════════════\r\n Page — Clientes (showcase usando AppShell + DataTable real)\r\n ═══════════════════════════════════════════════════════════════════════════ */\r\n\r\ntype ConfirmDeleteState = {\r\n ids: string[];\r\n label: string;\r\n /** Callback opcional após confirmar — usado pelo bulk pra limpar seleção. */\r\n onAfter?: () => void;\r\n} | null;\r\n\r\nexport default function ClientesShowcase() {\r\n const { theme, setTheme } = useTheme();\r\n const [rows, setRows] = useState<ClientRow[]>(() => CLIENTS_87);\r\n const [layout, setLayout] = useState<string>(\"fluid\");\r\n const [filterModel, setFilterModel] = useState<FilterModel>(INITIAL_FILTERS);\r\n const [viewMode, setViewMode] = useState<DataTableViewMode>(\"table\");\r\n const [novoClienteOpen, setNovoClienteOpen] = useState(false);\r\n const [detailRowId, setDetailRowId] = useState<string | null>(null);\r\n const [confirmDelete, setConfirmDelete] = useState<ConfirmDeleteState>(null);\r\n const detailRow = detailRowId ? rows.find((r) => r.id === detailRowId) ?? null : null;\r\n const tableRef = useRef<DataTableRef>(null);\r\n\r\n const askDelete = useCallback(\r\n (row: ClientRow) =>\r\n setConfirmDelete({ ids: [row.id], label: row.name }),\r\n [],\r\n );\r\n\r\n const askBulkDelete = useCallback(\r\n (ids: string[], onAfter: () => void) =>\r\n setConfirmDelete({\r\n ids,\r\n label: `${ids.length} cliente${ids.length === 1 ? \"\" : \"s\"}`,\r\n onAfter,\r\n }),\r\n [],\r\n );\r\n\r\n const handleConfirmDelete = useCallback(() => {\r\n if (!confirmDelete) return;\r\n const ids = new Set(confirmDelete.ids);\r\n setRows((prev) => prev.filter((r) => !ids.has(r.id)));\r\n if (detailRowId && ids.has(detailRowId)) setDetailRowId(null);\r\n confirmDelete.onAfter?.();\r\n setConfirmDelete(null);\r\n }, [confirmDelete, detailRowId]);\r\n\r\n const columns = useMemo(\r\n () => buildColumns({ onAskDelete: askDelete }),\r\n [askDelete],\r\n );\r\n\r\n return (\r\n <AppShell\r\n contexts={APP_SHELL_CONTEXTS}\r\n defaultActiveContextId=\"inbox\"\r\n defaultActiveItemHref=\"#atendimentos\"\r\n breadcrumb={[{ label: \"Atendimentos\" }]}\r\n commandGroups={APP_SHELL_COMMANDS}\r\n notifications={{\r\n items: APP_SHELL_NOTIFICATIONS,\r\n onMarkAllRead: () => alert(\"Marcar todas como lidas\"),\r\n onMoreActions: () => alert(\"Mais ações\"),\r\n onViewAll: () => alert(\"Ver todas\"),\r\n }}\r\n messages={{\r\n items: APP_SHELL_MESSAGES,\r\n onNewMessage: () => alert(\"Nova mensagem\"),\r\n onExpand: () => alert(\"Expandir\"),\r\n onViewAll: () => alert(\"Ver todas\"),\r\n }}\r\n theme={theme}\r\n onThemeChange={(id) => setTheme(id as Theme)}\r\n themeOptions={APP_SHELL_THEME_OPTIONS}\r\n user={APP_SHELL_USER}\r\n layout={layout}\r\n onLayoutChange={setLayout}\r\n layoutOptions={APP_SHELL_LAYOUT_OPTIONS}\r\n onSettings={() => alert(\"Abrir Configurações\")}\r\n onLogout={() => alert(\"Sair (mock)\")}\r\n >\r\n <PageHeader\r\n title=\"Clientes\"\r\n description=\"Gerencie sua base de clientes, acompanhe status de cadastro e abra atendimentos diretos pelo WhatsApp.\"\r\n badge={\r\n <Chip color=\"primary\" variant=\"soft\" size=\"sm\" shape=\"rounded\">\r\n {rows.length.toLocaleString(\"pt-BR\")} registros\r\n </Chip>\r\n }\r\n actions={\r\n <>\r\n <Button\r\n variant=\"outline\"\r\n color=\"secondary\"\r\n size=\"icon-md\"\r\n aria-label=\"Mais ações\"\r\n onClick={() => alert(\"Mais ações\")}\r\n >\r\n <MoreHorizontal />\r\n </Button>\r\n <Button\r\n variant=\"filled\"\r\n color=\"primary\"\r\n size=\"md\"\r\n iconLeft={<Plus />}\r\n onClick={() => setNovoClienteOpen(true)}\r\n >\r\n Novo cliente\r\n </Button>\r\n </>\r\n }\r\n />\r\n\r\n {/* DataTable — ocupa o resto do body ──────────────────────── */}\r\n <DataTable<ClientRow>\r\n ref={tableRef}\r\n rows={rows}\r\n columns={columns}\r\n getRowId={(r) => r.id}\r\n persistId=\"showcase-clientes-crud\"\r\n defaultViews={DEFAULT_VIEWS}\r\n filterModel={filterModel}\r\n onFilterModelChange={setFilterModel}\r\n viewMode={viewMode}\r\n onViewModeChange={setViewMode}\r\n kanbanConfig={KANBAN_CONFIG}\r\n toolbar={{\r\n enableSearch: true,\r\n enableFilters: true,\r\n enableColumns: true,\r\n enableDensity: true,\r\n enableExport: true,\r\n moreMenu: {\r\n items: [\r\n {\r\n id: \"fullscreen\",\r\n label: \"Tela cheia\",\r\n icon: <Maximize2 />,\r\n onSelect: () => alert(\"Tela cheia\"),\r\n },\r\n {\r\n id: \"duplicate\",\r\n label: \"Duplicar visualização\",\r\n icon: <Copy />,\r\n onSelect: () => alert(\"Duplicar visualização\"),\r\n },\r\n {\r\n id: \"import\",\r\n label: \"Importar CSV\",\r\n icon: <Upload />,\r\n onSelect: () => alert(\"Importar CSV\"),\r\n },\r\n {\r\n id: \"reset\",\r\n label: \"Resetar visualização\",\r\n icon: <RotateCcw />,\r\n destructive: true,\r\n onSelect: () => tableRef.current?.resetPersistedState(),\r\n },\r\n ],\r\n },\r\n }}\r\n paginationConfig={{\r\n enabled: true,\r\n initialPageSize: 10,\r\n pageSizeOptions: [10, 25, 50, 100],\r\n }}\r\n selectionConfig={{\r\n enabled: true,\r\n enableGlobal: true,\r\n actions: (selectedIds, clearSelection) => (\r\n <>\r\n <BulkActionButton\r\n icon={<Download />}\r\n onClick={() => tableRef.current?.exportCsv(\"selected\")}\r\n >\r\n Exportar\r\n </BulkActionButton>\r\n <BulkActionButton\r\n icon={<Trash2 />}\r\n variant=\"danger\"\r\n onClick={() => askBulkDelete(selectedIds.map(String), clearSelection)}\r\n >\r\n Excluir\r\n </BulkActionButton>\r\n </>\r\n ),\r\n }}\r\n onCellEditCommit={async ({ id, field, value }) => {\r\n await new Promise((res) => setTimeout(res, 400));\r\n setRows((prev) =>\r\n prev.map((r) => (r.id === id ? { ...r, [field]: value } : r)),\r\n );\r\n }}\r\n onRowClick={(row) => setDetailRowId(row.id)}\r\n className=\"flex-1 min-h-0\"\r\n />\r\n\r\n {/* Drawer \"Novo cliente\" — controlado pelo botão do header */}\r\n <NovoClienteDrawer\r\n open={novoClienteOpen}\r\n onOpenChange={setNovoClienteOpen}\r\n onSubmit={(data) => {\r\n console.log(\"Novo cliente:\", data);\r\n alert(`Cliente \"${data.name}\" criado (mock)`);\r\n }}\r\n />\r\n\r\n {/* DetailDrawer — abre ao clicar numa row, slide-in da direita SEM\r\n backdrop modal (tabela continua interativa atrás). */}\r\n <DetailDrawer\r\n row={detailRow}\r\n onClose={() => setDetailRowId(null)}\r\n onEdit={(r) => console.log(\"Editar\", r.id)}\r\n onDelete={(r) => askDelete(r)}\r\n onSave={(r) => alert(`Salvar alterações em ${r.name} (mock)`)}\r\n />\r\n\r\n {/* AlertModal de confirmação de exclusão — compartilhado entre\r\n row action menu, bulk action e DetailDrawer.onDelete. */}\r\n <AlertModal\r\n open={confirmDelete !== null}\r\n onOpenChange={(open) => {\r\n if (!open) setConfirmDelete(null);\r\n }}\r\n tone=\"danger\"\r\n title={\r\n confirmDelete && confirmDelete.ids.length > 1\r\n ? `Excluir ${confirmDelete.label}?`\r\n : \"Excluir cliente?\"\r\n }\r\n description={\r\n confirmDelete\r\n ? confirmDelete.ids.length > 1\r\n ? `Esta ação não pode ser desfeita. ${confirmDelete.label} serão removidos permanentemente.`\r\n : `Esta ação não pode ser desfeita. \"${confirmDelete.label}\" será removido permanentemente.`\r\n : null\r\n }\r\n confirmLabel=\"Excluir\"\r\n cancelLabel=\"Cancelar\"\r\n onConfirm={handleConfirmDelete}\r\n />\r\n </AppShell>\r\n );\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const React = require("react");
|
|
5
|
-
const useTheme = require("../chunks/useTheme-Dee4mo-A.
|
|
5
|
+
const useTheme = require("../chunks/useTheme-Dee4mo-A.cjs");
|
|
6
6
|
const lucideReact = require("lucide-react");
|
|
7
7
|
const recharts = require("recharts");
|
|
8
|
-
const chipGroup = require("../chunks/chip-group-
|
|
9
|
-
const appShell = require("../chunks/app-shell-
|
|
10
|
-
const pageHeader = require("../chunks/page-header-
|
|
11
|
-
const appShellMocks = require("../chunks/app-shell-mocks-oO_IV3Gw.
|
|
8
|
+
const chipGroup = require("../chunks/chip-group-2-f_Yo7Y.cjs");
|
|
9
|
+
const appShell = require("../chunks/app-shell-BdVam01i.cjs");
|
|
10
|
+
const pageHeader = require("../chunks/page-header-qOywgRWy.cjs");
|
|
11
|
+
const appShellMocks = require("../chunks/app-shell-mocks-oO_IV3Gw.cjs");
|
|
12
12
|
const KPIS_PRIMARY = [
|
|
13
13
|
{
|
|
14
14
|
id: "in-conv",
|
|
@@ -174,7 +174,7 @@ function KpiCard({ kpi }) {
|
|
|
174
174
|
const cls = TONE_CLASSES[kpi.tone];
|
|
175
175
|
return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "flex flex-col gap-gp-lg p-pad-3xl bg-bg-surface border border-border-subtle rounded-radius-xl shadow-sh-sm", children: [
|
|
176
176
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex items-start justify-between gap-gp-md", children: [
|
|
177
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "m-0 text-
|
|
177
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "m-0 text-body-md font-semibold text-fg-default", children: kpi.title }),
|
|
178
178
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
179
179
|
"span",
|
|
180
180
|
{
|
|
@@ -190,7 +190,7 @@ function KpiCard({ kpi }) {
|
|
|
190
190
|
] }),
|
|
191
191
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-gp-xs", children: [
|
|
192
192
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-md flex-wrap", children: [
|
|
193
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
193
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-2xl font-bold text-fg-default leading-none [font-variant-numeric:tabular-nums]", children: kpi.value }),
|
|
194
194
|
kpi.delta && /* @__PURE__ */ jsxRuntime.jsx(
|
|
195
195
|
chipGroup.Chip,
|
|
196
196
|
{
|
|
@@ -202,17 +202,17 @@ function KpiCard({ kpi }) {
|
|
|
202
202
|
}
|
|
203
203
|
)
|
|
204
204
|
] }),
|
|
205
|
-
kpi.delta && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
205
|
+
kpi.delta && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-caption-sm text-fg-subtle", children: kpi.delta.label })
|
|
206
206
|
] })
|
|
207
207
|
] });
|
|
208
208
|
}
|
|
209
209
|
function WelcomeBanner() {
|
|
210
210
|
return /* @__PURE__ */ jsxRuntime.jsx("article", { className: "relative overflow-hidden bg-bg-brand rounded-radius-xl p-pad-4xl flex items-center gap-gp-2xl flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-gp-md flex-1 min-w-0 z-[1]", children: [
|
|
211
|
-
/* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "m-0 flex items-center gap-gp-md text-
|
|
211
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "m-0 flex items-center gap-gp-md text-body-2xl font-bold text-fg-on-brand", children: [
|
|
212
212
|
"Boa tarde, Sergio",
|
|
213
213
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sun, { className: "size-icon-md text-fg-warning", fill: "currentColor" })
|
|
214
214
|
] }),
|
|
215
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "m-0 text-
|
|
215
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "m-0 text-body-md text-fg-on-brand opacity-80 max-w-[480px]", children: [
|
|
216
216
|
"Acompanhe a performance da sua equipe hoje.",
|
|
217
217
|
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
218
218
|
"Snapshot rápido das principais métricas do atendimento."
|
|
@@ -233,12 +233,12 @@ function WelcomeBanner() {
|
|
|
233
233
|
function KeyInsightsCard() {
|
|
234
234
|
return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "flex flex-col gap-gp-md p-pad-3xl bg-bg-surface border border-border-subtle rounded-radius-xl shadow-sh-sm h-full", children: [
|
|
235
235
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex items-center justify-between gap-gp-md", children: [
|
|
236
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "m-0 text-
|
|
236
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "m-0 text-body-md font-medium font-bold text-fg-default", children: "Key Insights" }),
|
|
237
237
|
/* @__PURE__ */ jsxRuntime.jsx(chipGroup.Button, { color: "secondary", variant: "ghost", size: "icon-sm", "aria-label": "Mais opções", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreVertical, {}) })
|
|
238
238
|
] }),
|
|
239
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0 text-
|
|
239
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0 text-body-xs font-normal text-fg-muted", children: "Receita acumulada (anual)" }),
|
|
240
240
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-md flex-wrap", children: [
|
|
241
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
241
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-2xl font-bold text-fg-default leading-none [font-variant-numeric:tabular-nums]", children: "R$ 395.7k" }),
|
|
242
242
|
/* @__PURE__ */ jsxRuntime.jsx(chipGroup.Chip, { color: "success", variant: "soft", size: "sm", shape: "pill", children: "+2.7%" })
|
|
243
243
|
] }),
|
|
244
244
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex flex-col gap-gp-md", children: [
|
|
@@ -247,7 +247,7 @@ function KeyInsightsCard() {
|
|
|
247
247
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-bg-warning", style: { flex: 3 }, "aria-hidden": true }),
|
|
248
248
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-bg-info", style: { flex: 4 }, "aria-hidden": true })
|
|
249
249
|
] }),
|
|
250
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-lg flex-wrap text-
|
|
250
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-lg flex-wrap text-caption-sm text-fg-muted", children: [
|
|
251
251
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[5px]", children: [
|
|
252
252
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-[8px] rounded-radius-full bg-bg-brand", "aria-hidden": true }),
|
|
253
253
|
"São Paulo"
|
|
@@ -281,8 +281,8 @@ function SectionCard({
|
|
|
281
281
|
children: [
|
|
282
282
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex items-center justify-between gap-gp-md", children: [
|
|
283
283
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-[2px] min-w-0", children: [
|
|
284
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "m-0 text-
|
|
285
|
-
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0 text-
|
|
284
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "m-0 text-body-md font-medium font-bold text-fg-default", children: title }),
|
|
285
|
+
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0 text-body-xs font-normal text-fg-muted", children: subtitle })
|
|
286
286
|
] }),
|
|
287
287
|
action ?? /* @__PURE__ */ jsxRuntime.jsx(chipGroup.Button, { color: "secondary", variant: "ghost", size: "icon-sm", "aria-label": "Mais opções", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreVertical, {}) })
|
|
288
288
|
] }),
|
|
@@ -309,16 +309,16 @@ function VolumeStackedChart() {
|
|
|
309
309
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-gp-lg", children: [
|
|
310
310
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-md flex-wrap", children: [
|
|
311
311
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-gp-md flex-wrap", children: [
|
|
312
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
312
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-2xl font-bold text-fg-default leading-none [font-variant-numeric:tabular-nums]", children: "R$ 395.7k" }),
|
|
313
313
|
/* @__PURE__ */ jsxRuntime.jsx(chipGroup.Chip, { color: "success", variant: "soft", size: "sm", shape: "pill", children: "+18%" }),
|
|
314
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
314
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-xs font-normal text-fg-muted", children: "vs ano passado" })
|
|
315
315
|
] }),
|
|
316
316
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-gp-md", children: [
|
|
317
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[4px] text-
|
|
317
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[4px] text-caption-sm text-fg-muted", children: [
|
|
318
318
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-[8px] rounded-radius-full bg-bg-brand", "aria-hidden": true }),
|
|
319
319
|
" Humano"
|
|
320
320
|
] }),
|
|
321
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[4px] text-
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[4px] text-caption-sm text-fg-muted", children: [
|
|
322
322
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-[8px] rounded-radius-full bg-bg-brand-subtle", "aria-hidden": true }),
|
|
323
323
|
" IA"
|
|
324
324
|
] }),
|
|
@@ -414,8 +414,8 @@ function CurrentVisitsCard() {
|
|
|
414
414
|
)
|
|
415
415
|
] }) }),
|
|
416
416
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center pointer-events-none", children: [
|
|
417
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
418
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
417
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-caption-sm text-fg-muted", children: "Total" }),
|
|
418
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-2xl font-bold text-fg-default leading-none [font-variant-numeric:tabular-nums]", children: total.toLocaleString("pt-BR") })
|
|
419
419
|
] })
|
|
420
420
|
] }),
|
|
421
421
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-gp-md", children: REGIONS.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-md", children: [
|
|
@@ -427,8 +427,8 @@ function CurrentVisitsCard() {
|
|
|
427
427
|
"aria-hidden": true
|
|
428
428
|
}
|
|
429
429
|
),
|
|
430
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-
|
|
431
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
430
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-body-xs text-fg-default", children: r.name }),
|
|
431
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-xs font-normal text-fg-default [font-variant-numeric:tabular-nums]", children: r.value.toLocaleString("pt-BR") }),
|
|
432
432
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
433
433
|
chipGroup.Chip,
|
|
434
434
|
{
|
|
@@ -443,7 +443,7 @@ function CurrentVisitsCard() {
|
|
|
443
443
|
] });
|
|
444
444
|
}
|
|
445
445
|
function PersonAvatar({ initials, hex, size = "md" }) {
|
|
446
|
-
const cls = size === "sm" ? "size-[24px] text-
|
|
446
|
+
const cls = size === "sm" ? "size-[24px] text-caption-xs" : "size-[32px] text-body-xs font-normal";
|
|
447
447
|
return /* @__PURE__ */ jsxRuntime.jsx(appShell.Avatar, { className: cls, style: { background: hex }, children: /* @__PURE__ */ jsxRuntime.jsx(appShell.AvatarFallback, { className: "bg-transparent text-white font-bold", children: initials }) });
|
|
448
448
|
}
|
|
449
449
|
function OpenConversationsList() {
|
|
@@ -457,10 +457,10 @@ function OpenConversationsList() {
|
|
|
457
457
|
/* @__PURE__ */ jsxRuntime.jsx(PersonAvatar, { initials: c.initials, hex: c.hex, size: "md" }),
|
|
458
458
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 flex flex-col gap-[2px]", children: [
|
|
459
459
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-sm", children: [
|
|
460
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
461
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
460
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-sm font-semibold text-fg-default whitespace-nowrap overflow-hidden text-ellipsis", children: c.name }),
|
|
461
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-caption-sm text-fg-subtle [font-variant-numeric:tabular-nums] shrink-0", children: c.id })
|
|
462
462
|
] }),
|
|
463
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-sm flex-wrap text-
|
|
463
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-gp-sm flex-wrap text-caption-sm text-fg-muted", children: [
|
|
464
464
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[3px]", children: [
|
|
465
465
|
/* @__PURE__ */ jsxRuntime.jsx(ChIcon, { size: 11, strokeWidth: 1.8, "aria-hidden": true }),
|
|
466
466
|
CHANNELS.find((ch) => ch.id === c.channel)?.name ?? c.channel
|
|
@@ -473,7 +473,7 @@ function OpenConversationsList() {
|
|
|
473
473
|
] }),
|
|
474
474
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end gap-[4px] shrink-0", children: [
|
|
475
475
|
/* @__PURE__ */ jsxRuntime.jsx(chipGroup.Chip, { color: STATUS_TONE[c.status], variant: "soft", size: "sm", shape: "pill", children: STATUS_LABEL[c.status] }),
|
|
476
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[3px] text-
|
|
476
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-[3px] text-caption-sm text-fg-muted [font-variant-numeric:tabular-nums]", children: [
|
|
477
477
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { size: 10, strokeWidth: 1.8, "aria-hidden": true }),
|
|
478
478
|
c.waitTime
|
|
479
479
|
] })
|
|
@@ -490,7 +490,7 @@ function AgentPerformanceList() {
|
|
|
490
490
|
{
|
|
491
491
|
className: "flex items-center gap-gp-md py-pad-lg border-b border-border-subtle last:border-b-0",
|
|
492
492
|
children: [
|
|
493
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "grid place-items-center size-[20px] rounded-radius-full bg-bg-muted text-
|
|
493
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "grid place-items-center size-[20px] rounded-radius-full bg-bg-muted text-caption-sm font-bold text-fg-muted shrink-0 [font-variant-numeric:tabular-nums]", children: i + 1 }),
|
|
494
494
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
|
|
495
495
|
/* @__PURE__ */ jsxRuntime.jsx(PersonAvatar, { initials: a.initials, hex: a.hex, size: "md" }),
|
|
496
496
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -505,15 +505,15 @@ function AgentPerformanceList() {
|
|
|
505
505
|
)
|
|
506
506
|
] }),
|
|
507
507
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 flex flex-col gap-[2px]", children: [
|
|
508
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
509
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-
|
|
508
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-sm font-semibold text-fg-default whitespace-nowrap overflow-hidden text-ellipsis", children: a.name }),
|
|
509
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-caption-sm text-fg-muted", children: [
|
|
510
510
|
a.resolved,
|
|
511
511
|
" resolvidos · ",
|
|
512
512
|
a.avgTime,
|
|
513
513
|
" médio"
|
|
514
514
|
] })
|
|
515
515
|
] }),
|
|
516
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[3px] shrink-0 text-
|
|
516
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[3px] shrink-0 text-body-xs font-semibold text-fg-default", children: [
|
|
517
517
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Star, { size: 11, strokeWidth: 2, className: "text-fg-warning fill-current", "aria-hidden": true }),
|
|
518
518
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "[font-variant-numeric:tabular-nums]", children: a.csat.toFixed(1) })
|
|
519
519
|
] })
|
|
@@ -540,8 +540,8 @@ function ChannelPerformanceList() {
|
|
|
540
540
|
}
|
|
541
541
|
),
|
|
542
542
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 flex flex-col gap-[2px]", children: [
|
|
543
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
544
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-
|
|
543
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-body-sm font-semibold text-fg-default", children: c.name }),
|
|
544
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-caption-sm text-fg-muted", children: [
|
|
545
545
|
c.volume,
|
|
546
546
|
" mensagens"
|
|
547
547
|
] })
|
|
@@ -574,18 +574,18 @@ function TrafficDataTable() {
|
|
|
574
574
|
{
|
|
575
575
|
type: "search",
|
|
576
576
|
placeholder: "Buscar...",
|
|
577
|
-
className: "h-form-md pl-[34px] pr-pad-md w-full rounded-radius-md bg-bg-muted border border-border-input text-
|
|
577
|
+
className: "h-form-md pl-[34px] pr-pad-md w-full rounded-radius-md bg-bg-muted border border-border-input text-body-md text-fg-default placeholder:text-fg-muted focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-brand focus-visible:border-border-brand"
|
|
578
578
|
}
|
|
579
579
|
)
|
|
580
580
|
] }),
|
|
581
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto -mx-pad-2xl px-pad-2xl", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-
|
|
582
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-
|
|
581
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto -mx-pad-2xl px-pad-2xl", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-body-md border-separate border-spacing-0", children: [
|
|
582
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-caption-sm font-bold tracking-[0.04em] text-fg-subtle uppercase", children: [
|
|
583
583
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-left pb-pad-md border-b border-border-subtle font-bold", children: "Fonte" }),
|
|
584
584
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-right pb-pad-md border-b border-border-subtle font-bold", children: "Visitas" }),
|
|
585
585
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-left pb-pad-md pl-pad-2xl border-b border-border-subtle font-bold", children: "Bounce" }),
|
|
586
586
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-left pb-pad-md pl-pad-2xl border-b border-border-subtle font-bold", children: "Meta (%)" })
|
|
587
587
|
] }) }),
|
|
588
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: TRAFFIC_ROWS.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-
|
|
588
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: TRAFFIC_ROWS.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-body-xs font-normal", children: [
|
|
589
589
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-pad-lg border-b border-border-subtle text-fg-default font-medium", children: r.source }),
|
|
590
590
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-pad-lg border-b border-border-subtle text-right text-fg-default [font-variant-numeric:tabular-nums]", children: r.visits }),
|
|
591
591
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-pad-sm pl-pad-2xl border-b border-border-subtle text-fg-muted [font-variant-numeric:tabular-nums]", children: r.bounce }),
|
|
@@ -597,7 +597,7 @@ function TrafficDataTable() {
|
|
|
597
597
|
style: { width: `${r.goal}%`, background: r.goalColor }
|
|
598
598
|
}
|
|
599
599
|
) }),
|
|
600
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-
|
|
600
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-caption-sm font-semibold text-fg-default [font-variant-numeric:tabular-nums] shrink-0 min-w-[32px] text-right", children: [
|
|
601
601
|
r.goal,
|
|
602
602
|
"%"
|
|
603
603
|
] })
|