@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 @@
|
|
|
1
|
+
export { RadioGroupField } from "./RadioGroupField";
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import styled from "styled-components"
|
|
2
|
+
import * as Dialog from "@radix-ui/react-dialog"
|
|
3
|
+
|
|
4
|
+
export const Overlay = styled(Dialog.Overlay)`
|
|
5
|
+
position: fixed;
|
|
6
|
+
inset: 0;
|
|
7
|
+
background-color: rgba(0, 0, 0, 0.6);
|
|
8
|
+
z-index: 50;
|
|
9
|
+
`
|
|
10
|
+
|
|
11
|
+
export const Content = styled(Dialog.Content)`
|
|
12
|
+
position: fixed;
|
|
13
|
+
top: 50%;
|
|
14
|
+
left: 50%;
|
|
15
|
+
transform: translate(-50%, -50%);
|
|
16
|
+
font-family: "Mulish", sans-serif;
|
|
17
|
+
background: white;
|
|
18
|
+
border-radius: 12px;
|
|
19
|
+
padding: 32px;
|
|
20
|
+
width: 100%;
|
|
21
|
+
max-width: 520px;
|
|
22
|
+
z-index: 1000;
|
|
23
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
|
24
|
+
border-top: 6px solid #c53030;
|
|
25
|
+
`
|
|
26
|
+
|
|
27
|
+
export const Title = styled.h2`
|
|
28
|
+
font-size: 28px;
|
|
29
|
+
font-weight: 600;
|
|
30
|
+
color: #1a1a1a;
|
|
31
|
+
margin-bottom: 8px;
|
|
32
|
+
font-family: "Mulish", sans-serif;
|
|
33
|
+
padding-right: 12px;
|
|
34
|
+
`
|
|
35
|
+
|
|
36
|
+
export const Description = styled.p`
|
|
37
|
+
font-size: 1rem;
|
|
38
|
+
line-height: 1.5;
|
|
39
|
+
color: #888;
|
|
40
|
+
margin-bottom: 16px;
|
|
41
|
+
font-family: "Mulish", sans-serif;
|
|
42
|
+
|
|
43
|
+
span {
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
color: #1a1a1a;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
strong {
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
color: #1a1a1a;
|
|
51
|
+
}
|
|
52
|
+
`
|
|
53
|
+
|
|
54
|
+
export const Label = styled.label`
|
|
55
|
+
font-size: 1rem;
|
|
56
|
+
margin-top: 16px;
|
|
57
|
+
margin-bottom: 4px;
|
|
58
|
+
display: block;
|
|
59
|
+
color: #888;
|
|
60
|
+
font-family: "Mulish", sans-serif;
|
|
61
|
+
`
|
|
62
|
+
|
|
63
|
+
export const Select = styled.select`
|
|
64
|
+
width: 100%;
|
|
65
|
+
color: #777;
|
|
66
|
+
padding: 12px;
|
|
67
|
+
font-size: 1rem;
|
|
68
|
+
border: 1px solid #d9d9d9;
|
|
69
|
+
border-radius: 8px;
|
|
70
|
+
background-color: white;
|
|
71
|
+
appearance: none;
|
|
72
|
+
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 20 20' fill='none' stroke='gray' strokeWidth='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
|
|
73
|
+
background-repeat: no-repeat;
|
|
74
|
+
background-position: right 12px center;
|
|
75
|
+
background-size: 16px;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
`
|
|
78
|
+
|
|
79
|
+
export const TextArea = styled.textarea`
|
|
80
|
+
width: 100%;
|
|
81
|
+
min-height: 80px;
|
|
82
|
+
padding: 12px;
|
|
83
|
+
font-size: 14px;
|
|
84
|
+
border: 1px solid #d9d9d9;
|
|
85
|
+
border-radius: 8px;
|
|
86
|
+
resize: none;
|
|
87
|
+
margin-top: 8px;
|
|
88
|
+
`
|
|
89
|
+
|
|
90
|
+
export const HelpText = styled.p`
|
|
91
|
+
font-size: 0.9rem;
|
|
92
|
+
color: #888;
|
|
93
|
+
margin-top: 4px;
|
|
94
|
+
`
|
|
95
|
+
|
|
96
|
+
export const CancelButton = styled(Dialog.Close)`
|
|
97
|
+
background: #fff;
|
|
98
|
+
border: 2px solid #7f7f7f;
|
|
99
|
+
border-radius: 8px;
|
|
100
|
+
padding: 10px 16px;
|
|
101
|
+
font-weight: 600;
|
|
102
|
+
color: #7f7f7f;
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
`
|
|
105
|
+
|
|
106
|
+
export const ConfirmButton = styled.button`
|
|
107
|
+
background: #c53030;
|
|
108
|
+
color: white;
|
|
109
|
+
border: none;
|
|
110
|
+
border-radius: 8px;
|
|
111
|
+
padding: 10px 16px;
|
|
112
|
+
font-weight: 600;
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
|
|
115
|
+
&:disabled {
|
|
116
|
+
background: #e2e2e2;
|
|
117
|
+
cursor: not-allowed;
|
|
118
|
+
}
|
|
119
|
+
`
|
|
120
|
+
|
|
121
|
+
export const CloseIcon = styled(Dialog.Close)`
|
|
122
|
+
position: absolute;
|
|
123
|
+
top: 32px;
|
|
124
|
+
right: 32px;
|
|
125
|
+
background: transparent;
|
|
126
|
+
border: none;
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
|
|
129
|
+
svg {
|
|
130
|
+
color: #888;
|
|
131
|
+
}
|
|
132
|
+
`
|
|
133
|
+
|
|
134
|
+
export const Footer = styled.div`
|
|
135
|
+
display: flex;
|
|
136
|
+
justify-content: flex-end;
|
|
137
|
+
gap: 12px;
|
|
138
|
+
margin-top: 24px;
|
|
139
|
+
`
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as Dialog from "@radix-ui/react-dialog"
|
|
4
|
+
import { X } from "lucide-react"
|
|
5
|
+
import { useState } from "react"
|
|
6
|
+
import {
|
|
7
|
+
CancelButton,
|
|
8
|
+
CloseIcon,
|
|
9
|
+
ConfirmButton,
|
|
10
|
+
Content,
|
|
11
|
+
Description,
|
|
12
|
+
Footer,
|
|
13
|
+
HelpText,
|
|
14
|
+
Label,
|
|
15
|
+
Overlay,
|
|
16
|
+
Select,
|
|
17
|
+
TextArea,
|
|
18
|
+
Title,
|
|
19
|
+
} from "./RefuseModal.styles"
|
|
20
|
+
import { type RefuseModalProps, motivos } from "./RefuseModal.types"
|
|
21
|
+
|
|
22
|
+
export const RefuseModal = ({ open, onOpenChange, onConfirm, onClose, orderId }: RefuseModalProps) => {
|
|
23
|
+
const [motivo, setMotivo] = useState("")
|
|
24
|
+
const [detalhes, setDetalhes] = useState("")
|
|
25
|
+
|
|
26
|
+
const handleConfirm = () => {
|
|
27
|
+
console.log("Proposta recusada:", { orderId, motivo, detalhes })
|
|
28
|
+
onConfirm()
|
|
29
|
+
onClose()
|
|
30
|
+
setMotivo("")
|
|
31
|
+
setDetalhes("")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
|
36
|
+
<Dialog.Portal>
|
|
37
|
+
<Overlay />
|
|
38
|
+
<Content>
|
|
39
|
+
<CloseIcon aria-label="Fechar" onClick={onClose}>
|
|
40
|
+
<X size={28} color="#BDBDBD" />
|
|
41
|
+
</CloseIcon>
|
|
42
|
+
|
|
43
|
+
<Title>Tem certeza de que deseja recusar esta proposta?</Title>
|
|
44
|
+
|
|
45
|
+
<Description>
|
|
46
|
+
Após recusar, você pode voltar e continuar de onde parou acessando{" "}
|
|
47
|
+
<span onClick={() => onClose()}>Minhas apólices</span>.<br />
|
|
48
|
+
<strong>Nota:</strong> pode ser que as condições oferecidas sejam diferentes das atuais.
|
|
49
|
+
</Description>
|
|
50
|
+
|
|
51
|
+
<Label>Nos ajude a entender o motivo da recusa:</Label>
|
|
52
|
+
<Select value={motivo} onChange={(e) => setMotivo(e.target.value)}>
|
|
53
|
+
<option value="">Selecione o motivo</option>
|
|
54
|
+
{motivos.map((item) => (
|
|
55
|
+
<option key={item} value={item}>
|
|
56
|
+
{item}
|
|
57
|
+
</option>
|
|
58
|
+
))}
|
|
59
|
+
</Select>
|
|
60
|
+
<HelpText>Sua resposta ajuda a melhorar nosso processo para você e outros usuários.</HelpText>
|
|
61
|
+
|
|
62
|
+
<Label>Se quiser, conte mais detalhes</Label>
|
|
63
|
+
<TextArea placeholder="Escreva aqui..." value={detalhes} onChange={(e) => setDetalhes(e.target.value)} />
|
|
64
|
+
<HelpText>Essas informações nos ajudam a melhorar sua experiência.</HelpText>
|
|
65
|
+
|
|
66
|
+
<Footer>
|
|
67
|
+
<CancelButton onClick={onClose}>Cancelar</CancelButton>
|
|
68
|
+
<ConfirmButton onClick={handleConfirm} disabled={!motivo}>
|
|
69
|
+
Sim, recusar
|
|
70
|
+
</ConfirmButton>
|
|
71
|
+
</Footer>
|
|
72
|
+
</Content>
|
|
73
|
+
</Dialog.Portal>
|
|
74
|
+
</Dialog.Root>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface RefuseModalProps {
|
|
2
|
+
open: boolean
|
|
3
|
+
onOpenChange: (open: boolean) => void
|
|
4
|
+
onClose: () => void
|
|
5
|
+
onConfirm: () => void
|
|
6
|
+
orderId: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const motivos = [
|
|
10
|
+
"Preço muito alto",
|
|
11
|
+
"Encontrei uma opção melhor",
|
|
12
|
+
"Não preciso mais do serviço",
|
|
13
|
+
"Condições não atendem minhas necessidades",
|
|
14
|
+
"Outro motivo",
|
|
15
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import styled from "styled-components"
|
|
2
|
+
import { semanticColors, primitiveColors } from "../../../styles/tokens/colors"
|
|
3
|
+
|
|
4
|
+
export const Results = styled.div<{ $isPositive: boolean }>`
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
font-size: 14px;
|
|
8
|
+
align-items: center;
|
|
9
|
+
gap: 8px;
|
|
10
|
+
background-color: ${({ $isPositive }) =>
|
|
11
|
+
$isPositive ? semanticColors.success.surface.feedback : primitiveColors.red[100]};
|
|
12
|
+
border: ${({ $isPositive }) =>
|
|
13
|
+
$isPositive
|
|
14
|
+
? `1px solid ${semanticColors.success.text.feedback.accent}`
|
|
15
|
+
: `1px solid ${semanticColors.danger.border.enabled}`};
|
|
16
|
+
border-radius: 9999px;
|
|
17
|
+
padding: 8px 16px;
|
|
18
|
+
color: ${({ $isPositive }) =>
|
|
19
|
+
$isPositive ? semanticColors.success.text.feedback.accent : semanticColors.danger.text.feedback.accent};
|
|
20
|
+
font-weight: 500;
|
|
21
|
+
width: fit-content;
|
|
22
|
+
`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TrendingDown, TrendingUp } from 'lucide-react'
|
|
2
|
+
import { Results } from "./ResultsChart.styles"
|
|
3
|
+
import type { ResultsChartProps } from "./ResultsChart.types"
|
|
4
|
+
|
|
5
|
+
const ResultsChart = ({ value }: ResultsChartProps) => {
|
|
6
|
+
const isPositive = value >= 0
|
|
7
|
+
const trendIcon = isPositive ? <TrendingUp size={16} /> : <TrendingDown size={16} />
|
|
8
|
+
const trendText = isPositive
|
|
9
|
+
? `${value}% a mais do que o mês anterior`
|
|
10
|
+
: `${Math.abs(value)}% a menos do que o mês anterior`
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Results $isPositive={isPositive}>
|
|
14
|
+
{trendIcon} {trendText}
|
|
15
|
+
</Results>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default ResultsChart
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import {
|
|
2
|
+
primitiveColors,
|
|
3
|
+
semanticColors,
|
|
4
|
+
typographyTokens,
|
|
5
|
+
} from '../../../styles/tokens';
|
|
6
|
+
import styled, { css } from 'styled-components';
|
|
7
|
+
import { TimelineVariant } from './TimeLine.types';
|
|
8
|
+
|
|
9
|
+
export const Time = styled.time`
|
|
10
|
+
color: #6b7280;
|
|
11
|
+
font-size: 0.78rem;
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export const ItemWrap = styled.li`
|
|
15
|
+
display: grid;
|
|
16
|
+
grid-template-columns: 24px 1fr;
|
|
17
|
+
gap: 12px;
|
|
18
|
+
position: relative;
|
|
19
|
+
padding-bottom: 16px;
|
|
20
|
+
&:last-child {
|
|
21
|
+
padding-bottom: 0;
|
|
22
|
+
}
|
|
23
|
+
&:not(:last-child)::before {
|
|
24
|
+
content: '';
|
|
25
|
+
position: absolute;
|
|
26
|
+
left: 11px;
|
|
27
|
+
top: 32px;
|
|
28
|
+
bottom: 0;
|
|
29
|
+
width: 2px;
|
|
30
|
+
height: 100%;
|
|
31
|
+
background-color: ${primitiveColors.gray[100]};
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
export const Dot = styled.span<{
|
|
36
|
+
$variant?: TimelineVariant | string;
|
|
37
|
+
}>`
|
|
38
|
+
width: 24px;
|
|
39
|
+
height: 24px;
|
|
40
|
+
border-radius: 50%;
|
|
41
|
+
border: 1px solid;
|
|
42
|
+
display: inline-block;
|
|
43
|
+
margin-top: 0.2rem;
|
|
44
|
+
${({ $variant = 'StatusChanged' }) => {
|
|
45
|
+
const map: Record<TimelineVariant, ReturnType<typeof css>> = {
|
|
46
|
+
StatusChanged: css`
|
|
47
|
+
background: ${semanticColors.branding.surface.disabled};
|
|
48
|
+
`,
|
|
49
|
+
accepted: css`
|
|
50
|
+
background: #3dcb2c;
|
|
51
|
+
`,
|
|
52
|
+
continued: css`
|
|
53
|
+
background: #f59e0b;
|
|
54
|
+
`,
|
|
55
|
+
rejected: css`
|
|
56
|
+
background: #cb2c2d;
|
|
57
|
+
`,
|
|
58
|
+
download: css`
|
|
59
|
+
background: #9ca3af;
|
|
60
|
+
`,
|
|
61
|
+
};
|
|
62
|
+
return map[$variant as TimelineVariant] ?? map['StatusChanged'];
|
|
63
|
+
}}
|
|
64
|
+
|
|
65
|
+
${({ $variant = 'StatusChanged' }) => {
|
|
66
|
+
const map: Record<TimelineVariant, ReturnType<typeof css>> = {
|
|
67
|
+
StatusChanged: css`
|
|
68
|
+
border-color: ${semanticColors.branding.surface.enabled};
|
|
69
|
+
`,
|
|
70
|
+
accepted: css`
|
|
71
|
+
border-color: #21731c;
|
|
72
|
+
`,
|
|
73
|
+
continued: css`
|
|
74
|
+
border-color: #f59e0b;
|
|
75
|
+
`,
|
|
76
|
+
rejected: css`
|
|
77
|
+
border-color: #731c1c;
|
|
78
|
+
`,
|
|
79
|
+
download: css`
|
|
80
|
+
border-color: #9ca3af;
|
|
81
|
+
`,
|
|
82
|
+
};
|
|
83
|
+
return map[$variant as TimelineVariant] ?? map['StatusChanged'];
|
|
84
|
+
}}
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
export const Card = styled.div`
|
|
88
|
+
background: #fff;
|
|
89
|
+
padding: 0px 14px;
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
export const Title = styled.h4`
|
|
93
|
+
margin: 0 0 4px 0;
|
|
94
|
+
font-size: ${typographyTokens.fontSizes.displayM};
|
|
95
|
+
color: ${semanticColors.global.text.default.enabled};
|
|
96
|
+
font-weight: ${typographyTokens.fontWeights.semibold};
|
|
97
|
+
`;
|
|
98
|
+
|
|
99
|
+
export const Sub = styled.div`
|
|
100
|
+
color: ${semanticColors.global.text.subtitle.enabled};
|
|
101
|
+
font-size: ${typographyTokens.fontSizes.headingM};
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
export const Row = styled.div`
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-wrap: wrap;
|
|
107
|
+
gap: 8px;
|
|
108
|
+
align-items: center;
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
export const List = styled.ol`
|
|
112
|
+
list-style: none;
|
|
113
|
+
margin: 0;
|
|
114
|
+
padding: 0;
|
|
115
|
+
gap: 32px;
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-direction: column;
|
|
118
|
+
`;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ItemWrap, Card, Sub, Row, Dot, List, Title } from './TimeLine.styles';
|
|
3
|
+
import { TimelineProps } from './TimeLine.types';
|
|
4
|
+
|
|
5
|
+
export const Timeline: React.FC<TimelineProps> = ({ items }) => {
|
|
6
|
+
return (
|
|
7
|
+
<List aria-label="Linha do tempo">
|
|
8
|
+
{items.map((it) => {
|
|
9
|
+
const d = new Date(it.timestamp);
|
|
10
|
+
const dateStr = d.toLocaleDateString('pt-BR');
|
|
11
|
+
const timeStr = d.toLocaleTimeString('pt-BR', {
|
|
12
|
+
hour: '2-digit',
|
|
13
|
+
minute: '2-digit',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const actorName = it.actor?.displayName || 'Sistema';
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<ItemWrap key={it.id}>
|
|
20
|
+
{it?.type && <Dot aria-hidden $variant={it.type || 'created'} />}
|
|
21
|
+
<Card>
|
|
22
|
+
<Row style={{ justifyContent: 'space-between' }}>
|
|
23
|
+
<Title>{it.title}</Title>
|
|
24
|
+
</Row>
|
|
25
|
+
|
|
26
|
+
<Sub>
|
|
27
|
+
<div>
|
|
28
|
+
Por: {actorName}{' '}
|
|
29
|
+
{dateStr ? `dia ${dateStr} às ${timeStr}` : ''}
|
|
30
|
+
</div>
|
|
31
|
+
</Sub>
|
|
32
|
+
</Card>
|
|
33
|
+
</ItemWrap>
|
|
34
|
+
);
|
|
35
|
+
})}
|
|
36
|
+
</List>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
export type TimelineVariant =
|
|
3
|
+
| 'StatusChanged'
|
|
4
|
+
| 'accepted'
|
|
5
|
+
| 'continued'
|
|
6
|
+
| 'rejected'
|
|
7
|
+
| 'download';
|
|
8
|
+
|
|
9
|
+
export interface TimelineItem {
|
|
10
|
+
id: string;
|
|
11
|
+
timestamp: string;
|
|
12
|
+
type: string;
|
|
13
|
+
title: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
actor?: TimelineActor;
|
|
16
|
+
origin?: string;
|
|
17
|
+
correlationId?: string;
|
|
18
|
+
metadata?: TimelineMetadata;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type TimelineProps = {
|
|
22
|
+
items: TimelineItem[];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export interface TimelineActor {
|
|
26
|
+
id: string;
|
|
27
|
+
displayName: string;
|
|
28
|
+
type: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TimelineMetadata {
|
|
32
|
+
from?: string;
|
|
33
|
+
to?: string;
|
|
34
|
+
[key: string]: any;
|
|
35
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import styled from "styled-components"
|
|
2
|
+
import {
|
|
3
|
+
primitiveColors,
|
|
4
|
+
semanticBorders,
|
|
5
|
+
semanticColors,
|
|
6
|
+
semanticRadius,
|
|
7
|
+
semanticSizes,
|
|
8
|
+
typographyTokens,
|
|
9
|
+
} from "../../../styles/tokens"
|
|
10
|
+
|
|
11
|
+
export const Card = styled.div`
|
|
12
|
+
background-color: ${semanticColors.base.background};
|
|
13
|
+
border: ${semanticBorders.global.sm} solid ${semanticColors.neutral[400]};
|
|
14
|
+
border-radius: 8px;
|
|
15
|
+
padding: ${semanticSizes.global.padding.lg};
|
|
16
|
+
width: 100%;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
`
|
|
20
|
+
|
|
21
|
+
export const CardHeader = styled.div`
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: row;
|
|
24
|
+
justify-content: space-between;
|
|
25
|
+
text-align: center;
|
|
26
|
+
gap: ${semanticSizes.global.gap.sm};
|
|
27
|
+
align-items: center;
|
|
28
|
+
margin-bottom: 24px;
|
|
29
|
+
`
|
|
30
|
+
|
|
31
|
+
export const CardTitle = styled.h2`
|
|
32
|
+
font-size: ${typographyTokens.fontSizes.headingS};
|
|
33
|
+
font-weight: ${typographyTokens.fontWeights.semibold};
|
|
34
|
+
margin: 0;
|
|
35
|
+
color: ${semanticColors.base.text};
|
|
36
|
+
text-align: center;
|
|
37
|
+
`
|
|
38
|
+
|
|
39
|
+
export const CardLink = styled.a`
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: row;
|
|
42
|
+
font-size: ${typographyTokens.fontSizes.labelS};
|
|
43
|
+
margin: 0;
|
|
44
|
+
color: ${semanticColors.branding.text.accent.enabled};
|
|
45
|
+
text-align: center;
|
|
46
|
+
gap: ${semanticSizes.global.gap.sm};
|
|
47
|
+
align-items: center;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
text-decoration: none;
|
|
50
|
+
|
|
51
|
+
&:hover {
|
|
52
|
+
color: ${semanticColors.branding.text.accent.hover};
|
|
53
|
+
}
|
|
54
|
+
`
|
|
55
|
+
|
|
56
|
+
export const CardContent = styled.div`
|
|
57
|
+
display: flex;
|
|
58
|
+
justify-content: flex-start;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: ${semanticSizes.global.gap.xl};
|
|
61
|
+
margin-bottom: 18px;
|
|
62
|
+
`
|
|
63
|
+
|
|
64
|
+
export const CardChartDescription = styled.div`
|
|
65
|
+
justify-content: flex-start;
|
|
66
|
+
align-items: center;
|
|
67
|
+
text-align: left;
|
|
68
|
+
|
|
69
|
+
.subtitle {
|
|
70
|
+
font-size: ${typographyTokens.fontSizes.labelS};
|
|
71
|
+
color: ${semanticColors.global.text.subtitle.enabled};
|
|
72
|
+
}
|
|
73
|
+
.description {
|
|
74
|
+
font-size: ${typographyTokens.fontSizes.headingM};
|
|
75
|
+
color: ${semanticColors.base.text};
|
|
76
|
+
margin-bottom: ${semanticSizes.global.spacings.sm};
|
|
77
|
+
}
|
|
78
|
+
`
|
|
79
|
+
|
|
80
|
+
export const CardFooter = styled.div`
|
|
81
|
+
text-align: left;
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
gap: ${semanticSizes.global.gap.xs};
|
|
85
|
+
|
|
86
|
+
.subtitle {
|
|
87
|
+
font-size: ${typographyTokens.fontSizes.labelS};
|
|
88
|
+
color: ${semanticColors.global.text.subtitle.enabled};
|
|
89
|
+
}
|
|
90
|
+
.description {
|
|
91
|
+
display: flex;
|
|
92
|
+
justify-content: flex-start;
|
|
93
|
+
align-items: center;
|
|
94
|
+
flex-direction: row;
|
|
95
|
+
gap: ${semanticSizes.global.gap.lg};
|
|
96
|
+
font-size: ${typographyTokens.fontSizes.captionM};
|
|
97
|
+
color: ${semanticColors.base.text};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.items {
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: ${semanticSizes.global.gap.sm};
|
|
104
|
+
margin-bottom: ${semanticSizes.global.spacings.sm};
|
|
105
|
+
}
|
|
106
|
+
`
|
|
107
|
+
|
|
108
|
+
export const Circle = styled.div<{ color?: string }>`
|
|
109
|
+
width: ${semanticSizes.global.gap.md};
|
|
110
|
+
height: ${semanticSizes.global.gap.md};
|
|
111
|
+
border-radius: ${semanticRadius.global.radius.full};
|
|
112
|
+
background-color: ${({ color }) => color || primitiveColors.orange[400]};
|
|
113
|
+
`
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
import { ArrowUpRight } from 'lucide-react'
|
|
3
|
+
import type { DonutEmissionsChartProps } from "./DonutEmissionsChart.types"
|
|
4
|
+
import type { PieChartComponentProps } from "../../molecules/PieChartComponent/PieChartComponent.types"
|
|
5
|
+
import {
|
|
6
|
+
Card,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
CardContent,
|
|
10
|
+
CardFooter,
|
|
11
|
+
CardLink,
|
|
12
|
+
CardChartDescription,
|
|
13
|
+
Circle,
|
|
14
|
+
} from "./DonutEmissionsChart.styles"
|
|
15
|
+
import { PieChartComponent } from "../../molecules/PieChartComponent"
|
|
16
|
+
import { primitiveColors } from "../../../styles/tokens"
|
|
17
|
+
import ResultsChart from "../../molecules/ResultsChart"
|
|
18
|
+
|
|
19
|
+
const DonutEmissionsChart: React.FC<DonutEmissionsChartProps> = ({ totalEmissions, companiesWithEmissions }) => {
|
|
20
|
+
const colors = [
|
|
21
|
+
primitiveColors.blue[400],
|
|
22
|
+
primitiveColors.orange[400],
|
|
23
|
+
primitiveColors.green[400],
|
|
24
|
+
primitiveColors.gray[400],
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const chartData: PieChartComponentProps = {
|
|
28
|
+
data: companiesWithEmissions.map((company, index) => ({
|
|
29
|
+
name: company.companyName,
|
|
30
|
+
value: company.totalEmissions,
|
|
31
|
+
fill: colors[index % colors.length],
|
|
32
|
+
})),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const currentMonth = new Date().toLocaleDateString("pt-BR", {
|
|
36
|
+
month: "long",
|
|
37
|
+
})
|
|
38
|
+
const currentMonthCapitalized = currentMonth.charAt(0).toUpperCase() + currentMonth.slice(1)
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Card>
|
|
42
|
+
<CardHeader>
|
|
43
|
+
<CardTitle>Emissões realizadas</CardTitle>
|
|
44
|
+
<CardLink href="#">
|
|
45
|
+
Acessar dashboard <ArrowUpRight size={16} />
|
|
46
|
+
</CardLink>
|
|
47
|
+
</CardHeader>
|
|
48
|
+
<CardContent>
|
|
49
|
+
<PieChartComponent data={chartData.data} />
|
|
50
|
+
<CardChartDescription>
|
|
51
|
+
<div className="subtitle">Emissões realizadas em</div>
|
|
52
|
+
<div className="description">{currentMonthCapitalized}</div>
|
|
53
|
+
<ResultsChart value={totalEmissions} />
|
|
54
|
+
</CardChartDescription>
|
|
55
|
+
</CardContent>
|
|
56
|
+
<CardFooter>
|
|
57
|
+
<div className="subtitle">Empresas que realizaram emissões</div>
|
|
58
|
+
<div className="description">
|
|
59
|
+
{chartData.data?.map((item, index) => (
|
|
60
|
+
<div key={index} className="items">
|
|
61
|
+
<Circle color={item.fill} />
|
|
62
|
+
{item.name}
|
|
63
|
+
</div>
|
|
64
|
+
))}
|
|
65
|
+
</div>
|
|
66
|
+
</CardFooter>
|
|
67
|
+
</Card>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default DonutEmissionsChart
|