react-lgpd-consent 0.2.5 → 0.3.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.
@@ -1,829 +0,0 @@
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 Typography2 from "@mui/material/Typography";
11
- import { useEffect as useEffect4, useState as useState2 } from "react";
12
-
13
- // src/context/CategoriesContext.tsx
14
- import * as React2 from "react";
15
-
16
- // src/utils/developerGuidance.ts
17
- import * as React from "react";
18
- var DEFAULT_PROJECT_CATEGORIES = {
19
- enabledCategories: ["analytics"],
20
- // Só analytics além de necessary
21
- customCategories: []
22
- };
23
- function analyzeDeveloperConfiguration(config) {
24
- const guidance = {
25
- warnings: [],
26
- suggestions: [],
27
- activeCategoriesInfo: [],
28
- usingDefaults: !config
29
- };
30
- const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
31
- if (!config) {
32
- guidance.warnings.push(
33
- 'LGPD-CONSENT: Nenhuma configura\xE7\xE3o de categorias especificada. Usando padr\xE3o: necessary + analytics. Para produ\xE7\xE3o, recomenda-se especificar explicitamente as categorias via prop "categories".'
34
- );
35
- }
36
- guidance.activeCategoriesInfo.push({
37
- id: "necessary",
38
- name: "Cookies Necess\xE1rios",
39
- description: "Essenciais para funcionamento b\xE1sico do site",
40
- essential: true,
41
- uiRequired: false
42
- // Não precisa de toggle (sempre ativo)
43
- });
44
- const enabledCategories = finalConfig.enabledCategories || [];
45
- const categoryNames = {
46
- analytics: {
47
- name: "Cookies Anal\xEDticos",
48
- description: "Medem uso e performance do site"
49
- },
50
- functional: {
51
- name: "Cookies Funcionais",
52
- description: "Melhoram experi\xEAncia e funcionalidades"
53
- },
54
- marketing: {
55
- name: "Cookies de Marketing",
56
- description: "Publicidade direcionada e campanhas"
57
- },
58
- social: {
59
- name: "Cookies de Redes Sociais",
60
- description: "Integra\xE7\xE3o com plataformas sociais"
61
- },
62
- personalization: {
63
- name: "Cookies de Personaliza\xE7\xE3o",
64
- description: "Adaptam conte\xFAdo \xE0s prefer\xEAncias do usu\xE1rio"
65
- }
66
- };
67
- enabledCategories.forEach((categoryId) => {
68
- const categoryInfo = categoryNames[categoryId];
69
- if (categoryInfo) {
70
- guidance.activeCategoriesInfo.push({
71
- id: categoryId,
72
- name: categoryInfo.name,
73
- description: categoryInfo.description,
74
- essential: false,
75
- uiRequired: true
76
- // Precisa de toggle na UI
77
- });
78
- }
79
- });
80
- const customCategories = finalConfig.customCategories || [];
81
- customCategories.forEach((category) => {
82
- guidance.activeCategoriesInfo.push({
83
- id: category.id,
84
- name: category.name,
85
- description: category.description,
86
- essential: category.essential === true,
87
- uiRequired: category.essential !== true
88
- // Apenas não-essenciais precisam toggle
89
- });
90
- });
91
- const totalToggleable = guidance.activeCategoriesInfo.filter(
92
- (c) => c.uiRequired
93
- ).length;
94
- if (totalToggleable === 0) {
95
- guidance.suggestions.push(
96
- 'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance completo LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.'
97
- );
98
- }
99
- if (totalToggleable > 5) {
100
- guidance.warnings.push(
101
- `${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode ' +
102
- 'prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
103
- );
104
- }
105
- const poorDescriptions = customCategories.filter(
106
- (c) => !c.description || c.description.length < 10
107
- );
108
- if (poorDescriptions.length > 0) {
109
- guidance.warnings.push(
110
- `Categorias customizadas com descri\xE7\xF5es inadequadas: ${poorDescriptions.map((c) => c.id).join(", ")}. Descri\xE7\xF5es claras s\xE3o obrigat\xF3rias para compliance LGPD.`
111
- );
112
- }
113
- return guidance;
114
- }
115
- function logDeveloperGuidance(guidance, disableGuidanceProp) {
116
- if (disableGuidanceProp === true) {
117
- return;
118
- }
119
- const isProduction = (
120
- // 1. NODE_ENV de bundlers (Vite, webpack, etc.)
121
- typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV === "production" || // 2. Flag customizada para desabilitar logs
122
- typeof globalThis !== "undefined" && globalThis.__LGPD_PRODUCTION__ === true || // 3. Flag de desenvolvimento desabilitada via window global (legado)
123
- typeof window !== "undefined" && window.__LGPD_DISABLE_GUIDANCE__ === true
124
- );
125
- if (isProduction) return;
126
- const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
127
- if (guidance.warnings.length > 0) {
128
- console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
129
- guidance.warnings.forEach((warning) => console.warn(`${PREFIX} ${warning}`));
130
- console.groupEnd();
131
- }
132
- if (guidance.suggestions.length > 0) {
133
- console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
134
- guidance.suggestions.forEach(
135
- (suggestion) => console.info(`${PREFIX} ${suggestion}`)
136
- );
137
- console.groupEnd();
138
- }
139
- if (guidance.usingDefaults) {
140
- console.info(
141
- `${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
142
- );
143
- }
144
- console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
145
- console.table(
146
- guidance.activeCategoriesInfo.map((cat) => ({
147
- ID: cat.id,
148
- Nome: cat.name,
149
- "Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
150
- "Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
151
- }))
152
- );
153
- console.info(
154
- `${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`
155
- );
156
- console.groupEnd();
157
- }
158
- function useDeveloperGuidance(config, disableGuidanceProp) {
159
- const guidance = analyzeDeveloperConfiguration(config);
160
- const stringifiedConfig = React.useMemo(
161
- () => JSON.stringify(config),
162
- [config]
163
- );
164
- React.useEffect(() => {
165
- logDeveloperGuidance(guidance, disableGuidanceProp);
166
- }, [guidance, stringifiedConfig, disableGuidanceProp]);
167
- return guidance;
168
- }
169
-
170
- // src/context/CategoriesContext.tsx
171
- import { jsx } from "react/jsx-runtime";
172
- var CategoriesContext = React2.createContext(
173
- null
174
- );
175
- var CategoriesCtx = React2.createContext([]);
176
- function CategoriesProvider({
177
- children,
178
- categories,
179
- // LEGACY: prop antiga (apenas customCategories)
180
- config
181
- // NOVO: configuração completa
182
- }) {
183
- const contextValue = React2.useMemo(() => {
184
- let finalConfig;
185
- if (categories && !config) {
186
- finalConfig = {
187
- enabledCategories: DEFAULT_PROJECT_CATEGORIES.enabledCategories,
188
- customCategories: categories
189
- };
190
- } else {
191
- finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
192
- }
193
- const guidance = analyzeDeveloperConfiguration(
194
- config || (categories ? { customCategories: categories } : void 0)
195
- );
196
- const toggleableCategories = guidance.activeCategoriesInfo.filter(
197
- (cat) => cat.uiRequired
198
- );
199
- return {
200
- config: finalConfig,
201
- guidance,
202
- toggleableCategories,
203
- allCategories: guidance.activeCategoriesInfo,
204
- legacyCategories: categories || []
205
- };
206
- }, [config, categories]);
207
- React2.useEffect(() => {
208
- logDeveloperGuidance(contextValue.guidance);
209
- }, [contextValue.guidance]);
210
- return /* @__PURE__ */ jsx(CategoriesContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(CategoriesCtx.Provider, { value: contextValue.legacyCategories, children }) });
211
- }
212
- function useCategories() {
213
- const context = React2.useContext(CategoriesContext);
214
- if (!context) {
215
- throw new Error(
216
- "useCategories deve ser usado dentro de CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
217
- );
218
- }
219
- return context;
220
- }
221
- function useCategoryStatus(categoryId) {
222
- const { allCategories } = useCategories();
223
- const category = allCategories.find((cat) => cat.id === categoryId);
224
- return {
225
- isActive: !!category,
226
- isEssential: category?.essential || false,
227
- needsToggle: category?.uiRequired || false,
228
- name: category?.name,
229
- description: category?.description
230
- };
231
- }
232
- function useCustomCategories() {
233
- return React2.useContext(CategoriesCtx);
234
- }
235
-
236
- // src/context/ConsentContext.tsx
237
- import * as React3 from "react";
238
- import { ThemeProvider } from "@mui/material/styles";
239
-
240
- // src/utils/cookieUtils.ts
241
- import Cookies from "js-cookie";
242
- var DEFAULT_COOKIE_OPTS = {
243
- name: "cookieConsent",
244
- maxAgeDays: 365,
245
- sameSite: "Lax",
246
- secure: typeof window !== "undefined" ? window.location.protocol === "https:" : false,
247
- path: "/"
248
- };
249
- var COOKIE_SCHEMA_VERSION = "1.0";
250
- function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
251
- if (typeof document === "undefined") return null;
252
- const raw = Cookies.get(name);
253
- if (!raw) return null;
254
- try {
255
- const data = JSON.parse(raw);
256
- if (!data.version) {
257
- return migrateLegacyCookie(data);
258
- }
259
- if (data.version !== COOKIE_SCHEMA_VERSION) {
260
- console.warn(
261
- `[react-lgpd-consent] Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`
262
- );
263
- return null;
264
- }
265
- return data;
266
- } catch {
267
- return null;
268
- }
269
- }
270
- function migrateLegacyCookie(legacyData) {
271
- try {
272
- const now = (/* @__PURE__ */ new Date()).toISOString();
273
- return {
274
- version: COOKIE_SCHEMA_VERSION,
275
- consented: legacyData.consented || false,
276
- preferences: legacyData.preferences || { necessary: true },
277
- consentDate: now,
278
- // Não temos o original, usar data atual
279
- lastUpdate: now,
280
- source: "banner",
281
- // Assumir origem banner
282
- isModalOpen: false
283
- // Nunca persistir estado de UI
284
- };
285
- } catch {
286
- return null;
287
- }
288
- }
289
- function writeConsentCookie(state, source = "banner", opts) {
290
- if (typeof document === "undefined") return;
291
- const now = (/* @__PURE__ */ new Date()).toISOString();
292
- const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
293
- const cookieData = {
294
- version: COOKIE_SCHEMA_VERSION,
295
- consented: state.consented,
296
- preferences: state.preferences,
297
- consentDate: state.consentDate || now,
298
- // Preservar data original ou usar atual
299
- lastUpdate: now,
300
- source
301
- // isModalOpen NÃO é persistido (campo de UI apenas)
302
- };
303
- Cookies.set(o.name, JSON.stringify(cookieData), {
304
- expires: o.maxAgeDays,
305
- sameSite: o.sameSite,
306
- secure: o.secure,
307
- path: o.path
308
- });
309
- }
310
- function removeConsentCookie(opts) {
311
- if (typeof document === "undefined") return;
312
- const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
313
- Cookies.remove(o.name, { path: o.path });
314
- }
315
-
316
- // src/utils/theme.ts
317
- import { createTheme } from "@mui/material/styles";
318
- var defaultConsentTheme = createTheme({
319
- palette: {
320
- primary: {
321
- main: "#1976d2",
322
- contrastText: "#ffffff"
323
- },
324
- secondary: {
325
- main: "#dc004e",
326
- contrastText: "#ffffff"
327
- },
328
- background: {
329
- default: "#fafafa",
330
- paper: "#ffffff"
331
- },
332
- text: {
333
- primary: "#333333",
334
- secondary: "#666666"
335
- },
336
- action: {
337
- hover: "rgba(25, 118, 210, 0.04)"
338
- }
339
- },
340
- typography: {
341
- fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
342
- body2: {
343
- fontSize: "0.875rem",
344
- lineHeight: 1.43
345
- },
346
- button: {
347
- fontWeight: 500,
348
- textTransform: "none"
349
- }
350
- },
351
- components: {
352
- MuiButton: {
353
- styleOverrides: {
354
- root: {
355
- borderRadius: 8,
356
- paddingX: 16,
357
- paddingY: 8
358
- },
359
- contained: {
360
- boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
361
- "&:hover": {
362
- boxShadow: "0 4px 8px rgba(0,0,0,0.15)"
363
- }
364
- }
365
- }
366
- },
367
- MuiPaper: {
368
- styleOverrides: {
369
- root: {
370
- borderRadius: 12
371
- }
372
- }
373
- },
374
- MuiDialog: {
375
- styleOverrides: {
376
- paper: {
377
- borderRadius: 16
378
- }
379
- }
380
- }
381
- }
382
- });
383
-
384
- // src/context/ConsentContext.tsx
385
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
386
- var PreferencesModal = React3.lazy(
387
- () => import("./PreferencesModal-B6N62JYB.js").then((m) => ({
388
- default: m.PreferencesModal
389
- }))
390
- );
391
- var DEFAULT_PREFERENCES = {
392
- necessary: true
393
- // Sempre ativo (essencial)
394
- };
395
- function createInitialPreferences(customCategories) {
396
- const prefs = { ...DEFAULT_PREFERENCES };
397
- if (customCategories) {
398
- customCategories.forEach((category) => {
399
- prefs[category.id] = category.essential === true;
400
- });
401
- }
402
- return prefs;
403
- }
404
- function createFullConsentState(consented, preferences, source, isModalOpen = false, existingState) {
405
- const now = (/* @__PURE__ */ new Date()).toISOString();
406
- return {
407
- version: "1.0",
408
- consented,
409
- preferences,
410
- consentDate: existingState?.consentDate || now,
411
- lastUpdate: now,
412
- source,
413
- isModalOpen
414
- };
415
- }
416
- var DEFAULT_TEXTS = {
417
- // Textos básicos
418
- bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
419
- acceptAll: "Aceitar todos",
420
- declineAll: "Recusar",
421
- preferences: "Prefer\xEAncias",
422
- policyLink: "Saiba mais",
423
- modalTitle: "Prefer\xEAncias de Cookies",
424
- modalIntro: "Ajuste as categorias de cookies. Cookies necess\xE1rios s\xE3o sempre utilizados para funcionalidades b\xE1sicas.",
425
- save: "Salvar prefer\xEAncias",
426
- necessaryAlwaysOn: "Cookies necess\xE1rios (sempre ativos)",
427
- // Textos ANPD expandidos (opcionais)
428
- controllerInfo: void 0,
429
- // Exibido se definido
430
- dataTypes: void 0,
431
- // Exibido se definido
432
- thirdPartySharing: void 0,
433
- // Exibido se definido
434
- userRights: void 0,
435
- // Exibido se definido
436
- contactInfo: void 0,
437
- // Exibido se definido
438
- retentionPeriod: void 0,
439
- // Exibido se definido
440
- lawfulBasis: void 0,
441
- // Exibido se definido
442
- transferCountries: void 0
443
- // Exibido se definido
444
- };
445
- function reducer(state, action) {
446
- switch (action.type) {
447
- case "ACCEPT_ALL": {
448
- const prefs = createInitialPreferences(action.customCategories);
449
- Object.keys(prefs).forEach((key) => {
450
- prefs[key] = true;
451
- });
452
- return createFullConsentState(true, prefs, "banner", false, state);
453
- }
454
- case "REJECT_ALL": {
455
- const prefs = createInitialPreferences(action.customCategories);
456
- if (action.customCategories) {
457
- action.customCategories.forEach((category) => {
458
- if (category.essential) {
459
- prefs[category.id] = true;
460
- }
461
- });
462
- }
463
- return createFullConsentState(true, prefs, "banner", false, state);
464
- }
465
- case "SET_CATEGORY":
466
- return {
467
- ...state,
468
- preferences: {
469
- ...state.preferences,
470
- [action.category]: action.value
471
- },
472
- lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
473
- };
474
- case "SET_PREFERENCES":
475
- return createFullConsentState(
476
- true,
477
- action.preferences,
478
- "modal",
479
- false,
480
- state
481
- );
482
- case "OPEN_MODAL":
483
- return { ...state, isModalOpen: true };
484
- case "CLOSE_MODAL":
485
- return createFullConsentState(
486
- true,
487
- state.preferences,
488
- "modal",
489
- false,
490
- state
491
- );
492
- case "RESET": {
493
- return createFullConsentState(
494
- false,
495
- createInitialPreferences(action.customCategories),
496
- "programmatic",
497
- false
498
- );
499
- }
500
- case "HYDRATE":
501
- return { ...action.state, isModalOpen: false };
502
- // Nunca hidratar com modal aberto
503
- default:
504
- return state;
505
- }
506
- }
507
- var StateCtx = React3.createContext(null);
508
- var ActionsCtx = React3.createContext(null);
509
- var TextsCtx = React3.createContext(DEFAULT_TEXTS);
510
- var HydrationCtx = React3.createContext(false);
511
- function ConsentProvider({
512
- initialState,
513
- categories,
514
- // NOVO: configuração completa de categorias
515
- texts: textsProp,
516
- theme,
517
- customCategories,
518
- // LEGACY: compatibilidade
519
- scriptIntegrations,
520
- // eslint-disable-line no-unused-vars
521
- PreferencesModalComponent,
522
- preferencesModalProps = {},
523
- disableAutomaticModal = false,
524
- hideBranding = false,
525
- onConsentGiven,
526
- onPreferencesSaved,
527
- cookie: cookieOpts,
528
- disableDeveloperGuidance,
529
- // NOVO: desabilita avisos de dev
530
- children
531
- }) {
532
- const texts = React3.useMemo(
533
- () => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }),
534
- [textsProp]
535
- );
536
- const cookie = React3.useMemo(
537
- () => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
538
- [cookieOpts]
539
- );
540
- const appliedTheme = React3.useMemo(
541
- () => theme || defaultConsentTheme,
542
- [theme]
543
- );
544
- const finalCategoriesConfig = React3.useMemo(() => {
545
- if (categories) return categories;
546
- if (customCategories) {
547
- return {
548
- enabledCategories: ["analytics"],
549
- // padrão quando usando API antiga
550
- customCategories
551
- };
552
- }
553
- return void 0;
554
- }, [categories, customCategories]);
555
- useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance);
556
- const boot = React3.useMemo(() => {
557
- if (initialState) return { ...initialState, isModalOpen: false };
558
- return createFullConsentState(
559
- false,
560
- createInitialPreferences(customCategories),
561
- "banner",
562
- false
563
- );
564
- }, [initialState, customCategories]);
565
- const [state, dispatch] = React3.useReducer(reducer, boot);
566
- const [isHydrated, setIsHydrated] = React3.useState(false);
567
- React3.useEffect(() => {
568
- if (!initialState) {
569
- const saved = readConsentCookie(cookie.name);
570
- if (saved?.consented) {
571
- console.log("\u{1F680} Immediate hydration: Cookie found", saved);
572
- dispatch({ type: "HYDRATE", state: saved });
573
- }
574
- }
575
- setIsHydrated(true);
576
- }, [cookie.name, initialState]);
577
- React3.useEffect(() => {
578
- if (state.consented) writeConsentCookie(state, state.source, cookie);
579
- }, [state, cookie]);
580
- const prevConsented = React3.useRef(state.consented);
581
- React3.useEffect(() => {
582
- if (!prevConsented.current && state.consented && onConsentGiven) {
583
- setTimeout(() => onConsentGiven(state), 150);
584
- }
585
- prevConsented.current = state.consented;
586
- }, [state, onConsentGiven]);
587
- const prevPrefs = React3.useRef(state.preferences);
588
- React3.useEffect(() => {
589
- if (state.consented && onPreferencesSaved && prevPrefs.current !== state.preferences) {
590
- setTimeout(() => onPreferencesSaved(state.preferences), 150);
591
- prevPrefs.current = state.preferences;
592
- }
593
- }, [state, onPreferencesSaved]);
594
- const api = React3.useMemo(() => {
595
- const acceptAll = () => dispatch({ type: "ACCEPT_ALL", customCategories });
596
- const rejectAll = () => dispatch({ type: "REJECT_ALL", customCategories });
597
- const setPreference = (category, value) => dispatch({ type: "SET_CATEGORY", category, value });
598
- const setPreferences = (preferences) => dispatch({ type: "SET_PREFERENCES", preferences });
599
- const openPreferences = () => dispatch({ type: "OPEN_MODAL" });
600
- const closePreferences = () => dispatch({ type: "CLOSE_MODAL" });
601
- const resetConsent = () => {
602
- removeConsentCookie(cookie);
603
- dispatch({ type: "RESET", customCategories });
604
- };
605
- return {
606
- consented: !!state.consented,
607
- preferences: state.preferences,
608
- isModalOpen: state.isModalOpen,
609
- acceptAll,
610
- rejectAll,
611
- setPreference,
612
- setPreferences,
613
- openPreferences,
614
- closePreferences,
615
- resetConsent
616
- };
617
- }, [state, cookie, customCategories]);
618
- return /* @__PURE__ */ jsx2(ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ jsx2(StateCtx.Provider, { value: state, children: /* @__PURE__ */ jsx2(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ jsx2(TextsCtx.Provider, { value: texts, children: /* @__PURE__ */ jsx2(HydrationCtx.Provider, { value: isHydrated, children: /* @__PURE__ */ jsxs(
619
- CategoriesProvider,
620
- {
621
- config: finalCategoriesConfig,
622
- categories: customCategories,
623
- children: [
624
- children,
625
- !disableAutomaticModal && /* @__PURE__ */ jsx2(React3.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ jsx2(PreferencesModalComponent, { ...preferencesModalProps }) : /* @__PURE__ */ jsx2(PreferencesModal, { hideBranding }) })
626
- ]
627
- }
628
- ) }) }) }) }) });
629
- }
630
- function useConsentStateInternal() {
631
- const ctx = React3.useContext(StateCtx);
632
- if (!ctx)
633
- throw new Error("useConsentState must be used within ConsentProvider");
634
- return ctx;
635
- }
636
- function useConsentActionsInternal() {
637
- const ctx = React3.useContext(ActionsCtx);
638
- if (!ctx)
639
- throw new Error("useConsentActions must be used within ConsentProvider");
640
- return ctx;
641
- }
642
- function useConsentTextsInternal() {
643
- const ctx = React3.useContext(TextsCtx);
644
- return ctx;
645
- }
646
- function useConsentHydrationInternal() {
647
- return React3.useContext(HydrationCtx);
648
- }
649
-
650
- // src/hooks/useConsent.ts
651
- function useConsent() {
652
- const state = useConsentStateInternal();
653
- const actions = useConsentActionsInternal();
654
- return {
655
- consented: state.consented,
656
- preferences: state.preferences,
657
- isModalOpen: state.isModalOpen,
658
- acceptAll: actions.acceptAll,
659
- rejectAll: actions.rejectAll,
660
- setPreference: actions.setPreference,
661
- setPreferences: actions.setPreferences,
662
- openPreferences: actions.openPreferences,
663
- closePreferences: actions.closePreferences,
664
- resetConsent: actions.resetConsent
665
- };
666
- }
667
- function useConsentTexts() {
668
- return useConsentTextsInternal();
669
- }
670
- function useConsentHydration() {
671
- return useConsentHydrationInternal();
672
- }
673
-
674
- // src/components/Branding.tsx
675
- import Link from "@mui/material/Link";
676
- import Typography from "@mui/material/Typography";
677
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
678
- var brandingStyles = {
679
- banner: {
680
- fontSize: "0.65rem",
681
- textAlign: "center",
682
- mt: 1,
683
- opacity: 0.7,
684
- fontStyle: "italic"
685
- },
686
- modal: {
687
- fontSize: "0.65rem",
688
- textAlign: "center",
689
- px: 3,
690
- pb: 1,
691
- opacity: 0.7,
692
- fontStyle: "italic"
693
- }
694
- };
695
- var linkStyles = {
696
- textDecoration: "none",
697
- fontWeight: 500,
698
- "&:hover": {
699
- textDecoration: "underline"
700
- }
701
- };
702
- function Branding({ variant, hidden = false }) {
703
- if (hidden) return null;
704
- return /* @__PURE__ */ jsxs2(
705
- Typography,
706
- {
707
- variant: "caption",
708
- sx: (theme) => ({
709
- ...brandingStyles[variant],
710
- color: theme.palette.text.secondary
711
- }),
712
- children: [
713
- "fornecido por",
714
- " ",
715
- /* @__PURE__ */ jsx3(
716
- Link,
717
- {
718
- href: "https://www.ledipo.eti.br",
719
- target: "_blank",
720
- rel: "noopener noreferrer",
721
- sx: (theme) => ({
722
- ...linkStyles,
723
- color: theme.palette.primary.main
724
- }),
725
- children: "L\xC9dipO.eti.br"
726
- }
727
- )
728
- ]
729
- }
730
- );
731
- }
732
-
733
- // src/components/PreferencesModal.tsx
734
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
735
- function PreferencesModal2({
736
- DialogProps: DialogProps2,
737
- hideBranding = false
738
- }) {
739
- const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
740
- const texts = useConsentTexts();
741
- const { toggleableCategories } = useCategories();
742
- const [tempPreferences, setTempPreferences] = useState2(
743
- () => {
744
- const initialPrefs = { necessary: true };
745
- toggleableCategories.forEach((category) => {
746
- initialPrefs[category.id] = preferences[category.id] ?? false;
747
- });
748
- return initialPrefs;
749
- }
750
- );
751
- useEffect4(() => {
752
- if (isModalOpen) {
753
- const syncedPrefs = { necessary: true };
754
- toggleableCategories.forEach((category) => {
755
- syncedPrefs[category.id] = preferences[category.id] ?? false;
756
- });
757
- setTempPreferences(syncedPrefs);
758
- }
759
- }, [isModalOpen, preferences, toggleableCategories]);
760
- const open = DialogProps2?.open ?? isModalOpen ?? false;
761
- const handleSave = () => {
762
- setPreferences(tempPreferences);
763
- };
764
- const handleCancel = () => {
765
- setTempPreferences(preferences);
766
- closePreferences();
767
- };
768
- return /* @__PURE__ */ jsxs3(
769
- Dialog,
770
- {
771
- "aria-labelledby": "cookie-pref-title",
772
- open,
773
- onClose: handleCancel,
774
- ...DialogProps2,
775
- children: [
776
- /* @__PURE__ */ jsx4(DialogTitle, { id: "cookie-pref-title", children: texts.modalTitle }),
777
- /* @__PURE__ */ jsxs3(DialogContent, { dividers: true, children: [
778
- /* @__PURE__ */ jsx4(Typography2, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
779
- /* @__PURE__ */ jsxs3(FormGroup, { children: [
780
- toggleableCategories.map((category) => /* @__PURE__ */ jsx4(
781
- FormControlLabel,
782
- {
783
- control: /* @__PURE__ */ jsx4(
784
- Switch,
785
- {
786
- checked: tempPreferences[category.id] ?? false,
787
- onChange: (e) => setTempPreferences((prev) => ({
788
- ...prev,
789
- [category.id]: e.target.checked
790
- }))
791
- }
792
- ),
793
- label: `${category.name} - ${category.description}`
794
- },
795
- category.id
796
- )),
797
- /* @__PURE__ */ jsx4(
798
- FormControlLabel,
799
- {
800
- control: /* @__PURE__ */ jsx4(Switch, { checked: true, disabled: true }),
801
- label: texts.necessaryAlwaysOn
802
- }
803
- )
804
- ] })
805
- ] }),
806
- !hideBranding && /* @__PURE__ */ jsx4(Branding, { variant: "modal" }),
807
- /* @__PURE__ */ jsxs3(DialogActions, { children: [
808
- /* @__PURE__ */ jsx4(Button, { variant: "outlined", onClick: handleCancel, children: "Cancelar" }),
809
- /* @__PURE__ */ jsx4(Button, { variant: "contained", onClick: handleSave, children: texts.save })
810
- ] })
811
- ]
812
- }
813
- );
814
- }
815
-
816
- export {
817
- defaultConsentTheme,
818
- DEFAULT_PROJECT_CATEGORIES,
819
- analyzeDeveloperConfiguration,
820
- useCategories,
821
- useCategoryStatus,
822
- useCustomCategories,
823
- Branding,
824
- PreferencesModal2 as PreferencesModal,
825
- ConsentProvider,
826
- useConsent,
827
- useConsentTexts,
828
- useConsentHydration
829
- };