@snksergio/design-system 0.62.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 (135) 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/exemplos/app-shell/app-shell-example.tsx +140 -0
  7. package/dist-lib/ai/exemplos/app-shell/index.ts +3 -0
  8. package/dist-lib/ai/exemplos/app-shell/nav-data.ts +97 -0
  9. package/dist-lib/ai/exemplos/app-shell/routes.tsx +75 -0
  10. package/dist-lib/ai/exemplos/chat/chat-screen.tsx +152 -0
  11. package/dist-lib/ai/exemplos/chat/chat-v2-mocks.ts +171 -0
  12. package/dist-lib/ai/exemplos/chat/chat-v2.styles.ts +23 -0
  13. package/dist-lib/ai/exemplos/chat/chat-v2.types.ts +81 -0
  14. package/dist-lib/ai/exemplos/chat/components/ChannelDot/channel-dot.tsx +28 -0
  15. package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/conversation-actions-menu.tsx +83 -0
  16. package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/index.ts +4 -0
  17. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.styles.ts +22 -0
  18. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.tsx +203 -0
  19. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.types.ts +10 -0
  20. package/dist-lib/ai/exemplos/chat/components/ConversationColumn/index.ts +2 -0
  21. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.styles.ts +55 -0
  22. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.tsx +52 -0
  23. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.types.ts +7 -0
  24. package/dist-lib/ai/exemplos/chat/components/ConversationListItem/index.ts +2 -0
  25. package/dist-lib/ai/exemplos/chat/components/DateSeparator/date-separator.tsx +18 -0
  26. package/dist-lib/ai/exemplos/chat/components/DetailField/detail-field.tsx +23 -0
  27. package/dist-lib/ai/exemplos/chat/components/DetailSection/detail-section.tsx +41 -0
  28. package/dist-lib/ai/exemplos/chat/components/DetailSection/index.ts +1 -0
  29. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.styles.ts +30 -0
  30. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.tsx +142 -0
  31. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.types.ts +16 -0
  32. package/dist-lib/ai/exemplos/chat/components/DetailsColumn/index.ts +5 -0
  33. package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.styles.ts +37 -0
  34. package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.tsx +45 -0
  35. package/dist-lib/ai/exemplos/chat/components/FilterRow/index.ts +1 -0
  36. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.styles.ts +27 -0
  37. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.tsx +66 -0
  38. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.types.ts +13 -0
  39. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-rail.tsx +38 -0
  40. package/dist-lib/ai/exemplos/chat/components/FiltersColumn/index.ts +6 -0
  41. package/dist-lib/ai/exemplos/chat/components/MessageBubble/index.ts +2 -0
  42. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.styles.ts +37 -0
  43. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.tsx +29 -0
  44. package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.types.ts +5 -0
  45. package/dist-lib/ai/exemplos/chat/components/PersonAvatar/index.ts +5 -0
  46. package/dist-lib/ai/exemplos/chat/components/PersonAvatar/person-avatar.tsx +31 -0
  47. package/dist-lib/ai/exemplos/chat/components/QueueColumn/index.ts +2 -0
  48. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.styles.ts +19 -0
  49. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.tsx +140 -0
  50. package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.types.ts +13 -0
  51. package/dist-lib/ai/exemplos/chat/components/RailItem/index.ts +1 -0
  52. package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.styles.ts +30 -0
  53. package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.tsx +42 -0
  54. package/dist-lib/ai/exemplos/chat/hooks/use-resizable.ts +98 -0
  55. package/dist-lib/ai/exemplos/chat/index.ts +1 -0
  56. package/dist-lib/ai/exemplos/clientes/_table-data.ts +59 -0
  57. package/dist-lib/ai/exemplos/clientes/clientes-screen.tsx +505 -0
  58. package/dist-lib/ai/exemplos/clientes/clientes-showcase-mocks.ts +117 -0
  59. package/dist-lib/ai/exemplos/clientes/clientes-showcase.styles.ts +13 -0
  60. package/dist-lib/ai/exemplos/clientes/clientes-showcase.types.ts +16 -0
  61. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.styles.ts +28 -0
  62. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.tsx +303 -0
  63. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.types.ts +14 -0
  64. package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/index.ts +2 -0
  65. package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/index.ts +2 -0
  66. package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
  67. package/dist-lib/ai/exemplos/clientes/index.ts +1 -0
  68. package/dist-lib/ai/exemplos/edit-page/components/StepNav.tsx +81 -0
  69. package/dist-lib/ai/exemplos/edit-page/components/section-card.tsx +85 -0
  70. package/dist-lib/ai/exemplos/edit-page/edit-page-screen.tsx +234 -0
  71. package/dist-lib/ai/exemplos/edit-page/index.ts +1 -0
  72. package/dist-lib/ai/exemplos/finance/_table-data.ts +57 -0
  73. package/dist-lib/ai/exemplos/finance/clientes-financeiro-mocks.ts +227 -0
  74. package/dist-lib/ai/exemplos/finance/clientes-financeiro.types.ts +75 -0
  75. package/dist-lib/ai/exemplos/finance/clientes-showcase-mocks.ts +117 -0
  76. package/dist-lib/ai/exemplos/finance/clientes-showcase.styles.ts +13 -0
  77. package/dist-lib/ai/exemplos/finance/clientes-showcase.types.ts +16 -0
  78. package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/editar-finance-drawer.tsx +241 -0
  79. package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/index.ts +5 -0
  80. package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/extrato-expansion.tsx +172 -0
  81. package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/index.ts +1 -0
  82. package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/finance-detail-panel.tsx +241 -0
  83. package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/index.ts +2 -0
  84. package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/index.ts +2 -0
  85. package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
  86. package/dist-lib/ai/exemplos/finance/components/SacarDialog/index.ts +2 -0
  87. package/dist-lib/ai/exemplos/finance/components/SacarDialog/sacar-dialog.tsx +346 -0
  88. package/dist-lib/ai/exemplos/finance/finance-screen.tsx +821 -0
  89. package/dist-lib/ai/exemplos/finance/index.ts +1 -0
  90. package/dist-lib/ai/exemplos/gantt/_gantt-data.tsx +402 -0
  91. package/dist-lib/ai/exemplos/gantt/gantt-screen.tsx +512 -0
  92. package/dist-lib/ai/exemplos/gantt/index.ts +1 -0
  93. package/dist-lib/ai/exemplos/login/index.ts +1 -0
  94. package/dist-lib/ai/exemplos/login/login-screen.tsx +246 -0
  95. package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/consultor-detail-panel.tsx +158 -0
  96. package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/index.ts +2 -0
  97. package/dist-lib/ai/exemplos/mapa-rede/index.ts +1 -0
  98. package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede-mocks.ts +655 -0
  99. package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede.types.ts +53 -0
  100. package/dist-lib/ai/exemplos/mapa-rede/mapa-rede-screen.tsx +227 -0
  101. package/dist-lib/ai/exemplos/order-detail/components/ActivityTab.tsx +77 -0
  102. package/dist-lib/ai/exemplos/order-detail/components/AttachmentsTab.tsx +45 -0
  103. package/dist-lib/ai/exemplos/order-detail/components/CommentsTab.tsx +111 -0
  104. package/dist-lib/ai/exemplos/order-detail/components/DetailsTab.tsx +189 -0
  105. package/dist-lib/ai/exemplos/order-detail/components/OverviewTab.tsx +200 -0
  106. package/dist-lib/ai/exemplos/order-detail/components/section-card.tsx +85 -0
  107. package/dist-lib/ai/exemplos/order-detail/index.ts +1 -0
  108. package/dist-lib/ai/exemplos/order-detail/order-detail-screen.tsx +119 -0
  109. package/dist-lib/ai/exemplos/order-detail/order-mocks.ts +186 -0
  110. package/dist-lib/ai/exemplos/order-detail/order.types.ts +118 -0
  111. package/dist-lib/ai/indice.json +30 -15
  112. package/dist-lib/ai/manifest.json +31 -5
  113. package/dist-lib/ai/roteiros/app-builder/roteiro.md +155 -0
  114. package/dist-lib/ai/roteiros/auth-builder/roteiro.md +42 -0
  115. package/dist-lib/ai/roteiros/cards/roteiro.md +34 -0
  116. package/dist-lib/ai/roteiros/charts/roteiro.md +32 -0
  117. package/dist-lib/ai/roteiros/chat/roteiro.md +31 -0
  118. package/dist-lib/ai/roteiros/crud-builder/blueprint.md +63 -0
  119. package/dist-lib/ai/roteiros/crud-builder/entrevista.md +139 -0
  120. package/dist-lib/ai/roteiros/crud-builder/geracao.md +113 -0
  121. package/dist-lib/ai/roteiros/crud-builder/roteiro.md +89 -0
  122. package/dist-lib/ai/roteiros/drawers/roteiro.md +41 -0
  123. package/dist-lib/ai/roteiros/list-builder/blueprint.md +94 -0
  124. package/dist-lib/ai/roteiros/list-builder/entrevista.md +188 -0
  125. package/dist-lib/ai/roteiros/list-builder/geracao.md +63 -0
  126. package/dist-lib/ai/roteiros/list-builder/roteiro.md +91 -0
  127. package/dist-lib/ai/roteiros/module-replicator/roteiro.md +56 -0
  128. package/dist-lib/ai/roteiros/page-detail/roteiro.md +32 -0
  129. package/dist-lib/ai/roteiros/page-edit/roteiro.md +31 -0
  130. package/dist-lib/ai/roteiros/screen-composer/roteiro.md +95 -0
  131. package/package.json +1 -1
  132. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/blueprint.md +0 -0
  133. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/entrevista.md +0 -0
  134. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/geracao.md +0 -0
  135. /package/dist-lib/ai/roteiros/{dashboard → dashboard-builder}/roteiro.md +0 -0
