react-lgpd-consent 0.1.5 → 0.1.6
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/README.md +105 -28
- package/dist/PreferencesModal-LWZAP5OT.js +6 -0
- package/dist/chunk-K3EVSUMQ.js +368 -0
- package/dist/index.cjs +283 -223
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +47 -385
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# react-lgpd-consent 🍪
|
|
2
2
|
|
|
3
|
-
[](https://www.
|
|
3
|
+
[](https://www.n useEffect(() => {
|
|
4
|
+
if (consented && preferences.analytics) {
|
|
5
|
+
loadScript(
|
|
6
|
+
'ga',
|
|
7
|
+
'https://www.googletagmanager.com/gtag/js?id=GA_ID',
|
|
8
|
+
'analytics' // Aguarda consentimento finalizado
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
}, [preferences, consented])package/react-lgpd-consent)
|
|
4
12
|
[](https://github.com/lucianoedipo/react-lgpd-consent/blob/main/LICENSE)
|
|
5
13
|
[](https://www.typescriptlang.org/)
|
|
6
14
|
[](https://reactjs.org/)
|
|
@@ -23,6 +31,7 @@ Solução moderna, acessível e personalizável para gerenciar consentimento de
|
|
|
23
31
|
- 🚫 **Banner Bloqueante**: Modo opcional para exigir interação antes de continuar
|
|
24
32
|
- 🎨 **Sistema de Temas**: Temas customizáveis para integração visual perfeita
|
|
25
33
|
- ⚡ **Carregamento Condicional**: Scripts só executam após consentimento explícito
|
|
34
|
+
- 🔌 **Modal Automático**: Modal de preferências incluído automaticamente com lazy loading
|
|
26
35
|
|
|
27
36
|
## 🚀 Instalação
|
|
28
37
|
|
|
@@ -40,7 +49,27 @@ pnpm add react-lgpd-consent
|
|
|
40
49
|
npm install @mui/material js-cookie
|
|
41
50
|
```
|
|
42
51
|
|
|
43
|
-
##
|
|
52
|
+
## � Exemplo Completo
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { ConsentProvider, CookieBanner } from 'react-lgpd-consent'
|
|
56
|
+
|
|
57
|
+
function App() {
|
|
58
|
+
return (
|
|
59
|
+
<ConsentProvider>
|
|
60
|
+
<div>
|
|
61
|
+
<h1>Meu Site</h1>
|
|
62
|
+
<p>Conteúdo do site...</p>
|
|
63
|
+
|
|
64
|
+
{/* Banner de cookies */}
|
|
65
|
+
<CookieBanner policyLinkUrl="/privacy-policy" blocking={true} />
|
|
66
|
+
</div>
|
|
67
|
+
</ConsentProvider>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## �📖 Uso Básico
|
|
44
73
|
|
|
45
74
|
### 1. Setup do Provider
|
|
46
75
|
|
|
@@ -69,6 +98,7 @@ function Layout() {
|
|
|
69
98
|
policyLinkUrl="/politica-privacidade"
|
|
70
99
|
blocking={true} // Padrão: bloqueia até decisão
|
|
71
100
|
/>
|
|
101
|
+
{/* Modal de preferências incluído automaticamente! */}
|
|
72
102
|
</>
|
|
73
103
|
)
|
|
74
104
|
}
|
|
@@ -92,10 +122,14 @@ function MyComponent() {
|
|
|
92
122
|
}
|
|
93
123
|
```
|
|
94
124
|
|
|
125
|
+
> ✅ **O modal de preferências é incluído automaticamente pelo ConsentProvider!** Não é mais necessário renderizá-lo manualmente.
|
|
126
|
+
|
|
127
|
+
````
|
|
128
|
+
|
|
95
129
|
### 4. Carregamento Condicional de Scripts
|
|
96
130
|
|
|
97
131
|
```tsx
|
|
98
|
-
import { ConsentGate,
|
|
132
|
+
import { ConsentGate, loadScript } from 'react-lgpd-consent'
|
|
99
133
|
|
|
100
134
|
function Analytics() {
|
|
101
135
|
return (
|
|
@@ -119,7 +153,7 @@ function MyComponent() {
|
|
|
119
153
|
}
|
|
120
154
|
}, [preferences, consented])
|
|
121
155
|
}
|
|
122
|
-
|
|
156
|
+
````
|
|
123
157
|
|
|
124
158
|
## 🎨 Customização
|
|
125
159
|
|
|
@@ -242,41 +276,87 @@ const temaCustomizado = createTheme({
|
|
|
242
276
|
})
|
|
243
277
|
```
|
|
244
278
|
|
|
245
|
-
## ⚡ Carregamento
|
|
279
|
+
## ⚡ Carregamento Inteligente de Scripts
|
|
246
280
|
|
|
247
|
-
### Função
|
|
281
|
+
### Função loadScript
|
|
248
282
|
|
|
249
|
-
|
|
283
|
+
Scripts aguardam automaticamente o **consentimento finalizado** (banner fechado ou preferências salvas):
|
|
250
284
|
|
|
251
285
|
```tsx
|
|
252
|
-
import {
|
|
286
|
+
import { loadScript } from 'react-lgpd-consent'
|
|
253
287
|
|
|
254
|
-
// Carrega script apenas
|
|
255
|
-
await
|
|
288
|
+
// Carrega script apenas após consentimento para analytics
|
|
289
|
+
await loadScript(
|
|
256
290
|
'gtag',
|
|
257
291
|
'https://www.googletagmanager.com/gtag/js?id=GA_ID',
|
|
258
|
-
|
|
259
|
-
{ timeout: 10000 }, // timeout opcional
|
|
292
|
+
'analytics', // Categoria obrigatória
|
|
260
293
|
)
|
|
294
|
+
|
|
295
|
+
// Script geral (sempre carrega após consentimento)
|
|
296
|
+
await loadScript('custom-script', 'https://example.com/script.js')
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Comportamento Inteligente
|
|
300
|
+
|
|
301
|
+
- **Aguarda decisão final**: Não executa durante mudanças no modal de preferências
|
|
302
|
+
- **Só executa após salvar**: Scripts só rodam quando o usuário finaliza as preferências
|
|
303
|
+
- **Baseado em categoria**: Respeita as permissões por categoria
|
|
304
|
+
|
|
305
|
+
## 🎨 Personalização Total
|
|
306
|
+
|
|
307
|
+
### Modal de Preferências Customizado
|
|
308
|
+
|
|
309
|
+
Substitua completamente o modal padrão com seu próprio componente:
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
import { ConsentProvider, useConsent } from 'react-lgpd-consent'
|
|
313
|
+
import MeuModalCustomizado from './MeuModalCustomizado'
|
|
314
|
+
|
|
315
|
+
function App() {
|
|
316
|
+
return (
|
|
317
|
+
<ConsentProvider
|
|
318
|
+
PreferencesModalComponent={MeuModalCustomizado}
|
|
319
|
+
preferencesModalProps={{ variant: 'custom' }}
|
|
320
|
+
>
|
|
321
|
+
<MeuApp />
|
|
322
|
+
</ConsentProvider>
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Seu componente customizado
|
|
327
|
+
function MeuModalCustomizado({ variant }) {
|
|
328
|
+
const { isModalOpen, closePreferences, setPreference } = useConsent()
|
|
329
|
+
|
|
330
|
+
return (
|
|
331
|
+
<MyCustomDialog open={isModalOpen} onClose={closePreferences}>
|
|
332
|
+
{/* Seu design personalizado aqui */}
|
|
333
|
+
</MyCustomDialog>
|
|
334
|
+
)
|
|
335
|
+
}
|
|
261
336
|
```
|
|
262
337
|
|
|
263
|
-
###
|
|
338
|
+
### Desabilitar Modal Automático
|
|
264
339
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
340
|
+
Para controle total, desabilite o modal automático:
|
|
341
|
+
|
|
342
|
+
```tsx
|
|
343
|
+
<ConsentProvider disableAutomaticModal>
|
|
344
|
+
<MeuApp />
|
|
345
|
+
{/* Renderize seus componentes customizados onde quiser */}
|
|
346
|
+
<MeuModalTotalmenteCustomizado />
|
|
347
|
+
</ConsentProvider>
|
|
348
|
+
```
|
|
269
349
|
|
|
270
350
|
## �🔧 API Completa
|
|
271
351
|
|
|
272
352
|
### Components
|
|
273
353
|
|
|
274
|
-
| Componente | Descrição
|
|
275
|
-
| ------------------ |
|
|
276
|
-
| `ConsentProvider` | Provider principal do contexto
|
|
277
|
-
| `CookieBanner` | Banner de consentimento
|
|
278
|
-
| `PreferencesModal` | Modal de preferências
|
|
279
|
-
| `ConsentGate` | Renderização condicional por categoria
|
|
354
|
+
| Componente | Descrição | Props Principais |
|
|
355
|
+
| ------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
|
|
356
|
+
| `ConsentProvider` | Provider principal do contexto | `initialState`, `texts`, `theme`, `PreferencesModalComponent`, `disableAutomaticModal`, callbacks |
|
|
357
|
+
| `CookieBanner` | Banner de consentimento | `policyLinkUrl`, `blocking`, `debug`, pass-through MUI props |
|
|
358
|
+
| `PreferencesModal` | Modal de preferências (incluído automaticamente) | `DialogProps` (MUI pass-through) - **Opcional** |
|
|
359
|
+
| `ConsentGate` | Renderização condicional por categoria | `category`, `children` |
|
|
280
360
|
|
|
281
361
|
### Hook `useConsent()`
|
|
282
362
|
|
|
@@ -304,12 +384,9 @@ console.log(texts.banner.title) // "Política de Cookies"
|
|
|
304
384
|
|
|
305
385
|
### Utilitários
|
|
306
386
|
|
|
307
|
-
- `loadScript(id, src, attrs?)` - Carrega scripts
|
|
308
|
-
- `loadConditionalScript(id, src, condition, options?)` - Carrega scripts condicionalmente
|
|
387
|
+
- `loadScript(id, src, category?, attrs?)` - Carrega scripts com consentimento inteligente
|
|
309
388
|
- `defaultConsentTheme` - Tema padrão do Material-UI
|
|
310
|
-
- Tipos TypeScript completos exportados
|
|
311
|
-
|
|
312
|
-
## 🌐 SSR / Next.js
|
|
389
|
+
- Tipos TypeScript completos exportados## 🌐 SSR / Next.js
|
|
313
390
|
|
|
314
391
|
Para evitar flash de conteúdo em SSR:
|
|
315
392
|
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
// src/components/PreferencesModal.tsx
|
|
2
|
+
import Button from "@mui/material/Button";
|
|
3
|
+
import Dialog from "@mui/material/Dialog";
|
|
4
|
+
import DialogActions from "@mui/material/DialogActions";
|
|
5
|
+
import DialogContent from "@mui/material/DialogContent";
|
|
6
|
+
import DialogTitle from "@mui/material/DialogTitle";
|
|
7
|
+
import FormControlLabel from "@mui/material/FormControlLabel";
|
|
8
|
+
import FormGroup from "@mui/material/FormGroup";
|
|
9
|
+
import Switch from "@mui/material/Switch";
|
|
10
|
+
import Typography from "@mui/material/Typography";
|
|
11
|
+
|
|
12
|
+
// src/context/ConsentContext.tsx
|
|
13
|
+
import * as React from "react";
|
|
14
|
+
import { ThemeProvider } from "@mui/material/styles";
|
|
15
|
+
|
|
16
|
+
// src/utils/cookieUtils.ts
|
|
17
|
+
import Cookies from "js-cookie";
|
|
18
|
+
var DEFAULT_COOKIE_OPTS = {
|
|
19
|
+
name: "cookieConsent",
|
|
20
|
+
maxAgeDays: 365,
|
|
21
|
+
sameSite: "Lax",
|
|
22
|
+
secure: true,
|
|
23
|
+
path: "/"
|
|
24
|
+
};
|
|
25
|
+
function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
26
|
+
if (typeof document === "undefined") return null;
|
|
27
|
+
const raw = Cookies.get(name);
|
|
28
|
+
if (!raw) return null;
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(raw);
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function writeConsentCookie(state, opts) {
|
|
36
|
+
if (typeof document === "undefined") return;
|
|
37
|
+
const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
|
|
38
|
+
Cookies.set(o.name, JSON.stringify(state), {
|
|
39
|
+
expires: o.maxAgeDays,
|
|
40
|
+
sameSite: o.sameSite,
|
|
41
|
+
secure: o.secure,
|
|
42
|
+
path: o.path
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function removeConsentCookie(opts) {
|
|
46
|
+
if (typeof document === "undefined") return;
|
|
47
|
+
const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
|
|
48
|
+
Cookies.remove(o.name, { path: o.path });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/utils/theme.ts
|
|
52
|
+
import { createTheme } from "@mui/material/styles";
|
|
53
|
+
var defaultConsentTheme = createTheme({
|
|
54
|
+
palette: {
|
|
55
|
+
primary: {
|
|
56
|
+
main: "#1976d2",
|
|
57
|
+
// Azul institucional
|
|
58
|
+
contrastText: "#ffffff"
|
|
59
|
+
},
|
|
60
|
+
secondary: {
|
|
61
|
+
main: "#dc004e",
|
|
62
|
+
// Rosa/vermelho para ações importantes
|
|
63
|
+
contrastText: "#ffffff"
|
|
64
|
+
},
|
|
65
|
+
background: {
|
|
66
|
+
default: "#fafafa",
|
|
67
|
+
paper: "#ffffff"
|
|
68
|
+
},
|
|
69
|
+
text: {
|
|
70
|
+
primary: "#333333",
|
|
71
|
+
secondary: "#666666"
|
|
72
|
+
},
|
|
73
|
+
action: {
|
|
74
|
+
hover: "rgba(25, 118, 210, 0.04)"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
typography: {
|
|
78
|
+
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
|
|
79
|
+
body2: {
|
|
80
|
+
fontSize: "0.875rem",
|
|
81
|
+
lineHeight: 1.43
|
|
82
|
+
},
|
|
83
|
+
button: {
|
|
84
|
+
fontWeight: 500,
|
|
85
|
+
textTransform: "none"
|
|
86
|
+
// Manter capitalização original
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
components: {
|
|
90
|
+
MuiButton: {
|
|
91
|
+
styleOverrides: {
|
|
92
|
+
root: {
|
|
93
|
+
borderRadius: 8,
|
|
94
|
+
paddingX: 16,
|
|
95
|
+
paddingY: 8
|
|
96
|
+
},
|
|
97
|
+
contained: {
|
|
98
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
|
|
99
|
+
"&:hover": {
|
|
100
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.15)"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
MuiPaper: {
|
|
106
|
+
styleOverrides: {
|
|
107
|
+
root: {
|
|
108
|
+
borderRadius: 12
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
MuiDialog: {
|
|
113
|
+
styleOverrides: {
|
|
114
|
+
paper: {
|
|
115
|
+
borderRadius: 16
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// src/context/ConsentContext.tsx
|
|
123
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
124
|
+
var PreferencesModal = React.lazy(
|
|
125
|
+
() => import("./PreferencesModal-LWZAP5OT.js").then((m) => ({
|
|
126
|
+
default: m.PreferencesModal
|
|
127
|
+
}))
|
|
128
|
+
);
|
|
129
|
+
var DEFAULT_PREFERENCES = {
|
|
130
|
+
analytics: false,
|
|
131
|
+
marketing: false
|
|
132
|
+
};
|
|
133
|
+
var DEFAULT_TEXTS = {
|
|
134
|
+
bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
|
|
135
|
+
acceptAll: "Aceitar todos",
|
|
136
|
+
declineAll: "Recusar",
|
|
137
|
+
preferences: "Prefer\xEAncias",
|
|
138
|
+
policyLink: "Saiba mais",
|
|
139
|
+
modalTitle: "Prefer\xEAncias de Cookies",
|
|
140
|
+
modalIntro: "Ajuste as categorias de cookies. Cookies necess\xE1rios s\xE3o sempre utilizados para funcionalidades b\xE1sicas.",
|
|
141
|
+
save: "Salvar prefer\xEAncias",
|
|
142
|
+
necessaryAlwaysOn: "Cookies necess\xE1rios (sempre ativos)"
|
|
143
|
+
};
|
|
144
|
+
function reducer(state, action) {
|
|
145
|
+
switch (action.type) {
|
|
146
|
+
case "ACCEPT_ALL":
|
|
147
|
+
return {
|
|
148
|
+
consented: true,
|
|
149
|
+
preferences: { analytics: true, marketing: true },
|
|
150
|
+
isModalOpen: false
|
|
151
|
+
};
|
|
152
|
+
case "REJECT_ALL":
|
|
153
|
+
return {
|
|
154
|
+
consented: true,
|
|
155
|
+
preferences: { analytics: false, marketing: false },
|
|
156
|
+
isModalOpen: false
|
|
157
|
+
};
|
|
158
|
+
case "SET_CATEGORY":
|
|
159
|
+
return {
|
|
160
|
+
...state,
|
|
161
|
+
preferences: {
|
|
162
|
+
...state.preferences,
|
|
163
|
+
[action.category]: action.value
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
case "OPEN_MODAL":
|
|
167
|
+
return { ...state, isModalOpen: true };
|
|
168
|
+
case "CLOSE_MODAL":
|
|
169
|
+
return { ...state, isModalOpen: false, consented: true };
|
|
170
|
+
// houve interação
|
|
171
|
+
case "RESET":
|
|
172
|
+
return {
|
|
173
|
+
consented: false,
|
|
174
|
+
preferences: { ...DEFAULT_PREFERENCES },
|
|
175
|
+
isModalOpen: false
|
|
176
|
+
};
|
|
177
|
+
case "HYDRATE":
|
|
178
|
+
return { ...action.state };
|
|
179
|
+
default:
|
|
180
|
+
return state;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
var StateCtx = React.createContext(null);
|
|
184
|
+
var ActionsCtx = React.createContext(null);
|
|
185
|
+
var TextsCtx = React.createContext(DEFAULT_TEXTS);
|
|
186
|
+
function ConsentProvider({
|
|
187
|
+
initialState,
|
|
188
|
+
texts: textsProp,
|
|
189
|
+
theme,
|
|
190
|
+
PreferencesModalComponent,
|
|
191
|
+
preferencesModalProps = {},
|
|
192
|
+
disableAutomaticModal = false,
|
|
193
|
+
onConsentGiven,
|
|
194
|
+
onPreferencesSaved,
|
|
195
|
+
cookie: cookieOpts,
|
|
196
|
+
children
|
|
197
|
+
}) {
|
|
198
|
+
const texts = React.useMemo(
|
|
199
|
+
() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }),
|
|
200
|
+
[textsProp]
|
|
201
|
+
);
|
|
202
|
+
const cookie = React.useMemo(
|
|
203
|
+
() => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
|
|
204
|
+
[cookieOpts]
|
|
205
|
+
);
|
|
206
|
+
const appliedTheme = React.useMemo(
|
|
207
|
+
() => theme || defaultConsentTheme,
|
|
208
|
+
[theme]
|
|
209
|
+
);
|
|
210
|
+
const boot = React.useMemo(() => {
|
|
211
|
+
if (initialState) return { ...initialState, isModalOpen: false };
|
|
212
|
+
const saved = readConsentCookie(cookie.name);
|
|
213
|
+
return saved ?? {
|
|
214
|
+
consented: false,
|
|
215
|
+
preferences: { ...DEFAULT_PREFERENCES },
|
|
216
|
+
isModalOpen: false
|
|
217
|
+
};
|
|
218
|
+
}, [initialState, cookie.name]);
|
|
219
|
+
const [state, dispatch] = React.useReducer(reducer, boot);
|
|
220
|
+
React.useEffect(() => {
|
|
221
|
+
if (state.consented) writeConsentCookie(state, cookie);
|
|
222
|
+
}, [state, cookie]);
|
|
223
|
+
const prevConsented = React.useRef(state.consented);
|
|
224
|
+
React.useEffect(() => {
|
|
225
|
+
if (!prevConsented.current && state.consented && onConsentGiven) {
|
|
226
|
+
setTimeout(() => onConsentGiven(state), 150);
|
|
227
|
+
}
|
|
228
|
+
prevConsented.current = state.consented;
|
|
229
|
+
}, [state, onConsentGiven]);
|
|
230
|
+
const prevPrefs = React.useRef(state.preferences);
|
|
231
|
+
React.useEffect(() => {
|
|
232
|
+
if (state.consented && onPreferencesSaved && prevPrefs.current !== state.preferences) {
|
|
233
|
+
setTimeout(() => onPreferencesSaved(state.preferences), 150);
|
|
234
|
+
prevPrefs.current = state.preferences;
|
|
235
|
+
}
|
|
236
|
+
}, [state, onPreferencesSaved]);
|
|
237
|
+
const api = React.useMemo(() => {
|
|
238
|
+
const acceptAll = () => dispatch({ type: "ACCEPT_ALL" });
|
|
239
|
+
const rejectAll = () => dispatch({ type: "REJECT_ALL" });
|
|
240
|
+
const setPreference = (category, value) => dispatch({ type: "SET_CATEGORY", category, value });
|
|
241
|
+
const openPreferences = () => dispatch({ type: "OPEN_MODAL" });
|
|
242
|
+
const closePreferences = () => dispatch({ type: "CLOSE_MODAL" });
|
|
243
|
+
const resetConsent = () => {
|
|
244
|
+
removeConsentCookie(cookie);
|
|
245
|
+
dispatch({ type: "RESET" });
|
|
246
|
+
};
|
|
247
|
+
return {
|
|
248
|
+
consented: !!state.consented,
|
|
249
|
+
preferences: state.preferences,
|
|
250
|
+
isModalOpen: state.isModalOpen,
|
|
251
|
+
acceptAll,
|
|
252
|
+
rejectAll,
|
|
253
|
+
setPreference,
|
|
254
|
+
openPreferences,
|
|
255
|
+
closePreferences,
|
|
256
|
+
resetConsent
|
|
257
|
+
};
|
|
258
|
+
}, [state, cookie]);
|
|
259
|
+
return /* @__PURE__ */ jsx(ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ jsx(StateCtx.Provider, { value: state, children: /* @__PURE__ */ jsx(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ jsxs(TextsCtx.Provider, { value: texts, children: [
|
|
260
|
+
children,
|
|
261
|
+
!disableAutomaticModal && /* @__PURE__ */ jsx(React.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ jsx(PreferencesModalComponent, { ...preferencesModalProps }) : /* @__PURE__ */ jsx(PreferencesModal, {}) })
|
|
262
|
+
] }) }) }) });
|
|
263
|
+
}
|
|
264
|
+
function useConsentStateInternal() {
|
|
265
|
+
const ctx = React.useContext(StateCtx);
|
|
266
|
+
if (!ctx)
|
|
267
|
+
throw new Error("useConsentState must be used within ConsentProvider");
|
|
268
|
+
return ctx;
|
|
269
|
+
}
|
|
270
|
+
function useConsentActionsInternal() {
|
|
271
|
+
const ctx = React.useContext(ActionsCtx);
|
|
272
|
+
if (!ctx)
|
|
273
|
+
throw new Error("useConsentActions must be used within ConsentProvider");
|
|
274
|
+
return ctx;
|
|
275
|
+
}
|
|
276
|
+
function useConsentTextsInternal() {
|
|
277
|
+
const ctx = React.useContext(TextsCtx);
|
|
278
|
+
return ctx;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// src/hooks/useConsent.ts
|
|
282
|
+
function useConsent() {
|
|
283
|
+
const state = useConsentStateInternal();
|
|
284
|
+
const actions = useConsentActionsInternal();
|
|
285
|
+
return {
|
|
286
|
+
consented: state.consented,
|
|
287
|
+
preferences: state.preferences,
|
|
288
|
+
isModalOpen: state.isModalOpen,
|
|
289
|
+
acceptAll: actions.acceptAll,
|
|
290
|
+
rejectAll: actions.rejectAll,
|
|
291
|
+
setPreference: actions.setPreference,
|
|
292
|
+
openPreferences: actions.openPreferences,
|
|
293
|
+
closePreferences: actions.closePreferences,
|
|
294
|
+
resetConsent: actions.resetConsent
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function useConsentTexts() {
|
|
298
|
+
return useConsentTextsInternal();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/components/PreferencesModal.tsx
|
|
302
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
303
|
+
function PreferencesModal2({
|
|
304
|
+
DialogProps: DialogProps2
|
|
305
|
+
}) {
|
|
306
|
+
const { preferences, setPreference, closePreferences, isModalOpen } = useConsent();
|
|
307
|
+
const texts = useConsentTexts();
|
|
308
|
+
const open = DialogProps2?.open ?? isModalOpen ?? false;
|
|
309
|
+
return /* @__PURE__ */ jsxs2(
|
|
310
|
+
Dialog,
|
|
311
|
+
{
|
|
312
|
+
"aria-labelledby": "cookie-pref-title",
|
|
313
|
+
open,
|
|
314
|
+
onClose: closePreferences,
|
|
315
|
+
...DialogProps2,
|
|
316
|
+
children: [
|
|
317
|
+
/* @__PURE__ */ jsx2(DialogTitle, { id: "cookie-pref-title", children: texts.modalTitle }),
|
|
318
|
+
/* @__PURE__ */ jsxs2(DialogContent, { dividers: true, children: [
|
|
319
|
+
/* @__PURE__ */ jsx2(Typography, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
|
|
320
|
+
/* @__PURE__ */ jsxs2(FormGroup, { children: [
|
|
321
|
+
/* @__PURE__ */ jsx2(
|
|
322
|
+
FormControlLabel,
|
|
323
|
+
{
|
|
324
|
+
control: /* @__PURE__ */ jsx2(
|
|
325
|
+
Switch,
|
|
326
|
+
{
|
|
327
|
+
checked: preferences.analytics,
|
|
328
|
+
onChange: (e) => setPreference("analytics", e.target.checked)
|
|
329
|
+
}
|
|
330
|
+
),
|
|
331
|
+
label: "Cookies Anal\xEDticos (medem uso do site)"
|
|
332
|
+
}
|
|
333
|
+
),
|
|
334
|
+
/* @__PURE__ */ jsx2(
|
|
335
|
+
FormControlLabel,
|
|
336
|
+
{
|
|
337
|
+
control: /* @__PURE__ */ jsx2(
|
|
338
|
+
Switch,
|
|
339
|
+
{
|
|
340
|
+
checked: preferences.marketing,
|
|
341
|
+
onChange: (e) => setPreference("marketing", e.target.checked)
|
|
342
|
+
}
|
|
343
|
+
),
|
|
344
|
+
label: "Cookies de Marketing/Publicidade"
|
|
345
|
+
}
|
|
346
|
+
),
|
|
347
|
+
/* @__PURE__ */ jsx2(
|
|
348
|
+
FormControlLabel,
|
|
349
|
+
{
|
|
350
|
+
control: /* @__PURE__ */ jsx2(Switch, { checked: true, disabled: true }),
|
|
351
|
+
label: texts.necessaryAlwaysOn
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
] })
|
|
355
|
+
] }),
|
|
356
|
+
/* @__PURE__ */ jsx2(DialogActions, { children: /* @__PURE__ */ jsx2(Button, { variant: "contained", onClick: closePreferences, children: texts.save }) })
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export {
|
|
363
|
+
defaultConsentTheme,
|
|
364
|
+
PreferencesModal2 as PreferencesModal,
|
|
365
|
+
ConsentProvider,
|
|
366
|
+
useConsent,
|
|
367
|
+
useConsentTexts
|
|
368
|
+
};
|