@snksergio/design-system 0.62.0 → 0.64.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 (149) 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/DataTable.md +2 -1
  7. package/dist-lib/ai/componentes/TableToolbar.md +1 -1
  8. package/dist-lib/ai/exemplos/app-shell/app-shell-example.tsx +140 -0
  9. package/dist-lib/ai/exemplos/app-shell/index.ts +3 -0
  10. package/dist-lib/ai/exemplos/app-shell/nav-data.ts +97 -0
  11. package/dist-lib/ai/exemplos/app-shell/routes.tsx +75 -0
  12. package/dist-lib/ai/exemplos/chat/chat-screen.tsx +152 -0
  13. package/dist-lib/ai/exemplos/chat/chat-v2-mocks.ts +171 -0
  14. package/dist-lib/ai/exemplos/chat/chat-v2.styles.ts +23 -0
  15. package/dist-lib/ai/exemplos/chat/chat-v2.types.ts +81 -0
  16. package/dist-lib/ai/exemplos/chat/components/ChannelDot/channel-dot.tsx +28 -0
  17. package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/conversation-actions-menu.tsx +83 -0
  18. package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/index.ts +4 -0
  19. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.styles.ts +22 -0
  20. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.tsx +203 -0
  21. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.types.ts +10 -0
  22. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/index.ts +2 -0
  23. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.styles.ts +55 -0
  24. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.tsx +52 -0
  25. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.types.ts +7 -0
  26. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/index.ts +2 -0
  27. package/dist-lib/ai/exemplos/chat/components/DateSeparator/date-separator.tsx +18 -0
  28. package/dist-lib/ai/exemplos/chat/components/DetailField/detail-field.tsx +23 -0
  29. package/dist-lib/ai/exemplos/chat/components/DetailSection/detail-section.tsx +41 -0
  30. package/dist-lib/ai/exemplos/chat/components/DetailSection/index.ts +1 -0
  31. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.styles.ts +30 -0
  32. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.tsx +142 -0
  33. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.types.ts +16 -0
  34. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/index.ts +5 -0
  35. package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.styles.ts +37 -0
  36. package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.tsx +45 -0
  37. package/dist-lib/ai/exemplos/chat/components/FilterRow/index.ts +1 -0
  38. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.styles.ts +27 -0
  39. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.tsx +66 -0
  40. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.types.ts +13 -0
  41. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-rail.tsx +38 -0
  42. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/index.ts +6 -0
  43. package/dist-lib/ai/exemplos/chat/components/MessageBubble/index.ts +2 -0
  44. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.styles.ts +37 -0
  45. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.tsx +29 -0
  46. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.types.ts +5 -0
  47. package/dist-lib/ai/exemplos/chat/components/PersonAvatar/index.ts +5 -0
  48. package/dist-lib/ai/exemplos/chat/components/PersonAvatar/person-avatar.tsx +31 -0
  49. package/dist-lib/ai/exemplos/chat/components/QueueColumn/index.ts +2 -0
  50. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.styles.ts +19 -0
  51. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.tsx +140 -0
  52. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.types.ts +13 -0
  53. package/dist-lib/ai/exemplos/chat/components/RailItem/index.ts +1 -0
  54. package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.styles.ts +30 -0
  55. package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.tsx +42 -0
  56. package/dist-lib/ai/exemplos/chat/hooks/use-resizable.ts +98 -0
  57. package/dist-lib/ai/exemplos/chat/index.ts +1 -0
  58. package/dist-lib/ai/exemplos/clientes/_table-data.ts +59 -0
  59. package/dist-lib/ai/exemplos/clientes/clientes-screen.tsx +505 -0
  60. package/dist-lib/ai/exemplos/clientes/clientes-showcase-mocks.ts +117 -0
  61. package/dist-lib/ai/exemplos/clientes/clientes-showcase.styles.ts +13 -0
  62. package/dist-lib/ai/exemplos/clientes/clientes-showcase.types.ts +16 -0
  63. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.styles.ts +28 -0
  64. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.tsx +303 -0
  65. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.types.ts +14 -0
  66. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/index.ts +2 -0
  67. package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/index.ts +2 -0
  68. package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
  69. package/dist-lib/ai/exemplos/clientes/index.ts +1 -0
  70. package/dist-lib/ai/exemplos/edit-page/components/StepNav.tsx +81 -0
  71. package/dist-lib/ai/exemplos/edit-page/components/section-card.tsx +85 -0
  72. package/dist-lib/ai/exemplos/edit-page/edit-page-screen.tsx +234 -0
  73. package/dist-lib/ai/exemplos/edit-page/index.ts +1 -0
  74. package/dist-lib/ai/exemplos/finance/_table-data.ts +57 -0
  75. package/dist-lib/ai/exemplos/finance/clientes-financeiro-mocks.ts +227 -0
  76. package/dist-lib/ai/exemplos/finance/clientes-financeiro.types.ts +75 -0
  77. package/dist-lib/ai/exemplos/finance/clientes-showcase-mocks.ts +117 -0
  78. package/dist-lib/ai/exemplos/finance/clientes-showcase.styles.ts +13 -0
  79. package/dist-lib/ai/exemplos/finance/clientes-showcase.types.ts +16 -0
  80. package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/editar-finance-drawer.tsx +241 -0
  81. package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/index.ts +5 -0
  82. package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/extrato-expansion.tsx +172 -0
  83. package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/index.ts +1 -0
  84. package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/finance-detail-panel.tsx +241 -0
  85. package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/index.ts +2 -0
  86. package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/index.ts +2 -0
  87. package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
  88. package/dist-lib/ai/exemplos/finance/components/SacarDialog/index.ts +2 -0
  89. package/dist-lib/ai/exemplos/finance/components/SacarDialog/sacar-dialog.tsx +346 -0
  90. package/dist-lib/ai/exemplos/finance/finance-screen.tsx +821 -0
  91. package/dist-lib/ai/exemplos/finance/index.ts +1 -0
  92. package/dist-lib/ai/exemplos/gantt/_gantt-data.tsx +402 -0
  93. package/dist-lib/ai/exemplos/gantt/gantt-screen.tsx +512 -0
  94. package/dist-lib/ai/exemplos/gantt/index.ts +1 -0
  95. package/dist-lib/ai/exemplos/login/index.ts +1 -0
  96. package/dist-lib/ai/exemplos/login/login-screen.tsx +246 -0
  97. package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/consultor-detail-panel.tsx +158 -0
  98. package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/index.ts +2 -0
  99. package/dist-lib/ai/exemplos/mapa-rede/index.ts +1 -0
  100. package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede-mocks.ts +655 -0
  101. package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede.types.ts +53 -0
  102. package/dist-lib/ai/exemplos/mapa-rede/mapa-rede-screen.tsx +227 -0
  103. package/dist-lib/ai/exemplos/order-detail/components/ActivityTab.tsx +77 -0
  104. package/dist-lib/ai/exemplos/order-detail/components/AttachmentsTab.tsx +45 -0
  105. package/dist-lib/ai/exemplos/order-detail/components/CommentsTab.tsx +111 -0
  106. package/dist-lib/ai/exemplos/order-detail/components/DetailsTab.tsx +189 -0
  107. package/dist-lib/ai/exemplos/order-detail/components/OverviewTab.tsx +200 -0
  108. package/dist-lib/ai/exemplos/order-detail/components/section-card.tsx +85 -0
  109. package/dist-lib/ai/exemplos/order-detail/index.ts +1 -0
  110. package/dist-lib/ai/exemplos/order-detail/order-detail-screen.tsx +119 -0
  111. package/dist-lib/ai/exemplos/order-detail/order-mocks.ts +186 -0
  112. package/dist-lib/ai/exemplos/order-detail/order.types.ts +118 -0
  113. package/dist-lib/ai/global/componentes.md +7 -0
  114. package/dist-lib/ai/indice.json +30 -15
  115. package/dist-lib/ai/manifest.json +32 -6
  116. package/dist-lib/ai/roteiros/app-builder/roteiro.md +155 -0
  117. package/dist-lib/ai/roteiros/auth-builder/roteiro.md +42 -0
  118. package/dist-lib/ai/roteiros/cards/roteiro.md +34 -0
  119. package/dist-lib/ai/roteiros/charts/roteiro.md +32 -0
  120. package/dist-lib/ai/roteiros/chat/roteiro.md +31 -0
  121. package/dist-lib/ai/roteiros/crud-builder/blueprint.md +63 -0
  122. package/dist-lib/ai/roteiros/crud-builder/entrevista.md +146 -0
  123. package/dist-lib/ai/roteiros/crud-builder/geracao.md +113 -0
  124. package/dist-lib/ai/roteiros/crud-builder/roteiro.md +89 -0
  125. package/dist-lib/ai/roteiros/drawers/roteiro.md +41 -0
  126. package/dist-lib/ai/roteiros/list-builder/blueprint.md +94 -0
  127. package/dist-lib/ai/roteiros/list-builder/entrevista.md +193 -0
  128. package/dist-lib/ai/roteiros/list-builder/geracao.md +63 -0
  129. package/dist-lib/ai/roteiros/list-builder/roteiro.md +91 -0
  130. package/dist-lib/ai/roteiros/module-replicator/roteiro.md +56 -0
  131. package/dist-lib/ai/roteiros/page-detail/roteiro.md +32 -0
  132. package/dist-lib/ai/roteiros/page-edit/roteiro.md +31 -0
  133. package/dist-lib/ai/roteiros/screen-composer/roteiro.md +95 -0
  134. package/dist-lib/chunks/{panel-B-liPlxr.mjs → panel-CN0ChoHM.mjs} +5 -2
  135. package/dist-lib/chunks/{panel-B-liPlxr.mjs.map → panel-CN0ChoHM.mjs.map} +1 -1
  136. package/dist-lib/chunks/{panel-DoNbjeqX.cjs → panel-Cpq1xHck.cjs} +5 -2
  137. package/dist-lib/chunks/{panel-DoNbjeqX.cjs.map → panel-Cpq1xHck.cjs.map} +1 -1
  138. package/dist-lib/index.cjs +1 -1
  139. package/dist-lib/index.mjs +2 -2
  140. package/dist-lib/preview/clientes.cjs +1 -1
  141. package/dist-lib/preview/clientes.mjs +1 -1
  142. package/dist-lib/src/components/ui/DataTable/data-table.d.ts.map +1 -1
  143. package/dist-lib/src/components/ui/DataTable/data-table.types.d.ts +20 -2
  144. package/dist-lib/src/components/ui/DataTable/data-table.types.d.ts.map +1 -1
  145. package/package.json +1 -1
  146. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/blueprint.md +0 -0
  147. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/entrevista.md +0 -0
  148. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/geracao.md +0 -0
  149. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/roteiro.md +0 -0
