@snksergio/design-system 0.61.0 → 0.63.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.
Files changed (193) hide show
  1. package/dist-lib/ai/blocos/chart/budget-breakdown.tsx +174 -0
  2. package/dist-lib/ai/blocos/indice.md +43 -0
  3. package/dist-lib/ai/blocos/paneldetail/detalhe-com-tabela.tsx +450 -0
  4. package/dist-lib/ai/blocos/paneldetail/detalhe-de-tarefa-com-abas.tsx +570 -0
  5. package/dist-lib/ai/blocos/paneldetail/detalhe-do-registro.tsx +555 -0
  6. package/dist-lib/ai/componentes/AlertModal.md +47 -0
  7. package/dist-lib/ai/componentes/AppShell.md +117 -0
  8. package/dist-lib/ai/componentes/Breadcrumb.md +187 -0
  9. package/dist-lib/ai/componentes/Button.md +116 -0
  10. package/dist-lib/ai/componentes/ButtonGroup.md +162 -0
  11. package/dist-lib/ai/componentes/CardCheckbox.md +99 -0
  12. package/dist-lib/ai/componentes/CardOption.md +133 -0
  13. package/dist-lib/ai/componentes/Chart.md +93 -0
  14. package/dist-lib/ai/componentes/Chip.md +68 -0
  15. package/dist-lib/ai/componentes/ChoroplethMap.md +118 -0
  16. package/dist-lib/ai/componentes/ColorPicker.md +70 -0
  17. package/dist-lib/ai/componentes/Combobox.md +51 -0
  18. package/dist-lib/ai/componentes/ConversationListItem.md +90 -0
  19. package/dist-lib/ai/componentes/DataList.md +111 -0
  20. package/dist-lib/ai/componentes/DataTable.md +867 -0
  21. package/dist-lib/ai/componentes/DatePicker.md +84 -0
  22. package/dist-lib/ai/componentes/DateSeparatorChip.md +59 -0
  23. package/dist-lib/ai/componentes/EmptyState.md +72 -0
  24. package/dist-lib/ai/componentes/FileUploadField.md +95 -0
  25. package/dist-lib/ai/componentes/FloatingPanel.md +118 -0
  26. package/dist-lib/ai/componentes/FooterTable.md +62 -0
  27. package/dist-lib/ai/componentes/FormField.md +110 -0
  28. package/dist-lib/ai/componentes/Gantt.md +552 -0
  29. package/dist-lib/ai/componentes/Header.md +98 -0
  30. package/dist-lib/ai/componentes/Icon.md +65 -0
  31. package/dist-lib/ai/componentes/Kanban.md +343 -0
  32. package/dist-lib/ai/componentes/Kpi.md +103 -0
  33. package/dist-lib/ai/componentes/List.md +61 -0
  34. package/dist-lib/ai/componentes/MarkdownText.md +59 -0
  35. package/dist-lib/ai/componentes/MenuSidebar.md +128 -0
  36. package/dist-lib/ai/componentes/MessageAck.md +53 -0
  37. package/dist-lib/ai/componentes/MessageBubble.md +115 -0
  38. package/dist-lib/ai/componentes/MessageComposer.md +80 -0
  39. package/dist-lib/ai/componentes/MessageVariablesPicker.md +104 -0
  40. package/dist-lib/ai/componentes/Modal.md +88 -0
  41. package/dist-lib/ai/componentes/MonthYearPicker.md +49 -0
  42. package/dist-lib/ai/componentes/PageHeader.md +129 -0
  43. package/dist-lib/ai/componentes/Panel.md +84 -0
  44. package/dist-lib/ai/componentes/Scheduler.md +421 -0
  45. package/dist-lib/ai/componentes/ScreenLoader.md +60 -0
  46. package/dist-lib/ai/componentes/SingleMenuSidebar.md +171 -0
  47. package/dist-lib/ai/componentes/Spinner.md +52 -0
  48. package/dist-lib/ai/componentes/Table.md +192 -0
  49. package/dist-lib/ai/componentes/TableToolbar.md +87 -0
  50. package/dist-lib/ai/componentes/TabsNavigation.md +152 -0
  51. package/dist-lib/ai/componentes/Toast.md +49 -0
  52. package/dist-lib/ai/componentes/_primitivos.md +74 -0
  53. package/dist-lib/ai/componentes/avatar-ig.md +181 -0
  54. package/dist-lib/ai/componentes/indice.json +49 -0
  55. package/dist-lib/ai/exemplos/app-shell/app-shell-example.tsx +140 -0
  56. package/dist-lib/ai/exemplos/app-shell/index.ts +3 -0
  57. package/dist-lib/ai/exemplos/app-shell/nav-data.ts +97 -0
  58. package/dist-lib/ai/exemplos/app-shell/routes.tsx +75 -0
  59. package/dist-lib/ai/exemplos/chat/chat-screen.tsx +152 -0
  60. package/dist-lib/ai/exemplos/chat/chat-v2-mocks.ts +171 -0
  61. package/dist-lib/ai/exemplos/chat/chat-v2.styles.ts +23 -0
  62. package/dist-lib/ai/exemplos/chat/chat-v2.types.ts +81 -0
  63. package/dist-lib/ai/exemplos/chat/components/ChannelDot/channel-dot.tsx +28 -0
  64. package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/conversation-actions-menu.tsx +83 -0
  65. package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/index.ts +4 -0
  66. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.styles.ts +22 -0
  67. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.tsx +203 -0
  68. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.types.ts +10 -0
  69. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/index.ts +2 -0
  70. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.styles.ts +55 -0
  71. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.tsx +52 -0
  72. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.types.ts +7 -0
  73. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/index.ts +2 -0
  74. package/dist-lib/ai/exemplos/chat/components/DateSeparator/date-separator.tsx +18 -0
  75. package/dist-lib/ai/exemplos/chat/components/DetailField/detail-field.tsx +23 -0
  76. package/dist-lib/ai/exemplos/chat/components/DetailSection/detail-section.tsx +41 -0
  77. package/dist-lib/ai/exemplos/chat/components/DetailSection/index.ts +1 -0
  78. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.styles.ts +30 -0
  79. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.tsx +142 -0
  80. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.types.ts +16 -0
  81. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/index.ts +5 -0
  82. package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.styles.ts +37 -0
  83. package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.tsx +45 -0
  84. package/dist-lib/ai/exemplos/chat/components/FilterRow/index.ts +1 -0
  85. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.styles.ts +27 -0
  86. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.tsx +66 -0
  87. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.types.ts +13 -0
  88. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-rail.tsx +38 -0
  89. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/index.ts +6 -0
  90. package/dist-lib/ai/exemplos/chat/components/MessageBubble/index.ts +2 -0
  91. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.styles.ts +37 -0
  92. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.tsx +29 -0
  93. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.types.ts +5 -0
  94. package/dist-lib/ai/exemplos/chat/components/PersonAvatar/index.ts +5 -0
  95. package/dist-lib/ai/exemplos/chat/components/PersonAvatar/person-avatar.tsx +31 -0
  96. package/dist-lib/ai/exemplos/chat/components/QueueColumn/index.ts +2 -0
  97. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.styles.ts +19 -0
  98. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.tsx +140 -0
  99. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.types.ts +13 -0
  100. package/dist-lib/ai/exemplos/chat/components/RailItem/index.ts +1 -0
  101. package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.styles.ts +30 -0
  102. package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.tsx +42 -0
  103. package/dist-lib/ai/exemplos/chat/hooks/use-resizable.ts +98 -0
  104. package/dist-lib/ai/exemplos/chat/index.ts +1 -0
  105. package/dist-lib/ai/exemplos/clientes/_table-data.ts +59 -0
  106. package/dist-lib/ai/exemplos/clientes/clientes-screen.tsx +505 -0
  107. package/dist-lib/ai/exemplos/clientes/clientes-showcase-mocks.ts +117 -0
  108. package/dist-lib/ai/exemplos/clientes/clientes-showcase.styles.ts +13 -0
  109. package/dist-lib/ai/exemplos/clientes/clientes-showcase.types.ts +16 -0
  110. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.styles.ts +28 -0
  111. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.tsx +303 -0
  112. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.types.ts +14 -0
  113. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/index.ts +2 -0
  114. package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/index.ts +2 -0
  115. package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
  116. package/dist-lib/ai/exemplos/clientes/index.ts +1 -0
  117. package/dist-lib/ai/exemplos/dashboard/dashboard-brazil-map.ts +33 -0
  118. package/dist-lib/ai/exemplos/dashboard/dashboard-screen.tsx +1110 -0
  119. package/dist-lib/ai/exemplos/dashboard/index.ts +1 -0
  120. package/dist-lib/ai/exemplos/edit-page/components/StepNav.tsx +81 -0
  121. package/dist-lib/ai/exemplos/edit-page/components/section-card.tsx +85 -0
  122. package/dist-lib/ai/exemplos/edit-page/edit-page-screen.tsx +234 -0
  123. package/dist-lib/ai/exemplos/edit-page/index.ts +1 -0
  124. package/dist-lib/ai/exemplos/finance/_table-data.ts +57 -0
  125. package/dist-lib/ai/exemplos/finance/clientes-financeiro-mocks.ts +227 -0
  126. package/dist-lib/ai/exemplos/finance/clientes-financeiro.types.ts +75 -0
  127. package/dist-lib/ai/exemplos/finance/clientes-showcase-mocks.ts +117 -0
  128. package/dist-lib/ai/exemplos/finance/clientes-showcase.styles.ts +13 -0
  129. package/dist-lib/ai/exemplos/finance/clientes-showcase.types.ts +16 -0
  130. package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/editar-finance-drawer.tsx +241 -0
  131. package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/index.ts +5 -0
  132. package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/extrato-expansion.tsx +172 -0
  133. package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/index.ts +1 -0
  134. package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/finance-detail-panel.tsx +241 -0
  135. package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/index.ts +2 -0
  136. package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/index.ts +2 -0
  137. package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
  138. package/dist-lib/ai/exemplos/finance/components/SacarDialog/index.ts +2 -0
  139. package/dist-lib/ai/exemplos/finance/components/SacarDialog/sacar-dialog.tsx +346 -0
  140. package/dist-lib/ai/exemplos/finance/finance-screen.tsx +821 -0
  141. package/dist-lib/ai/exemplos/finance/index.ts +1 -0
  142. package/dist-lib/ai/exemplos/gantt/_gantt-data.tsx +402 -0
  143. package/dist-lib/ai/exemplos/gantt/gantt-screen.tsx +512 -0
  144. package/dist-lib/ai/exemplos/gantt/index.ts +1 -0
  145. package/dist-lib/ai/exemplos/login/index.ts +1 -0
  146. package/dist-lib/ai/exemplos/login/login-screen.tsx +246 -0
  147. package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/consultor-detail-panel.tsx +158 -0
  148. package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/index.ts +2 -0
  149. package/dist-lib/ai/exemplos/mapa-rede/index.ts +1 -0
  150. package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede-mocks.ts +655 -0
  151. package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede.types.ts +53 -0
  152. package/dist-lib/ai/exemplos/mapa-rede/mapa-rede-screen.tsx +227 -0
  153. package/dist-lib/ai/exemplos/order-detail/components/ActivityTab.tsx +77 -0
  154. package/dist-lib/ai/exemplos/order-detail/components/AttachmentsTab.tsx +45 -0
  155. package/dist-lib/ai/exemplos/order-detail/components/CommentsTab.tsx +111 -0
  156. package/dist-lib/ai/exemplos/order-detail/components/DetailsTab.tsx +189 -0
  157. package/dist-lib/ai/exemplos/order-detail/components/OverviewTab.tsx +200 -0
  158. package/dist-lib/ai/exemplos/order-detail/components/section-card.tsx +85 -0
  159. package/dist-lib/ai/exemplos/order-detail/index.ts +1 -0
  160. package/dist-lib/ai/exemplos/order-detail/order-detail-screen.tsx +119 -0
  161. package/dist-lib/ai/exemplos/order-detail/order-mocks.ts +186 -0
  162. package/dist-lib/ai/exemplos/order-detail/order.types.ts +118 -0
  163. package/dist-lib/ai/global/componentes.md +217 -0
  164. package/dist-lib/ai/global/composicao.md +182 -0
  165. package/dist-lib/ai/indice.json +192 -0
  166. package/dist-lib/ai/lint/ds-lint-patterns.mjs +115 -0
  167. package/dist-lib/ai/manifest.json +42 -0
  168. package/dist-lib/ai/regras/design.md +88 -0
  169. package/dist-lib/ai/regras/temas.md +192 -0
  170. package/dist-lib/ai/regras-por-componente.json +103 -0
  171. package/dist-lib/ai/roteiros/app-builder/roteiro.md +155 -0
  172. package/dist-lib/ai/roteiros/auth-builder/roteiro.md +42 -0
  173. package/dist-lib/ai/roteiros/cards/roteiro.md +34 -0
  174. package/dist-lib/ai/roteiros/charts/roteiro.md +32 -0
  175. package/dist-lib/ai/roteiros/chat/roteiro.md +31 -0
  176. package/dist-lib/ai/roteiros/crud-builder/blueprint.md +63 -0
  177. package/dist-lib/ai/roteiros/crud-builder/entrevista.md +139 -0
  178. package/dist-lib/ai/roteiros/crud-builder/geracao.md +113 -0
  179. package/dist-lib/ai/roteiros/crud-builder/roteiro.md +89 -0
  180. package/dist-lib/ai/roteiros/dashboard-builder/blueprint.md +47 -0
  181. package/dist-lib/ai/roteiros/dashboard-builder/entrevista.md +62 -0
  182. package/dist-lib/ai/roteiros/dashboard-builder/geracao.md +88 -0
  183. package/dist-lib/ai/roteiros/dashboard-builder/roteiro.md +88 -0
  184. package/dist-lib/ai/roteiros/drawers/roteiro.md +41 -0
  185. package/dist-lib/ai/roteiros/list-builder/blueprint.md +94 -0
  186. package/dist-lib/ai/roteiros/list-builder/entrevista.md +188 -0
  187. package/dist-lib/ai/roteiros/list-builder/geracao.md +63 -0
  188. package/dist-lib/ai/roteiros/list-builder/roteiro.md +91 -0
  189. package/dist-lib/ai/roteiros/module-replicator/roteiro.md +56 -0
  190. package/dist-lib/ai/roteiros/page-detail/roteiro.md +32 -0
  191. package/dist-lib/ai/roteiros/page-edit/roteiro.md +31 -0
  192. package/dist-lib/ai/roteiros/screen-composer/roteiro.md +95 -0
  193. package/package.json +4 -1