@@ -0,0 +1,200 @@
1
+ import { Mail, Phone } from "lucide-react";
2
+ import { Avatar } from "@/components/ui/avatar-ig";
3
+ import { Chip } from "@/components/ui/Chip";
4
+ import { SectionCard, SectionDivider } from "./section-card";
5
+ import { formatBRL } from "../order-mocks";
6
+ import type { Order } from "../order.types";
7
+
8
+ export function OverviewTab({ order }: { order: Order }) {
9
+ const c = order.customer;
10
+ const addr = order.shippingAddress;
11
+
12
+ return (
13
+ <div className="grid grid-cols-1 gap-gp-2xl lg:grid-cols-3">
14
+ {/* Coluna principal */}
15
+ <div className="flex flex-col gap-gp-2xl lg:col-span-2">
16
+ {/* Produtos */}
17
+ <SectionCard title="Produtos do pedido">
18
+ <ul className="flex flex-col">
19
+ {order.items.map((item, i) => (
20
+ <li
21
+ key={item.id}
22
+ className={
23
+ "flex items-center gap-gp-lg py-pad-lg" +
24
+ (i > 0 ? " border-t border-border-subtle" : "")
25
+ }
26
+ >
27
+ <span
28
+ className="size-12 shrink-0 rounded-radius-md"
29
+ style={{ backgroundColor: `${item.thumb}1f` }}
30
+ aria-hidden="true"
31
+ />
32
+ <div className="min-w-0 flex-1">
33
+ <p className="text-body-md font-semibold text-fg-default">
34
+ {item.name}
35
+ </p>
36
+ <p className="text-caption-sm text-fg-muted">
37
+ SKU: {item.sku}
38
+ </p>
39
+ </div>
40
+ <div className="shrink-0 text-right">
41
+ <p className="text-body-md font-semibold text-fg-default [font-variant-numeric:tabular-nums]">
42
+ {formatBRL(item.price)}
43
+ </p>
44
+ <p className="text-caption-sm text-fg-muted">
45
+ Qtd: {item.qty}
46
+ </p>
47
+ </div>
48
+ </li>
49
+ ))}
50
+ </ul>
51
+ </SectionCard>
52
+
53
+ {/* Pagamento */}
54
+ <SectionCard
55
+ title="Pagamento"
56
+ action={
57
+ <Chip color="success" variant="soft" size="sm" shape="pill">
58
+ Pago
59
+ </Chip>
60
+ }
61
+ >
62
+ <dl className="flex flex-col gap-gp-md">
63
+ <Row label="Subtotal" value={formatBRL(order.subtotal)} />
64
+ <Row label="Frete" value={formatBRL(order.shipping)} />
65
+ <Row label="Impostos" value={formatBRL(order.tax)} />
66
+ {order.discountValue != null && (
67
+ <Row
68
+ label={`Desconto (${order.discountCode})`}
69
+ value={`- ${formatBRL(order.discountValue)}`}
70
+ accent
71
+ />
72
+ )}
73
+ <div className="mt-gp-xs flex items-center justify-between border-t border-border-subtle pt-pad-lg">
74
+ <dt className="text-body-md font-semibold text-fg-default">
75
+ Total
76
+ </dt>
77
+ <dd className="text-body-md font-semibold text-fg-default [font-variant-numeric:tabular-nums]">
78
+ {formatBRL(order.total)}
79
+ </dd>
80
+ </div>
81
+ <div className="flex items-center justify-between">
82
+ <dt className="text-title-md font-semibold text-fg-default">
83
+ Pago pelo cliente
84
+ </dt>
85
+ <dd className="text-title-md font-semibold text-fg-default [font-variant-numeric:tabular-nums]">
86
+ {formatBRL(order.total)}
87
+ </dd>
88
+ </div>
89
+ </dl>
90
+ </SectionCard>
91
+ </div>
92
+
93
+ {/* Coluna lateral */}
94
+ <div className="flex flex-col gap-gp-2xl">
95
+ <SectionCard title="Cliente">
96
+ <div className="flex items-center gap-gp-md">
97
+ <Avatar size="lg" colorHex={c.colorHex} aria-label={`${c.firstName} ${c.lastName}`}>
98
+ {c.initials}
99
+ </Avatar>
100
+ <div className="min-w-0">
101
+ <p className="text-body-md font-semibold text-fg-default">
102
+ {c.firstName} {c.lastName}
103
+ </p>
104
+ <p className="text-caption-sm text-fg-muted">
105
+ {c.previousOrders} pedidos anteriores
106
+ </p>
107
+ </div>
108
+ </div>
109
+
110
+ <SectionDivider className="my-gp-2xl" />
111
+
112
+ <div className="flex flex-col gap-gp-md">
113
+ <a
114
+ href={`mailto:${c.email}`}
115
+ className="flex items-center gap-gp-sm text-body-sm text-fg-default hover:text-fg-brand"
116
+ >
117
+ <Mail className="size-icon-sm shrink-0 text-fg-muted" />
118
+ <span className="truncate">{c.email}</span>
119
+ </a>
120
+ <span className="flex items-center gap-gp-sm text-body-sm text-fg-default">
121
+ <Phone className="size-icon-sm shrink-0 text-fg-muted" />
122
+ {c.phone}
123
+ </span>
124
+ </div>
125
+
126
+ <SectionDivider className="my-gp-2xl" />
127
+
128
+ <AddressBlock
129
+ title="Endereço de entrega"
130
+ lines={[
131
+ addr.line1,
132
+ addr.line2,
133
+ `${addr.city} — ${addr.state}`,
134
+ addr.zip,
135
+ addr.country,
136
+ ]}
137
+ />
138
+
139
+ <SectionDivider className="my-gp-2xl" />
140
+
141
+ <AddressBlock
142
+ title="Endereço de cobrança"
143
+ lines={[
144
+ order.billing.address,
145
+ order.billing.cityState,
146
+ order.billing.country,
147
+ ]}
148
+ />
149
+ </SectionCard>
150
+
151
+ <SectionCard title="Observação do cliente">
152
+ <p className="text-body-sm leading-relaxed text-fg-muted">
153
+ {order.note}
154
+ </p>
155
+ </SectionCard>
156
+ </div>
157
+ </div>
158
+ );
159
+ }
160
+
161
+ function Row({
162
+ label,
163
+ value,
164
+ accent,
165
+ }: {
166
+ label: string;
167
+ value: string;
168
+ accent?: boolean;
169
+ }) {
170
+ return (
171
+ <div className="flex items-center justify-between">
172
+ <dt className="text-body-sm text-fg-muted">{label}</dt>
173
+ <dd
174
+ className={
175
+ "text-body-sm [font-variant-numeric:tabular-nums] " +
176
+ (accent ? "text-fg-success" : "text-fg-default")
177
+ }
178
+ >
179
+ {value}
180
+ </dd>
181
+ </div>
182
+ );
183
+ }
184
+
185
+ function AddressBlock({ title, lines }: { title: string; lines: (string | undefined)[] }) {
186
+ return (
187
+ <div>
188
+ <p className="mb-gp-xs text-caption-sm font-semibold uppercase tracking-wider text-fg-muted">
189
+ {title}
190
+ </p>
191
+ <address className="not-italic text-body-sm leading-relaxed text-fg-default">
192
+ {lines.filter(Boolean).map((l, i) => (
193
+ <span key={i} className="block">
194
+ {l}
195
+ </span>
196
+ ))}
197
+ </address>
198
+ </div>
199
+ );
200
+ }
@@ -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 @@
1
+ export { OrderDetailScreen, default } from "./order-detail-screen";
@@ -0,0 +1,119 @@
1
+ import { useState } from "react";
2
+ import {
3
+ ChevronLeft,
4
+ ChevronRight,
5
+ MoreHorizontal,
6
+ Pencil,
7
+ RotateCcw,
8
+ } from "lucide-react";
9
+ import { Button } from "@/components/ui/Button/button";
10
+ import { Chip } from "@/components/ui/Chip";
11
+ import { PageHeader } from "@/components/ui/PageHeader";
12
+ import { Tabs, TabsList, TabsTrigger } from "@/components/shadcn/tabs";
13
+ import { ORDER } from "./order-mocks";
14
+ import { OverviewTab } from "./components/OverviewTab";
15
+ import { DetailsTab } from "./components/DetailsTab";
16
+ import { ActivityTab } from "./components/ActivityTab";
17
+ import { CommentsTab } from "./components/CommentsTab";
18
+ import { AttachmentsTab } from "./components/AttachmentsTab";
19
+
20
+ /**
21
+ * OrderDetailScreen — conteúdo da página de detalhe de pedido consumindo o DS:
22
+ * PageHeader (título + status + ações) + Tabs (Visão geral / Detalhes /
23
+ * Atividade / Comentários / Anexos). Domínio iGreen (energia solar).
24
+ *
25
+ * Sem shell — embrulhe no seu AppShell/layout. O parent precisa dar altura
26
+ * (h-full/flex) pro conteúdo preencher.
27
+ */
28
+ export function OrderDetailScreen() {
29
+ const [tab, setTab] = useState("overview");
30
+
31
+ const order = ORDER;
32
+
33
+ return (
34
+ <div className="flex flex-col h-full min-h-0 gap-gp-2xl">
35
+ <PageHeader
36
+ title={`Pedido #${order.id}`}
37
+ description={order.placedAt}
38
+ hideTextOnMobile={false}
39
+ badge={
40
+ <span className="flex items-center gap-gp-sm">
41
+ <Chip color="success" variant="soft" size="sm" shape="pill">
42
+ Pago
43
+ </Chip>
44
+ <Chip color="info" variant="soft" size="sm" shape="pill">
45
+ Enviado
46
+ </Chip>
47
+ </span>
48
+ }
49
+ actions={
50
+ <>
51
+ <Button
52
+ variant="outline"
53
+ color="secondary"
54
+ size="md"
55
+ iconLeft={<RotateCcw />}
56
+ >
57
+ Reabastecer
58
+ </Button>
59
+ <Button
60
+ variant="outline"
61
+ color="secondary"
62
+ size="md"
63
+ iconLeft={<Pencil />}
64
+ >
65
+ Editar
66
+ </Button>
67
+ <Button
68
+ variant="outline"
69
+ color="secondary"
70
+ size="icon-md"
71
+ aria-label="Mais ações"
72
+ >
73
+ <MoreHorizontal />
74
+ </Button>
75
+ <Button
76
+ variant="outline"
77
+ color="secondary"
78
+ size="icon-md"
79
+ aria-label="Pedido anterior"
80
+ >
81
+ <ChevronLeft />
82
+ </Button>
83
+ <Button
84
+ variant="outline"
85
+ color="secondary"
86
+ size="icon-md"
87
+ aria-label="Próximo pedido"
88
+ >
89
+ <ChevronRight />
90
+ </Button>
91
+ </>
92
+ }
93
+ >
94
+ <Tabs value={tab} onValueChange={setTab}>
95
+ <TabsList>
96
+ <TabsTrigger value="overview">Visão geral</TabsTrigger>
97
+ <TabsTrigger value="details">Detalhes</TabsTrigger>
98
+ <TabsTrigger value="activity">Atividade</TabsTrigger>
99
+ <TabsTrigger value="comments">
100
+ Comentários
101
+ <Chip color="danger" variant="soft" size="sm" shape="pill">
102
+ {order.comments.length}
103
+ </Chip>
104
+ </TabsTrigger>
105
+ <TabsTrigger value="attachments">Anexos</TabsTrigger>
106
+ </TabsList>
107
+ </Tabs>
108
+ </PageHeader>
109
+
110
+ {tab === "overview" && <OverviewTab order={order} />}
111
+ {tab === "details" && <DetailsTab order={order} />}
112
+ {tab === "activity" && <ActivityTab order={order} />}
113
+ {tab === "comments" && <CommentsTab order={order} />}
114
+ {tab === "attachments" && <AttachmentsTab order={order} />}
115
+ </div>
116
+ );
117
+ }
118
+
119
+ export default OrderDetailScreen;
@@ -0,0 +1,186 @@
1
+ import type { Order } from "./order.types";
2
+
3
+ /** Formata número como BRL. */
4
+ export const formatBRL = (v: number): string =>
5
+ v.toLocaleString("pt-BR", { style: "currency", currency: "BRL" });
6
+
7
+ /**
8
+ * Pedido mock no domínio iGreen (energia solar). Espelha a estrutura da
9
+ * referência (Overview / Details / Activity / Comments / Attachments) com
10
+ * dados coerentes ao resto do showcase.
11
+ */
12
+ export const ORDER: Order = {
13
+ id: "84021",
14
+ status: "paid",
15
+ fulfillment: "fulfilled",
16
+ placedAt: "8 de janeiro de 2024 às 21:48 · via Pedidos rascunho",
17
+ source: "Pedidos rascunho",
18
+
19
+ items: [
20
+ {
21
+ id: "SOL-4KWP-098",
22
+ name: "Kit Solar Residencial 4 kWp",
23
+ sku: "SOL-4KWP-098",
24
+ price: 12480,
25
+ qty: 1,
26
+ thumb: "#22A06B",
27
+ },
28
+ {
29
+ id: "INV-5KW-336",
30
+ name: "Inversor Híbrido 5 kW",
31
+ sku: "INV-5KW-336",
32
+ price: 4890,
33
+ qty: 1,
34
+ thumb: "#3B82F6",
35
+ },
36
+ {
37
+ id: "PNL-550-368",
38
+ name: "Painel Monocristalino 550 W",
39
+ sku: "PNL-550-368",
40
+ price: 689,
41
+ qty: 8,
42
+ thumb: "#F59E0B",
43
+ },
44
+ ],
45
+ subtotal: 22882,
46
+ shipping: 320,
47
+ tax: 1373,
48
+ discountCode: "INVERNO2024",
49
+ discountLabel: "-10%",
50
+ discountValue: 2288.2,
51
+ total: 22286.8,
52
+
53
+ customer: {
54
+ firstName: "Helena",
55
+ middleName: "Rocha",
56
+ lastName: "Martins",
57
+ initials: "HM",
58
+ colorHex: "#22A06B",
59
+ email: "helena.martins@example.com",
60
+ phone: "+55 (31) 99845-2014",
61
+ customerId: "#CLI-52365",
62
+ accountType: "Premium",
63
+ registeredAt: "17/12/2023",
64
+ active: true,
65
+ previousOrders: 11,
66
+ },
67
+
68
+ shippingAddress: {
69
+ line1: "Rua das Acácias, 2780",
70
+ line2: "Sala 4",
71
+ city: "Belo Horizonte",
72
+ state: "Minas Gerais",
73
+ zip: "30513-200",
74
+ country: "Brasil",
75
+ carrier: "Correios SEDEX",
76
+ tracking: "BR7489204588 31",
77
+ eta: "12 de janeiro de 2024",
78
+ },
79
+
80
+ billing: {
81
+ address: "Rua das Acácias, 2780, Sala 4",
82
+ cityState: "Belo Horizonte, Minas Gerais 30513-200",
83
+ country: "Brasil",
84
+ method: "Visa terminando em 4242",
85
+ transactionId: "TXN-8847291",
86
+ paymentDate: "8 de janeiro de 2024",
87
+ },
88
+
89
+ note: "Caso haja qualquer atraso ou problema com meu pedido, por favor me avise. Valorizo uma comunicação clara e a atenção aos detalhes.",
90
+ internalNote:
91
+ "Cliente solicitou embalagem reforçada para todos os itens. A etiqueta de envio deve incluir a nota \"Frágil — manusear com cuidado\". Prioridade confirmada pelo status de conta Premium.",
92
+
93
+ tags: [
94
+ { label: "Cliente verificado", color: "success" },
95
+ { label: "Premium", color: "info" },
96
+ { label: "Alta prioridade", color: "warning" },
97
+ { label: "Recorrente", color: "neutral" },
98
+ { label: "Frágil", color: "danger" },
99
+ ],
100
+
101
+ activity: [
102
+ {
103
+ id: "a1",
104
+ dateGroup: "Domingo, 06 de março",
105
+ title: "Pedido entregue",
106
+ description: "Recebido por: Helena Martins",
107
+ time: "14:05",
108
+ done: true,
109
+ },
110
+ {
111
+ id: "a2",
112
+ dateGroup: "Domingo, 06 de março",
113
+ title: "Saiu para entrega",
114
+ time: "09:12",
115
+ },
116
+ {
117
+ id: "a3",
118
+ dateGroup: "Domingo, 06 de março",
119
+ title: "Chegou ao centro de distribuição",
120
+ time: "22:15",
121
+ },
122
+ {
123
+ id: "a4",
124
+ dateGroup: "Sexta, 04 de março",
125
+ title: "Coletado pela transportadora",
126
+ time: "03:43",
127
+ },
128
+ {
129
+ id: "a5",
130
+ dateGroup: "Sexta, 04 de março",
131
+ title: "Saiu do centro de distribuição",
132
+ time: "01:12",
133
+ },
134
+ {
135
+ id: "a6",
136
+ dateGroup: "Quinta, 03 de março",
137
+ title: "Em preparação para envio",
138
+ time: "23:30",
139
+ },
140
+ {
141
+ id: "a7",
142
+ dateGroup: "Quinta, 03 de março",
143
+ title: "Pedido confirmado",
144
+ description: "Pagamento recebido via cartão de crédito",
145
+ time: "21:15",
146
+ },
147
+ ],
148
+
149
+ comments: [
150
+ {
151
+ id: "c1",
152
+ author: "Helena Martins",
153
+ initials: "HM",
154
+ colorHex: "#22A06B",
155
+ when: "2 dias atrás",
156
+ text: "Vocês conseguem atualizar o endereço de entrega? Mudei recentemente e esqueci de alterar antes de fazer o pedido.",
157
+ },
158
+ {
159
+ id: "c2",
160
+ author: "Suporte iGreen",
161
+ initials: "SI",
162
+ colorHex: "#3B82F6",
163
+ when: "1 dia atrás",
164
+ text: "Claro! Atualizei o endereço para Rua das Acácias, 2780, Sala 4, Belo Horizonte/MG. Pode confirmar se está correto?",
165
+ },
166
+ {
167
+ id: "c3",
168
+ author: "Helena Martins",
169
+ initials: "HM",
170
+ colorHex: "#22A06B",
171
+ when: "1 dia atrás",
172
+ text: "Isso mesmo, muito obrigada pela agilidade!",
173
+ },
174
+ ],
175
+
176
+ attachments: [
177
+ { id: "f1", name: "nota_fiscal_84021.pdf", kind: "pdf", size: "245 KB" },
178
+ { id: "f2", name: "etiqueta_envio.png", kind: "image", size: "128 KB" },
179
+ {
180
+ id: "f3",
181
+ name: "comprovante_pagamento.pdf",
182
+ kind: "pdf",
183
+ size: "89 KB",
184
+ },
185
+ ],
186
+ };