@@ -0,0 +1,655 @@
1
+ import type { FilterableField, DataListView } from "@/components/ui/DataList";
2
+ import type { Consultor, Graduacao, Regiao } from "./mapa-de-rede.types";
3
+
4
+ /** Meta de graduação → label + cor do Chip (tokens DS). */
5
+ export const GRADUACAO: Record<
6
+ Graduacao,
7
+ {
8
+ label: string;
9
+ color: "primary" | "info" | "success" | "warning" | "neutral";
10
+ }
11
+ > = {
12
+ presidente: { label: "Presidente", color: "primary" },
13
+ diretor: { label: "Diretor", color: "warning" },
14
+ gestor: { label: "Gestor", color: "info" },
15
+ senior: { label: "Sênior", color: "success" },
16
+ pleno: { label: "Pleno", color: "neutral" },
17
+ junior: { label: "Júnior", color: "neutral" },
18
+ };
19
+
20
+ export const REGIAO: Record<Regiao, string> = {
21
+ sudeste: "Sudeste",
22
+ sul: "Sul",
23
+ nordeste: "Nordeste",
24
+ "centro-oeste": "Centro-Oeste",
25
+ norte: "Norte",
26
+ };
27
+
28
+ const CIDADES: Record<Regiao, string[]> = {
29
+ sudeste: [
30
+ "São Paulo, SP",
31
+ "Campinas, SP",
32
+ "Rio de Janeiro, RJ",
33
+ "Belo Horizonte, MG",
34
+ ],
35
+ sul: [
36
+ "Curitiba, PR",
37
+ "Porto Alegre, RS",
38
+ "Florianópolis, SC",
39
+ "Londrina, PR",
40
+ ],
41
+ nordeste: ["Recife, PE", "Salvador, BA", "Fortaleza, CE", "Natal, RN"],
42
+ "centro-oeste": [
43
+ "Goiânia, GO",
44
+ "Brasília, DF",
45
+ "Cuiabá, MT",
46
+ "Campo Grande, MS",
47
+ ],
48
+ norte: ["Manaus, AM", "Belém, PA", "Porto Velho, RO", "Palmas, TO"],
49
+ };
50
+
51
+ /** Paleta de cores de avatar (hex) — o Avatar calcula contraste do texto (L-027). */
52
+ const COLORS = [
53
+ "#2E7D32",
54
+ "#1565C0",
55
+ "#6A1B9A",
56
+ "#C62828",
57
+ "#EF6C00",
58
+ "#00838F",
59
+ "#AD1457",
60
+ "#4527A0",
61
+ "#283593",
62
+ "#558B0F",
63
+ "#D84315",
64
+ "#00695C",
65
+ ];
66
+
67
+ export function formatNum(n: number): string {
68
+ return n.toLocaleString("pt-BR");
69
+ }
70
+
71
+ export function formatLongDate(ms: number): string {
72
+ if (!ms) return "—";
73
+ return new Date(ms).toLocaleDateString("pt-BR", {
74
+ day: "numeric",
75
+ month: "long",
76
+ year: "numeric",
77
+ });
78
+ }
79
+
80
+ export function initials(name: string): string {
81
+ return name
82
+ .split(" ")
83
+ .filter(Boolean)
84
+ .slice(0, 2)
85
+ .map((w) => w[0])
86
+ .join("")
87
+ .toUpperCase();
88
+ }
89
+
90
+ /** Texto do agregado da subárvore (ex: "28 consult · 1.240 GP · 96 clientes"). */
91
+ export function subtreeLabel(c: Consultor): string {
92
+ if (!c.subtree) return "folha · sem descendentes";
93
+ const { consultores, gp, clientes } = c.subtree;
94
+ return `${formatNum(consultores)} consult · ${formatNum(gp)} GP · ${formatNum(clientes)} clientes`;
95
+ }
96
+
97
+ /* ── builder conciso (deriva email/phone/cidade/since/cor) ────────── */
98
+
99
+ const D = (y: number, m: number, d: number) => new Date(y, m - 1, d).getTime();
100
+ type Raw = Omit<Consultor, "subtree" | "children"> & { children?: Raw[] };
101
+ let _seq = 0;
102
+
103
+ type Spec = {
104
+ name: string;
105
+ level: string;
106
+ grad: Graduacao;
107
+ regiao: Regiao;
108
+ gp: number;
109
+ clientes: number;
110
+ pro: boolean;
111
+ lastActive: string;
112
+ since: [number, number, number];
113
+ children?: Raw[];
114
+ };
115
+
116
+ function n(s: Spec): Raw {
117
+ _seq += 1;
118
+ const first = s.name.split(" ")[0].toLowerCase();
119
+ const last = (s.name.split(" ")[1] ?? "ig").toLowerCase();
120
+ return {
121
+ id: `c${_seq}`,
122
+ name: s.name,
123
+ level: s.level,
124
+ graduacao: s.grad,
125
+ regiao: s.regiao,
126
+ gpProprio: s.gp,
127
+ clientes: s.clientes,
128
+ pro: s.pro,
129
+ avatarColor: COLORS[(_seq - 1) % COLORS.length],
130
+ email: `${first}.${last}@igreen.com`,
131
+ phone: `(${10 + (_seq % 89)}) 9${1000 + ((_seq * 37) % 9000)}-${1000 + ((_seq * 53) % 9000)}`,
132
+ location: CIDADES[s.regiao][_seq % CIDADES[s.regiao].length],
133
+ since: D(...s.since),
134
+ lastActive: s.lastActive,
135
+ children: s.children,
136
+ };
137
+ }
138
+
139
+ /* ── rede (multi-raiz: linhas/líderes diretos, cada um com downline) ── */
140
+
141
+ const ROOTS: Raw[] = [
142
+ n({
143
+ name: "Marina Alves",
144
+ level: "Líder",
145
+ grad: "presidente",
146
+ regiao: "sudeste",
147
+ gp: 431,
148
+ clientes: 18,
149
+ pro: true,
150
+ lastActive: "agora há pouco",
151
+ since: [2020, 2, 10],
152
+ children: [
153
+ n({
154
+ name: "Rafael Souza",
155
+ level: "N1",
156
+ grad: "diretor",
157
+ regiao: "sudeste",
158
+ gp: 320,
159
+ clientes: 14,
160
+ pro: true,
161
+ lastActive: "2 h",
162
+ since: [2020, 9, 4],
163
+ children: [
164
+ n({
165
+ name: "Bianca Lima",
166
+ level: "N2",
167
+ grad: "gestor",
168
+ regiao: "sudeste",
169
+ gp: 180,
170
+ clientes: 11,
171
+ pro: true,
172
+ lastActive: "ontem",
173
+ since: [2021, 5, 2],
174
+ children: [
175
+ n({
176
+ name: "Caio Moreira",
177
+ level: "N3",
178
+ grad: "senior",
179
+ regiao: "sudeste",
180
+ gp: 90,
181
+ clientes: 6,
182
+ pro: false,
183
+ lastActive: "3 dias",
184
+ since: [2022, 1, 14],
185
+ }),
186
+ n({
187
+ name: "Duda Prado",
188
+ level: "N3",
189
+ grad: "pleno",
190
+ regiao: "sudeste",
191
+ gp: 50,
192
+ clientes: 4,
193
+ pro: false,
194
+ lastActive: "1 semana",
195
+ since: [2022, 8, 9],
196
+ }),
197
+ ],
198
+ }),
199
+ n({
200
+ name: "Felipe Aragão",
201
+ level: "N2",
202
+ grad: "senior",
203
+ regiao: "sul",
204
+ gp: 70,
205
+ clientes: 5,
206
+ pro: false,
207
+ lastActive: "5 dias",
208
+ since: [2022, 3, 20],
209
+ }),
210
+ ],
211
+ }),
212
+ n({
213
+ name: "Paula Castro",
214
+ level: "N1",
215
+ grad: "gestor",
216
+ regiao: "sudeste",
217
+ gp: 210,
218
+ clientes: 9,
219
+ pro: true,
220
+ lastActive: "4 h",
221
+ since: [2021, 1, 30],
222
+ children: [
223
+ n({
224
+ name: "Gustavo Reis",
225
+ level: "N2",
226
+ grad: "pleno",
227
+ regiao: "sudeste",
228
+ gp: 60,
229
+ clientes: 3,
230
+ pro: false,
231
+ lastActive: "2 dias",
232
+ since: [2022, 6, 1],
233
+ }),
234
+ n({
235
+ name: "Helena Vega",
236
+ level: "N2",
237
+ grad: "junior",
238
+ regiao: "sudeste",
239
+ gp: 25,
240
+ clientes: 1,
241
+ pro: false,
242
+ lastActive: "2 semanas",
243
+ since: [2023, 2, 18],
244
+ }),
245
+ ],
246
+ }),
247
+ ],
248
+ }),
249
+ n({
250
+ name: "Diego Fernandes",
251
+ level: "Líder",
252
+ grad: "presidente",
253
+ regiao: "sul",
254
+ gp: 388,
255
+ clientes: 16,
256
+ pro: true,
257
+ lastActive: "1 h",
258
+ since: [2020, 4, 22],
259
+ children: [
260
+ n({
261
+ name: "Letícia Rocha",
262
+ level: "N1",
263
+ grad: "diretor",
264
+ regiao: "sul",
265
+ gp: 250,
266
+ clientes: 12,
267
+ pro: true,
268
+ lastActive: "30 min",
269
+ since: [2021, 2, 8],
270
+ children: [
271
+ n({
272
+ name: "Tiago Nunes",
273
+ level: "N2",
274
+ grad: "gestor",
275
+ regiao: "sul",
276
+ gp: 120,
277
+ clientes: 8,
278
+ pro: true,
279
+ lastActive: "ontem",
280
+ since: [2021, 11, 17],
281
+ children: [
282
+ n({
283
+ name: "Vera Antunes",
284
+ level: "N3",
285
+ grad: "senior",
286
+ regiao: "sul",
287
+ gp: 70,
288
+ clientes: 5,
289
+ pro: false,
290
+ lastActive: "4 dias",
291
+ since: [2022, 9, 3],
292
+ }),
293
+ ],
294
+ }),
295
+ n({
296
+ name: "Sofia Martins",
297
+ level: "N2",
298
+ grad: "senior",
299
+ regiao: "sul",
300
+ gp: 85,
301
+ clientes: 7,
302
+ pro: false,
303
+ lastActive: "6 dias",
304
+ since: [2022, 5, 11],
305
+ }),
306
+ ],
307
+ }),
308
+ n({
309
+ name: "Otávio Belo",
310
+ level: "N1",
311
+ grad: "gestor",
312
+ regiao: "sul",
313
+ gp: 140,
314
+ clientes: 6,
315
+ pro: false,
316
+ lastActive: "3 dias",
317
+ since: [2021, 7, 25],
318
+ children: [
319
+ n({
320
+ name: "Iara Costa",
321
+ level: "N2",
322
+ grad: "pleno",
323
+ regiao: "sul",
324
+ gp: 55,
325
+ clientes: 3,
326
+ pro: false,
327
+ lastActive: "1 semana",
328
+ since: [2022, 10, 2],
329
+ }),
330
+ ],
331
+ }),
332
+ ],
333
+ }),
334
+ n({
335
+ name: "Beatriz Nogueira",
336
+ level: "Líder",
337
+ grad: "diretor",
338
+ regiao: "nordeste",
339
+ gp: 296,
340
+ clientes: 13,
341
+ pro: true,
342
+ lastActive: "20 min",
343
+ since: [2020, 8, 14],
344
+ children: [
345
+ n({
346
+ name: "André Maia",
347
+ level: "N1",
348
+ grad: "gestor",
349
+ regiao: "nordeste",
350
+ gp: 160,
351
+ clientes: 10,
352
+ pro: true,
353
+ lastActive: "2 h",
354
+ since: [2021, 4, 6],
355
+ children: [
356
+ n({
357
+ name: "Júlia Pires",
358
+ level: "N2",
359
+ grad: "senior",
360
+ regiao: "nordeste",
361
+ gp: 80,
362
+ clientes: 6,
363
+ pro: false,
364
+ lastActive: "2 dias",
365
+ since: [2022, 2, 21],
366
+ }),
367
+ n({
368
+ name: "Kevin Sá",
369
+ level: "N2",
370
+ grad: "pleno",
371
+ regiao: "nordeste",
372
+ gp: 45,
373
+ clientes: 2,
374
+ pro: false,
375
+ lastActive: "5 dias",
376
+ since: [2022, 12, 8],
377
+ }),
378
+ ],
379
+ }),
380
+ n({
381
+ name: "Carla Dantas",
382
+ level: "N1",
383
+ grad: "senior",
384
+ regiao: "nordeste",
385
+ gp: 95,
386
+ clientes: 5,
387
+ pro: false,
388
+ lastActive: "1 dia",
389
+ since: [2021, 9, 19],
390
+ }),
391
+ ],
392
+ }),
393
+ n({
394
+ name: "Eduardo Tavares",
395
+ level: "Líder",
396
+ grad: "diretor",
397
+ regiao: "centro-oeste",
398
+ gp: 248,
399
+ clientes: 11,
400
+ pro: true,
401
+ lastActive: "1 h",
402
+ since: [2020, 11, 3],
403
+ children: [
404
+ n({
405
+ name: "Mariana Goia",
406
+ level: "N1",
407
+ grad: "gestor",
408
+ regiao: "centro-oeste",
409
+ gp: 130,
410
+ clientes: 7,
411
+ pro: true,
412
+ lastActive: "3 h",
413
+ since: [2021, 6, 12],
414
+ children: [
415
+ n({
416
+ name: "Nina Brito",
417
+ level: "N2",
418
+ grad: "pleno",
419
+ regiao: "centro-oeste",
420
+ gp: 50,
421
+ clientes: 3,
422
+ pro: false,
423
+ lastActive: "4 dias",
424
+ since: [2022, 7, 28],
425
+ }),
426
+ ],
427
+ }),
428
+ n({
429
+ name: "Paulo Henrique",
430
+ level: "N1",
431
+ grad: "senior",
432
+ regiao: "centro-oeste",
433
+ gp: 78,
434
+ clientes: 4,
435
+ pro: false,
436
+ lastActive: "1 semana",
437
+ since: [2021, 12, 1],
438
+ }),
439
+ ],
440
+ }),
441
+ n({
442
+ name: "Camila Ribeiro",
443
+ level: "Líder",
444
+ grad: "gestor",
445
+ regiao: "sudeste",
446
+ gp: 184,
447
+ clientes: 8,
448
+ pro: false,
449
+ lastActive: "2 dias",
450
+ since: [2021, 3, 9],
451
+ children: [
452
+ n({
453
+ name: "Renato Lopes",
454
+ level: "N1",
455
+ grad: "senior",
456
+ regiao: "sudeste",
457
+ gp: 90,
458
+ clientes: 5,
459
+ pro: false,
460
+ lastActive: "3 dias",
461
+ since: [2021, 10, 14],
462
+ children: [
463
+ n({
464
+ name: "Sara Quintela",
465
+ level: "N2",
466
+ grad: "junior",
467
+ regiao: "sudeste",
468
+ gp: 20,
469
+ clientes: 1,
470
+ pro: false,
471
+ lastActive: "2 semanas",
472
+ since: [2023, 1, 30],
473
+ }),
474
+ ],
475
+ }),
476
+ ],
477
+ }),
478
+ n({
479
+ name: "Lucas Amorim",
480
+ level: "Líder",
481
+ grad: "gestor",
482
+ regiao: "norte",
483
+ gp: 152,
484
+ clientes: 7,
485
+ pro: true,
486
+ lastActive: "5 h",
487
+ since: [2021, 5, 27],
488
+ children: [
489
+ n({
490
+ name: "Tainá Albuquerque",
491
+ level: "N1",
492
+ grad: "pleno",
493
+ regiao: "norte",
494
+ gp: 60,
495
+ clientes: 3,
496
+ pro: false,
497
+ lastActive: "6 dias",
498
+ since: [2022, 4, 4],
499
+ }),
500
+ n({
501
+ name: "Wesley Farias",
502
+ level: "N1",
503
+ grad: "junior",
504
+ regiao: "norte",
505
+ gp: 28,
506
+ clientes: 2,
507
+ pro: false,
508
+ lastActive: "3 semanas",
509
+ since: [2023, 3, 16],
510
+ }),
511
+ ],
512
+ }),
513
+ ];
514
+
515
+ /** Preenche `subtree` (agregado dos descendentes) recursivamente. */
516
+ function enrich(node: Raw): Consultor {
517
+ if (!node.children?.length) {
518
+ return { ...node, subtree: null } as Consultor;
519
+ }
520
+ const kids = node.children.map(enrich);
521
+ const subtree = kids.reduce(
522
+ (a, k) => ({
523
+ consultores: a.consultores + 1 + (k.subtree?.consultores ?? 0),
524
+ gp: a.gp + k.gpProprio + (k.subtree?.gp ?? 0),
525
+ clientes: a.clientes + k.clientes + (k.subtree?.clientes ?? 0),
526
+ }),
527
+ { consultores: 0, gp: 0, clientes: 0 },
528
+ );
529
+ return { ...node, subtree, children: kids };
530
+ }
531
+
532
+ /** Árvore do Mapa de Rede (multi-raiz — suas linhas diretas). */
533
+ export const NETWORK: Consultor[] = ROOTS.map(enrich);
534
+
535
+ /** Lookup id → consultor (pro painel de detalhe). */
536
+ export function findConsultor(
537
+ nodes: Consultor[],
538
+ id: string,
539
+ ): Consultor | null {
540
+ for (const node of nodes) {
541
+ if (node.id === id) return node;
542
+ if (node.children) {
543
+ const r = findConsultor(node.children, id);
544
+ if (r) return r;
545
+ }
546
+ }
547
+ return null;
548
+ }
549
+
550
+ /** Conta total de consultores na rede (badge do header). */
551
+ export function countNetwork(nodes: Consultor[]): number {
552
+ return nodes.reduce(
553
+ (acc, node) => acc + 1 + (node.children ? countNetwork(node.children) : 0),
554
+ 0,
555
+ );
556
+ }
557
+
558
+ /** Nível por profundidade na árvore: raiz (líder) = N1, filhos = N2, etc. */
559
+ export function levelOf(id: string): string {
560
+ const walk = (nodes: Consultor[], depth: number): string | null => {
561
+ for (const node of nodes) {
562
+ if (node.id === id) return `N${depth + 1}`;
563
+ if (node.children) {
564
+ const r = walk(node.children, depth + 1);
565
+ if (r) return r;
566
+ }
567
+ }
568
+ return null;
569
+ };
570
+ return walk(NETWORK, 0) ?? "N1";
571
+ }
572
+
573
+ /* ── toolbar: filtros + visões ────────────────────────────────────── */
574
+
575
+ export const FILTER_FIELDS: FilterableField[] = [
576
+ {
577
+ id: "graduacao",
578
+ label: "Graduação",
579
+ type: "select",
580
+ accessor: (i) => (i.data as Consultor).graduacao,
581
+ options: (Object.keys(GRADUACAO) as Graduacao[]).map((g) => ({
582
+ value: g,
583
+ label: GRADUACAO[g].label,
584
+ })),
585
+ },
586
+ {
587
+ id: "regiao",
588
+ label: "Região",
589
+ type: "select",
590
+ accessor: (i) => (i.data as Consultor).regiao,
591
+ options: (Object.keys(REGIAO) as Regiao[]).map((r) => ({
592
+ value: r,
593
+ label: REGIAO[r],
594
+ })),
595
+ },
596
+ {
597
+ id: "pro",
598
+ label: "Plano PRO",
599
+ type: "boolean",
600
+ accessor: (i) => (i.data as Consultor).pro,
601
+ },
602
+ ];
603
+
604
+ export const VIEWS: DataListView[] = [
605
+ {
606
+ id: "pro",
607
+ label: "PRO",
608
+ query: {
609
+ search: "",
610
+ filterModel: {
611
+ logicOperator: "AND",
612
+ items: [
613
+ { id: "vpro", field: "pro", operator: "equals", value: "true" },
614
+ ],
615
+ },
616
+ },
617
+ },
618
+ {
619
+ id: "diretoria",
620
+ label: "Diretoria",
621
+ query: {
622
+ search: "",
623
+ filterModel: {
624
+ logicOperator: "AND",
625
+ items: [
626
+ {
627
+ id: "vd1",
628
+ field: "graduacao",
629
+ operator: "isAnyOf",
630
+ value: "presidente",
631
+ },
632
+ {
633
+ id: "vd2",
634
+ field: "graduacao",
635
+ operator: "isAnyOf",
636
+ value: "diretor",
637
+ },
638
+ ],
639
+ },
640
+ },
641
+ },
642
+ {
643
+ id: "sudeste",
644
+ label: "Sudeste",
645
+ query: {
646
+ search: "",
647
+ filterModel: {
648
+ logicOperator: "AND",
649
+ items: [
650
+ { id: "vse", field: "regiao", operator: "equals", value: "sudeste" },
651
+ ],
652
+ },
653
+ },
654
+ },
655
+ ];
@@ -0,0 +1,53 @@
1
+ /** Graduação do consultor na rede (ranking). */
2
+ export type Graduacao =
3
+ | "presidente"
4
+ | "diretor"
5
+ | "gestor"
6
+ | "senior"
7
+ | "pleno"
8
+ | "junior";
9
+
10
+ /** Região comercial (filtro). */
11
+ export type Regiao = "sudeste" | "sul" | "nordeste" | "centro-oeste" | "norte";
12
+
13
+ /** Agregado da subárvore (descendentes) de um consultor. `null` = folha. */
14
+ export type Subtree = {
15
+ /** Nº de consultores descendentes (toda a subárvore). */
16
+ consultores: number;
17
+ /** GP somado da subárvore. */
18
+ gp: number;
19
+ /** Clientes somados da subárvore. */
20
+ clientes: number;
21
+ } | null;
22
+
23
+ /** Um consultor na árvore do Mapa de Rede (nó da hierarquia). */
24
+ export type Consultor = {
25
+ id: string;
26
+ name: string;
27
+ /** Rótulo de nível relativo ("Líder", "N1", "N2"...). */
28
+ level: string;
29
+ graduacao: Graduacao;
30
+ regiao: Regiao;
31
+ /** GP gerado pelo próprio consultor. */
32
+ gpProprio: number;
33
+ /** Clientes diretos. */
34
+ clientes: number;
35
+ /** Plano PRO ativo. */
36
+ pro: boolean;
37
+ /** Cor do avatar (hex) — calibrada por contraste no Avatar. */
38
+ avatarColor: string;
39
+ /** Agregado dos descendentes (calculado); `null` em folhas. */
40
+ subtree: Subtree;
41
+ /** Email/contato (detalhe). */
42
+ email: string;
43
+ /** Telefone (detalhe). */
44
+ phone: string;
45
+ /** Cidade/UF (detalhe). */
46
+ location: string;
47
+ /** Consultor desde (ms epoch). */
48
+ since: number;
49
+ /** Última atividade (texto relativo). */
50
+ lastActive: string;
51
+ /** Descendentes diretos. */
52
+ children?: Consultor[];
53
+ };