@granto-umbrella/umbrella-components 2.3.23 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/umbrella-components.css +1 -1
- package/dist/umbrella-components.es.js +42753 -63037
- package/dist/umbrella-components.umd.js +2038 -581
- package/package.json +9 -4
- package/src/assets/_banner_contato.png +0 -0
- package/src/assets/_logoUmbrella.svg +34 -0
- package/src/assets.d.ts +19 -0
- package/src/components/atoms/DropDownMenu/DropdownMenu.styles.tsx +106 -0
- package/src/components/atoms/DropDownMenu/DropdownMenu.tsx +48 -0
- package/src/components/atoms/DropDownMenu/DropdownMenu.types.ts +15 -0
- package/src/components/atoms/DropDownMenu/index.tsx +2 -0
- package/src/components/atoms/ErrorMessage/ErrorMessage.styles.tsx +28 -0
- package/src/components/atoms/ErrorMessage/ErrorMessage.tsx +12 -0
- package/src/components/atoms/ErrorMessage/ErrorMessage.types.ts +6 -0
- package/src/components/atoms/ErrorMessage/index.tsx +1 -0
- package/src/components/atoms/Footer/Footer.styles.tsx +22 -0
- package/src/components/atoms/Footer/Footer.tsx +9 -0
- package/src/components/atoms/Footer/Footer.types.tsx +5 -0
- package/src/components/atoms/Footer/index.tsx +1 -0
- package/src/components/atoms/GenericContainer/GenericContainer.styles.tsx +21 -0
- package/src/components/atoms/GenericContainer/GenericContainer.tsx +9 -0
- package/src/components/atoms/GenericContainer/GenericContainer.types.ts +5 -0
- package/src/components/atoms/GenericContainer/index.tsx +1 -0
- package/src/components/atoms/Loading/Loading.styles.tsx +23 -0
- package/src/components/atoms/Loading/Loading.tsx +8 -0
- package/src/components/atoms/Loading/index.tsx +1 -0
- package/src/components/atoms/LogoContainer/LogoContainer.Types.tsx +5 -0
- package/src/components/atoms/LogoContainer/LogoContainer.styles.tsx +11 -0
- package/src/components/atoms/LogoContainer/LogoContainer.tsx +11 -0
- package/src/components/atoms/LogoContainer/index.tsx +1 -0
- package/src/components/atoms/ModalAviso/ModalAviso.styles.tsx +54 -0
- package/src/components/atoms/ModalAviso/ModalAviso.tsx +37 -0
- package/src/components/atoms/ModalAviso/ModalAviso.types.ts +5 -0
- package/src/components/atoms/ModalAviso/index.tsx +1 -0
- package/src/components/atoms/MultiSelect/MultiSelect.styles.tsx +92 -0
- package/src/components/atoms/MultiSelect/MultiSelect.tsx +346 -0
- package/src/components/atoms/MultiSelect/MultiSelect.types.ts +38 -0
- package/src/components/atoms/MultiSelect/index.tsx +1 -0
- package/src/components/atoms/ResendLink/ResendLink.styles.tsx +20 -0
- package/src/components/atoms/ResendLink/ResendLink.tsx +16 -0
- package/src/components/atoms/ResendLink/ResendLink.types.ts +9 -0
- package/src/components/atoms/ResendLink/index.tsx +1 -0
- package/src/components/atoms/Subtitle/Subtitle.styles.tsx +21 -0
- package/src/components/atoms/Subtitle/Subtitle.tsx +7 -0
- package/src/components/atoms/Subtitle/Subtitle.types.ts +5 -0
- package/src/components/atoms/Subtitle/index.tsx +1 -0
- package/src/components/atoms/Tapbar/Tapbar.styles.tsx +57 -0
- package/src/components/atoms/Tapbar/Tapbar.tsx +24 -0
- package/src/components/atoms/Tapbar/Tapbar.types.ts +11 -0
- package/src/components/atoms/Tapbar/index.tsx +2 -0
- package/src/components/atoms/Text/Text.styles.tsx +8 -5
- package/src/components/atoms/Text/Text.tsx +1 -0
- package/src/components/atoms/Title/Title.styles.tsx +17 -0
- package/src/components/atoms/Title/Title.tsx +7 -0
- package/src/components/atoms/Title/Title.types.ts +5 -0
- package/src/components/atoms/Title/index.tsx +1 -0
- package/src/components/molecules/BannerAjuda/BannerAjuda.styles.tsx +9 -0
- package/src/components/molecules/BannerAjuda/BannerAjuda.tsx +19 -0
- package/src/components/molecules/BannerAjuda/BannerAjuda.types.ts +5 -0
- package/src/components/molecules/BannerAjuda/index.tsx +1 -0
- package/src/components/molecules/CodeInputContainer/CodeInputContainer.styles.tsx +7 -0
- package/src/components/molecules/CodeInputContainer/CodeInputContainer.tsx +32 -0
- package/src/components/molecules/CodeInputContainer/CodeInputContainer.types.ts +13 -0
- package/src/components/molecules/CodeInputContainer/index.tsx +3 -0
- package/src/components/molecules/ExcludeModal/ExcludeModal.styles.tsx +118 -0
- package/src/components/molecules/ExcludeModal/ExcludeModal.tsx +48 -0
- package/src/components/molecules/ExcludeModal/ExcludeModal.types.ts +10 -0
- package/src/components/molecules/ExcludeModal/index.tsx +1 -0
- package/src/components/molecules/HighlightsCard/HighlightsCard.styles.tsx +68 -0
- package/src/components/molecules/HighlightsCard/HighlightsCard.tsx +26 -0
- package/src/components/molecules/HighlightsCard/HighlightsCard.types.ts +10 -0
- package/src/components/molecules/HighlightsCard/index.tsx +1 -0
- package/src/components/molecules/InsuranceCard/InsuranceCard.styles.tsx +174 -0
- package/src/components/molecules/InsuranceCard/InsuranceCard.tsx +418 -0
- package/src/components/molecules/InsuranceCard/InsuranceCard.types.ts +32 -0
- package/src/components/molecules/InsuranceCard/index.tsx +1 -0
- package/src/components/molecules/PieChartComponent/PieChartComponent.styles.tsx +8 -0
- package/src/components/molecules/PieChartComponent/PieChartComponent.tsx +73 -0
- package/src/components/molecules/PieChartComponent/PieChartComponent.types.ts +11 -0
- package/src/components/molecules/PieChartComponent/index.tsx +1 -0
- package/src/components/molecules/RadioGroupField/RadioGroupField.styles.tsx +64 -0
- package/src/components/molecules/RadioGroupField/RadioGroupField.tsx +69 -0
- package/src/components/molecules/RadioGroupField/RadioGroupField.types.ts +17 -0
- package/src/components/molecules/RadioGroupField/index.tsx +1 -0
- package/src/components/molecules/RefuseModal/RefuseModal.styles.tsx +139 -0
- package/src/components/molecules/RefuseModal/RefuseModal.tsx +76 -0
- package/src/components/molecules/RefuseModal/RefuseModal.types.ts +15 -0
- package/src/components/molecules/RefuseModal/index.tsx +2 -0
- package/src/components/molecules/ResultsChart/ResultsChart.styles.tsx +22 -0
- package/src/components/molecules/ResultsChart/ResultsChart.tsx +19 -0
- package/src/components/molecules/ResultsChart/ResultsChart.types.ts +3 -0
- package/src/components/molecules/ResultsChart/index.tsx +2 -0
- package/src/components/molecules/TimeLine/TimeLine.styles.ts +118 -0
- package/src/components/molecules/TimeLine/TimeLine.tsx +38 -0
- package/src/components/molecules/TimeLine/TimeLine.types.ts +35 -0
- package/src/components/organisms/DonutEmissionsChart/DonutEmissionsChart.styles.tsx +113 -0
- package/src/components/organisms/DonutEmissionsChart/DonutEmissionsChart.tsx +71 -0
- package/src/components/organisms/DonutEmissionsChart/DonutEmissionsChart.types.ts +9 -0
- package/src/components/organisms/DonutEmissionsChart/index.tsx +2 -0
- package/src/components/organisms/ListagemUltimasEmissoes/ListagemUltimasEmissoes.styles.tsx +114 -0
- package/src/components/organisms/ListagemUltimasEmissoes/ListagemUltimasEmissoes.tsx +89 -0
- package/src/components/organisms/ListagemUltimasEmissoes/ListagemUltimasEmissoes.types.ts +16 -0
- package/src/components/organisms/ListagemUltimasEmissoes/index.tsx +1 -0
- package/src/components/organisms/TimelineModal/TimelineModal.styles.ts +49 -0
- package/src/components/organisms/TimelineModal/TimelineModal.tsx +37 -0
- package/src/global.d.ts +6 -0
- package/src/index.ts +68 -37
- package/src/lib/helpers.ts +17 -0
- package/src/styles/tokens/sizes.ts +12 -1
- package/src/styles/tokens/typography.ts +1 -1
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
FileText,
|
|
4
|
+
CreditCard,
|
|
5
|
+
Download,
|
|
6
|
+
PlusCircle,
|
|
7
|
+
ChevronDown,
|
|
8
|
+
ChevronUp,
|
|
9
|
+
Loader2,
|
|
10
|
+
} from "lucide-react";
|
|
11
|
+
import {
|
|
12
|
+
CardContainer,
|
|
13
|
+
HeaderRow,
|
|
14
|
+
InfoRow,
|
|
15
|
+
InfoLabel,
|
|
16
|
+
TruncatedValue,
|
|
17
|
+
Actions,
|
|
18
|
+
DropdownWrapper,
|
|
19
|
+
DropdownMenu,
|
|
20
|
+
StyledMenuItem,
|
|
21
|
+
Text,
|
|
22
|
+
BodyRow,
|
|
23
|
+
InfoSubValue,
|
|
24
|
+
ProdValue,
|
|
25
|
+
ProcessValue,
|
|
26
|
+
ActionButton,
|
|
27
|
+
} from "./InsuranceCard.styles";
|
|
28
|
+
import { InsuranceCardProps, MenuItemProps, StatusVariant } from "./InsuranceCard.types";
|
|
29
|
+
|
|
30
|
+
import Pill from "../../atoms/Pill/Pill";
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
const applyMask = (value: string, mask: string): string => {
|
|
36
|
+
let result = "";
|
|
37
|
+
let valueIndex = 0;
|
|
38
|
+
|
|
39
|
+
for (let i = 0; i < mask.length && valueIndex < value.length; i++) {
|
|
40
|
+
if (mask[i] === "0") {
|
|
41
|
+
result += value[valueIndex];
|
|
42
|
+
valueIndex++;
|
|
43
|
+
} else {
|
|
44
|
+
result += mask[i];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
const isValidCNPJ = (value: string): boolean => {
|
|
53
|
+
const cleanValue = value.replace(/\D/g, "");
|
|
54
|
+
return cleanValue.length === 14;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
const formatDate = (isoDate: string): string => {
|
|
59
|
+
const date = new Date(isoDate);
|
|
60
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
61
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
62
|
+
const year = date.getFullYear();
|
|
63
|
+
return `${day}/${month}/${year}`;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
const product_list = [
|
|
68
|
+
{ value: "001", label: "Seguro Garantia" },
|
|
69
|
+
{ value: "002", label: "Seguro Fiança" },
|
|
70
|
+
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
const formatProduct = (modality: string) => {
|
|
74
|
+
const type = modality.at(2);
|
|
75
|
+
const result = [];
|
|
76
|
+
|
|
77
|
+
switch (type) {
|
|
78
|
+
case "1":
|
|
79
|
+
result.push("Tradicional");
|
|
80
|
+
break;
|
|
81
|
+
case "2":
|
|
82
|
+
result.push("Judicial");
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
result.push("Desconhecido");
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
result.push(
|
|
90
|
+
product_list.find((item) => item.value === modality)?.label ??
|
|
91
|
+
"Desconhecido"
|
|
92
|
+
);
|
|
93
|
+
return result;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Ícones do phosphor-react substituídos por componentes inline
|
|
97
|
+
const ArrowCircleUpRight = ({ size = 16 }: { size?: number }) => (
|
|
98
|
+
<svg width={size} height={size} viewBox="0 0 256 256" fill="currentColor">
|
|
99
|
+
<path d="M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z" />
|
|
100
|
+
</svg>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const Cube = ({ size = 16 }: { size?: number }) => (
|
|
104
|
+
<svg width={size} height={size} viewBox="0 0 256 256" fill="currentColor">
|
|
105
|
+
<path d="M223.68,66.15,135.68,18a15.88,15.88,0,0,0-15.36,0l-88,48.17a16,16,0,0,0-8.32,14v95.64a16,16,0,0,0,8.32,14l88,48.17a15.88,15.88,0,0,0,15.36,0l88-48.17a16,16,0,0,0,8.32-14V80.18A16,16,0,0,0,223.68,66.15ZM128,32l80.34,44L128,120,47.66,76ZM40,90l80,43.78v85.79L40,175.82Zm176,85.78h0l-80,43.79V133.82l80-43.78Z" />
|
|
106
|
+
</svg>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const XCircle = ({ size = 16 }: { size?: number }) => (
|
|
110
|
+
<svg width={size} height={size} viewBox="0 0 256 256" fill="currentColor">
|
|
111
|
+
<path d="M165.66,101.66,139.31,128l26.35,26.34a8,8,0,0,1-11.32,11.32L128,139.31l-26.34,26.35a8,8,0,0,1-11.32-11.32L116.69,128,90.34,101.66a8,8,0,0,1,11.32-11.32L128,116.69l26.34-26.35a8,8,0,0,1,11.32,11.32ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z" />
|
|
112
|
+
</svg>
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// ===== COMPONENTE PRINCIPAL =====
|
|
116
|
+
|
|
117
|
+
export const InsuranceCard: React.FC<InsuranceCardProps> = ({
|
|
118
|
+
idGranto,
|
|
119
|
+
idOrder,
|
|
120
|
+
idInsurance,
|
|
121
|
+
idInterno,
|
|
122
|
+
isSupply,
|
|
123
|
+
hasMinute,
|
|
124
|
+
statusLabel,
|
|
125
|
+
statusVariant,
|
|
126
|
+
seguradoName,
|
|
127
|
+
seguradoCnpj,
|
|
128
|
+
product,
|
|
129
|
+
issuedDate,
|
|
130
|
+
totalValue,
|
|
131
|
+
processId,
|
|
132
|
+
activeIndex,
|
|
133
|
+
testId,
|
|
134
|
+
openCardId,
|
|
135
|
+
setOpenCardId,
|
|
136
|
+
|
|
137
|
+
}) => {
|
|
138
|
+
const [loadingItem, setLoadingItem] = useState<string | null>(null);
|
|
139
|
+
const isOpen = openCardId === idOrder;
|
|
140
|
+
|
|
141
|
+
const toggleOpen = () => {
|
|
142
|
+
setOpenCardId(isOpen ? null : idOrder);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const handleClick = async (
|
|
146
|
+
key: string,
|
|
147
|
+
callback: () => Promise<void> | void
|
|
148
|
+
) => {
|
|
149
|
+
setLoadingItem(key);
|
|
150
|
+
await Promise.resolve(callback());
|
|
151
|
+
setLoadingItem(null);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const [productTitle, productDescription] = formatProduct(product);
|
|
155
|
+
|
|
156
|
+
// Mock das funções (você ajustará quando os hooks existirem)
|
|
157
|
+
const downloadFile = (type: string, flag: boolean) => {
|
|
158
|
+
console.log(`Download ${type}:`, flag);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const searchCerts = (insurance: string, order: string) => {
|
|
162
|
+
console.log(`Search certs for ${insurance}, ${order}`);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const onEndorsementClick = (company: string, insurance: string) => {
|
|
166
|
+
console.log(`Endorsement for ${company}, ${insurance}`);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const irParaContinuarEmissao = () => {
|
|
170
|
+
console.log("Continuar emissão");
|
|
171
|
+
// Implementar navegação quando disponível
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const abrirModalExcluirProposta = () => {
|
|
175
|
+
console.log("Abrir modal excluir");
|
|
176
|
+
// Modal será implementado depois
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const abrirModalRecusarProposta = () => {
|
|
180
|
+
console.log("Abrir modal recusar");
|
|
181
|
+
// Modal será implementado depois
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<CardContainer
|
|
186
|
+
data-testid={testId}
|
|
187
|
+
id={testId}
|
|
188
|
+
$variant={statusVariant as StatusVariant}
|
|
189
|
+
>
|
|
190
|
+
<HeaderRow>
|
|
191
|
+
{isSupply && (
|
|
192
|
+
<Pill size={"sm"} variant="supply">
|
|
193
|
+
<Cube />
|
|
194
|
+
Supply
|
|
195
|
+
</Pill>
|
|
196
|
+
)}
|
|
197
|
+
<Text>ID Granto: {idGranto}</Text>
|
|
198
|
+
<Text>ID interno: {idInterno}</Text>
|
|
199
|
+
<Text $variant={statusVariant as StatusVariant}>
|
|
200
|
+
{activeIndex === 0 ? "Etapa" : "Status"}: {statusLabel}
|
|
201
|
+
</Text>
|
|
202
|
+
</HeaderRow>
|
|
203
|
+
<BodyRow>
|
|
204
|
+
<InfoRow>
|
|
205
|
+
<InfoLabel>Segurado</InfoLabel>
|
|
206
|
+
<TruncatedValue>{seguradoName}</TruncatedValue>
|
|
207
|
+
<InfoSubValue>
|
|
208
|
+
{applyMask(
|
|
209
|
+
seguradoCnpj,
|
|
210
|
+
isValidCNPJ(seguradoCnpj)
|
|
211
|
+
? "00.000.000/0000-00"
|
|
212
|
+
: "000.000.000-00"
|
|
213
|
+
)}
|
|
214
|
+
</InfoSubValue>
|
|
215
|
+
</InfoRow>
|
|
216
|
+
<InfoRow>
|
|
217
|
+
<InfoLabel>Produto</InfoLabel>
|
|
218
|
+
<ProdValue>{productTitle}</ProdValue>
|
|
219
|
+
<InfoSubValue>{productDescription}</InfoSubValue>
|
|
220
|
+
</InfoRow>
|
|
221
|
+
<InfoRow>
|
|
222
|
+
<InfoLabel>
|
|
223
|
+
{activeIndex === 0 ? "Iniciado em" : "Emitido em"}
|
|
224
|
+
</InfoLabel>
|
|
225
|
+
<InfoSubValue>{formatDate(issuedDate)}</InfoSubValue>
|
|
226
|
+
</InfoRow>
|
|
227
|
+
<InfoRow>
|
|
228
|
+
<InfoLabel>
|
|
229
|
+
{activeIndex === 0 ? "Valor a ser pago" : "Valor pago"}
|
|
230
|
+
</InfoLabel>
|
|
231
|
+
<InfoSubValue>{totalValue}</InfoSubValue>
|
|
232
|
+
</InfoRow>
|
|
233
|
+
<InfoRow>
|
|
234
|
+
<InfoLabel>Processo</InfoLabel>
|
|
235
|
+
<ProcessValue>
|
|
236
|
+
{processId
|
|
237
|
+
? applyMask(processId || "", "0000000-00.0000.0.00.0000")
|
|
238
|
+
: "-"}
|
|
239
|
+
</ProcessValue>
|
|
240
|
+
</InfoRow>
|
|
241
|
+
<Actions>
|
|
242
|
+
<DropdownWrapper>
|
|
243
|
+
<ActionButton
|
|
244
|
+
data-testid={`btn_minhas_emissoes_mais_informacoes_${processId}`}
|
|
245
|
+
id={`btn_minhas_emissoes_mais_informacoes_${processId}`}
|
|
246
|
+
onClick={toggleOpen}
|
|
247
|
+
>
|
|
248
|
+
Mais informações{" "}
|
|
249
|
+
{isOpen ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
|
|
250
|
+
</ActionButton>
|
|
251
|
+
{isOpen && activeIndex === 0 && (
|
|
252
|
+
<DropdownMenu>
|
|
253
|
+
<MenuItem
|
|
254
|
+
data-testid={`btn_minhas_emissoes_continuar_emissao_${processId}`}
|
|
255
|
+
id={`btn_minhas_emissoes_continuar_emissao_${processId}`}
|
|
256
|
+
icon={
|
|
257
|
+
loadingItem === "continuar_emissao" ? (
|
|
258
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
259
|
+
) : (
|
|
260
|
+
<ArrowCircleUpRight size={16} />
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
onClick={() =>
|
|
264
|
+
handleClick("continuar_emissao", irParaContinuarEmissao)
|
|
265
|
+
}
|
|
266
|
+
>
|
|
267
|
+
Continuar emissão
|
|
268
|
+
</MenuItem>
|
|
269
|
+
{hasMinute && (
|
|
270
|
+
<MenuItem
|
|
271
|
+
data-testid={`btn_minhas_emissoes_baixar_minuta_${processId}`}
|
|
272
|
+
id={`btn_minhas_emissoes_baixar_minuta_${processId}`}
|
|
273
|
+
icon={
|
|
274
|
+
loadingItem === "minuta" ? (
|
|
275
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
276
|
+
) : (
|
|
277
|
+
<Download size={16} />
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
onClick={() =>
|
|
281
|
+
handleClick("minuta", () => downloadFile("MINUTE", true))
|
|
282
|
+
}
|
|
283
|
+
>
|
|
284
|
+
Baixar minuta
|
|
285
|
+
</MenuItem>
|
|
286
|
+
)}
|
|
287
|
+
{statusLabel === "Aguardando aprovação" && (
|
|
288
|
+
<MenuItem
|
|
289
|
+
danger
|
|
290
|
+
data-testid={`btn_minhas_emissoes_recusar_proposta_${processId}`}
|
|
291
|
+
id={`btn_minhas_emissoes_recusar_proposta_${processId}`}
|
|
292
|
+
icon={
|
|
293
|
+
loadingItem === "recusar_proposta" ? (
|
|
294
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
295
|
+
) : (
|
|
296
|
+
<XCircle size={16} />
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
onClick={() =>
|
|
300
|
+
handleClick("recusar_proposta", abrirModalRecusarProposta)
|
|
301
|
+
}
|
|
302
|
+
>
|
|
303
|
+
Recusar proposta
|
|
304
|
+
</MenuItem>
|
|
305
|
+
)}
|
|
306
|
+
{statusLabel === "Proposta recusada" && (
|
|
307
|
+
<MenuItem
|
|
308
|
+
danger
|
|
309
|
+
data-testid={`btn_minhas_emissoes_excluir_proposta_${processId}`}
|
|
310
|
+
id={`btn_minhas_emissoes_excluir_proposta_${processId}`}
|
|
311
|
+
icon={
|
|
312
|
+
loadingItem === "excluir_proposta" ? (
|
|
313
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
314
|
+
) : (
|
|
315
|
+
<XCircle size={16} />
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
onClick={() =>
|
|
319
|
+
handleClick("excluir_proposta", abrirModalExcluirProposta)
|
|
320
|
+
}
|
|
321
|
+
>
|
|
322
|
+
Excluir proposta
|
|
323
|
+
</MenuItem>
|
|
324
|
+
)}
|
|
325
|
+
</DropdownMenu>
|
|
326
|
+
)}
|
|
327
|
+
{isOpen && activeIndex === 1 && (
|
|
328
|
+
<DropdownMenu>
|
|
329
|
+
<MenuItem
|
|
330
|
+
data-testid={`btn_minhas_emissoes_baixar_apolice_${processId}`}
|
|
331
|
+
id={`btn_minhas_emissoes_baixar_apolice_${processId}`}
|
|
332
|
+
icon={
|
|
333
|
+
loadingItem === "apolice" ? (
|
|
334
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
335
|
+
) : (
|
|
336
|
+
<FileText size={16} />
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
onClick={() =>
|
|
340
|
+
handleClick("apolice", () => downloadFile("POLICY", true))
|
|
341
|
+
}
|
|
342
|
+
>
|
|
343
|
+
Baixar apólice
|
|
344
|
+
</MenuItem>
|
|
345
|
+
<MenuItem
|
|
346
|
+
data-testid={`btn_minhas_emissoes_baixar_boleto_${processId}`}
|
|
347
|
+
id={`btn_minhas_emissoes_baixar_boleto_${processId}`}
|
|
348
|
+
icon={
|
|
349
|
+
loadingItem === "boleto" ? (
|
|
350
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
351
|
+
) : (
|
|
352
|
+
<CreditCard size={16} />
|
|
353
|
+
)
|
|
354
|
+
}
|
|
355
|
+
onClick={() =>
|
|
356
|
+
handleClick("boleto", () => downloadFile("SLIP", true))
|
|
357
|
+
}
|
|
358
|
+
>
|
|
359
|
+
Baixar boleto
|
|
360
|
+
</MenuItem>
|
|
361
|
+
<MenuItem
|
|
362
|
+
data-testid={`btn_minhas_emissoes_baixar_certidoes_${processId}`}
|
|
363
|
+
id={`btn_minhas_emissoes_baixar_certidoes_${processId}`}
|
|
364
|
+
icon={
|
|
365
|
+
loadingItem === "certidoes" ? (
|
|
366
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
367
|
+
) : (
|
|
368
|
+
<Download size={16} />
|
|
369
|
+
)
|
|
370
|
+
}
|
|
371
|
+
onClick={() =>
|
|
372
|
+
handleClick("certidoes", () =>
|
|
373
|
+
searchCerts(idInsurance!, idOrder)
|
|
374
|
+
)
|
|
375
|
+
}
|
|
376
|
+
>
|
|
377
|
+
Baixar certidões
|
|
378
|
+
</MenuItem>
|
|
379
|
+
<MenuItem
|
|
380
|
+
data-testid={`btn_minhas_emissoes_solicitar_endosso_${processId}`}
|
|
381
|
+
id={`btn_minhas_emissoes_solicitar_endosso_${processId}`}
|
|
382
|
+
icon={
|
|
383
|
+
loadingItem === "endosso" ? (
|
|
384
|
+
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
|
385
|
+
) : (
|
|
386
|
+
<PlusCircle size={16} />
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
onClick={() =>
|
|
390
|
+
handleClick("endosso", () =>
|
|
391
|
+
onEndorsementClick("Umbrela Corp", idInsurance!)
|
|
392
|
+
)
|
|
393
|
+
}
|
|
394
|
+
>
|
|
395
|
+
Solicitar endosso
|
|
396
|
+
</MenuItem>
|
|
397
|
+
</DropdownMenu>
|
|
398
|
+
)}
|
|
399
|
+
</DropdownWrapper>
|
|
400
|
+
</Actions>
|
|
401
|
+
</BodyRow>
|
|
402
|
+
</CardContainer>
|
|
403
|
+
);
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
const MenuItem: React.FC<MenuItemProps> = ({
|
|
407
|
+
icon,
|
|
408
|
+
danger,
|
|
409
|
+
children,
|
|
410
|
+
...rest
|
|
411
|
+
}) => {
|
|
412
|
+
return (
|
|
413
|
+
<StyledMenuItem {...rest} $danger={danger}>
|
|
414
|
+
{icon}
|
|
415
|
+
{children}
|
|
416
|
+
</StyledMenuItem>
|
|
417
|
+
);
|
|
418
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type StatusVariant = "primary" | "success" | "warning" | "danger";
|
|
2
|
+
|
|
3
|
+
export interface InsuranceCardProps {
|
|
4
|
+
idGranto: string;
|
|
5
|
+
idOrder: string;
|
|
6
|
+
idInsurance?: string;
|
|
7
|
+
idInterno: string;
|
|
8
|
+
isSupply: boolean;
|
|
9
|
+
hasMinute: boolean;
|
|
10
|
+
statusLabel: string;
|
|
11
|
+
statusVariant: StatusVariant;
|
|
12
|
+
seguradoName: string;
|
|
13
|
+
seguradoCnpj: string;
|
|
14
|
+
product: string;
|
|
15
|
+
issuedDate: string;
|
|
16
|
+
totalValue: string;
|
|
17
|
+
processId?: string;
|
|
18
|
+
activeIndex: number;
|
|
19
|
+
testId?: string;
|
|
20
|
+
openCardId: string | null;
|
|
21
|
+
setOpenCardId: (id: string | null) => void;
|
|
22
|
+
runQuery: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface MenuItemProps {
|
|
26
|
+
icon: React.ReactNode;
|
|
27
|
+
danger?: boolean;
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
onClick?: () => void;
|
|
30
|
+
id?: string;
|
|
31
|
+
"data-testid"?: string;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { InsuranceCard } from "./InsuranceCard";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { PieChart, Pie, Label, Tooltip } from "recharts";
|
|
3
|
+
import { StyledPieChart } from "./PieChartComponent.styles";
|
|
4
|
+
import { PieChartComponentProps } from "./PieChartComponent.types";
|
|
5
|
+
import {
|
|
6
|
+
semanticColors,
|
|
7
|
+
typographyTokens,
|
|
8
|
+
} from "../../../styles/tokens";
|
|
9
|
+
|
|
10
|
+
const PieChartComponent = ({ data }: PieChartComponentProps) => {
|
|
11
|
+
const totalEmissoes = useMemo(
|
|
12
|
+
() => data.reduce((acc, curr) => acc + curr.value, 0),
|
|
13
|
+
[data]
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<StyledPieChart>
|
|
18
|
+
<PieChart width={155} height={155}>
|
|
19
|
+
<Tooltip cursor={false} />
|
|
20
|
+
<Pie
|
|
21
|
+
data={data}
|
|
22
|
+
dataKey="value"
|
|
23
|
+
nameKey="name"
|
|
24
|
+
innerRadius={52}
|
|
25
|
+
outerRadius={62}
|
|
26
|
+
stroke="none"
|
|
27
|
+
paddingAngle={2}
|
|
28
|
+
>
|
|
29
|
+
<Label
|
|
30
|
+
content={({ viewBox }) => {
|
|
31
|
+
if (viewBox && "cx" in viewBox && "cy" in viewBox) {
|
|
32
|
+
const { cx, cy } = viewBox;
|
|
33
|
+
return (
|
|
34
|
+
<text
|
|
35
|
+
x={cx}
|
|
36
|
+
y={cy}
|
|
37
|
+
textAnchor="middle"
|
|
38
|
+
dominantBaseline="middle"
|
|
39
|
+
>
|
|
40
|
+
<tspan
|
|
41
|
+
x={cx}
|
|
42
|
+
y={(cy ?? 0) - 8}
|
|
43
|
+
style={{
|
|
44
|
+
fontSize: typographyTokens.fontSizes.displayL,
|
|
45
|
+
fontWeight: typographyTokens.fontWeights.bold,
|
|
46
|
+
fill: semanticColors.base.text,
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
{totalEmissoes}
|
|
50
|
+
</tspan>
|
|
51
|
+
<tspan
|
|
52
|
+
x={cx}
|
|
53
|
+
y={(cy ?? 0) + 16}
|
|
54
|
+
style={{
|
|
55
|
+
fontSize: typographyTokens.fontSizes.bodyS,
|
|
56
|
+
fill: semanticColors.base.text,
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
emissões
|
|
60
|
+
</tspan>
|
|
61
|
+
</text>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}}
|
|
66
|
+
/>
|
|
67
|
+
</Pie>
|
|
68
|
+
</PieChart>
|
|
69
|
+
</StyledPieChart>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { PieChartComponent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PieChartComponent } from "./PieChartComponent";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import {
|
|
3
|
+
semanticColors,
|
|
4
|
+
semanticRadius,
|
|
5
|
+
semanticSizes,
|
|
6
|
+
typographyTokens,
|
|
7
|
+
} from "../../../styles/tokens";
|
|
8
|
+
|
|
9
|
+
export const RadioGroupContainer = styled.div`
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-wrap: wrap;
|
|
12
|
+
gap: ${semanticSizes.global.gap.md};
|
|
13
|
+
width: 100%;
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
export const RadioButton = styled.div<{ isSelected: boolean }>`
|
|
17
|
+
min-width: 274px;
|
|
18
|
+
padding: ${semanticSizes.global.padding.md} ${semanticSizes.global.padding["2xl"]};
|
|
19
|
+
height: 40px;
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
border-radius: ${semanticRadius.global.radius.md2};
|
|
25
|
+
transition: all 0.2s;
|
|
26
|
+
font-size: ${typographyTokens.fontSizes.bodyS};
|
|
27
|
+
font-weight: ${typographyTokens.fontWeights.regular};
|
|
28
|
+
|
|
29
|
+
${({ isSelected }) =>
|
|
30
|
+
isSelected
|
|
31
|
+
? `
|
|
32
|
+
background-color: ${semanticColors.branding.surface.enabled};
|
|
33
|
+
color: ${semanticColors.branding.text.onSurfaceAccent.enabled};
|
|
34
|
+
border: none;
|
|
35
|
+
`
|
|
36
|
+
: `
|
|
37
|
+
background-color: ${semanticColors.base.background};
|
|
38
|
+
color: ${semanticColors.neutral[700]};
|
|
39
|
+
border: 1px solid ${semanticColors.global.border.default};
|
|
40
|
+
|
|
41
|
+
&:hover {
|
|
42
|
+
border-color: ${semanticColors.global.border.medium};
|
|
43
|
+
}
|
|
44
|
+
`}
|
|
45
|
+
|
|
46
|
+
&:disabled {
|
|
47
|
+
cursor: not-allowed;
|
|
48
|
+
opacity: 0.5;
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
export const RadioLabel = styled.label`
|
|
53
|
+
display: inline-flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: ${semanticSizes.global.gap.lg};
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
margin: 0;
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
export const HiddenRadioInput = styled.input`
|
|
61
|
+
position: absolute;
|
|
62
|
+
opacity: 0;
|
|
63
|
+
pointer-events: none;
|
|
64
|
+
`;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
RadioGroupContainer,
|
|
4
|
+
RadioButton,
|
|
5
|
+
RadioLabel,
|
|
6
|
+
HiddenRadioInput,
|
|
7
|
+
} from "./RadioGroupField.styles";
|
|
8
|
+
import { RadioGroupFieldProps } from "./RadioGroupField.types";
|
|
9
|
+
|
|
10
|
+
const RadioGroupField: React.FC<RadioGroupFieldProps> = ({
|
|
11
|
+
options,
|
|
12
|
+
value: controlledValue,
|
|
13
|
+
defaultValue,
|
|
14
|
+
onChange,
|
|
15
|
+
name = "radio-group",
|
|
16
|
+
disabled = false,
|
|
17
|
+
}) => {
|
|
18
|
+
const [internalValue, setInternalValue] = useState(defaultValue || "");
|
|
19
|
+
|
|
20
|
+
// Componente controlado ou não-controlado
|
|
21
|
+
const isControlled = controlledValue !== undefined;
|
|
22
|
+
const currentValue = isControlled ? controlledValue : internalValue;
|
|
23
|
+
|
|
24
|
+
const handleChange = (optionValue: string) => {
|
|
25
|
+
if (disabled) return;
|
|
26
|
+
|
|
27
|
+
if (!isControlled) {
|
|
28
|
+
setInternalValue(optionValue);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
onChange?.(optionValue);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<RadioGroupContainer>
|
|
36
|
+
{options.map((option) => {
|
|
37
|
+
const isSelected = currentValue === option.value;
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<RadioButton
|
|
41
|
+
key={option.value}
|
|
42
|
+
isSelected={isSelected}
|
|
43
|
+
onClick={() => handleChange(option.value)}
|
|
44
|
+
role="radio"
|
|
45
|
+
aria-checked={isSelected}
|
|
46
|
+
aria-disabled={disabled}
|
|
47
|
+
>
|
|
48
|
+
<RadioLabel>
|
|
49
|
+
<HiddenRadioInput
|
|
50
|
+
type="radio"
|
|
51
|
+
name={name}
|
|
52
|
+
value={option.value}
|
|
53
|
+
checked={isSelected}
|
|
54
|
+
onChange={() => handleChange(option.value)}
|
|
55
|
+
disabled={disabled}
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
{isSelected ? option.iconActive : option.iconInactive}
|
|
59
|
+
|
|
60
|
+
<span>{option.label}</span>
|
|
61
|
+
</RadioLabel>
|
|
62
|
+
</RadioButton>
|
|
63
|
+
);
|
|
64
|
+
})}
|
|
65
|
+
</RadioGroupContainer>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export { RadioGroupField };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export interface RadioOption {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
iconActive?: ReactNode;
|
|
7
|
+
iconInactive?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface RadioGroupFieldProps {
|
|
11
|
+
options: RadioOption[];
|
|
12
|
+
value?: string;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
onChange?: (value: string) => void;
|
|
15
|
+
name?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
}
|