react-lgpd-consent 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPLIANCE.md +73 -287
- package/README.md +86 -667
- package/dist/{PreferencesModal-SOVV24DU.js → PreferencesModal-XCTM6WJN.js} +1 -1
- package/dist/{chunk-UKKWGQN7.js → chunk-R3IKVZBC.js} +506 -272
- package/dist/index.cjs +737 -655
- package/dist/index.d.cts +141 -125
- package/dist/index.d.ts +141 -125
- package/dist/index.js +7 -182
- package/package.json +12 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,208 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
+
// src/utils/developerGuidance.ts
|
|
34
|
+
function analyzeDeveloperConfiguration(config) {
|
|
35
|
+
const guidance = {
|
|
36
|
+
warnings: [],
|
|
37
|
+
suggestions: [],
|
|
38
|
+
activeCategoriesInfo: [],
|
|
39
|
+
usingDefaults: !config
|
|
40
|
+
};
|
|
41
|
+
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
42
|
+
if (!config) {
|
|
43
|
+
guidance.warnings.push(
|
|
44
|
+
'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".'
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
guidance.activeCategoriesInfo.push({
|
|
48
|
+
id: "necessary",
|
|
49
|
+
name: "Cookies Necess\xE1rios",
|
|
50
|
+
description: "Essenciais para funcionamento b\xE1sico do site",
|
|
51
|
+
essential: true,
|
|
52
|
+
uiRequired: false
|
|
53
|
+
// Não precisa de toggle (sempre ativo)
|
|
54
|
+
});
|
|
55
|
+
const enabledCategories = finalConfig.enabledCategories || [];
|
|
56
|
+
const categoryNames = {
|
|
57
|
+
analytics: {
|
|
58
|
+
name: "Cookies Anal\xEDticos",
|
|
59
|
+
description: "Medem uso e performance do site"
|
|
60
|
+
},
|
|
61
|
+
functional: {
|
|
62
|
+
name: "Cookies Funcionais",
|
|
63
|
+
description: "Melhoram experi\xEAncia e funcionalidades"
|
|
64
|
+
},
|
|
65
|
+
marketing: {
|
|
66
|
+
name: "Cookies de Marketing",
|
|
67
|
+
description: "Publicidade direcionada e campanhas"
|
|
68
|
+
},
|
|
69
|
+
social: {
|
|
70
|
+
name: "Cookies de Redes Sociais",
|
|
71
|
+
description: "Integra\xE7\xE3o com plataformas sociais"
|
|
72
|
+
},
|
|
73
|
+
personalization: {
|
|
74
|
+
name: "Cookies de Personaliza\xE7\xE3o",
|
|
75
|
+
description: "Adaptam conte\xFAdo \xE0s prefer\xEAncias do usu\xE1rio"
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
enabledCategories.forEach((categoryId) => {
|
|
79
|
+
const categoryInfo = categoryNames[categoryId];
|
|
80
|
+
if (categoryInfo) {
|
|
81
|
+
guidance.activeCategoriesInfo.push({
|
|
82
|
+
id: categoryId,
|
|
83
|
+
name: categoryInfo.name,
|
|
84
|
+
description: categoryInfo.description,
|
|
85
|
+
essential: false,
|
|
86
|
+
uiRequired: true
|
|
87
|
+
// Precisa de toggle na UI
|
|
88
|
+
});
|
|
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
|
+
return guidance;
|
|
106
|
+
}
|
|
107
|
+
function logDeveloperGuidance(guidance, disableGuidanceProp) {
|
|
108
|
+
if (disableGuidanceProp) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const isProduction = (
|
|
112
|
+
// 1. NODE_ENV de bundlers (Vite, webpack, etc.)
|
|
113
|
+
typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV === "production" || // 2. Flag customizada para desabilitar logs
|
|
114
|
+
typeof globalThis !== "undefined" && globalThis.__LGPD_PRODUCTION__ === true || // 3. Flag de desenvolvimento desabilitada via window global (legado)
|
|
115
|
+
typeof window !== "undefined" && window.__LGPD_DISABLE_GUIDANCE__ === true
|
|
116
|
+
);
|
|
117
|
+
if (isProduction) return;
|
|
118
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
119
|
+
if (guidance.warnings.length > 0) {
|
|
120
|
+
console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
|
|
121
|
+
guidance.warnings.forEach((warning) => console.warn(`${PREFIX} ${warning}`));
|
|
122
|
+
console.groupEnd();
|
|
123
|
+
}
|
|
124
|
+
if (guidance.suggestions.length > 0) {
|
|
125
|
+
console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
|
|
126
|
+
guidance.suggestions.forEach(
|
|
127
|
+
(suggestion) => console.info(`${PREFIX} ${suggestion}`)
|
|
128
|
+
);
|
|
129
|
+
console.groupEnd();
|
|
130
|
+
}
|
|
131
|
+
if (guidance.usingDefaults) {
|
|
132
|
+
console.warn(
|
|
133
|
+
// Changed from console.info to console.warn
|
|
134
|
+
`${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
|
|
138
|
+
console.table(
|
|
139
|
+
guidance.activeCategoriesInfo.map((cat) => ({
|
|
140
|
+
ID: cat.id,
|
|
141
|
+
Nome: cat.name,
|
|
142
|
+
"Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
|
|
143
|
+
"Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
|
|
144
|
+
}))
|
|
145
|
+
);
|
|
146
|
+
console.info(
|
|
147
|
+
`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`
|
|
148
|
+
);
|
|
149
|
+
console.groupEnd();
|
|
150
|
+
}
|
|
151
|
+
function useDeveloperGuidance(config, disableGuidanceProp) {
|
|
152
|
+
const guidance = analyzeDeveloperConfiguration(config);
|
|
153
|
+
const stringifiedConfig = React.useMemo(
|
|
154
|
+
() => JSON.stringify(config),
|
|
155
|
+
[config]
|
|
156
|
+
);
|
|
157
|
+
React.useEffect(() => {
|
|
158
|
+
if (disableGuidanceProp === true) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
logDeveloperGuidance(guidance, disableGuidanceProp);
|
|
162
|
+
}, [guidance, stringifiedConfig, disableGuidanceProp]);
|
|
163
|
+
return guidance;
|
|
164
|
+
}
|
|
165
|
+
var React, DEFAULT_PROJECT_CATEGORIES;
|
|
166
|
+
var init_developerGuidance = __esm({
|
|
167
|
+
"src/utils/developerGuidance.ts"() {
|
|
168
|
+
"use strict";
|
|
169
|
+
React = __toESM(require("react"), 1);
|
|
170
|
+
DEFAULT_PROJECT_CATEGORIES = {
|
|
171
|
+
enabledCategories: ["analytics"]
|
|
172
|
+
// Só analytics além de necessary
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// src/context/CategoriesContext.tsx
|
|
178
|
+
function CategoriesProvider({
|
|
179
|
+
children,
|
|
180
|
+
config,
|
|
181
|
+
// NOVO: configuração completa
|
|
182
|
+
disableDeveloperGuidance
|
|
183
|
+
}) {
|
|
184
|
+
const contextValue = React2.useMemo(() => {
|
|
185
|
+
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
186
|
+
const guidance = analyzeDeveloperConfiguration(config);
|
|
187
|
+
const toggleableCategories = guidance.activeCategoriesInfo.filter(
|
|
188
|
+
(cat) => cat.uiRequired
|
|
189
|
+
);
|
|
190
|
+
return {
|
|
191
|
+
config: finalConfig,
|
|
192
|
+
guidance,
|
|
193
|
+
toggleableCategories,
|
|
194
|
+
allCategories: guidance.activeCategoriesInfo
|
|
195
|
+
};
|
|
196
|
+
}, [config]);
|
|
197
|
+
React2.useEffect(() => {
|
|
198
|
+
logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
|
|
199
|
+
}, [contextValue.guidance, disableDeveloperGuidance]);
|
|
200
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CategoriesContext.Provider, { value: contextValue, children });
|
|
201
|
+
}
|
|
202
|
+
function useCategories() {
|
|
203
|
+
const context = React2.useContext(CategoriesContext);
|
|
204
|
+
if (!context) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
"useCategories deve ser usado dentro de CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return context;
|
|
210
|
+
}
|
|
211
|
+
function useCategoryStatus(categoryId) {
|
|
212
|
+
const { allCategories } = useCategories();
|
|
213
|
+
const category = allCategories.find((cat) => cat.id === categoryId);
|
|
214
|
+
return {
|
|
215
|
+
isActive: !!category,
|
|
216
|
+
isEssential: category?.essential || false,
|
|
217
|
+
needsToggle: category?.uiRequired || false,
|
|
218
|
+
name: category?.name,
|
|
219
|
+
description: category?.description
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
var React2, import_jsx_runtime, CategoriesContext;
|
|
223
|
+
var init_CategoriesContext = __esm({
|
|
224
|
+
"src/context/CategoriesContext.tsx"() {
|
|
225
|
+
"use strict";
|
|
226
|
+
React2 = __toESM(require("react"), 1);
|
|
227
|
+
init_developerGuidance();
|
|
228
|
+
import_jsx_runtime = require("react/jsx-runtime");
|
|
229
|
+
CategoriesContext = React2.createContext(
|
|
230
|
+
null
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
33
235
|
// src/utils/cookieUtils.ts
|
|
34
236
|
function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
35
237
|
if (typeof document === "undefined") return null;
|
|
@@ -70,7 +272,7 @@ function migrateLegacyCookie(legacyData) {
|
|
|
70
272
|
return null;
|
|
71
273
|
}
|
|
72
274
|
}
|
|
73
|
-
function writeConsentCookie(state, source = "banner"
|
|
275
|
+
function writeConsentCookie(state, config, opts, source = "banner") {
|
|
74
276
|
if (typeof document === "undefined") return;
|
|
75
277
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
76
278
|
const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
|
|
@@ -81,7 +283,8 @@ function writeConsentCookie(state, source = "banner", opts) {
|
|
|
81
283
|
consentDate: state.consentDate || now,
|
|
82
284
|
// Preservar data original ou usar atual
|
|
83
285
|
lastUpdate: now,
|
|
84
|
-
source
|
|
286
|
+
source,
|
|
287
|
+
projectConfig: config
|
|
85
288
|
// isModalOpen NÃO é persistido (campo de UI apenas)
|
|
86
289
|
};
|
|
87
290
|
import_js_cookie.default.set(o.name, JSON.stringify(cookieData), {
|
|
@@ -112,6 +315,39 @@ var init_cookieUtils = __esm({
|
|
|
112
315
|
}
|
|
113
316
|
});
|
|
114
317
|
|
|
318
|
+
// src/utils/categoryUtils.ts
|
|
319
|
+
function createProjectPreferences(config, defaultValue = false) {
|
|
320
|
+
const preferences = {
|
|
321
|
+
necessary: true
|
|
322
|
+
// Sempre presente e true (essencial)
|
|
323
|
+
};
|
|
324
|
+
const enabledCategories = config?.enabledCategories || [];
|
|
325
|
+
enabledCategories.forEach((category) => {
|
|
326
|
+
if (category !== "necessary") {
|
|
327
|
+
preferences[category] = defaultValue;
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
return preferences;
|
|
331
|
+
}
|
|
332
|
+
function validateProjectPreferences(preferences, config) {
|
|
333
|
+
const validPreferences = {
|
|
334
|
+
necessary: true
|
|
335
|
+
// Sempre válida
|
|
336
|
+
};
|
|
337
|
+
const enabledCategories = config?.enabledCategories || [];
|
|
338
|
+
enabledCategories.forEach((category) => {
|
|
339
|
+
if (category !== "necessary" && preferences[category] !== void 0) {
|
|
340
|
+
validPreferences[category] = preferences[category];
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
return validPreferences;
|
|
344
|
+
}
|
|
345
|
+
var init_categoryUtils = __esm({
|
|
346
|
+
"src/utils/categoryUtils.ts"() {
|
|
347
|
+
"use strict";
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
|
|
115
351
|
// src/utils/theme.ts
|
|
116
352
|
var import_styles, defaultConsentTheme;
|
|
117
353
|
var init_theme = __esm({
|
|
@@ -186,300 +422,81 @@ var init_theme = __esm({
|
|
|
186
422
|
}
|
|
187
423
|
});
|
|
188
424
|
|
|
189
|
-
// src/
|
|
190
|
-
function
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
425
|
+
// src/context/DesignContext.tsx
|
|
426
|
+
function DesignProvider({
|
|
427
|
+
tokens,
|
|
428
|
+
children
|
|
429
|
+
}) {
|
|
430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DesignContext.Provider, { value: tokens, children });
|
|
431
|
+
}
|
|
432
|
+
function useDesignTokens() {
|
|
433
|
+
return React3.useContext(DesignContext);
|
|
434
|
+
}
|
|
435
|
+
var React3, import_jsx_runtime2, DesignContext;
|
|
436
|
+
var init_DesignContext = __esm({
|
|
437
|
+
"src/context/DesignContext.tsx"() {
|
|
438
|
+
"use strict";
|
|
439
|
+
React3 = __toESM(require("react"), 1);
|
|
440
|
+
import_jsx_runtime2 = require("react/jsx-runtime");
|
|
441
|
+
DesignContext = React3.createContext(void 0);
|
|
202
442
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
// src/components/Branding.tsx
|
|
446
|
+
function Branding({ variant, hidden = false }) {
|
|
447
|
+
if (hidden) return null;
|
|
448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
449
|
+
import_Typography.default,
|
|
450
|
+
{
|
|
451
|
+
variant: "caption",
|
|
452
|
+
sx: (theme) => ({
|
|
453
|
+
...brandingStyles[variant],
|
|
454
|
+
color: theme.palette.text.secondary
|
|
455
|
+
}),
|
|
456
|
+
children: [
|
|
457
|
+
"fornecido por",
|
|
458
|
+
" ",
|
|
459
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
460
|
+
import_Link.default,
|
|
461
|
+
{
|
|
462
|
+
href: "https://www.ledipo.eti.br",
|
|
463
|
+
target: "_blank",
|
|
464
|
+
rel: "noopener noreferrer",
|
|
465
|
+
sx: (theme) => ({
|
|
466
|
+
...linkStyles,
|
|
467
|
+
color: theme.palette.primary.main
|
|
468
|
+
}),
|
|
469
|
+
children: "L\xC9dipO.eti.br"
|
|
470
|
+
}
|
|
471
|
+
)
|
|
472
|
+
]
|
|
232
473
|
}
|
|
233
|
-
};
|
|
234
|
-
enabledCategories.forEach((categoryId) => {
|
|
235
|
-
const categoryInfo = categoryNames[categoryId];
|
|
236
|
-
if (categoryInfo) {
|
|
237
|
-
guidance.activeCategoriesInfo.push({
|
|
238
|
-
id: categoryId,
|
|
239
|
-
name: categoryInfo.name,
|
|
240
|
-
description: categoryInfo.description,
|
|
241
|
-
essential: false,
|
|
242
|
-
uiRequired: true
|
|
243
|
-
// Precisa de toggle na UI
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
const customCategories = finalConfig.customCategories || [];
|
|
248
|
-
customCategories.forEach((category) => {
|
|
249
|
-
guidance.activeCategoriesInfo.push({
|
|
250
|
-
id: category.id,
|
|
251
|
-
name: category.name,
|
|
252
|
-
description: category.description,
|
|
253
|
-
essential: category.essential === true,
|
|
254
|
-
uiRequired: category.essential !== true
|
|
255
|
-
// Apenas não-essenciais precisam toggle
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
const totalToggleable = guidance.activeCategoriesInfo.filter(
|
|
259
|
-
(c) => c.uiRequired
|
|
260
|
-
).length;
|
|
261
|
-
if (totalToggleable === 0) {
|
|
262
|
-
guidance.suggestions.push(
|
|
263
|
-
'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance completo LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.'
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
if (totalToggleable > 5) {
|
|
267
|
-
guidance.warnings.push(
|
|
268
|
-
`${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode ' +
|
|
269
|
-
'prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
const poorDescriptions = customCategories.filter(
|
|
273
|
-
(c) => !c.description || c.description.length < 10
|
|
274
474
|
);
|
|
275
|
-
if (poorDescriptions.length > 0) {
|
|
276
|
-
guidance.warnings.push(
|
|
277
|
-
`Categorias customizadas com descri\xE7\xF5es inadequadas: ${poorDescriptions.map((c) => c.id).join(", ")}. Descri\xE7\xF5es claras s\xE3o obrigat\xF3rias para compliance LGPD.`
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
return guidance;
|
|
281
475
|
}
|
|
282
|
-
|
|
283
|
-
try {
|
|
284
|
-
const isProduction = (
|
|
285
|
-
// 1. NODE_ENV de bundlers (Vite, webpack, etc.)
|
|
286
|
-
typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV === "production" || // 2. Vite/bundler env vars (apenas em ESM)
|
|
287
|
-
typeof globalThis !== "undefined" && typeof globalThis.import !== "undefined" && globalThis.import.meta?.env?.PROD === true || // 3. Flag customizada para desabilitar logs
|
|
288
|
-
typeof globalThis !== "undefined" && globalThis.__LGPD_PRODUCTION__ || // 4. Flag de desenvolvimento desabilitada via window global (legado)
|
|
289
|
-
typeof window !== "undefined" && window.__LGPD_DISABLE_GUIDANCE__ || // 5. Flag de desenvolvimento desabilitada via prop do ConsentProvider (preferencial)
|
|
290
|
-
disableGuidanceProp
|
|
291
|
-
);
|
|
292
|
-
if (isProduction) return;
|
|
293
|
-
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
294
|
-
if (guidance.warnings.length > 0) {
|
|
295
|
-
console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
|
|
296
|
-
guidance.warnings.forEach(
|
|
297
|
-
(warning) => console.warn(`${PREFIX} ${warning}`)
|
|
298
|
-
);
|
|
299
|
-
console.groupEnd();
|
|
300
|
-
}
|
|
301
|
-
if (guidance.suggestions.length > 0) {
|
|
302
|
-
console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
|
|
303
|
-
guidance.suggestions.forEach(
|
|
304
|
-
(suggestion) => console.info(`${PREFIX} ${suggestion}`)
|
|
305
|
-
);
|
|
306
|
-
console.groupEnd();
|
|
307
|
-
}
|
|
308
|
-
if (guidance.usingDefaults) {
|
|
309
|
-
console.info(
|
|
310
|
-
`${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
|
|
314
|
-
console.table(
|
|
315
|
-
guidance.activeCategoriesInfo.map((cat) => ({
|
|
316
|
-
ID: cat.id,
|
|
317
|
-
Nome: cat.name,
|
|
318
|
-
"Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
|
|
319
|
-
"Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
|
|
320
|
-
}))
|
|
321
|
-
);
|
|
322
|
-
console.info(
|
|
323
|
-
`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`
|
|
324
|
-
);
|
|
325
|
-
console.groupEnd();
|
|
326
|
-
} catch (error) {
|
|
327
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
328
|
-
console.warn(
|
|
329
|
-
"[\u{1F36A} LGPD-CONSENT] Sistema de orienta\xE7\xF5es encontrou erro:",
|
|
330
|
-
error
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
function useDeveloperGuidance(config, disableGuidanceProp) {
|
|
336
|
-
const guidance = analyzeDeveloperConfiguration(config);
|
|
337
|
-
const stringifiedConfig = React.useMemo(() => JSON.stringify(config), [config]);
|
|
338
|
-
React.useEffect(() => {
|
|
339
|
-
logDeveloperGuidance(guidance, disableGuidanceProp);
|
|
340
|
-
}, [guidance, stringifiedConfig, disableGuidanceProp]);
|
|
341
|
-
return guidance;
|
|
342
|
-
}
|
|
343
|
-
var React, DEFAULT_PROJECT_CATEGORIES;
|
|
344
|
-
var init_developerGuidance = __esm({
|
|
345
|
-
"src/utils/developerGuidance.ts"() {
|
|
346
|
-
"use strict";
|
|
347
|
-
React = __toESM(require("react"), 1);
|
|
348
|
-
DEFAULT_PROJECT_CATEGORIES = {
|
|
349
|
-
enabledCategories: ["analytics"],
|
|
350
|
-
// Só analytics além de necessary
|
|
351
|
-
customCategories: []
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
// src/context/CategoriesContext.tsx
|
|
357
|
-
function CategoriesProvider({
|
|
358
|
-
children,
|
|
359
|
-
categories,
|
|
360
|
-
// LEGACY: prop antiga (apenas customCategories)
|
|
361
|
-
config
|
|
362
|
-
// NOVO: configuração completa
|
|
363
|
-
}) {
|
|
364
|
-
const contextValue = React2.useMemo(() => {
|
|
365
|
-
let finalConfig;
|
|
366
|
-
if (categories && !config) {
|
|
367
|
-
finalConfig = {
|
|
368
|
-
enabledCategories: DEFAULT_PROJECT_CATEGORIES.enabledCategories,
|
|
369
|
-
customCategories: categories
|
|
370
|
-
};
|
|
371
|
-
} else {
|
|
372
|
-
finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
373
|
-
}
|
|
374
|
-
const guidance = analyzeDeveloperConfiguration(
|
|
375
|
-
config || (categories ? { customCategories: categories } : void 0)
|
|
376
|
-
);
|
|
377
|
-
const toggleableCategories = guidance.activeCategoriesInfo.filter(
|
|
378
|
-
(cat) => cat.uiRequired
|
|
379
|
-
);
|
|
380
|
-
return {
|
|
381
|
-
config: finalConfig,
|
|
382
|
-
guidance,
|
|
383
|
-
toggleableCategories,
|
|
384
|
-
allCategories: guidance.activeCategoriesInfo,
|
|
385
|
-
legacyCategories: categories || []
|
|
386
|
-
};
|
|
387
|
-
}, [config, categories]);
|
|
388
|
-
React2.useEffect(() => {
|
|
389
|
-
logDeveloperGuidance(contextValue.guidance);
|
|
390
|
-
}, [contextValue.guidance]);
|
|
391
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CategoriesContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CategoriesCtx.Provider, { value: contextValue.legacyCategories, children }) });
|
|
392
|
-
}
|
|
393
|
-
function useCategories() {
|
|
394
|
-
const context = React2.useContext(CategoriesContext);
|
|
395
|
-
if (!context) {
|
|
396
|
-
throw new Error(
|
|
397
|
-
"useCategories deve ser usado dentro de CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
|
|
398
|
-
);
|
|
399
|
-
}
|
|
400
|
-
return context;
|
|
401
|
-
}
|
|
402
|
-
function useCategoryStatus(categoryId) {
|
|
403
|
-
const { allCategories } = useCategories();
|
|
404
|
-
const category = allCategories.find((cat) => cat.id === categoryId);
|
|
405
|
-
return {
|
|
406
|
-
isActive: !!category,
|
|
407
|
-
isEssential: category?.essential || false,
|
|
408
|
-
needsToggle: category?.uiRequired || false,
|
|
409
|
-
name: category?.name,
|
|
410
|
-
description: category?.description
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
function useCustomCategories() {
|
|
414
|
-
return React2.useContext(CategoriesCtx);
|
|
415
|
-
}
|
|
416
|
-
var React2, import_jsx_runtime, CategoriesContext, CategoriesCtx;
|
|
417
|
-
var init_CategoriesContext = __esm({
|
|
418
|
-
"src/context/CategoriesContext.tsx"() {
|
|
419
|
-
"use strict";
|
|
420
|
-
React2 = __toESM(require("react"), 1);
|
|
421
|
-
init_developerGuidance();
|
|
422
|
-
import_jsx_runtime = require("react/jsx-runtime");
|
|
423
|
-
CategoriesContext = React2.createContext(
|
|
424
|
-
null
|
|
425
|
-
);
|
|
426
|
-
CategoriesCtx = React2.createContext([]);
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
// src/components/Branding.tsx
|
|
431
|
-
function Branding({ variant, hidden = false }) {
|
|
432
|
-
if (hidden) return null;
|
|
433
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
434
|
-
import_Typography.default,
|
|
435
|
-
{
|
|
436
|
-
variant: "caption",
|
|
437
|
-
sx: (theme) => ({
|
|
438
|
-
...brandingStyles[variant],
|
|
439
|
-
color: theme.palette.text.secondary
|
|
440
|
-
}),
|
|
441
|
-
children: [
|
|
442
|
-
"fornecido por",
|
|
443
|
-
" ",
|
|
444
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
445
|
-
import_Link.default,
|
|
446
|
-
{
|
|
447
|
-
href: "https://www.ledipo.eti.br",
|
|
448
|
-
target: "_blank",
|
|
449
|
-
rel: "noopener noreferrer",
|
|
450
|
-
sx: (theme) => ({
|
|
451
|
-
...linkStyles,
|
|
452
|
-
color: theme.palette.primary.main
|
|
453
|
-
}),
|
|
454
|
-
children: "L\xC9dipO.eti.br"
|
|
455
|
-
}
|
|
456
|
-
)
|
|
457
|
-
]
|
|
458
|
-
}
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
var import_Link, import_Typography, import_jsx_runtime2, brandingStyles, linkStyles;
|
|
476
|
+
var import_Link, import_Typography, import_jsx_runtime3, brandingStyles, linkStyles;
|
|
462
477
|
var init_Branding = __esm({
|
|
463
478
|
"src/components/Branding.tsx"() {
|
|
464
479
|
"use strict";
|
|
465
480
|
import_Link = __toESM(require("@mui/material/Link"), 1);
|
|
466
481
|
import_Typography = __toESM(require("@mui/material/Typography"), 1);
|
|
467
|
-
|
|
482
|
+
import_jsx_runtime3 = require("react/jsx-runtime");
|
|
468
483
|
brandingStyles = {
|
|
469
484
|
banner: {
|
|
470
485
|
fontSize: "0.65rem",
|
|
471
|
-
textAlign: "
|
|
486
|
+
textAlign: "right",
|
|
472
487
|
mt: 1,
|
|
473
488
|
opacity: 0.7,
|
|
474
|
-
fontStyle: "italic"
|
|
489
|
+
fontStyle: "italic",
|
|
490
|
+
width: "100%"
|
|
475
491
|
},
|
|
476
492
|
modal: {
|
|
477
493
|
fontSize: "0.65rem",
|
|
478
|
-
textAlign: "
|
|
494
|
+
textAlign: "right",
|
|
479
495
|
px: 3,
|
|
480
496
|
pb: 1,
|
|
481
497
|
opacity: 0.7,
|
|
482
|
-
fontStyle: "italic"
|
|
498
|
+
fontStyle: "italic",
|
|
499
|
+
width: "100%"
|
|
483
500
|
}
|
|
484
501
|
};
|
|
485
502
|
linkStyles = {
|
|
@@ -492,123 +509,218 @@ var init_Branding = __esm({
|
|
|
492
509
|
}
|
|
493
510
|
});
|
|
494
511
|
|
|
495
|
-
// src/components/
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
512
|
+
// src/components/CookieBanner.tsx
|
|
513
|
+
function CookieBanner({
|
|
514
|
+
policyLinkUrl,
|
|
515
|
+
debug,
|
|
516
|
+
blocking = true,
|
|
517
|
+
hideBranding = false,
|
|
518
|
+
SnackbarProps,
|
|
519
|
+
PaperProps
|
|
503
520
|
}) {
|
|
504
|
-
const {
|
|
521
|
+
const { consented, acceptAll, rejectAll, openPreferences } = useConsent();
|
|
505
522
|
const texts = useConsentTexts();
|
|
506
|
-
const
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const syncedPrefs = { necessary: true };
|
|
519
|
-
toggleableCategories.forEach((category) => {
|
|
520
|
-
syncedPrefs[category.id] = preferences[category.id] ?? false;
|
|
521
|
-
});
|
|
522
|
-
setTempPreferences(syncedPrefs);
|
|
523
|
-
}
|
|
524
|
-
}, [isModalOpen, preferences, toggleableCategories]);
|
|
525
|
-
const open = DialogProps2?.open ?? isModalOpen ?? false;
|
|
526
|
-
const handleSave = () => {
|
|
527
|
-
setPreferences(tempPreferences);
|
|
523
|
+
const isHydrated = useConsentHydration();
|
|
524
|
+
const designTokens = useDesignTokens();
|
|
525
|
+
const open = debug ? true : isHydrated && !consented;
|
|
526
|
+
if (!open) return null;
|
|
527
|
+
const bannerStyle = {
|
|
528
|
+
p: designTokens?.spacing?.padding?.banner ?? 2,
|
|
529
|
+
maxWidth: 720,
|
|
530
|
+
mx: "auto",
|
|
531
|
+
backgroundColor: designTokens?.colors?.background,
|
|
532
|
+
color: designTokens?.colors?.text,
|
|
533
|
+
borderRadius: designTokens?.spacing?.borderRadius?.banner,
|
|
534
|
+
fontFamily: designTokens?.typography?.fontFamily
|
|
528
535
|
};
|
|
529
|
-
const
|
|
530
|
-
|
|
531
|
-
|
|
536
|
+
const bannerContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Paper.default, { elevation: 3, sx: bannerStyle, ...PaperProps, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Stack.default, { spacing: 1, children: [
|
|
537
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
538
|
+
import_Typography2.default,
|
|
539
|
+
{
|
|
540
|
+
variant: "body2",
|
|
541
|
+
sx: { fontSize: designTokens?.typography?.fontSize?.banner },
|
|
542
|
+
children: [
|
|
543
|
+
texts.bannerMessage,
|
|
544
|
+
" ",
|
|
545
|
+
policyLinkUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
546
|
+
import_Link2.default,
|
|
547
|
+
{
|
|
548
|
+
href: policyLinkUrl,
|
|
549
|
+
underline: "hover",
|
|
550
|
+
target: "_blank",
|
|
551
|
+
rel: "noopener noreferrer",
|
|
552
|
+
sx: { color: designTokens?.colors?.primary },
|
|
553
|
+
children: texts.policyLink ?? "Saiba mais"
|
|
554
|
+
}
|
|
555
|
+
)
|
|
556
|
+
]
|
|
557
|
+
}
|
|
558
|
+
),
|
|
559
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
560
|
+
import_Stack.default,
|
|
561
|
+
{
|
|
562
|
+
direction: { xs: "column", sm: "row" },
|
|
563
|
+
spacing: 1,
|
|
564
|
+
justifyContent: "flex-end",
|
|
565
|
+
children: [
|
|
566
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
567
|
+
import_Button.default,
|
|
568
|
+
{
|
|
569
|
+
variant: "outlined",
|
|
570
|
+
onClick: rejectAll,
|
|
571
|
+
sx: { color: designTokens?.colors?.secondary },
|
|
572
|
+
children: texts.declineAll
|
|
573
|
+
}
|
|
574
|
+
),
|
|
575
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
576
|
+
import_Button.default,
|
|
577
|
+
{
|
|
578
|
+
variant: "contained",
|
|
579
|
+
onClick: acceptAll,
|
|
580
|
+
sx: { backgroundColor: designTokens?.colors?.primary },
|
|
581
|
+
children: texts.acceptAll
|
|
582
|
+
}
|
|
583
|
+
),
|
|
584
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
585
|
+
import_Button.default,
|
|
586
|
+
{
|
|
587
|
+
variant: "text",
|
|
588
|
+
onClick: openPreferences,
|
|
589
|
+
sx: { color: designTokens?.colors?.text },
|
|
590
|
+
children: texts.preferences
|
|
591
|
+
}
|
|
592
|
+
)
|
|
593
|
+
]
|
|
594
|
+
}
|
|
595
|
+
),
|
|
596
|
+
!hideBranding && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Branding, { variant: "banner" })
|
|
597
|
+
] }) });
|
|
598
|
+
const positionStyle = {
|
|
599
|
+
position: "fixed",
|
|
600
|
+
zIndex: 1300,
|
|
601
|
+
...designTokens?.layout?.position === "top" ? { top: 0 } : { bottom: 0 },
|
|
602
|
+
left: 0,
|
|
603
|
+
right: 0,
|
|
604
|
+
width: designTokens?.layout?.width?.desktop ?? "100%",
|
|
605
|
+
p: 2
|
|
532
606
|
};
|
|
533
|
-
|
|
534
|
-
|
|
607
|
+
if (blocking) {
|
|
608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
609
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
610
|
+
import_Box.default,
|
|
611
|
+
{
|
|
612
|
+
sx: {
|
|
613
|
+
position: "fixed",
|
|
614
|
+
top: 0,
|
|
615
|
+
left: 0,
|
|
616
|
+
right: 0,
|
|
617
|
+
bottom: 0,
|
|
618
|
+
backgroundColor: designTokens?.layout?.backdrop ? "rgba(0, 0, 0, 0.5)" : "transparent",
|
|
619
|
+
zIndex: 1299
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
),
|
|
623
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Box.default, { sx: positionStyle, children: bannerContent })
|
|
624
|
+
] });
|
|
625
|
+
}
|
|
626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
627
|
+
import_Snackbar.default,
|
|
535
628
|
{
|
|
536
|
-
"aria-labelledby": "cookie-pref-title",
|
|
537
629
|
open,
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_FormGroup.default, { children: [
|
|
545
|
-
toggleableCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
546
|
-
import_FormControlLabel.default,
|
|
547
|
-
{
|
|
548
|
-
control: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
549
|
-
import_Switch.default,
|
|
550
|
-
{
|
|
551
|
-
checked: tempPreferences[category.id] ?? false,
|
|
552
|
-
onChange: (e) => setTempPreferences((prev) => ({
|
|
553
|
-
...prev,
|
|
554
|
-
[category.id]: e.target.checked
|
|
555
|
-
}))
|
|
556
|
-
}
|
|
557
|
-
),
|
|
558
|
-
label: `${category.name} - ${category.description}`
|
|
559
|
-
},
|
|
560
|
-
category.id
|
|
561
|
-
)),
|
|
562
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
563
|
-
import_FormControlLabel.default,
|
|
564
|
-
{
|
|
565
|
-
control: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_Switch.default, { checked: true, disabled: true }),
|
|
566
|
-
label: texts.necessaryAlwaysOn
|
|
567
|
-
}
|
|
568
|
-
)
|
|
569
|
-
] })
|
|
570
|
-
] }),
|
|
571
|
-
!hideBranding && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Branding, { variant: "modal" }),
|
|
572
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_DialogActions.default, { children: [
|
|
573
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_Button.default, { variant: "outlined", onClick: handleCancel, children: "Cancelar" }),
|
|
574
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_Button.default, { variant: "contained", onClick: handleSave, children: texts.save })
|
|
575
|
-
] })
|
|
576
|
-
]
|
|
630
|
+
anchorOrigin: {
|
|
631
|
+
vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
|
|
632
|
+
horizontal: "center"
|
|
633
|
+
},
|
|
634
|
+
...SnackbarProps,
|
|
635
|
+
children: bannerContent
|
|
577
636
|
}
|
|
578
637
|
);
|
|
579
638
|
}
|
|
580
|
-
var import_Button,
|
|
581
|
-
var
|
|
582
|
-
"src/components/
|
|
639
|
+
var import_Button, import_Box, import_Paper, import_Snackbar, import_Stack, import_Typography2, import_Link2, import_jsx_runtime4;
|
|
640
|
+
var init_CookieBanner = __esm({
|
|
641
|
+
"src/components/CookieBanner.tsx"() {
|
|
583
642
|
"use strict";
|
|
584
643
|
import_Button = __toESM(require("@mui/material/Button"), 1);
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
import_FormControlLabel = __toESM(require("@mui/material/FormControlLabel"), 1);
|
|
590
|
-
import_FormGroup = __toESM(require("@mui/material/FormGroup"), 1);
|
|
591
|
-
import_Switch = __toESM(require("@mui/material/Switch"), 1);
|
|
644
|
+
import_Box = __toESM(require("@mui/material/Box"), 1);
|
|
645
|
+
import_Paper = __toESM(require("@mui/material/Paper"), 1);
|
|
646
|
+
import_Snackbar = __toESM(require("@mui/material/Snackbar"), 1);
|
|
647
|
+
import_Stack = __toESM(require("@mui/material/Stack"), 1);
|
|
592
648
|
import_Typography2 = __toESM(require("@mui/material/Typography"), 1);
|
|
593
|
-
|
|
594
|
-
|
|
649
|
+
import_Link2 = __toESM(require("@mui/material/Link"), 1);
|
|
650
|
+
init_useConsent();
|
|
651
|
+
init_DesignContext();
|
|
652
|
+
init_Branding();
|
|
653
|
+
import_jsx_runtime4 = require("react/jsx-runtime");
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
// src/components/FloatingPreferencesButton.tsx
|
|
658
|
+
function FloatingPreferencesButton({
|
|
659
|
+
position = "bottom-right",
|
|
660
|
+
offset = 24,
|
|
661
|
+
icon = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_CookieOutlined.default, {}),
|
|
662
|
+
tooltip,
|
|
663
|
+
FabProps,
|
|
664
|
+
hideWhenConsented = false
|
|
665
|
+
}) {
|
|
666
|
+
const { openPreferences, consented } = useConsent();
|
|
667
|
+
const theme = (0, import_styles2.useTheme)();
|
|
668
|
+
if (hideWhenConsented && consented) {
|
|
669
|
+
return null;
|
|
670
|
+
}
|
|
671
|
+
const tooltipText = tooltip ?? "Gerenciar Prefer\xEAncias de Cookies";
|
|
672
|
+
const getPosition = () => {
|
|
673
|
+
const styles = {
|
|
674
|
+
position: "fixed",
|
|
675
|
+
zIndex: 1200
|
|
676
|
+
};
|
|
677
|
+
switch (position) {
|
|
678
|
+
case "bottom-left":
|
|
679
|
+
return { ...styles, bottom: offset, left: offset };
|
|
680
|
+
case "bottom-right":
|
|
681
|
+
return { ...styles, bottom: offset, right: offset };
|
|
682
|
+
case "top-left":
|
|
683
|
+
return { ...styles, top: offset, left: offset };
|
|
684
|
+
case "top-right":
|
|
685
|
+
return { ...styles, top: offset, right: offset };
|
|
686
|
+
default:
|
|
687
|
+
return { ...styles, bottom: offset, right: offset };
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Tooltip.default, { title: tooltipText, placement: "top", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
691
|
+
import_Fab.default,
|
|
692
|
+
{
|
|
693
|
+
size: "medium",
|
|
694
|
+
color: "primary",
|
|
695
|
+
onClick: openPreferences,
|
|
696
|
+
sx: {
|
|
697
|
+
...getPosition(),
|
|
698
|
+
backgroundColor: theme.palette.primary.main,
|
|
699
|
+
"&:hover": {
|
|
700
|
+
backgroundColor: theme.palette.primary.dark
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
"aria-label": tooltipText,
|
|
704
|
+
...FabProps,
|
|
705
|
+
children: icon
|
|
706
|
+
}
|
|
707
|
+
) });
|
|
708
|
+
}
|
|
709
|
+
var import_CookieOutlined, import_Fab, import_Tooltip, import_styles2, import_jsx_runtime5;
|
|
710
|
+
var init_FloatingPreferencesButton = __esm({
|
|
711
|
+
"src/components/FloatingPreferencesButton.tsx"() {
|
|
712
|
+
"use strict";
|
|
713
|
+
import_CookieOutlined = __toESM(require("@mui/icons-material/CookieOutlined"), 1);
|
|
714
|
+
import_Fab = __toESM(require("@mui/material/Fab"), 1);
|
|
715
|
+
import_Tooltip = __toESM(require("@mui/material/Tooltip"), 1);
|
|
716
|
+
import_styles2 = require("@mui/material/styles");
|
|
595
717
|
init_useConsent();
|
|
596
|
-
|
|
597
|
-
import_jsx_runtime3 = require("react/jsx-runtime");
|
|
718
|
+
import_jsx_runtime5 = require("react/jsx-runtime");
|
|
598
719
|
}
|
|
599
720
|
});
|
|
600
721
|
|
|
601
722
|
// src/context/ConsentContext.tsx
|
|
602
|
-
function
|
|
603
|
-
const prefs = { ...DEFAULT_PREFERENCES };
|
|
604
|
-
if (customCategories) {
|
|
605
|
-
customCategories.forEach((category) => {
|
|
606
|
-
prefs[category.id] = category.essential === true;
|
|
607
|
-
});
|
|
608
|
-
}
|
|
609
|
-
return prefs;
|
|
610
|
-
}
|
|
611
|
-
function createFullConsentState(consented, preferences, source, isModalOpen = false, existingState) {
|
|
723
|
+
function createFullConsentState(consented, preferences, source, projectConfig, isModalOpen = false, existingState) {
|
|
612
724
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
613
725
|
return {
|
|
614
726
|
version: "1.0",
|
|
@@ -617,28 +729,33 @@ function createFullConsentState(consented, preferences, source, isModalOpen = fa
|
|
|
617
729
|
consentDate: existingState?.consentDate || now,
|
|
618
730
|
lastUpdate: now,
|
|
619
731
|
source,
|
|
732
|
+
projectConfig,
|
|
620
733
|
isModalOpen
|
|
621
734
|
};
|
|
622
735
|
}
|
|
623
736
|
function reducer(state, action) {
|
|
624
737
|
switch (action.type) {
|
|
625
738
|
case "ACCEPT_ALL": {
|
|
626
|
-
const prefs =
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
739
|
+
const prefs = createProjectPreferences(action.config, true);
|
|
740
|
+
return createFullConsentState(
|
|
741
|
+
true,
|
|
742
|
+
prefs,
|
|
743
|
+
"banner",
|
|
744
|
+
action.config,
|
|
745
|
+
false,
|
|
746
|
+
state
|
|
747
|
+
);
|
|
631
748
|
}
|
|
632
749
|
case "REJECT_ALL": {
|
|
633
|
-
const prefs =
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
750
|
+
const prefs = createProjectPreferences(action.config, false);
|
|
751
|
+
return createFullConsentState(
|
|
752
|
+
true,
|
|
753
|
+
prefs,
|
|
754
|
+
"banner",
|
|
755
|
+
action.config,
|
|
756
|
+
false,
|
|
757
|
+
state
|
|
758
|
+
);
|
|
642
759
|
}
|
|
643
760
|
case "SET_CATEGORY":
|
|
644
761
|
return {
|
|
@@ -654,6 +771,7 @@ function reducer(state, action) {
|
|
|
654
771
|
true,
|
|
655
772
|
action.preferences,
|
|
656
773
|
"modal",
|
|
774
|
+
action.config,
|
|
657
775
|
false,
|
|
658
776
|
state
|
|
659
777
|
);
|
|
@@ -664,20 +782,30 @@ function reducer(state, action) {
|
|
|
664
782
|
true,
|
|
665
783
|
state.preferences,
|
|
666
784
|
"modal",
|
|
785
|
+
action.config,
|
|
667
786
|
false,
|
|
668
787
|
state
|
|
669
788
|
);
|
|
670
789
|
case "RESET": {
|
|
671
790
|
return createFullConsentState(
|
|
672
791
|
false,
|
|
673
|
-
|
|
792
|
+
createProjectPreferences(action.config),
|
|
674
793
|
"programmatic",
|
|
794
|
+
action.config,
|
|
675
795
|
false
|
|
676
796
|
);
|
|
677
797
|
}
|
|
678
|
-
case "HYDRATE":
|
|
679
|
-
|
|
680
|
-
|
|
798
|
+
case "HYDRATE": {
|
|
799
|
+
const validatedPreferences = validateProjectPreferences(
|
|
800
|
+
action.state.preferences,
|
|
801
|
+
action.config
|
|
802
|
+
);
|
|
803
|
+
return {
|
|
804
|
+
...action.state,
|
|
805
|
+
preferences: validatedPreferences,
|
|
806
|
+
isModalOpen: false
|
|
807
|
+
};
|
|
808
|
+
}
|
|
681
809
|
default:
|
|
682
810
|
return state;
|
|
683
811
|
}
|
|
@@ -685,96 +813,98 @@ function reducer(state, action) {
|
|
|
685
813
|
function ConsentProvider({
|
|
686
814
|
initialState,
|
|
687
815
|
categories,
|
|
688
|
-
//
|
|
816
|
+
// Nova prop para configuração de categorias
|
|
689
817
|
texts: textsProp,
|
|
690
818
|
theme,
|
|
691
|
-
|
|
692
|
-
// LEGACY: compatibilidade
|
|
819
|
+
designTokens,
|
|
693
820
|
scriptIntegrations,
|
|
694
821
|
// eslint-disable-line no-unused-vars
|
|
695
822
|
PreferencesModalComponent,
|
|
696
823
|
preferencesModalProps = {},
|
|
697
|
-
|
|
824
|
+
CookieBannerComponent,
|
|
825
|
+
cookieBannerProps = {},
|
|
826
|
+
FloatingPreferencesButtonComponent,
|
|
827
|
+
floatingPreferencesButtonProps = {},
|
|
828
|
+
disableFloatingPreferencesButton = false,
|
|
698
829
|
hideBranding = false,
|
|
699
830
|
onConsentGiven,
|
|
700
831
|
onPreferencesSaved,
|
|
701
832
|
cookie: cookieOpts,
|
|
702
833
|
disableDeveloperGuidance,
|
|
703
|
-
// NOVO: desabilita avisos de dev
|
|
704
834
|
children
|
|
705
835
|
}) {
|
|
706
|
-
const texts =
|
|
836
|
+
const texts = React4.useMemo(
|
|
707
837
|
() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }),
|
|
708
838
|
[textsProp]
|
|
709
839
|
);
|
|
710
|
-
const cookie =
|
|
840
|
+
const cookie = React4.useMemo(
|
|
711
841
|
() => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
|
|
712
842
|
[cookieOpts]
|
|
713
843
|
);
|
|
714
|
-
const appliedTheme =
|
|
844
|
+
const appliedTheme = React4.useMemo(
|
|
715
845
|
() => theme || defaultConsentTheme,
|
|
716
846
|
[theme]
|
|
717
847
|
);
|
|
718
|
-
const finalCategoriesConfig =
|
|
848
|
+
const finalCategoriesConfig = React4.useMemo(() => {
|
|
719
849
|
if (categories) return categories;
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
enabledCategories: ["analytics"],
|
|
723
|
-
// padrão quando usando API antiga
|
|
724
|
-
customCategories
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
|
-
return void 0;
|
|
728
|
-
}, [categories, customCategories]);
|
|
850
|
+
return DEFAULT_PROJECT_CATEGORIES;
|
|
851
|
+
}, [categories]);
|
|
729
852
|
useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance);
|
|
730
|
-
const boot =
|
|
853
|
+
const boot = React4.useMemo(() => {
|
|
731
854
|
if (initialState) return { ...initialState, isModalOpen: false };
|
|
732
855
|
return createFullConsentState(
|
|
733
856
|
false,
|
|
734
|
-
|
|
857
|
+
createProjectPreferences(finalCategoriesConfig),
|
|
735
858
|
"banner",
|
|
859
|
+
finalCategoriesConfig,
|
|
736
860
|
false
|
|
737
861
|
);
|
|
738
|
-
}, [initialState,
|
|
739
|
-
const [state, dispatch] =
|
|
740
|
-
const [isHydrated, setIsHydrated] =
|
|
741
|
-
|
|
862
|
+
}, [initialState, finalCategoriesConfig]);
|
|
863
|
+
const [state, dispatch] = React4.useReducer(reducer, boot);
|
|
864
|
+
const [isHydrated, setIsHydrated] = React4.useState(false);
|
|
865
|
+
React4.useEffect(() => {
|
|
742
866
|
if (!initialState) {
|
|
743
867
|
const saved = readConsentCookie(cookie.name);
|
|
744
868
|
if (saved?.consented) {
|
|
745
|
-
|
|
746
|
-
|
|
869
|
+
dispatch({
|
|
870
|
+
type: "HYDRATE",
|
|
871
|
+
state: saved,
|
|
872
|
+
config: finalCategoriesConfig
|
|
873
|
+
});
|
|
747
874
|
}
|
|
748
875
|
}
|
|
749
876
|
setIsHydrated(true);
|
|
750
|
-
}, [cookie.name, initialState]);
|
|
751
|
-
|
|
752
|
-
if (state.consented)
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
877
|
+
}, [cookie.name, initialState, finalCategoriesConfig]);
|
|
878
|
+
React4.useEffect(() => {
|
|
879
|
+
if (state.consented)
|
|
880
|
+
writeConsentCookie(state, finalCategoriesConfig, cookie);
|
|
881
|
+
}, [state, cookie, finalCategoriesConfig]);
|
|
882
|
+
const prevConsented = React4.useRef(state.consented);
|
|
883
|
+
React4.useEffect(() => {
|
|
756
884
|
if (!prevConsented.current && state.consented && onConsentGiven) {
|
|
757
885
|
setTimeout(() => onConsentGiven(state), 150);
|
|
758
886
|
}
|
|
759
887
|
prevConsented.current = state.consented;
|
|
760
888
|
}, [state, onConsentGiven]);
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
setTimeout(() => onPreferencesSaved(state.preferences), 150);
|
|
765
|
-
prevPrefs.current = state.preferences;
|
|
766
|
-
}
|
|
767
|
-
}, [state, onPreferencesSaved]);
|
|
768
|
-
const api = React3.useMemo(() => {
|
|
769
|
-
const acceptAll = () => dispatch({ type: "ACCEPT_ALL", customCategories });
|
|
770
|
-
const rejectAll = () => dispatch({ type: "REJECT_ALL", customCategories });
|
|
889
|
+
const api = React4.useMemo(() => {
|
|
890
|
+
const acceptAll = () => dispatch({ type: "ACCEPT_ALL", config: finalCategoriesConfig });
|
|
891
|
+
const rejectAll = () => dispatch({ type: "REJECT_ALL", config: finalCategoriesConfig });
|
|
771
892
|
const setPreference = (category, value) => dispatch({ type: "SET_CATEGORY", category, value });
|
|
772
|
-
const setPreferences = (preferences) =>
|
|
893
|
+
const setPreferences = (preferences) => {
|
|
894
|
+
dispatch({
|
|
895
|
+
type: "SET_PREFERENCES",
|
|
896
|
+
preferences,
|
|
897
|
+
config: finalCategoriesConfig
|
|
898
|
+
});
|
|
899
|
+
if (onPreferencesSaved) {
|
|
900
|
+
setTimeout(() => onPreferencesSaved(preferences), 150);
|
|
901
|
+
}
|
|
902
|
+
};
|
|
773
903
|
const openPreferences = () => dispatch({ type: "OPEN_MODAL" });
|
|
774
|
-
const closePreferences = () => dispatch({ type: "CLOSE_MODAL" });
|
|
904
|
+
const closePreferences = () => dispatch({ type: "CLOSE_MODAL", config: finalCategoriesConfig });
|
|
775
905
|
const resetConsent = () => {
|
|
776
906
|
removeConsentCookie(cookie);
|
|
777
|
-
dispatch({ type: "RESET",
|
|
907
|
+
dispatch({ type: "RESET", config: finalCategoriesConfig });
|
|
778
908
|
};
|
|
779
909
|
return {
|
|
780
910
|
consented: !!state.consented,
|
|
@@ -788,58 +918,87 @@ function ConsentProvider({
|
|
|
788
918
|
closePreferences,
|
|
789
919
|
resetConsent
|
|
790
920
|
};
|
|
791
|
-
}, [state, cookie,
|
|
792
|
-
return /* @__PURE__ */ (0,
|
|
921
|
+
}, [state, cookie, finalCategoriesConfig, onPreferencesSaved]);
|
|
922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_styles3.ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StateCtx.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TextsCtx.Provider, { value: texts, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(HydrationCtx.Provider, { value: isHydrated, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DesignProvider, { tokens: designTokens, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
793
923
|
CategoriesProvider,
|
|
794
924
|
{
|
|
795
925
|
config: finalCategoriesConfig,
|
|
796
|
-
|
|
926
|
+
disableDeveloperGuidance,
|
|
797
927
|
children: [
|
|
798
928
|
children,
|
|
799
|
-
|
|
929
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(React4.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
930
|
+
PreferencesModalComponent,
|
|
931
|
+
{
|
|
932
|
+
preferences: api.preferences,
|
|
933
|
+
setPreferences: api.setPreferences,
|
|
934
|
+
closePreferences: api.closePreferences,
|
|
935
|
+
isModalOpen: api.isModalOpen,
|
|
936
|
+
texts,
|
|
937
|
+
...preferencesModalProps
|
|
938
|
+
}
|
|
939
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PreferencesModal, { hideBranding }) }),
|
|
940
|
+
!state.consented && isHydrated && (CookieBannerComponent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
941
|
+
CookieBannerComponent,
|
|
942
|
+
{
|
|
943
|
+
consented: api.consented,
|
|
944
|
+
acceptAll: api.acceptAll,
|
|
945
|
+
rejectAll: api.rejectAll,
|
|
946
|
+
openPreferences: api.openPreferences,
|
|
947
|
+
texts,
|
|
948
|
+
...cookieBannerProps
|
|
949
|
+
}
|
|
950
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CookieBanner, {})),
|
|
951
|
+
state.consented && !disableFloatingPreferencesButton && (FloatingPreferencesButtonComponent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
952
|
+
FloatingPreferencesButtonComponent,
|
|
953
|
+
{
|
|
954
|
+
openPreferences: api.openPreferences,
|
|
955
|
+
consented: api.consented,
|
|
956
|
+
...floatingPreferencesButtonProps
|
|
957
|
+
}
|
|
958
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FloatingPreferencesButton, {}))
|
|
800
959
|
]
|
|
801
960
|
}
|
|
802
|
-
) }) }) }) }) });
|
|
961
|
+
) }) }) }) }) }) });
|
|
803
962
|
}
|
|
804
963
|
function useConsentStateInternal() {
|
|
805
|
-
const ctx =
|
|
964
|
+
const ctx = React4.useContext(StateCtx);
|
|
806
965
|
if (!ctx)
|
|
807
966
|
throw new Error("useConsentState must be used within ConsentProvider");
|
|
808
967
|
return ctx;
|
|
809
968
|
}
|
|
810
969
|
function useConsentActionsInternal() {
|
|
811
|
-
const ctx =
|
|
970
|
+
const ctx = React4.useContext(ActionsCtx);
|
|
812
971
|
if (!ctx)
|
|
813
972
|
throw new Error("useConsentActions must be used within ConsentProvider");
|
|
814
973
|
return ctx;
|
|
815
974
|
}
|
|
816
975
|
function useConsentTextsInternal() {
|
|
817
|
-
const ctx =
|
|
976
|
+
const ctx = React4.useContext(TextsCtx);
|
|
818
977
|
return ctx;
|
|
819
978
|
}
|
|
820
979
|
function useConsentHydrationInternal() {
|
|
821
|
-
return
|
|
980
|
+
return React4.useContext(HydrationCtx);
|
|
822
981
|
}
|
|
823
|
-
var
|
|
982
|
+
var React4, import_styles3, import_jsx_runtime6, PreferencesModal, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx;
|
|
824
983
|
var init_ConsentContext = __esm({
|
|
825
984
|
"src/context/ConsentContext.tsx"() {
|
|
826
985
|
"use strict";
|
|
827
|
-
|
|
828
|
-
|
|
986
|
+
React4 = __toESM(require("react"), 1);
|
|
987
|
+
import_styles3 = require("@mui/material/styles");
|
|
829
988
|
init_cookieUtils();
|
|
989
|
+
init_categoryUtils();
|
|
830
990
|
init_theme();
|
|
831
991
|
init_CategoriesContext();
|
|
992
|
+
init_DesignContext();
|
|
832
993
|
init_developerGuidance();
|
|
833
|
-
|
|
834
|
-
|
|
994
|
+
init_CookieBanner();
|
|
995
|
+
init_FloatingPreferencesButton();
|
|
996
|
+
import_jsx_runtime6 = require("react/jsx-runtime");
|
|
997
|
+
PreferencesModal = React4.lazy(
|
|
835
998
|
() => Promise.resolve().then(() => (init_PreferencesModal(), PreferencesModal_exports)).then((m) => ({
|
|
836
999
|
default: m.PreferencesModal
|
|
837
1000
|
}))
|
|
838
1001
|
);
|
|
839
|
-
DEFAULT_PREFERENCES = {
|
|
840
|
-
necessary: true
|
|
841
|
-
// Sempre ativo (essencial)
|
|
842
|
-
};
|
|
843
1002
|
DEFAULT_TEXTS = {
|
|
844
1003
|
// Textos básicos
|
|
845
1004
|
bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
|
|
@@ -869,10 +1028,10 @@ var init_ConsentContext = __esm({
|
|
|
869
1028
|
transferCountries: void 0
|
|
870
1029
|
// Exibido se definido
|
|
871
1030
|
};
|
|
872
|
-
StateCtx =
|
|
873
|
-
ActionsCtx =
|
|
874
|
-
TextsCtx =
|
|
875
|
-
HydrationCtx =
|
|
1031
|
+
StateCtx = React4.createContext(null);
|
|
1032
|
+
ActionsCtx = React4.createContext(null);
|
|
1033
|
+
TextsCtx = React4.createContext(DEFAULT_TEXTS);
|
|
1034
|
+
HydrationCtx = React4.createContext(false);
|
|
876
1035
|
}
|
|
877
1036
|
});
|
|
878
1037
|
|
|
@@ -906,6 +1065,112 @@ var init_useConsent = __esm({
|
|
|
906
1065
|
}
|
|
907
1066
|
});
|
|
908
1067
|
|
|
1068
|
+
// src/components/PreferencesModal.tsx
|
|
1069
|
+
var PreferencesModal_exports = {};
|
|
1070
|
+
__export(PreferencesModal_exports, {
|
|
1071
|
+
PreferencesModal: () => PreferencesModal2
|
|
1072
|
+
});
|
|
1073
|
+
function PreferencesModal2({
|
|
1074
|
+
DialogProps: DialogProps2,
|
|
1075
|
+
hideBranding = false
|
|
1076
|
+
}) {
|
|
1077
|
+
const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
|
|
1078
|
+
const texts = useConsentTexts();
|
|
1079
|
+
const { toggleableCategories } = useCategories();
|
|
1080
|
+
const [tempPreferences, setTempPreferences] = (0, import_react.useState)(
|
|
1081
|
+
() => {
|
|
1082
|
+
const initialPrefs = { necessary: true };
|
|
1083
|
+
toggleableCategories.forEach((category) => {
|
|
1084
|
+
initialPrefs[category.id] = preferences[category.id] ?? false;
|
|
1085
|
+
});
|
|
1086
|
+
return initialPrefs;
|
|
1087
|
+
}
|
|
1088
|
+
);
|
|
1089
|
+
(0, import_react.useEffect)(() => {
|
|
1090
|
+
if (isModalOpen) {
|
|
1091
|
+
const syncedPrefs = { necessary: true };
|
|
1092
|
+
toggleableCategories.forEach((category) => {
|
|
1093
|
+
syncedPrefs[category.id] = preferences[category.id] ?? false;
|
|
1094
|
+
});
|
|
1095
|
+
setTempPreferences(syncedPrefs);
|
|
1096
|
+
}
|
|
1097
|
+
}, [isModalOpen, preferences, toggleableCategories]);
|
|
1098
|
+
const open = DialogProps2?.open ?? isModalOpen ?? false;
|
|
1099
|
+
const handleSave = () => {
|
|
1100
|
+
setPreferences(tempPreferences);
|
|
1101
|
+
};
|
|
1102
|
+
const handleCancel = () => {
|
|
1103
|
+
setTempPreferences(preferences);
|
|
1104
|
+
closePreferences();
|
|
1105
|
+
};
|
|
1106
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1107
|
+
import_Dialog.default,
|
|
1108
|
+
{
|
|
1109
|
+
"aria-labelledby": "cookie-pref-title",
|
|
1110
|
+
open,
|
|
1111
|
+
onClose: handleCancel,
|
|
1112
|
+
...DialogProps2,
|
|
1113
|
+
children: [
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_DialogTitle.default, { id: "cookie-pref-title", children: texts.modalTitle }),
|
|
1115
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogContent.default, { dividers: true, children: [
|
|
1116
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Typography3.default, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
|
|
1117
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_FormGroup.default, { children: [
|
|
1118
|
+
toggleableCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1119
|
+
import_FormControlLabel.default,
|
|
1120
|
+
{
|
|
1121
|
+
control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1122
|
+
import_Switch.default,
|
|
1123
|
+
{
|
|
1124
|
+
checked: tempPreferences[category.id] ?? false,
|
|
1125
|
+
onChange: (e) => setTempPreferences((prev) => ({
|
|
1126
|
+
...prev,
|
|
1127
|
+
[category.id]: e.target.checked
|
|
1128
|
+
}))
|
|
1129
|
+
}
|
|
1130
|
+
),
|
|
1131
|
+
label: `${category.name} - ${category.description}`
|
|
1132
|
+
},
|
|
1133
|
+
category.id
|
|
1134
|
+
)),
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1136
|
+
import_FormControlLabel.default,
|
|
1137
|
+
{
|
|
1138
|
+
control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Switch.default, { checked: true, disabled: true }),
|
|
1139
|
+
label: texts.necessaryAlwaysOn
|
|
1140
|
+
}
|
|
1141
|
+
)
|
|
1142
|
+
] })
|
|
1143
|
+
] }),
|
|
1144
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogActions.default, { children: [
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Button2.default, { variant: "outlined", onClick: handleCancel, children: "Cancelar" }),
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Button2.default, { variant: "contained", onClick: handleSave, children: texts.save })
|
|
1147
|
+
] }),
|
|
1148
|
+
!hideBranding && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Branding, { variant: "modal" })
|
|
1149
|
+
]
|
|
1150
|
+
}
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
var import_Button2, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography3, import_react, import_jsx_runtime7;
|
|
1154
|
+
var init_PreferencesModal = __esm({
|
|
1155
|
+
"src/components/PreferencesModal.tsx"() {
|
|
1156
|
+
"use strict";
|
|
1157
|
+
import_Button2 = __toESM(require("@mui/material/Button"), 1);
|
|
1158
|
+
import_Dialog = __toESM(require("@mui/material/Dialog"), 1);
|
|
1159
|
+
import_DialogActions = __toESM(require("@mui/material/DialogActions"), 1);
|
|
1160
|
+
import_DialogContent = __toESM(require("@mui/material/DialogContent"), 1);
|
|
1161
|
+
import_DialogTitle = __toESM(require("@mui/material/DialogTitle"), 1);
|
|
1162
|
+
import_FormControlLabel = __toESM(require("@mui/material/FormControlLabel"), 1);
|
|
1163
|
+
import_FormGroup = __toESM(require("@mui/material/FormGroup"), 1);
|
|
1164
|
+
import_Switch = __toESM(require("@mui/material/Switch"), 1);
|
|
1165
|
+
import_Typography3 = __toESM(require("@mui/material/Typography"), 1);
|
|
1166
|
+
import_react = require("react");
|
|
1167
|
+
init_CategoriesContext();
|
|
1168
|
+
init_useConsent();
|
|
1169
|
+
init_Branding();
|
|
1170
|
+
import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
|
|
909
1174
|
// src/index.ts
|
|
910
1175
|
var index_exports = {};
|
|
911
1176
|
__export(index_exports, {
|
|
@@ -913,10 +1178,8 @@ __export(index_exports, {
|
|
|
913
1178
|
ConsentGate: () => ConsentGate,
|
|
914
1179
|
ConsentProvider: () => ConsentProvider,
|
|
915
1180
|
ConsentScriptLoader: () => ConsentScriptLoader,
|
|
916
|
-
CookieBanner: () => CookieBanner,
|
|
917
1181
|
DEFAULT_PROJECT_CATEGORIES: () => DEFAULT_PROJECT_CATEGORIES,
|
|
918
|
-
|
|
919
|
-
PreferencesModal: () => PreferencesModal,
|
|
1182
|
+
PreferencesModal: () => PreferencesModal2,
|
|
920
1183
|
analyzeDeveloperConfiguration: () => analyzeDeveloperConfiguration,
|
|
921
1184
|
createGoogleAnalyticsIntegration: () => createGoogleAnalyticsIntegration,
|
|
922
1185
|
createGoogleTagManagerIntegration: () => createGoogleTagManagerIntegration,
|
|
@@ -928,193 +1191,21 @@ __export(index_exports, {
|
|
|
928
1191
|
useConsent: () => useConsent,
|
|
929
1192
|
useConsentHydration: () => useConsentHydration,
|
|
930
1193
|
useConsentScriptLoader: () => useConsentScriptLoader,
|
|
931
|
-
useConsentTexts: () => useConsentTexts
|
|
932
|
-
useCustomCategories: () => useCustomCategories
|
|
1194
|
+
useConsentTexts: () => useConsentTexts
|
|
933
1195
|
});
|
|
934
1196
|
module.exports = __toCommonJS(index_exports);
|
|
935
|
-
|
|
936
|
-
// src/components/CookieBanner.tsx
|
|
937
|
-
var import_Button2 = __toESM(require("@mui/material/Button"), 1);
|
|
938
|
-
var import_Box = __toESM(require("@mui/material/Box"), 1);
|
|
939
|
-
var import_Paper = __toESM(require("@mui/material/Paper"), 1);
|
|
940
|
-
var import_Snackbar = __toESM(require("@mui/material/Snackbar"), 1);
|
|
941
|
-
var import_Stack = __toESM(require("@mui/material/Stack"), 1);
|
|
942
|
-
var import_Typography3 = __toESM(require("@mui/material/Typography"), 1);
|
|
943
|
-
var import_Link2 = __toESM(require("@mui/material/Link"), 1);
|
|
944
|
-
init_useConsent();
|
|
945
|
-
init_Branding();
|
|
946
|
-
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
947
|
-
function CookieBanner({
|
|
948
|
-
policyLinkUrl,
|
|
949
|
-
debug,
|
|
950
|
-
blocking = true,
|
|
951
|
-
// Por padrão, bloqueia até decisão
|
|
952
|
-
hideBranding = false,
|
|
953
|
-
SnackbarProps,
|
|
954
|
-
PaperProps
|
|
955
|
-
}) {
|
|
956
|
-
const { consented, acceptAll, rejectAll, openPreferences } = useConsent();
|
|
957
|
-
const texts = useConsentTexts();
|
|
958
|
-
const isHydrated = useConsentHydration();
|
|
959
|
-
const open = debug ? true : isHydrated && !consented;
|
|
960
|
-
if (!open) return null;
|
|
961
|
-
const bannerContent = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
962
|
-
import_Paper.default,
|
|
963
|
-
{
|
|
964
|
-
elevation: 3,
|
|
965
|
-
sx: { p: 2, maxWidth: 720, mx: "auto" },
|
|
966
|
-
...PaperProps,
|
|
967
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_Stack.default, { spacing: 1, children: [
|
|
968
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_Typography3.default, { variant: "body2", children: [
|
|
969
|
-
texts.bannerMessage,
|
|
970
|
-
" ",
|
|
971
|
-
policyLinkUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
972
|
-
import_Link2.default,
|
|
973
|
-
{
|
|
974
|
-
href: policyLinkUrl,
|
|
975
|
-
underline: "hover",
|
|
976
|
-
target: "_blank",
|
|
977
|
-
rel: "noopener noreferrer",
|
|
978
|
-
children: texts.policyLink ?? "Saiba mais"
|
|
979
|
-
}
|
|
980
|
-
)
|
|
981
|
-
] }),
|
|
982
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
983
|
-
import_Stack.default,
|
|
984
|
-
{
|
|
985
|
-
direction: { xs: "column", sm: "row" },
|
|
986
|
-
spacing: 1,
|
|
987
|
-
justifyContent: "flex-end",
|
|
988
|
-
children: [
|
|
989
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Button2.default, { variant: "outlined", onClick: rejectAll, children: texts.declineAll }),
|
|
990
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Button2.default, { variant: "contained", onClick: acceptAll, children: texts.acceptAll }),
|
|
991
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Button2.default, { variant: "text", onClick: openPreferences, children: texts.preferences })
|
|
992
|
-
]
|
|
993
|
-
}
|
|
994
|
-
),
|
|
995
|
-
!hideBranding && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Branding, { variant: "banner" })
|
|
996
|
-
] })
|
|
997
|
-
}
|
|
998
|
-
);
|
|
999
|
-
if (blocking) {
|
|
1000
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1001
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1002
|
-
import_Box.default,
|
|
1003
|
-
{
|
|
1004
|
-
sx: {
|
|
1005
|
-
position: "fixed",
|
|
1006
|
-
top: 0,
|
|
1007
|
-
left: 0,
|
|
1008
|
-
right: 0,
|
|
1009
|
-
bottom: 0,
|
|
1010
|
-
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
1011
|
-
zIndex: 1299
|
|
1012
|
-
// Abaixo do banner mas acima do conteúdo
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
),
|
|
1016
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1017
|
-
import_Box.default,
|
|
1018
|
-
{
|
|
1019
|
-
sx: {
|
|
1020
|
-
position: "fixed",
|
|
1021
|
-
bottom: 0,
|
|
1022
|
-
left: 0,
|
|
1023
|
-
right: 0,
|
|
1024
|
-
zIndex: 1300,
|
|
1025
|
-
// Acima do overlay
|
|
1026
|
-
p: 2
|
|
1027
|
-
},
|
|
1028
|
-
children: bannerContent
|
|
1029
|
-
}
|
|
1030
|
-
)
|
|
1031
|
-
] });
|
|
1032
|
-
}
|
|
1033
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1034
|
-
import_Snackbar.default,
|
|
1035
|
-
{
|
|
1036
|
-
open,
|
|
1037
|
-
anchorOrigin: { vertical: "bottom", horizontal: "center" },
|
|
1038
|
-
...SnackbarProps,
|
|
1039
|
-
children: bannerContent
|
|
1040
|
-
}
|
|
1041
|
-
);
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
// src/index.ts
|
|
1045
1197
|
init_PreferencesModal();
|
|
1046
|
-
|
|
1047
|
-
// src/components/FloatingPreferencesButton.tsx
|
|
1048
|
-
var import_CookieOutlined = __toESM(require("@mui/icons-material/CookieOutlined"), 1);
|
|
1049
|
-
var import_Fab = __toESM(require("@mui/material/Fab"), 1);
|
|
1050
|
-
var import_Tooltip = __toESM(require("@mui/material/Tooltip"), 1);
|
|
1051
|
-
var import_styles3 = require("@mui/material/styles");
|
|
1052
|
-
init_useConsent();
|
|
1053
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1054
|
-
function FloatingPreferencesButton({
|
|
1055
|
-
position = "bottom-right",
|
|
1056
|
-
offset = 24,
|
|
1057
|
-
icon = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_CookieOutlined.default, {}),
|
|
1058
|
-
tooltip,
|
|
1059
|
-
FabProps,
|
|
1060
|
-
hideWhenConsented = false
|
|
1061
|
-
}) {
|
|
1062
|
-
const { openPreferences, consented } = useConsent();
|
|
1063
|
-
const theme = (0, import_styles3.useTheme)();
|
|
1064
|
-
if (hideWhenConsented && consented) {
|
|
1065
|
-
return null;
|
|
1066
|
-
}
|
|
1067
|
-
const tooltipText = tooltip ?? "Gerenciar Prefer\xEAncias de Cookies";
|
|
1068
|
-
const getPosition = () => {
|
|
1069
|
-
const styles = {
|
|
1070
|
-
position: "fixed",
|
|
1071
|
-
zIndex: 1200
|
|
1072
|
-
};
|
|
1073
|
-
switch (position) {
|
|
1074
|
-
case "bottom-left":
|
|
1075
|
-
return { ...styles, bottom: offset, left: offset };
|
|
1076
|
-
case "bottom-right":
|
|
1077
|
-
return { ...styles, bottom: offset, right: offset };
|
|
1078
|
-
case "top-left":
|
|
1079
|
-
return { ...styles, top: offset, left: offset };
|
|
1080
|
-
case "top-right":
|
|
1081
|
-
return { ...styles, top: offset, right: offset };
|
|
1082
|
-
default:
|
|
1083
|
-
return { ...styles, bottom: offset, right: offset };
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_Tooltip.default, { title: tooltipText, placement: "top", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1087
|
-
import_Fab.default,
|
|
1088
|
-
{
|
|
1089
|
-
size: "medium",
|
|
1090
|
-
color: "primary",
|
|
1091
|
-
onClick: openPreferences,
|
|
1092
|
-
sx: {
|
|
1093
|
-
...getPosition(),
|
|
1094
|
-
backgroundColor: theme.palette.primary.main,
|
|
1095
|
-
"&:hover": {
|
|
1096
|
-
backgroundColor: theme.palette.primary.dark
|
|
1097
|
-
}
|
|
1098
|
-
},
|
|
1099
|
-
"aria-label": tooltipText,
|
|
1100
|
-
...FabProps,
|
|
1101
|
-
children: icon
|
|
1102
|
-
}
|
|
1103
|
-
) });
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
// src/index.ts
|
|
1107
1198
|
init_ConsentContext();
|
|
1108
1199
|
init_useConsent();
|
|
1109
1200
|
init_CategoriesContext();
|
|
1110
1201
|
|
|
1111
1202
|
// src/utils/ConsentGate.tsx
|
|
1112
1203
|
init_useConsent();
|
|
1113
|
-
var
|
|
1204
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1114
1205
|
function ConsentGate(props) {
|
|
1115
1206
|
const { preferences } = useConsent();
|
|
1116
1207
|
if (!preferences[props.category]) return null;
|
|
1117
|
-
return /* @__PURE__ */ (0,
|
|
1208
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: props.children });
|
|
1118
1209
|
}
|
|
1119
1210
|
|
|
1120
1211
|
// src/utils/scriptLoader.ts
|
|
@@ -1158,15 +1249,15 @@ function loadScript(id, src, category = null, attrs = {}) {
|
|
|
1158
1249
|
init_theme();
|
|
1159
1250
|
|
|
1160
1251
|
// src/utils/ConsentScriptLoader.tsx
|
|
1161
|
-
var
|
|
1252
|
+
var React5 = __toESM(require("react"), 1);
|
|
1162
1253
|
init_useConsent();
|
|
1163
1254
|
function ConsentScriptLoader({
|
|
1164
1255
|
integrations,
|
|
1165
1256
|
reloadOnChange = false
|
|
1166
1257
|
}) {
|
|
1167
1258
|
const { preferences, consented } = useConsent();
|
|
1168
|
-
const loadedScripts =
|
|
1169
|
-
|
|
1259
|
+
const loadedScripts = React5.useRef(/* @__PURE__ */ new Set());
|
|
1260
|
+
React5.useEffect(() => {
|
|
1170
1261
|
if (!consented) return;
|
|
1171
1262
|
integrations.forEach(async (integration) => {
|
|
1172
1263
|
const shouldLoad = preferences[integration.category];
|
|
@@ -1184,9 +1275,6 @@ function ConsentScriptLoader({
|
|
|
1184
1275
|
integration.init();
|
|
1185
1276
|
}
|
|
1186
1277
|
loadedScripts.current.add(integration.id);
|
|
1187
|
-
console.log(
|
|
1188
|
-
`\u2705 Script loaded: ${integration.id} (${integration.category})`
|
|
1189
|
-
);
|
|
1190
1278
|
} catch (error) {
|
|
1191
1279
|
console.error(`\u274C Failed to load script: ${integration.id}`, error);
|
|
1192
1280
|
}
|
|
@@ -1197,7 +1285,7 @@ function ConsentScriptLoader({
|
|
|
1197
1285
|
}
|
|
1198
1286
|
function useConsentScriptLoader() {
|
|
1199
1287
|
const { preferences, consented } = useConsent();
|
|
1200
|
-
return
|
|
1288
|
+
return React5.useCallback(
|
|
1201
1289
|
async (integration) => {
|
|
1202
1290
|
if (!consented) {
|
|
1203
1291
|
console.warn(
|
|
@@ -1223,9 +1311,6 @@ function useConsentScriptLoader() {
|
|
|
1223
1311
|
if (integration.init) {
|
|
1224
1312
|
integration.init();
|
|
1225
1313
|
}
|
|
1226
|
-
console.log(
|
|
1227
|
-
`\u2705 Script loaded: ${integration.id} (${integration.category})`
|
|
1228
|
-
);
|
|
1229
1314
|
return true;
|
|
1230
1315
|
} catch (error) {
|
|
1231
1316
|
console.error(`\u274C Failed to load script: ${integration.id}`, error);
|
|
@@ -1277,8 +1362,8 @@ function createGoogleTagManagerIntegration(config) {
|
|
|
1277
1362
|
function createUserWayIntegration(config) {
|
|
1278
1363
|
return {
|
|
1279
1364
|
id: "userway",
|
|
1280
|
-
category: "
|
|
1281
|
-
//
|
|
1365
|
+
category: "functional",
|
|
1366
|
+
// Categoria mais apropriada para acessibilidade
|
|
1282
1367
|
src: `https://cdn.userway.org/widget.js`,
|
|
1283
1368
|
init: () => {
|
|
1284
1369
|
if (typeof window !== "undefined") {
|
|
@@ -1303,9 +1388,7 @@ init_developerGuidance();
|
|
|
1303
1388
|
ConsentGate,
|
|
1304
1389
|
ConsentProvider,
|
|
1305
1390
|
ConsentScriptLoader,
|
|
1306
|
-
CookieBanner,
|
|
1307
1391
|
DEFAULT_PROJECT_CATEGORIES,
|
|
1308
|
-
FloatingPreferencesButton,
|
|
1309
1392
|
PreferencesModal,
|
|
1310
1393
|
analyzeDeveloperConfiguration,
|
|
1311
1394
|
createGoogleAnalyticsIntegration,
|
|
@@ -1318,6 +1401,5 @@ init_developerGuidance();
|
|
|
1318
1401
|
useConsent,
|
|
1319
1402
|
useConsentHydration,
|
|
1320
1403
|
useConsentScriptLoader,
|
|
1321
|
-
useConsentTexts
|
|
1322
|
-
useCustomCategories
|
|
1404
|
+
useConsentTexts
|
|
1323
1405
|
});
|