@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 { FinanceScreen, default } from "./finance-screen";
@@ -0,0 +1,402 @@
1
+ /**
2
+ * Dados de exemplo do cronograma — o que você troca PRIMEIRO.
3
+ *
4
+ * Extraído 1:1 do showcase `GanttFullPreview` do DS (L-034): não é toy, é o
5
+ * mesmo dado que a página de exemplo exercita — 20 linhas, 4 níveis de
6
+ * hierarquia, 16 vínculos dos 4 tipos e 2 conflitos de prazo.
7
+ *
8
+ * ⚠️ **Um dos dois conflitos não foi plantado.** As datas foram escritas e o
9
+ * componente achou (o front termina 1 dia depois de o QA começar). Ficou de
10
+ * propósito: é o caso mais comum em cronograma real, e mostra o contador
11
+ * somando déficits de vínculos diferentes.
12
+ *
13
+ * ⚠️ `hoje` é uma data FIXA (17/09/2026), não `new Date()`. O exemplo precisa
14
+ * ser estável: com data corrente, o `now` andaria e o cronograma sairia da
15
+ * janela em algumas semanas. Ao ligar em dado real, troque por `new Date()`.
16
+ */
17
+
18
+ import { addDays, startOfDay } from "date-fns";
19
+ import type {
20
+ GanttColumn,
21
+ GanttFilterField,
22
+ GanttLink,
23
+ GanttRow,
24
+ } from "@/components/ui/Gantt";
25
+ import { Avatar } from "@/components/ui/avatar-ig";
26
+ import { Chip } from "@/components/ui/Chip";
27
+
28
+ export const hoje = startOfDay(new Date(2026, 8, 17));
29
+ export const d = (offset: number) => addDays(hoje, offset);
30
+
31
+ export type Meta = {
32
+ responsavel: string;
33
+ frente: string;
34
+ descricao: string;
35
+ };
36
+
37
+ /** Iniciais pro avatar. O `avatar-ig` recebe iniciais como children. */
38
+ export const iniciais = (nome: string) =>
39
+ nome
40
+ .split(" ")
41
+ .slice(0, 2)
42
+ .map((p) => p[0])
43
+ .join("")
44
+ .toUpperCase();
45
+
46
+ /**
47
+ * Oito pessoas, e o número importa: o painel de filtro liga a busca a partir de
48
+ * **7 opções**. Com 4 o campo não aparecia — e é justamente no grupo de
49
+ * responsável que procurar por nome ganha da varredura visual.
50
+ *
51
+ * Não usei `searchable: true` no campo pra forçar: deixar o limiar natural
52
+ * disparar é o que prova que ele funciona.
53
+ */
54
+ export const PESSOAS: Record<string, string> = {
55
+ ana: "Ana Ribeiro",
56
+ bruno: "Bruno Camargo",
57
+ carla: "Carla Menezes",
58
+ diego: "Diego Sato",
59
+ elisa: "Elisa Nakamura",
60
+ fabio: "Fábio Queiroz",
61
+ gabriela: "Gabriela Prado",
62
+ henrique: "Henrique Vilela",
63
+ };
64
+
65
+ /**
66
+ * As cores que o drawer oferece.
67
+ *
68
+ * ⚠️ São as **chaves de chart** do DS, não hex. A cor da barra diz CATEGORIA
69
+ * (qual frente), e o rótulo aqui é o nome da frente — não "verde", "roxo". Um
70
+ * seletor de cor por nome de cor convidaria o usuário a usar cor como STATUS,
71
+ * que é exatamente a assumption que a spec declara e que status em
72
+ * `row.trailing` resolve.
73
+ */
74
+ export const CORES_DISPONIVEIS = [
75
+ { value: "chart-1", label: "Produto" },
76
+ { value: "chart-5", label: "Design" },
77
+ { value: "chart-3", label: "Engenharia" },
78
+ { value: "chart-4", label: "QA" },
79
+ { value: "chart-2", label: "Integração" },
80
+ ] as const;
81
+
82
+ export const ROWS_SEMENTE: GanttRow[] = [
83
+ /* ── Fase 1 ──────────────────────────────────────────────────── */
84
+ {
85
+ id: "f1",
86
+ label: "1. Descoberta e escopo",
87
+ type: "summary",
88
+ bars: [],
89
+ trailing: <Chip size="sm" variant="soft" color="success">Concluída</Chip>,
90
+ },
91
+ {
92
+ id: "f1-a",
93
+ label: "Entrevistas com a operação",
94
+ sublabel: "5 sessões · Ana",
95
+ parent: "f1",
96
+ bars: [{ id: "b1", label: "Entrevistas", start: d(-16), end: d(-11), colorKey: "chart-1", progress: 100, meta: { responsavel: "ana", frente: "produto", descricao: "Levantamento com o time de atendimento e a supervisão." } satisfies Meta }],
97
+ },
98
+ {
99
+ id: "f1-b",
100
+ label: "Mapa de processos",
101
+ sublabel: "Bruno",
102
+ parent: "f1",
103
+ bars: [{ id: "b2", label: "Mapa", start: d(-13), end: d(-8), colorKey: "chart-1", progress: 100, meta: { responsavel: "bruno", frente: "produto", descricao: "Fluxo atual documentado, com os 4 pontos de retrabalho." } satisfies Meta }],
104
+ },
105
+ {
106
+ id: "f1-c",
107
+ label: "Escopo e estimativa",
108
+ sublabel: "Ana",
109
+ parent: "f1",
110
+ bars: [{ id: "b3", label: "Escopo", start: d(-8), end: d(-4), colorKey: "chart-1", progress: 100, meta: { responsavel: "ana", frente: "produto", descricao: "Três fases, 22 entregas, marco de aprovação." } satisfies Meta }],
111
+ },
112
+ {
113
+ id: "f1-m",
114
+ label: "Escopo aprovado",
115
+ type: "milestone",
116
+ parent: "f1",
117
+ bars: [{ id: "m1", start: d(-4), end: d(-4), colorKey: "brand", meta: { responsavel: "ana", frente: "produto", descricao: "Aprovado em comitê." } satisfies Meta }],
118
+ },
119
+
120
+ /* ── Fase 2 ──────────────────────────────────────────────────── */
121
+ {
122
+ id: "f2",
123
+ label: "2. Design",
124
+ type: "summary",
125
+ bars: [],
126
+ trailing: <Chip size="sm" variant="soft" color="warning">Em andamento</Chip>,
127
+ },
128
+ {
129
+ id: "f2-a",
130
+ label: "Fluxos e arquitetura de informação",
131
+ sublabel: "Carla",
132
+ parent: "f2",
133
+ bars: [{ id: "b4", label: "Fluxos e IA", start: d(-3), end: d(3), colorKey: "chart-5", progress: 100, meta: { responsavel: "carla", frente: "design", descricao: "12 fluxos, incluindo os 3 de exceção." } satisfies Meta }],
134
+ },
135
+ {
136
+ id: "f2-b",
137
+ label: "Sistema de design",
138
+ type: "summary",
139
+ parent: "f2",
140
+ bars: [],
141
+ },
142
+ {
143
+ id: "f2-b1",
144
+ label: "Tokens e fundações",
145
+ sublabel: "Elisa",
146
+ parent: "f2-b",
147
+ bars: [{ id: "b5", label: "Tokens", start: d(1), end: d(6), colorKey: "chart-5", progress: 70, meta: { responsavel: "elisa", frente: "design", descricao: "Cor, tipografia e espaçamento em 3 tiers." } satisfies Meta }],
148
+ },
149
+ {
150
+ id: "f2-b2",
151
+ label: "Componentes de formulário",
152
+ sublabel: "Fábio",
153
+ parent: "f2-b",
154
+ bars: [{ id: "b6", label: "Formulário", start: d(4), end: d(11), colorKey: "chart-5", progress: 30, meta: { responsavel: "fabio", frente: "design", descricao: "Input, select, date picker e validação." } satisfies Meta }],
155
+ },
156
+ {
157
+ id: "f2-c",
158
+ label: "Telas de alta fidelidade",
159
+ sublabel: "Carla · Diego",
160
+ parent: "f2",
161
+ bars: [{ id: "b7", label: "Telas", start: d(6), end: d(17), colorKey: "chart-5", progress: 15, meta: { responsavel: "carla", frente: "design", descricao: "18 telas, 2 estados cada." } satisfies Meta }],
162
+ },
163
+ {
164
+ id: "f2-d",
165
+ label: "Revisão com o time",
166
+ sublabel: "todos",
167
+ parent: "f2",
168
+ bars: [{ id: "b8", label: "Revisão", start: d(16), end: d(19), colorKey: "chart-5", progress: 0, meta: { responsavel: "ana", frente: "design", descricao: "Sessão de crítica com engenharia e operação." } satisfies Meta }],
169
+ },
170
+
171
+ /* ── Fase 3 ──────────────────────────────────────────────────── */
172
+ {
173
+ id: "f3",
174
+ label: "3. Construção",
175
+ type: "summary",
176
+ bars: [],
177
+ trailing: <Chip size="sm" variant="soft" color="neutral">Planejada</Chip>,
178
+ },
179
+ {
180
+ id: "f3-a",
181
+ label: "API de cronograma",
182
+ sublabel: "Bruno",
183
+ parent: "f3",
184
+ bars: [{ id: "b9", label: "API", start: d(19), end: d(30), colorKey: "chart-3", meta: { responsavel: "bruno", frente: "engenharia", descricao: "CRUD de tarefa, vínculo e recálculo." } satisfies Meta }],
185
+ },
186
+ {
187
+ id: "f3-b",
188
+ label: "Front do painel",
189
+ sublabel: "Diego",
190
+ parent: "f3",
191
+ bars: [{ id: "b10", label: "Front", start: d(23), end: d(37), colorKey: "chart-3", meta: { responsavel: "diego", frente: "engenharia", descricao: "Consome o Gantt do DS." } satisfies Meta }],
192
+ },
193
+ {
194
+ id: "f3-c",
195
+ label: "Integração com o ERP",
196
+ sublabel: "Bruno",
197
+ parent: "f3",
198
+ // ⚠️ CONFLITO PLANTADO: começa antes de a API terminar, e o vínculo é FS.
199
+ bars: [{ id: "b11", label: "Integração", start: d(26), end: d(35), colorKey: "chart-2", meta: { responsavel: "bruno", frente: "engenharia", descricao: "Começa antes do permitido — o componente sinaliza." } satisfies Meta }],
200
+ },
201
+ {
202
+ id: "f3-d",
203
+ label: "QA e correções",
204
+ sublabel: "todos",
205
+ parent: "f3",
206
+ bars: [{ id: "b12", label: "QA", start: d(36), end: d(43), colorKey: "chart-4", meta: { responsavel: "gabriela", frente: "qa", descricao: "Regressão e acessibilidade." } satisfies Meta }],
207
+ },
208
+ {
209
+ id: "f3-e",
210
+ label: "Documentação",
211
+ sublabel: "Ana",
212
+ parent: "f3",
213
+ bars: [{ id: "b13", label: "Docs", start: d(38), end: d(44), colorKey: "chart-1", meta: { responsavel: "ana", frente: "produto", descricao: "USAGE, doc page e vocabulário do consumidor." } satisfies Meta }],
214
+ },
215
+
216
+ /* ── Portfólio: a linha como contêiner ───────────────────────── */
217
+ {
218
+ id: "sustentacao",
219
+ label: "Sustentação (paralelo)",
220
+ sublabel: "3 frentes simultâneas",
221
+ lanePacking: "stack",
222
+ bars: [
223
+ { id: "s1", label: "Bugs P1", start: d(-10), end: d(5), colorKey: "chart-4", meta: { responsavel: "diego", frente: "engenharia", descricao: "Fila contínua." } satisfies Meta },
224
+ { id: "s2", label: "Débito técnico", start: d(0), end: d(20), colorKey: "chart-2", meta: { responsavel: "bruno", frente: "engenharia", descricao: "Refatoração do módulo de faturamento." } satisfies Meta },
225
+ { id: "s3", label: "Observabilidade", start: d(12), end: d(34), colorKey: "chart-3", meta: { responsavel: "henrique", frente: "engenharia", descricao: "Métricas e alertas." } satisfies Meta },
226
+ ],
227
+ },
228
+
229
+ {
230
+ id: "entrega",
231
+ label: "Entrega em produção",
232
+ type: "milestone",
233
+ bars: [{ id: "m2", start: d(45), end: d(45), colorKey: "danger", meta: { responsavel: "ana", frente: "produto", descricao: "Go-live com o piloto de 3 filiais." } satisfies Meta }],
234
+ },
235
+ ];
236
+
237
+ export const LINKS_SEMENTE: GanttLink[] = [
238
+ { id: "l1", source: "b1", target: "b2", type: "SS", lag: 3 },
239
+ { id: "l2", source: "b2", target: "b3", type: "FS" },
240
+ { id: "l3", source: "b3", target: "m1", type: "FS" },
241
+ { id: "l4", source: "m1", target: "b4", type: "FS" },
242
+ { id: "l5", source: "b4", target: "b5", type: "SS", lag: 4 },
243
+ { id: "l6", source: "b5", target: "b6", type: "SS", lag: 3 },
244
+ { id: "l7", source: "b6", target: "b7", type: "SS", lag: 2 },
245
+ { id: "l8", source: "b7", target: "b8", type: "FF", lag: 2 },
246
+ { id: "l9", source: "b8", target: "b9", type: "FS" },
247
+ { id: "l10", source: "b9", target: "b10", type: "SS", lag: 4 },
248
+ // Este é o conflito: a integração começa antes de a API terminar.
249
+ { id: "l11", source: "b9", target: "b11", type: "FS" },
250
+ /**
251
+ * SEGUNDO conflito, e ele foi acidental — eu escrevi as datas e o componente
252
+ * achou: o front termina em d(37) e o QA começa em d(36), 1 dia antes.
253
+ *
254
+ * Ficou de propósito. É o caso mais comum em cronograma real (duas frentes
255
+ * convergindo no mesmo marco, uma delas escorregando) e é o que mostra o
256
+ * contador somando déficit de vínculos diferentes: 4d + 1d = 5d.
257
+ */
258
+ { id: "l12", source: "b10", target: "b12", type: "FS" },
259
+ { id: "l13", source: "b11", target: "b12", type: "FS", lag: 1 },
260
+ { id: "l14", source: "b12", target: "b13", type: "SS", lag: 2 },
261
+ { id: "l15", source: "b12", target: "m2", type: "FS", lag: 2 },
262
+ { id: "l16", source: "b13", target: "m2", type: "FS" },
263
+ ];
264
+
265
+ /** Duração em dias da primeira barra — o mesmo número da coluna "Duração". */
266
+ export const duracaoEmDias = (row: GanttRow): number | undefined => {
267
+ const b = row.bars[0];
268
+ if (!b) return undefined;
269
+ return Math.round((b.end.getTime() - b.start.getTime()) / 86_400_000) + 1;
270
+ };
271
+
272
+ /**
273
+ * Os **6 tipos** de filtro, um de cada — e é de propósito.
274
+ *
275
+ * Até a v0.59 o `Gantt` só aceitava `multi`, então o exemplo só exercitava
276
+ * `multi`. Um exemplo que cobre 1 de 6 caminhos não prova que os outros 5
277
+ * funcionam: prova que existem no tipo. Aqui cada `kind` aparece com dado real,
278
+ * e é isso que faz a tela ser gate e não vitrine.
279
+ *
280
+ * A ordem importa pra leitura do painel: os dois de opções primeiro (que é o
281
+ * caso comum), depois os de valor.
282
+ */
283
+ export const FILTROS: GanttFilterField[] = [
284
+ {
285
+ id: "frente",
286
+ label: "Frente",
287
+ kind: "multi",
288
+ options: [
289
+ { value: "produto", label: "Produto", colorKey: "chart-1" },
290
+ { value: "design", label: "Design", colorKey: "chart-5" },
291
+ { value: "engenharia", label: "Engenharia", colorKey: "chart-3" },
292
+ { value: "qa", label: "QA", colorKey: "chart-4" },
293
+ ],
294
+ accessor: (row) =>
295
+ row.bars.map((b) => (b.meta as Meta | undefined)?.frente ?? "").filter(Boolean),
296
+ },
297
+ {
298
+ id: "responsavel",
299
+ label: "Responsável",
300
+ options: Object.entries(PESSOAS).map(([value, label]) => ({ value, label })),
301
+ accessor: (row) =>
302
+ row.bars
303
+ .map((b) => (b.meta as Meta | undefined)?.responsavel ?? "")
304
+ .filter(Boolean),
305
+ },
306
+
307
+ /**
308
+ * `single` — uma frente só. Radio, não checkbox.
309
+ *
310
+ * Convive com o `multi` de "Frente" no mesmo painel de propósito: é o par
311
+ * que mostra que a diferença entre os dois é de CONTROLE (checkbox × radio),
312
+ * não de dado — os dois leem o mesmo campo.
313
+ */
314
+ {
315
+ id: "frenteUnica",
316
+ label: "Frente (só uma)",
317
+ kind: "single",
318
+ options: [
319
+ { value: "produto", label: "Produto", colorKey: "chart-1" },
320
+ { value: "design", label: "Design", colorKey: "chart-5" },
321
+ { value: "engenharia", label: "Engenharia", colorKey: "chart-3" },
322
+ { value: "qa", label: "QA", colorKey: "chart-4" },
323
+ ],
324
+ accessor: (row) => (row.bars[0]?.meta as Meta | undefined)?.frente,
325
+ },
326
+
327
+ /** `text` — busca na descrição, que não é nenhuma das colunas visíveis. */
328
+ {
329
+ id: "descricao",
330
+ label: "Descrição",
331
+ kind: "text",
332
+ placeholder: "Ex.: retrabalho, comitê…",
333
+ accessor: (row) => (row.bars[0]?.meta as Meta | undefined)?.descricao,
334
+ },
335
+
336
+ /**
337
+ * `number` — faixa de duração.
338
+ *
339
+ * O acessor devolve **número**, não string: é o caminho que o núcleo trata
340
+ * sem conversão, e o que um consumidor real teria.
341
+ */
342
+ {
343
+ id: "duracao",
344
+ label: "Duração (dias)",
345
+ kind: "number",
346
+ accessor: duracaoEmDias,
347
+ },
348
+
349
+ /**
350
+ * `date` — período de início.
351
+ *
352
+ * O acessor devolve um `Date` de verdade. É este campo que exercita o
353
+ * `parseDiaISO`: o input emite `YYYY-MM-DD` e o dado é `Date` local, dois
354
+ * lados que só casam porque o parser não passa pelo `new Date(iso)` (que
355
+ * seria UTC e voltaria um dia em UTC−3).
356
+ */
357
+ {
358
+ id: "inicio",
359
+ label: "Início",
360
+ kind: "date",
361
+ accessor: (row) => row.bars[0]?.start,
362
+ },
363
+
364
+ /**
365
+ * `boolean` — concluída ou não.
366
+ *
367
+ * `options` presente pra o chip dizer "Concluída"/"Em aberto" em vez do par
368
+ * universal "Sim"/"Não" — que é o que aparece quando o consumidor omite.
369
+ */
370
+ {
371
+ id: "concluida",
372
+ label: "Concluída",
373
+ kind: "boolean",
374
+ options: [
375
+ { value: "true", label: "Concluída", colorKey: "success" },
376
+ { value: "false", label: "Em aberto", colorKey: "neutral" },
377
+ ],
378
+ accessor: (row) => (row.bars[0]?.progress ?? 0) >= 100,
379
+ },
380
+ ];
381
+
382
+ export const COLUNAS: GanttColumn[] = [
383
+ { id: "label", header: "Tarefa" },
384
+ { id: "start", header: "Início", width: 82 },
385
+ { id: "duration", header: "Duração", width: 74, align: "right" },
386
+ {
387
+ id: "resp",
388
+ header: "Resp.",
389
+ width: 56,
390
+ align: "center",
391
+ render: (row) => {
392
+ const r = (row.bars[0]?.meta as Meta | undefined)?.responsavel;
393
+ if (!r) return null;
394
+ const nome = PESSOAS[r] ?? r;
395
+ return (
396
+ <Avatar size="xs" color="brand" aria-label={nome}>
397
+ {iniciais(nome)}
398
+ </Avatar>
399
+ );
400
+ },
401
+ },
402
+ ];