@@ -0,0 +1 @@
1
+ export { DashboardScreen, default } from "./dashboard-screen";
@@ -0,0 +1,81 @@
1
+ import type { LucideIcon } from "@/lib/lucide-types";
2
+ import { cn } from "@/lib/utils";
3
+
4
+ export type Step = {
5
+ id: string;
6
+ icon: LucideIcon;
7
+ title: string;
8
+ description: string;
9
+ };
10
+
11
+ /**
12
+ * Nav lateral (stepper) da tela de edição — itens com ícone + título +
13
+ * descrição; o ativo ganha destaque de marca. Clicar seleciona + rola até a
14
+ * seção. Composição local do showcase usando tokens DS.
15
+ */
16
+ export function StepNav({
17
+ steps,
18
+ activeId,
19
+ onSelect,
20
+ className,
21
+ }: {
22
+ steps: Step[];
23
+ activeId: string;
24
+ onSelect: (id: string) => void;
25
+ className?: string;
26
+ }) {
27
+ return (
28
+ <nav
29
+ className={cn(
30
+ "flex flex-col gap-gp-xs rounded-radius-lg border border-border-subtle bg-bg-surface p-pad-md shadow-sh-sm",
31
+ className,
32
+ )}
33
+ aria-label="Etapas do pedido"
34
+ >
35
+ {steps.map((s) => {
36
+ const Icon = s.icon;
37
+ const active = s.id === activeId;
38
+ return (
39
+ <button
40
+ key={s.id}
41
+ type="button"
42
+ onClick={() => onSelect(s.id)}
43
+ aria-current={active ? "step" : undefined}
44
+ className={cn(
45
+ "flex items-start gap-gp-md rounded-radius-md border p-pad-lg text-left transition-colors",
46
+ active
47
+ ? "border-border-brand bg-bg-brand-subtle"
48
+ : "border-transparent hover:bg-bg-muted",
49
+ )}
50
+ >
51
+ <span
52
+ className={cn(
53
+ "grid size-8 shrink-0 place-items-center rounded-radius-md border",
54
+ active
55
+ ? "border-transparent bg-bg-brand text-fg-on-brand"
56
+ // bg-surface (branco no light) + borda: contrasta tanto no card
57
+ // quanto no hover cinza (senão o ícone funde com o hover).
58
+ : "border-border-subtle bg-bg-surface text-fg-muted",
59
+ )}
60
+ >
61
+ <Icon className="size-icon-sm" />
62
+ </span>
63
+ <span className="min-w-0 flex-1">
64
+ <span
65
+ className={cn(
66
+ "block text-body-sm font-semibold",
67
+ active ? "text-fg-brand" : "text-fg-default",
68
+ )}
69
+ >
70
+ {s.title}
71
+ </span>
72
+ <span className="mt-gp-2xs block text-caption-sm leading-snug text-fg-muted">
73
+ {s.description}
74
+ </span>
75
+ </span>
76
+ </button>
77
+ );
78
+ })}
79
+ </nav>
80
+ );
81
+ }
@@ -0,0 +1,85 @@
1
+ import type { ReactNode } from "react";
2
+ import { cn } from "@/lib/utils";
3
+
4
+ /**
5
+ * Card de seção flat — bg-surface + borda sutil, sem elevação pesada.
6
+ * Espelha o visual dos blocos da referência (Products ordered, Customer, etc).
7
+ * Composição local do showcase consumindo tokens DS via classes.
8
+ */
9
+ export function SectionCard({
10
+ title,
11
+ icon,
12
+ action,
13
+ children,
14
+ className,
15
+ bodyClassName,
16
+ }: {
17
+ title?: ReactNode;
18
+ icon?: ReactNode;
19
+ action?: ReactNode;
20
+ children: ReactNode;
21
+ className?: string;
22
+ bodyClassName?: string;
23
+ }) {
24
+ const hasHeader = !!(title || action);
25
+ const header = hasHeader && (
26
+ // Header: padding 16px (pad-2xl) + divider full-bleed embaixo.
27
+ <header className="flex items-center justify-between gap-gp-md border-b border-border-subtle bg-bg-subtle p-pad-2xl">
28
+ {/* gap ícone↔título = 12px (gap-gp-md) */}
29
+ <div className="flex items-center gap-gp-md">
30
+ {icon && (
31
+ <span className="grid size-8 shrink-0 place-items-center rounded-radius-md bg-bg-muted text-fg-muted">
32
+ {icon}
33
+ </span>
34
+ )}
35
+ {title && (
36
+ <h2 className="text-title-md font-semibold text-fg-default">
37
+ {title}
38
+ </h2>
39
+ )}
40
+ </div>
41
+ {action}
42
+ </header>
43
+ );
44
+
45
+ return (
46
+ <section className={cn("overflow-hidden rounded-radius-lg border border-border-subtle bg-bg-surface shadow-sh-sm", className)}>
47
+ {header}
48
+ {/* body: padding 16px (pad-2xl) — uniforme; abaixo do divider quando há header */}
49
+ <div className={cn("p-pad-2xl", bodyClassName)}>{children}</div>
50
+ </section>
51
+ );
52
+ }
53
+
54
+ /** Divisória sutil de seção. `my` controla o respiro vertical (default md). */
55
+ export function SectionDivider({ className }: { className?: string }) {
56
+ return <div className={cn("h-px bg-border-subtle", className)} />;
57
+ }
58
+
59
+ /** Par label-uppercase + valor (grid de Customer/Shipping/Billing Information). */
60
+ export function Field({
61
+ label,
62
+ value,
63
+ accent,
64
+ }: {
65
+ label: string;
66
+ value: ReactNode;
67
+ /** Destaca o valor com a cor de marca (links, ids de transação, etc). */
68
+ accent?: boolean;
69
+ }) {
70
+ return (
71
+ <div className="flex flex-col gap-gp-2xs">
72
+ <span className="text-caption-sm font-medium uppercase tracking-wider text-fg-muted">
73
+ {label}
74
+ </span>
75
+ <span
76
+ className={cn(
77
+ "text-body-md",
78
+ accent ? "text-fg-brand" : "text-fg-default",
79
+ )}
80
+ >
81
+ {value}
82
+ </span>
83
+ </div>
84
+ );
85
+ }
@@ -0,0 +1,234 @@
1
+ import { useRef, useState } from "react";
2
+ import { CreditCard, MapPin, Package, User } from "lucide-react";
3
+ import { Button } from "@/components/ui/Button/button";
4
+ import { ChipGroup, ChipGroupItem } from "@/components/ui/Chip";
5
+ import { PageHeader } from "@/components/ui/PageHeader";
6
+ import {
7
+ FormField,
8
+ FormFieldInput,
9
+ FormFieldSelect,
10
+ } from "@/components/ui/FormField";
11
+ import {
12
+ Select,
13
+ SelectContent,
14
+ SelectItem,
15
+ SelectTrigger,
16
+ SelectValue,
17
+ } from "@/components/shadcn/select";
18
+ import { Input } from "@/components/shadcn/input";
19
+ import { SectionCard } from "./components/section-card";
20
+ import { StepNav, type Step } from "./components/StepNav";
21
+
22
+ const STEPS: Step[] = [
23
+ {
24
+ id: "produtos",
25
+ icon: Package,
26
+ title: "Selecionar produtos",
27
+ description: "Adicione produtos à lista de compra.",
28
+ },
29
+ {
30
+ id: "cliente",
31
+ icon: User,
32
+ title: "Dados do cliente",
33
+ description: "Nome, e-mail e telefone do cliente.",
34
+ },
35
+ {
36
+ id: "endereco",
37
+ icon: MapPin,
38
+ title: "Endereço",
39
+ description: "Informe o endereço de entrega.",
40
+ },
41
+ {
42
+ id: "pagamento",
43
+ icon: CreditCard,
44
+ title: "Pagamento",
45
+ description: "Método e dados do pagamento.",
46
+ },
47
+ ];
48
+
49
+ const COUNTRY_OPTIONS = [
50
+ { value: "br", label: "Brasil" },
51
+ { value: "pt", label: "Portugal" },
52
+ { value: "us", label: "Estados Unidos" },
53
+ ];
54
+
55
+ const PAYMENT_OPTIONS = [
56
+ { value: "card", label: "Cartão de crédito/débito" },
57
+ { value: "pix", label: "PIX" },
58
+ { value: "boleto", label: "Boleto" },
59
+ ];
60
+
61
+ const DDI_OPTIONS = ["+55", "+1", "+351"];
62
+
63
+ /**
64
+ * EditPageScreen — tela de edição de pedido (formulário em etapas). Mesmo
65
+ * modelo de design da OrderDetail (SectionCard) + nav lateral (stepper).
66
+ * Toggle de layout: 1 coluna (igual à referência) ou 2 colunas. Domínio
67
+ * iGreen (energia solar).
68
+ */
69
+ export function EditPageScreen() {
70
+ const [cols, setCols] = useState<"one" | "two">("one");
71
+ const [activeStep, setActiveStep] = useState("produtos");
72
+
73
+ const sectionRefs = useRef<Record<string, HTMLDivElement | null>>({});
74
+
75
+ const goTo = (id: string) => {
76
+ setActiveStep(id);
77
+ sectionRefs.current[id]?.scrollIntoView({ behavior: "smooth", block: "start" });
78
+ };
79
+
80
+ const setRef = (id: string) => (el: HTMLDivElement | null) => {
81
+ sectionRefs.current[id] = el;
82
+ };
83
+
84
+ return (
85
+ // Conteúdo da página (sem shell). Embrulhe no seu AppShell/layout — o
86
+ // parent precisa dar altura (h-full/flex) pra página preencher.
87
+ <div className="flex flex-col h-full min-h-0 gap-gp-2xl">
88
+ <PageHeader
89
+ title="Editar pedido"
90
+ description="Pedido #84021 · atualize produtos, cliente, entrega e pagamento."
91
+ hideTextOnMobile={false}
92
+ actions={
93
+ <ChipGroup
94
+ type="single"
95
+ value={cols}
96
+ onValueChange={(v) => v && setCols(v as "one" | "two")}
97
+ size="sm"
98
+ ariaLabel="Layout das colunas"
99
+ >
100
+ <ChipGroupItem value="one">1 coluna</ChipGroupItem>
101
+ <ChipGroupItem value="two">2 colunas</ChipGroupItem>
102
+ </ChipGroup>
103
+ }
104
+ />
105
+
106
+ <div className="grid grid-cols-1 items-start gap-gp-4xl pb-pad-6xl lg:grid-cols-[260px_1fr]">
107
+ {/* Nav lateral */}
108
+ <StepNav
109
+ steps={STEPS}
110
+ activeId={activeStep}
111
+ onSelect={goTo}
112
+ className="lg:sticky lg:top-gp-2xl"
113
+ />
114
+
115
+ {/* Seções do formulário */}
116
+ <div
117
+ className={
118
+ cols === "two"
119
+ ? "grid grid-cols-1 items-start gap-gp-4xl xl:grid-cols-2"
120
+ : "flex flex-col gap-gp-4xl"
121
+ }
122
+ >
123
+ <div ref={setRef("produtos")} className="scroll-mt-gp-2xl">
124
+ <SectionCard title="Selecionar produtos">
125
+ <FormFieldInput
126
+ label="Buscar produto"
127
+ placeholder="Busque por nome ou SKU..."
128
+ />
129
+ </SectionCard>
130
+ </div>
131
+
132
+ <div ref={setRef("cliente")} className="scroll-mt-gp-2xl">
133
+ <SectionCard title="Dados do cliente">
134
+ <div className="flex flex-col gap-form-gap">
135
+ <div className="grid grid-cols-1 gap-form-gap sm:grid-cols-2">
136
+ <FormFieldInput label="Nome" placeholder="Nome" />
137
+ <FormFieldInput label="Usuário" placeholder="Nome de usuário" />
138
+ </div>
139
+ <FormFieldInput
140
+ label="Email"
141
+ type="email"
142
+ placeholder="email@exemplo.com"
143
+ />
144
+ <FormField label="Telefone">
145
+ {({ id }) => (
146
+ <div className="flex gap-gp-sm">
147
+ <Select defaultValue="+55">
148
+ <SelectTrigger className="w-24 shrink-0">
149
+ <SelectValue />
150
+ </SelectTrigger>
151
+ <SelectContent>
152
+ {DDI_OPTIONS.map((d) => (
153
+ <SelectItem key={d} value={d}>
154
+ {d}
155
+ </SelectItem>
156
+ ))}
157
+ </SelectContent>
158
+ </Select>
159
+ <Input
160
+ id={id}
161
+ type="tel"
162
+ placeholder="Número de telefone"
163
+ className="flex-1"
164
+ />
165
+ </div>
166
+ )}
167
+ </FormField>
168
+ </div>
169
+ </SectionCard>
170
+ </div>
171
+
172
+ <div ref={setRef("endereco")} className="scroll-mt-gp-2xl">
173
+ <SectionCard title="Endereço">
174
+ <div className="flex flex-col gap-form-gap">
175
+ <FormFieldSelect
176
+ label="País"
177
+ placeholder="Selecione o país"
178
+ options={COUNTRY_OPTIONS}
179
+ />
180
+ <FormFieldInput label="Endereço" placeholder="Rua, número" />
181
+ <div className="grid grid-cols-1 gap-form-gap sm:grid-cols-2">
182
+ <FormFieldInput label="Cidade" placeholder="Cidade" />
183
+ <FormFieldInput label="CEP" placeholder="00000-000" />
184
+ </div>
185
+ </div>
186
+ </SectionCard>
187
+ </div>
188
+
189
+ <div ref={setRef("pagamento")} className="scroll-mt-gp-2xl">
190
+ <SectionCard title="Pagamento">
191
+ <div className="flex flex-col gap-form-gap">
192
+ <FormFieldSelect
193
+ label="Método de pagamento"
194
+ defaultValue="card"
195
+ options={PAYMENT_OPTIONS}
196
+ />
197
+ <FormFieldInput
198
+ label="Nome no cartão"
199
+ placeholder="Nome impresso no cartão"
200
+ />
201
+ <FormFieldInput
202
+ label="Número do cartão"
203
+ placeholder="0000 0000 0000 0000"
204
+ inputMode="numeric"
205
+ />
206
+ <div className="grid grid-cols-1 gap-form-gap sm:grid-cols-2">
207
+ <FormFieldInput label="Validade" placeholder="MM/AA" />
208
+ <FormFieldInput label="CVV" placeholder="123" />
209
+ </div>
210
+ </div>
211
+ </SectionCard>
212
+ </div>
213
+
214
+ {/* Footer de ações */}
215
+ <div
216
+ className={
217
+ "flex items-center justify-end gap-gp-md" +
218
+ (cols === "two" ? " xl:col-span-2" : "")
219
+ }
220
+ >
221
+ <Button variant="outline" color="secondary" size="md">
222
+ Cancelar
223
+ </Button>
224
+ <Button variant="filled" color="primary" size="md">
225
+ Salvar pedido
226
+ </Button>
227
+ </div>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ );
232
+ }
233
+
234
+ export default EditPageScreen;
@@ -0,0 +1 @@
1
+ export { EditPageScreen, default } from "./edit-page-screen";
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Dados base compartilhados (extraídos do showcase TableDoc do DS).
3
+ * Mantém o exemplo autossuficiente — sem dependência da infra de preview.
4
+ */
5
+
6
+ export const STATUSES: Record<string, { label: string; color: string }> = {
7
+ active: { label: "Ativo", color: "var(--color-fg-success)" },
8
+ pending: { label: "Pendente", color: "var(--color-fg-warning)" },
9
+ paused: { label: "Pausado", color: "var(--color-fg-info)" },
10
+ inactive: { label: "Inativo", color: "var(--color-fg-muted)" },
11
+ };
12
+
13
+ export type CategoryKind = "warning" | "info" | "success" | "neutral";
14
+ export const CATEGORIES: Record<string, { label: string; kind: CategoryKind }> = {
15
+ royal: { label: "Royal", kind: "warning" },
16
+ licenciado: { label: "Licenciado", kind: "info" },
17
+ lead: { label: "Lead", kind: "success" },
18
+ };
19
+
20
+ export const AGENTS: Record<string, { name: string; initials: string; color: string }> = {
21
+ you: { name: "Voce", initials: "VC", color: "#0a3a2e" },
22
+ aline: { name: "Aline Castro", initials: "AC", color: "#f59e0b" },
23
+ carlos: { name: "Carlos Souza", initials: "CS", color: "#8754ec" },
24
+ maria: { name: "Maria Lima", initials: "ML", color: "#ef4444" },
25
+ };
26
+
27
+ export type ClientRow = {
28
+ id: string;
29
+ name: string;
30
+ initials: string;
31
+ avatarColor: string;
32
+ email: string;
33
+ phone: string;
34
+ statusId: keyof typeof STATUSES;
35
+ categoryId: keyof typeof CATEGORIES;
36
+ location: string;
37
+ value: number;
38
+ agentId: keyof typeof AGENTS;
39
+ createdAt: number;
40
+ lastContact: number;
41
+ };
42
+
43
+ const BASE_DATE = new Date("2026-04-15T12:00:00Z").getTime();
44
+ const DAY_MS = 86400000;
45
+
46
+ export const CLIENTS_MOCK: ClientRow[] = [
47
+ { id: "CLI-2401", name: "Maria Silva", initials: "MS", avatarColor: "#f59e0b", email: "maria.silva@example.com", phone: "+55 11 91234-5678", statusId: "active", categoryId: "royal", location: "São Paulo, SP", value: 4800, agentId: "you", createdAt: BASE_DATE - 65 * DAY_MS, lastContact: BASE_DATE - 2 * DAY_MS },
48
+ { id: "CLI-2402", name: "João Santos", initials: "JS", avatarColor: "#0a3a2e", email: "joao.santos@example.com", phone: "+55 11 92345-6789", statusId: "pending", categoryId: "licenciado", location: "Rio de Janeiro, RJ", value: 12300, agentId: "aline", createdAt: BASE_DATE - 58 * DAY_MS, lastContact: BASE_DATE - 5 * DAY_MS },
49
+ { id: "CLI-2403", name: "Carlos Oliveira", initials: "CO", avatarColor: "#8754ec", email: "carlos.oliveira@example.com", phone: "+55 11 93456-7890", statusId: "active", categoryId: "lead", location: "Belo Horizonte, MG", value: 2150, agentId: "carlos", createdAt: BASE_DATE - 51 * DAY_MS, lastContact: BASE_DATE - 1 * DAY_MS },
50
+ { id: "CLI-2404", name: "Ana Costa", initials: "AC", avatarColor: "#1cb280", email: "ana.costa@example.com", phone: "+55 11 94567-8901", statusId: "paused", categoryId: "royal", location: "Porto Alegre, RS", value: 8900, agentId: "maria", createdAt: BASE_DATE - 44 * DAY_MS, lastContact: BASE_DATE - 12 * DAY_MS },
51
+ { id: "CLI-2405", name: "Pedro Pereira", initials: "PP", avatarColor: "#ef4444", email: "pedro.pereira@example.com", phone: "+55 11 95678-9012", statusId: "inactive", categoryId: "lead", location: "Curitiba, PR", value: 1100, agentId: "you", createdAt: BASE_DATE - 37 * DAY_MS, lastContact: BASE_DATE - 30 * DAY_MS },
52
+ { id: "CLI-2406", name: "Lúcia Almeida", initials: "LA", avatarColor: "#f9a47a", email: "lucia.almeida@example.com", phone: "+55 11 96789-0123", statusId: "active", categoryId: "licenciado", location: "Recife, PE", value: 6750, agentId: "aline", createdAt: BASE_DATE - 30 * DAY_MS, lastContact: BASE_DATE - 3 * DAY_MS },
53
+ { id: "CLI-2407", name: "Roberto Souza", initials: "RS", avatarColor: "#0088cc", email: "roberto.souza@example.com", phone: "+55 11 97890-1234", statusId: "pending", categoryId: "royal", location: "São Paulo, SP", value: 15200, agentId: "carlos", createdAt: BASE_DATE - 23 * DAY_MS, lastContact: BASE_DATE - 7 * DAY_MS },
54
+ { id: "CLI-2408", name: "Fernanda Lima", initials: "FL", avatarColor: "#e1306c", email: "fernanda.lima@example.com", phone: "+55 11 98901-2345", statusId: "active", categoryId: "lead", location: "Rio de Janeiro, RJ", value: 3400, agentId: "maria", createdAt: BASE_DATE - 16 * DAY_MS, lastContact: BASE_DATE - 1 * DAY_MS },
55
+ { id: "CLI-2409", name: "Bruno Rodrigues", initials: "BR", avatarColor: "#70c748", email: "bruno.rodrigues@example.com", phone: "+55 11 99012-3456", statusId: "paused", categoryId: "licenciado", location: "Belo Horizonte, MG", value: 5600, agentId: "you", createdAt: BASE_DATE - 9 * DAY_MS, lastContact: BASE_DATE - 6 * DAY_MS },
56
+ { id: "CLI-2410", name: "Camila Ribeiro", initials: "CR", avatarColor: "#8754ec", email: "camila.ribeiro@example.com", phone: "+55 11 90123-4567", statusId: "active", categoryId: "royal", location: "Porto Alegre, RS", value: 9800, agentId: "aline", createdAt: BASE_DATE - 2 * DAY_MS, lastContact: BASE_DATE },
57
+ ];