@tantainnovative/ndpr-toolkit 1.0.6 → 1.0.9

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.
Files changed (50) hide show
  1. package/README.md +113 -402
  2. package/dist/index.d.mts +448 -0
  3. package/dist/index.d.ts +448 -31
  4. package/dist/index.js +191 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +191 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/styles.css +38 -0
  9. package/dist/unstyled.d.mts +22 -0
  10. package/dist/unstyled.d.ts +22 -0
  11. package/dist/unstyled.js +2 -0
  12. package/dist/unstyled.js.map +1 -0
  13. package/dist/unstyled.mjs +2 -0
  14. package/dist/unstyled.mjs.map +1 -0
  15. package/package.json +88 -46
  16. package/dist/components/breach/BreachNotificationManager.d.ts +0 -62
  17. package/dist/components/breach/BreachReportForm.d.ts +0 -66
  18. package/dist/components/breach/BreachRiskAssessment.d.ts +0 -50
  19. package/dist/components/breach/RegulatoryReportGenerator.d.ts +0 -94
  20. package/dist/components/consent/ConsentBanner.d.ts +0 -79
  21. package/dist/components/consent/ConsentManager.d.ts +0 -73
  22. package/dist/components/consent/ConsentStorage.d.ts +0 -41
  23. package/dist/components/dpia/DPIAQuestionnaire.d.ts +0 -70
  24. package/dist/components/dpia/DPIAReport.d.ts +0 -40
  25. package/dist/components/dpia/StepIndicator.d.ts +0 -64
  26. package/dist/components/dsr/DSRDashboard.d.ts +0 -58
  27. package/dist/components/dsr/DSRRequestForm.d.ts +0 -74
  28. package/dist/components/dsr/DSRTracker.d.ts +0 -56
  29. package/dist/components/policy/PolicyExporter.d.ts +0 -65
  30. package/dist/components/policy/PolicyGenerator.d.ts +0 -54
  31. package/dist/components/policy/PolicyPreview.d.ts +0 -71
  32. package/dist/hooks/useBreach.d.ts +0 -97
  33. package/dist/hooks/useConsent.d.ts +0 -63
  34. package/dist/hooks/useDPIA.d.ts +0 -92
  35. package/dist/hooks/useDSR.d.ts +0 -72
  36. package/dist/hooks/usePrivacyPolicy.d.ts +0 -87
  37. package/dist/index.esm.js +0 -2
  38. package/dist/index.esm.js.map +0 -1
  39. package/dist/setupTests.d.ts +0 -2
  40. package/dist/types/breach.d.ts +0 -239
  41. package/dist/types/consent.d.ts +0 -95
  42. package/dist/types/dpia.d.ts +0 -196
  43. package/dist/types/dsr.d.ts +0 -162
  44. package/dist/types/index.d.ts +0 -35
  45. package/dist/types/privacy.d.ts +0 -204
  46. package/dist/utils/breach.d.ts +0 -14
  47. package/dist/utils/consent.d.ts +0 -10
  48. package/dist/utils/dpia.d.ts +0 -12
  49. package/dist/utils/dsr.d.ts +0 -11
  50. package/dist/utils/privacy.d.ts +0 -12
@@ -0,0 +1,38 @@
1
+ @keyframes slide-in-bottom {
2
+ from {
3
+ transform: translateY(100%);
4
+ }
5
+ to {
6
+ transform: translateY(0);
7
+ }
8
+ }
9
+
10
+ @keyframes slide-in-top {
11
+ from {
12
+ transform: translateY(-100%);
13
+ }
14
+ to {
15
+ transform: translateY(0);
16
+ }
17
+ }
18
+
19
+ @keyframes fade-in {
20
+ from {
21
+ opacity: 0;
22
+ }
23
+ to {
24
+ opacity: 1;
25
+ }
26
+ }
27
+
28
+ .animate-slide-in {
29
+ animation: slide-in-bottom 0.3s ease-out;
30
+ }
31
+
32
+ .animate-slide-in-top {
33
+ animation: slide-in-top 0.3s ease-out;
34
+ }
35
+
36
+ .animate-fade-in {
37
+ animation: fade-in 0.3s ease-out;
38
+ }
@@ -0,0 +1,22 @@
1
+ import React__default, { ReactNode } from 'react';
2
+
3
+ interface UnstyledConsentBannerProps {
4
+ className?: string;
5
+ children?: ReactNode;
6
+ }
7
+ declare const UnstyledConsentBanner: React__default.FC<UnstyledConsentBannerProps>;
8
+
9
+ interface UnstyledConsentSettingsProps {
10
+ className?: string;
11
+ children?: ReactNode;
12
+ }
13
+ declare const UnstyledConsentSettings: React__default.FC<UnstyledConsentSettingsProps>;
14
+
15
+ interface UnstyledConsentToggleProps {
16
+ category: 'analytics' | 'marketing' | 'functional';
17
+ className?: string;
18
+ label?: string;
19
+ }
20
+ declare const UnstyledConsentToggle: React__default.FC<UnstyledConsentToggleProps>;
21
+
22
+ export { UnstyledConsentBanner as ConsentBanner, UnstyledConsentSettings as ConsentSettings, UnstyledConsentToggle as ConsentToggle };
@@ -0,0 +1,22 @@
1
+ import React__default, { ReactNode } from 'react';
2
+
3
+ interface UnstyledConsentBannerProps {
4
+ className?: string;
5
+ children?: ReactNode;
6
+ }
7
+ declare const UnstyledConsentBanner: React__default.FC<UnstyledConsentBannerProps>;
8
+
9
+ interface UnstyledConsentSettingsProps {
10
+ className?: string;
11
+ children?: ReactNode;
12
+ }
13
+ declare const UnstyledConsentSettings: React__default.FC<UnstyledConsentSettingsProps>;
14
+
15
+ interface UnstyledConsentToggleProps {
16
+ category: 'analytics' | 'marketing' | 'functional';
17
+ className?: string;
18
+ label?: string;
19
+ }
20
+ declare const UnstyledConsentToggle: React__default.FC<UnstyledConsentToggleProps>;
21
+
22
+ export { UnstyledConsentBanner as ConsentBanner, UnstyledConsentSettings as ConsentSettings, UnstyledConsentToggle as ConsentToggle };
@@ -0,0 +1,2 @@
1
+ 'use strict';var e=require('react');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var e__default=/*#__PURE__*/_interopDefault(e);var v=e.createContext(void 0);function i(){let n=e.useContext(v);if(!n)throw new Error("useConsent must be used within a ConsentProvider");return n}var C=({className:n,children:a})=>{let{showBanner:o,acceptAll:r,rejectAll:l,openSettings:c}=i();return o?e__default.default.createElement("div",{className:n,role:"region","aria-label":"Cookie consent"},a||e__default.default.createElement(e__default.default.Fragment,null,e__default.default.createElement("div",null,e__default.default.createElement("h3",null,"Cookie Consent"),e__default.default.createElement("p",null,"We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.")),e__default.default.createElement("div",null,e__default.default.createElement("button",{onClick:r,"aria-label":"Accept all cookies"},"Accept All"),e__default.default.createElement("button",{onClick:l,"aria-label":"Reject non-essential cookies"},"Reject All"),e__default.default.createElement("button",{onClick:c,"aria-label":"Manage cookie preferences"},"Manage Preferences")))):null};var h=[{id:"necessary",name:"Necessary Cookies",description:"These cookies are essential for the website to function properly.",disabled:true},{id:"analytics",name:"Analytics Cookies",description:"These cookies help us understand how visitors interact with our website.",disabled:false},{id:"marketing",name:"Marketing Cookies",description:"These cookies are used to track visitors across websites for marketing purposes.",disabled:false},{id:"functional",name:"Functional Cookies",description:"These cookies enable personalized features and functionality.",disabled:false}],f=({className:n,children:a})=>{let{showSettings:o,consentState:r,updateConsent:l,savePreferences:c,closeSettings:p}=i();if(!o)return null;let g=()=>{c(r);};return e__default.default.createElement("div",{className:n,role:"dialog","aria-label":"Cookie preferences"},a||e__default.default.createElement(e__default.default.Fragment,null,e__default.default.createElement("div",null,e__default.default.createElement("h2",null,"Cookie Preferences"),e__default.default.createElement("p",null,"Manage your cookie preferences. You can enable or disable different categories of cookies below.")),e__default.default.createElement("div",null,h.map(s=>e__default.default.createElement("div",{key:s.id},e__default.default.createElement("div",null,e__default.default.createElement("h4",null,s.name),e__default.default.createElement("p",null,s.description)),e__default.default.createElement("input",{type:"checkbox",checked:r[s.id],onChange:k=>l(s.id,k.target.checked),disabled:s.disabled,"aria-label":`Toggle ${s.name}`})))),e__default.default.createElement("div",null,e__default.default.createElement("button",{onClick:p,"aria-label":"Cancel changes"},"Cancel"),e__default.default.createElement("button",{onClick:g,"aria-label":"Save cookie preferences"},"Save Preferences"))))};var u=({category:n,className:a,label:o})=>{let{consentState:r,updateConsent:l}=i();return e__default.default.createElement("label",{className:a},e__default.default.createElement("input",{type:"checkbox",checked:r[n],onChange:c=>l(n,c.target.checked),"aria-label":o||`Toggle ${n} cookies`}),o&&e__default.default.createElement("span",null,o))};exports.ConsentBanner=C;exports.ConsentSettings=f;exports.ConsentToggle=u;//# sourceMappingURL=unstyled.js.map
2
+ //# sourceMappingURL=unstyled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/contexts/ConsentContext.tsx","../src/components/consent/unstyled/UnstyledConsentBanner.tsx","../src/components/consent/unstyled/UnstyledConsentSettings.tsx","../src/components/consent/unstyled/UnstyledConsentToggle.tsx"],"names":["ConsentContext","createContext","useConsent","context","useContext","UnstyledConsentBanner","className","children","showBanner","acceptAll","rejectAll","openSettings","React","cookieCategories","UnstyledConsentSettings","showSettings","consentState","updateConsent","savePreferences","closeSettings","handleSave","category","e","UnstyledConsentToggle","label"],"mappings":"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","file":"unstyled.js","sourcesContent":["import React, { createContext, useContext, useState, useCallback, useEffect, ReactNode } from 'react';\n\nexport interface ConsentCategories {\n necessary: boolean;\n analytics: boolean;\n marketing: boolean;\n functional: boolean;\n [key: string]: boolean;\n}\n\nexport interface ConsentState {\n hasUserConsented: boolean;\n consentState: ConsentCategories;\n showBanner: boolean;\n showSettings: boolean;\n}\n\nexport interface ConsentActions {\n acceptAll: () => void;\n rejectAll: () => void;\n savePreferences: (preferences: Partial<ConsentCategories>) => void;\n openSettings: () => void;\n closeSettings: () => void;\n updateConsent: (category: keyof ConsentCategories, value: boolean) => void;\n}\n\nexport interface ConsentContextValue extends ConsentState, ConsentActions {}\n\nconst ConsentContext = createContext<ConsentContextValue | undefined>(undefined);\n\nexport interface ConsentProviderProps {\n children: ReactNode;\n initialConsent?: Partial<ConsentCategories>;\n onConsentChange?: (consent: ConsentCategories) => void;\n storageKey?: string;\n}\n\nconst defaultConsent: ConsentCategories = {\n necessary: true, // Always true\n analytics: false,\n marketing: false,\n functional: false,\n};\n\nexport function ConsentProvider({\n children,\n initialConsent = {},\n onConsentChange,\n storageKey = 'ndpr-consent',\n}: ConsentProviderProps) {\n const [consentState, setConsentState] = useState<ConsentCategories>(() => {\n // Try to load from localStorage\n if (typeof window !== 'undefined') {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n try {\n const parsed = JSON.parse(stored);\n return { ...defaultConsent, ...parsed };\n } catch (e) {\n console.error('Failed to parse consent from localStorage', e);\n }\n }\n }\n return { ...defaultConsent, ...initialConsent };\n });\n\n const [hasUserConsented, setHasUserConsented] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(`${storageKey}-set`) === 'true';\n }\n return false;\n });\n\n const [showBanner, setShowBanner] = useState(!hasUserConsented);\n const [showSettings, setShowSettings] = useState(false);\n\n // Persist consent to localStorage\n useEffect(() => {\n if (typeof window !== 'undefined' && hasUserConsented) {\n localStorage.setItem(storageKey, JSON.stringify(consentState));\n localStorage.setItem(`${storageKey}-set`, 'true');\n }\n }, [consentState, hasUserConsented, storageKey]);\n\n // Notify parent of consent changes\n useEffect(() => {\n if (hasUserConsented && onConsentChange) {\n onConsentChange(consentState);\n }\n }, [consentState, hasUserConsented, onConsentChange]);\n\n const acceptAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: true,\n marketing: true,\n functional: true,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const rejectAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: false,\n marketing: false,\n functional: false,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const savePreferences = useCallback((preferences: Partial<ConsentCategories>) => {\n setConsentState(prev => ({\n ...prev,\n ...preferences,\n necessary: true, // Always keep necessary as true\n }));\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const updateConsent = useCallback((category: keyof ConsentCategories, value: boolean) => {\n if (category === 'necessary') return; // Can't change necessary cookies\n \n setConsentState(prev => ({\n ...prev,\n [category]: value,\n }));\n }, []);\n\n const openSettings = useCallback(() => {\n setShowSettings(true);\n setShowBanner(false);\n }, []);\n\n const closeSettings = useCallback(() => {\n setShowSettings(false);\n }, []);\n\n const value: ConsentContextValue = {\n hasUserConsented,\n consentState,\n showBanner,\n showSettings,\n acceptAll,\n rejectAll,\n savePreferences,\n openSettings,\n closeSettings,\n updateConsent,\n };\n\n return (\n <ConsentContext.Provider value={value}>\n {children}\n </ConsentContext.Provider>\n );\n}\n\nexport function useConsent() {\n const context = useContext(ConsentContext);\n if (!context) {\n throw new Error('useConsent must be used within a ConsentProvider');\n }\n return context;\n}\n\n// Export for external use\nexport { ConsentContext };","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentBannerProps {\n className?: string;\n children?: ReactNode;\n}\n\nexport const UnstyledConsentBanner: React.FC<UnstyledConsentBannerProps> = ({\n className,\n children,\n}) => {\n const { showBanner, acceptAll, rejectAll, openSettings } = useConsent();\n\n if (!showBanner) return null;\n\n return (\n <div className={className} role=\"region\" aria-label=\"Cookie consent\">\n {children || (\n <>\n <div>\n <h3>Cookie Consent</h3>\n <p>We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.</p>\n </div>\n <div>\n <button onClick={acceptAll} aria-label=\"Accept all cookies\">\n Accept All\n </button>\n <button onClick={rejectAll} aria-label=\"Reject non-essential cookies\">\n Reject All\n </button>\n <button onClick={openSettings} aria-label=\"Manage cookie preferences\">\n Manage Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentSettingsProps {\n className?: string;\n children?: ReactNode;\n}\n\nconst cookieCategories = [\n {\n id: 'necessary',\n name: 'Necessary Cookies',\n description: 'These cookies are essential for the website to function properly.',\n disabled: true,\n },\n {\n id: 'analytics',\n name: 'Analytics Cookies',\n description: 'These cookies help us understand how visitors interact with our website.',\n disabled: false,\n },\n {\n id: 'marketing',\n name: 'Marketing Cookies',\n description: 'These cookies are used to track visitors across websites for marketing purposes.',\n disabled: false,\n },\n {\n id: 'functional',\n name: 'Functional Cookies',\n description: 'These cookies enable personalized features and functionality.',\n disabled: false,\n },\n];\n\nexport const UnstyledConsentSettings: React.FC<UnstyledConsentSettingsProps> = ({\n className,\n children,\n}) => {\n const { showSettings, consentState, updateConsent, savePreferences, closeSettings } = useConsent();\n\n if (!showSettings) return null;\n\n const handleSave = () => {\n savePreferences(consentState);\n };\n\n return (\n <div className={className} role=\"dialog\" aria-label=\"Cookie preferences\">\n {children || (\n <>\n <div>\n <h2>Cookie Preferences</h2>\n <p>Manage your cookie preferences. You can enable or disable different categories of cookies below.</p>\n </div>\n \n <div>\n {cookieCategories.map((category) => (\n <div key={category.id}>\n <div>\n <h4>{category.name}</h4>\n <p>{category.description}</p>\n </div>\n <input\n type=\"checkbox\"\n checked={consentState[category.id as keyof typeof consentState]}\n onChange={(e) => updateConsent(category.id as keyof typeof consentState, e.target.checked)}\n disabled={category.disabled}\n aria-label={`Toggle ${category.name}`}\n />\n </div>\n ))}\n </div>\n\n <div>\n <button onClick={closeSettings} aria-label=\"Cancel changes\">\n Cancel\n </button>\n <button onClick={handleSave} aria-label=\"Save cookie preferences\">\n Save Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentToggleProps {\n category: 'analytics' | 'marketing' | 'functional';\n className?: string;\n label?: string;\n}\n\nexport const UnstyledConsentToggle: React.FC<UnstyledConsentToggleProps> = ({\n category,\n className,\n label,\n}) => {\n const { consentState, updateConsent } = useConsent();\n\n return (\n <label className={className}>\n <input\n type=\"checkbox\"\n checked={consentState[category]}\n onChange={(e) => updateConsent(category, e.target.checked)}\n aria-label={label || `Toggle ${category} cookies`}\n />\n {label && <span>{label}</span>}\n </label>\n );\n};"]}
@@ -0,0 +1,2 @@
1
+ import e,{createContext,useContext}from'react';var v=createContext(void 0);function i(){let n=useContext(v);if(!n)throw new Error("useConsent must be used within a ConsentProvider");return n}var C=({className:n,children:a})=>{let{showBanner:o,acceptAll:r,rejectAll:l,openSettings:c}=i();return o?e.createElement("div",{className:n,role:"region","aria-label":"Cookie consent"},a||e.createElement(e.Fragment,null,e.createElement("div",null,e.createElement("h3",null,"Cookie Consent"),e.createElement("p",null,"We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.")),e.createElement("div",null,e.createElement("button",{onClick:r,"aria-label":"Accept all cookies"},"Accept All"),e.createElement("button",{onClick:l,"aria-label":"Reject non-essential cookies"},"Reject All"),e.createElement("button",{onClick:c,"aria-label":"Manage cookie preferences"},"Manage Preferences")))):null};var h=[{id:"necessary",name:"Necessary Cookies",description:"These cookies are essential for the website to function properly.",disabled:true},{id:"analytics",name:"Analytics Cookies",description:"These cookies help us understand how visitors interact with our website.",disabled:false},{id:"marketing",name:"Marketing Cookies",description:"These cookies are used to track visitors across websites for marketing purposes.",disabled:false},{id:"functional",name:"Functional Cookies",description:"These cookies enable personalized features and functionality.",disabled:false}],f=({className:n,children:a})=>{let{showSettings:o,consentState:r,updateConsent:l,savePreferences:c,closeSettings:p}=i();if(!o)return null;let g=()=>{c(r);};return e.createElement("div",{className:n,role:"dialog","aria-label":"Cookie preferences"},a||e.createElement(e.Fragment,null,e.createElement("div",null,e.createElement("h2",null,"Cookie Preferences"),e.createElement("p",null,"Manage your cookie preferences. You can enable or disable different categories of cookies below.")),e.createElement("div",null,h.map(s=>e.createElement("div",{key:s.id},e.createElement("div",null,e.createElement("h4",null,s.name),e.createElement("p",null,s.description)),e.createElement("input",{type:"checkbox",checked:r[s.id],onChange:k=>l(s.id,k.target.checked),disabled:s.disabled,"aria-label":`Toggle ${s.name}`})))),e.createElement("div",null,e.createElement("button",{onClick:p,"aria-label":"Cancel changes"},"Cancel"),e.createElement("button",{onClick:g,"aria-label":"Save cookie preferences"},"Save Preferences"))))};var u=({category:n,className:a,label:o})=>{let{consentState:r,updateConsent:l}=i();return e.createElement("label",{className:a},e.createElement("input",{type:"checkbox",checked:r[n],onChange:c=>l(n,c.target.checked),"aria-label":o||`Toggle ${n} cookies`}),o&&e.createElement("span",null,o))};export{C as ConsentBanner,f as ConsentSettings,u as ConsentToggle};//# sourceMappingURL=unstyled.mjs.map
2
+ //# sourceMappingURL=unstyled.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/contexts/ConsentContext.tsx","../src/components/consent/unstyled/UnstyledConsentBanner.tsx","../src/components/consent/unstyled/UnstyledConsentSettings.tsx","../src/components/consent/unstyled/UnstyledConsentToggle.tsx"],"names":["ConsentContext","createContext","useConsent","context","useContext","UnstyledConsentBanner","className","children","showBanner","acceptAll","rejectAll","openSettings","React","cookieCategories","UnstyledConsentSettings","showSettings","consentState","updateConsent","savePreferences","closeSettings","handleSave","category","e","UnstyledConsentToggle","label"],"mappings":"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","file":"unstyled.mjs","sourcesContent":["import React, { createContext, useContext, useState, useCallback, useEffect, ReactNode } from 'react';\n\nexport interface ConsentCategories {\n necessary: boolean;\n analytics: boolean;\n marketing: boolean;\n functional: boolean;\n [key: string]: boolean;\n}\n\nexport interface ConsentState {\n hasUserConsented: boolean;\n consentState: ConsentCategories;\n showBanner: boolean;\n showSettings: boolean;\n}\n\nexport interface ConsentActions {\n acceptAll: () => void;\n rejectAll: () => void;\n savePreferences: (preferences: Partial<ConsentCategories>) => void;\n openSettings: () => void;\n closeSettings: () => void;\n updateConsent: (category: keyof ConsentCategories, value: boolean) => void;\n}\n\nexport interface ConsentContextValue extends ConsentState, ConsentActions {}\n\nconst ConsentContext = createContext<ConsentContextValue | undefined>(undefined);\n\nexport interface ConsentProviderProps {\n children: ReactNode;\n initialConsent?: Partial<ConsentCategories>;\n onConsentChange?: (consent: ConsentCategories) => void;\n storageKey?: string;\n}\n\nconst defaultConsent: ConsentCategories = {\n necessary: true, // Always true\n analytics: false,\n marketing: false,\n functional: false,\n};\n\nexport function ConsentProvider({\n children,\n initialConsent = {},\n onConsentChange,\n storageKey = 'ndpr-consent',\n}: ConsentProviderProps) {\n const [consentState, setConsentState] = useState<ConsentCategories>(() => {\n // Try to load from localStorage\n if (typeof window !== 'undefined') {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n try {\n const parsed = JSON.parse(stored);\n return { ...defaultConsent, ...parsed };\n } catch (e) {\n console.error('Failed to parse consent from localStorage', e);\n }\n }\n }\n return { ...defaultConsent, ...initialConsent };\n });\n\n const [hasUserConsented, setHasUserConsented] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(`${storageKey}-set`) === 'true';\n }\n return false;\n });\n\n const [showBanner, setShowBanner] = useState(!hasUserConsented);\n const [showSettings, setShowSettings] = useState(false);\n\n // Persist consent to localStorage\n useEffect(() => {\n if (typeof window !== 'undefined' && hasUserConsented) {\n localStorage.setItem(storageKey, JSON.stringify(consentState));\n localStorage.setItem(`${storageKey}-set`, 'true');\n }\n }, [consentState, hasUserConsented, storageKey]);\n\n // Notify parent of consent changes\n useEffect(() => {\n if (hasUserConsented && onConsentChange) {\n onConsentChange(consentState);\n }\n }, [consentState, hasUserConsented, onConsentChange]);\n\n const acceptAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: true,\n marketing: true,\n functional: true,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const rejectAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: false,\n marketing: false,\n functional: false,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const savePreferences = useCallback((preferences: Partial<ConsentCategories>) => {\n setConsentState(prev => ({\n ...prev,\n ...preferences,\n necessary: true, // Always keep necessary as true\n }));\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const updateConsent = useCallback((category: keyof ConsentCategories, value: boolean) => {\n if (category === 'necessary') return; // Can't change necessary cookies\n \n setConsentState(prev => ({\n ...prev,\n [category]: value,\n }));\n }, []);\n\n const openSettings = useCallback(() => {\n setShowSettings(true);\n setShowBanner(false);\n }, []);\n\n const closeSettings = useCallback(() => {\n setShowSettings(false);\n }, []);\n\n const value: ConsentContextValue = {\n hasUserConsented,\n consentState,\n showBanner,\n showSettings,\n acceptAll,\n rejectAll,\n savePreferences,\n openSettings,\n closeSettings,\n updateConsent,\n };\n\n return (\n <ConsentContext.Provider value={value}>\n {children}\n </ConsentContext.Provider>\n );\n}\n\nexport function useConsent() {\n const context = useContext(ConsentContext);\n if (!context) {\n throw new Error('useConsent must be used within a ConsentProvider');\n }\n return context;\n}\n\n// Export for external use\nexport { ConsentContext };","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentBannerProps {\n className?: string;\n children?: ReactNode;\n}\n\nexport const UnstyledConsentBanner: React.FC<UnstyledConsentBannerProps> = ({\n className,\n children,\n}) => {\n const { showBanner, acceptAll, rejectAll, openSettings } = useConsent();\n\n if (!showBanner) return null;\n\n return (\n <div className={className} role=\"region\" aria-label=\"Cookie consent\">\n {children || (\n <>\n <div>\n <h3>Cookie Consent</h3>\n <p>We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.</p>\n </div>\n <div>\n <button onClick={acceptAll} aria-label=\"Accept all cookies\">\n Accept All\n </button>\n <button onClick={rejectAll} aria-label=\"Reject non-essential cookies\">\n Reject All\n </button>\n <button onClick={openSettings} aria-label=\"Manage cookie preferences\">\n Manage Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentSettingsProps {\n className?: string;\n children?: ReactNode;\n}\n\nconst cookieCategories = [\n {\n id: 'necessary',\n name: 'Necessary Cookies',\n description: 'These cookies are essential for the website to function properly.',\n disabled: true,\n },\n {\n id: 'analytics',\n name: 'Analytics Cookies',\n description: 'These cookies help us understand how visitors interact with our website.',\n disabled: false,\n },\n {\n id: 'marketing',\n name: 'Marketing Cookies',\n description: 'These cookies are used to track visitors across websites for marketing purposes.',\n disabled: false,\n },\n {\n id: 'functional',\n name: 'Functional Cookies',\n description: 'These cookies enable personalized features and functionality.',\n disabled: false,\n },\n];\n\nexport const UnstyledConsentSettings: React.FC<UnstyledConsentSettingsProps> = ({\n className,\n children,\n}) => {\n const { showSettings, consentState, updateConsent, savePreferences, closeSettings } = useConsent();\n\n if (!showSettings) return null;\n\n const handleSave = () => {\n savePreferences(consentState);\n };\n\n return (\n <div className={className} role=\"dialog\" aria-label=\"Cookie preferences\">\n {children || (\n <>\n <div>\n <h2>Cookie Preferences</h2>\n <p>Manage your cookie preferences. You can enable or disable different categories of cookies below.</p>\n </div>\n \n <div>\n {cookieCategories.map((category) => (\n <div key={category.id}>\n <div>\n <h4>{category.name}</h4>\n <p>{category.description}</p>\n </div>\n <input\n type=\"checkbox\"\n checked={consentState[category.id as keyof typeof consentState]}\n onChange={(e) => updateConsent(category.id as keyof typeof consentState, e.target.checked)}\n disabled={category.disabled}\n aria-label={`Toggle ${category.name}`}\n />\n </div>\n ))}\n </div>\n\n <div>\n <button onClick={closeSettings} aria-label=\"Cancel changes\">\n Cancel\n </button>\n <button onClick={handleSave} aria-label=\"Save cookie preferences\">\n Save Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentToggleProps {\n category: 'analytics' | 'marketing' | 'functional';\n className?: string;\n label?: string;\n}\n\nexport const UnstyledConsentToggle: React.FC<UnstyledConsentToggleProps> = ({\n category,\n className,\n label,\n}) => {\n const { consentState, updateConsent } = useConsent();\n\n return (\n <label className={className}>\n <input\n type=\"checkbox\"\n checked={consentState[category]}\n onChange={(e) => updateConsent(category, e.target.checked)}\n aria-label={label || `Toggle ${category} cookies`}\n />\n {label && <span>{label}</span>}\n </label>\n );\n};"]}
package/package.json CHANGED
@@ -1,71 +1,113 @@
1
1
  {
2
2
  "name": "@tantainnovative/ndpr-toolkit",
3
- "version": "1.0.6",
4
- "description": "A comprehensive toolkit for implementing NDPR-compliant features in web applications",
5
- "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
7
- "types": "dist/index.d.ts",
8
- "files": [
9
- "dist"
10
- ],
3
+ "version": "1.0.9",
4
+ "private": false,
5
+ "description": "Nigerian Data Protection Compliance Toolkit for implementing NDPR and DPA compliant features",
11
6
  "scripts": {
12
- "build": "rollup -c",
13
- "dev": "rollup -c -w",
14
- "test": "jest",
15
- "lint": "eslint src --ext .ts,.tsx",
16
- "prepublishOnly": "npm run build"
7
+ "dev": "next dev --turbopack",
8
+ "build": "next build",
9
+ "build:lib": "tsup",
10
+ "prepublishOnly": "pnpm build:lib",
11
+ "start": "next start",
12
+ "lint": "next lint",
13
+ "test": "jest --passWithNoTests",
14
+ "export": "next export",
15
+ "build:static": "next build",
16
+ "deploy": "next build && touch out/.nojekyll && gh-pages -d out",
17
+ "release": "standard-version",
18
+ "release:minor": "standard-version --release-as minor",
19
+ "release:major": "standard-version --release-as major",
20
+ "release:patch": "standard-version --release-as patch"
17
21
  },
18
22
  "keywords": [
19
23
  "ndpr",
24
+ "dpa",
25
+ "nigeria",
20
26
  "data-protection",
21
- "privacy",
22
27
  "compliance",
23
- "nigeria",
24
- "consent",
25
- "dpia",
26
- "data-subject-rights",
27
- "breach-notification"
28
+ "privacy",
29
+ "gdpr"
28
30
  ],
29
31
  "author": "Tanta Innovative",
30
32
  "license": "MIT",
31
33
  "repository": {
32
34
  "type": "git",
33
- "url": "https://github.com/tantainnovative/ndpr-toolkit"
35
+ "url": "git+https://github.com/tantainnovative/ndpr-toolkit.git"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/tantainnovative/ndpr-toolkit/issues"
34
39
  },
40
+ "homepage": "https://github.com/tantainnovative/ndpr-toolkit#readme",
41
+ "main": "./dist/index.js",
42
+ "module": "./dist/index.mjs",
43
+ "exports": {
44
+ ".": {
45
+ "import": "./dist/index.mjs",
46
+ "require": "./dist/index.js"
47
+ },
48
+ "./unstyled": {
49
+ "import": "./dist/unstyled.mjs",
50
+ "require": "./dist/unstyled.js"
51
+ },
52
+ "./styles": {
53
+ "import": "./dist/styles.css",
54
+ "require": "./dist/styles.css"
55
+ }
56
+ },
57
+ "files": [
58
+ "dist",
59
+ "README.md",
60
+ "LICENSE"
61
+ ],
35
62
  "publishConfig": {
36
63
  "access": "public"
37
64
  },
65
+ "dependencies": {
66
+ "@radix-ui/react-label": "^2.1.4",
67
+ "@radix-ui/react-slot": "^1.2.0",
68
+ "@radix-ui/react-switch": "^1.2.2",
69
+ "@radix-ui/react-tabs": "^1.1.9",
70
+ "class-variance-authority": "^0.7.1",
71
+ "clsx": "^2.1.1",
72
+ "jspdf": "^3.0.3",
73
+ "lucide-react": "^0.507.0",
74
+ "tailwind-merge": "^2.6.0",
75
+ "tslib": "^2.4.0",
76
+ "uuid": "^13.0.0"
77
+ },
38
78
  "peerDependencies": {
39
- "react": "^18.0.0 || ^19.0.0",
40
- "react-dom": "^18.0.0 || ^19.0.0"
79
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
80
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
41
81
  },
42
82
  "devDependencies": {
43
- "@rollup/plugin-commonjs": "^22.0.0",
44
- "@rollup/plugin-node-resolve": "^13.3.0",
45
- "@rollup/plugin-typescript": "^8.3.2",
46
- "@testing-library/jest-dom": "^5.17.0",
47
- "@testing-library/react": "^13.4.0",
48
- "@testing-library/react-hooks": "^8.0.1",
49
- "@testing-library/user-event": "^14.6.1",
50
- "@types/jest": "^28.1.6",
51
- "@types/react": "^18.0.0",
52
- "@types/react-dom": "^18.0.0",
53
- "@typescript-eslint/eslint-plugin": "^5.27.0",
54
- "@typescript-eslint/parser": "^5.27.0",
55
- "eslint": "^8.16.0",
83
+ "@next/font": "^14.2.15",
84
+ "@tailwindcss/postcss": "^4.1.13",
85
+ "@testing-library/jest-dom": "^6.6.3",
86
+ "@testing-library/react": "^16.3.0",
87
+ "@types/jest": "^29.5.0",
88
+ "@types/react": "^19.1.15",
89
+ "@types/react-dom": "^19.1.9",
90
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
91
+ "@typescript-eslint/parser": "^8.0.0",
92
+ "autoprefixer": "^10.4.21",
93
+ "eslint": "^9.0.0",
56
94
  "eslint-plugin-react": "^7.30.0",
57
95
  "eslint-plugin-react-hooks": "^4.5.0",
58
- "identity-obj-proxy": "^3.0.0",
59
- "jest": "^28.1.0",
60
- "jest-environment-jsdom": "^28.1.3",
96
+ "gh-pages": "^6.3.0",
97
+ "husky": "^9.1.7",
98
+ "jest": "^29.5.0",
99
+ "jest-environment-jsdom": "^29.5.0",
100
+ "lint-staged": "^16.2.3",
101
+ "next": "^15.5.4",
102
+ "postcss": "^8.5.6",
103
+ "react": "^19.1.1",
104
+ "react-dom": "^19.1.1",
61
105
  "react-test-renderer": "^18.2.0",
62
- "rollup": "^2.75.5",
63
- "rollup-plugin-peer-deps-external": "^2.2.4",
64
- "rollup-plugin-terser": "^7.0.2",
65
- "ts-jest": "^28.0.8",
66
- "typescript": "^4.7.2"
67
- },
68
- "dependencies": {
69
- "tslib": "^2.4.0"
106
+ "standard-version": "^9.5.0",
107
+ "tailwindcss": "^4.1.13",
108
+ "ts-jest": "^29.0.0",
109
+ "tsup": "^8.5.0",
110
+ "tw-animate-css": "^1.4.0",
111
+ "typescript": "^5.0.0"
70
112
  }
71
113
  }
@@ -1,62 +0,0 @@
1
- import React from 'react';
2
- import { BreachReport, RiskAssessment, RegulatoryNotification } from '../../types/breach';
3
- export interface BreachNotificationManagerProps {
4
- /**
5
- * List of breach reports to manage
6
- */
7
- breachReports: BreachReport[];
8
- /**
9
- * List of risk assessments
10
- */
11
- riskAssessments: RiskAssessment[];
12
- /**
13
- * List of regulatory notifications
14
- */
15
- regulatoryNotifications: RegulatoryNotification[];
16
- /**
17
- * Callback function called when a breach is selected
18
- */
19
- onSelectBreach?: (breachId: string) => void;
20
- /**
21
- * Callback function called when a risk assessment is requested
22
- */
23
- onRequestAssessment?: (breachId: string) => void;
24
- /**
25
- * Callback function called when a notification is requested
26
- */
27
- onRequestNotification?: (breachId: string) => void;
28
- /**
29
- * Title displayed on the manager
30
- * @default "Breach Notification Manager"
31
- */
32
- title?: string;
33
- /**
34
- * Description text displayed on the manager
35
- * @default "Manage data breach notifications and track compliance with NDPR requirements."
36
- */
37
- description?: string;
38
- /**
39
- * Custom CSS class for the manager
40
- */
41
- className?: string;
42
- /**
43
- * Custom CSS class for the buttons
44
- */
45
- buttonClassName?: string;
46
- /**
47
- * Whether to show the breach details
48
- * @default true
49
- */
50
- showBreachDetails?: boolean;
51
- /**
52
- * Whether to show the notification timeline
53
- * @default true
54
- */
55
- showNotificationTimeline?: boolean;
56
- /**
57
- * Whether to show the deadline alerts
58
- * @default true
59
- */
60
- showDeadlineAlerts?: boolean;
61
- }
62
- export declare const BreachNotificationManager: React.FC<BreachNotificationManagerProps>;
@@ -1,66 +0,0 @@
1
- import React from 'react';
2
- import { BreachCategory } from '../../types/breach';
3
- export interface BreachReportFormProps {
4
- /**
5
- * Available breach categories
6
- */
7
- categories: BreachCategory[];
8
- /**
9
- * Callback function called when form is submitted
10
- */
11
- onSubmit: (formData: any) => void;
12
- /**
13
- * Title displayed on the form
14
- * @default "Report a Data Breach"
15
- */
16
- title?: string;
17
- /**
18
- * Description text displayed on the form
19
- * @default "Use this form to report a suspected or confirmed data breach. All fields marked with * are required."
20
- */
21
- formDescription?: string;
22
- /**
23
- * Text for the submit button
24
- * @default "Submit Report"
25
- */
26
- submitButtonText?: string;
27
- /**
28
- * Custom CSS class for the form
29
- */
30
- className?: string;
31
- /**
32
- * Custom CSS class for the submit button
33
- */
34
- buttonClassName?: string;
35
- /**
36
- * Whether to show a confirmation message after submission
37
- * @default true
38
- */
39
- showConfirmation?: boolean;
40
- /**
41
- * Confirmation message to display after submission
42
- * @default "Your breach report has been submitted successfully. The data protection team has been notified."
43
- */
44
- confirmationMessage?: string;
45
- /**
46
- * Whether to allow file attachments
47
- * @default true
48
- */
49
- allowAttachments?: boolean;
50
- /**
51
- * Maximum number of attachments allowed
52
- * @default 5
53
- */
54
- maxAttachments?: number;
55
- /**
56
- * Maximum file size for attachments (in bytes)
57
- * @default 5242880 (5MB)
58
- */
59
- maxFileSize?: number;
60
- /**
61
- * Allowed file types for attachments
62
- * @default ['.pdf', '.jpg', '.jpeg', '.png', '.doc', '.docx', '.xls', '.xlsx', '.txt']
63
- */
64
- allowedFileTypes?: string[];
65
- }
66
- export declare const BreachReportForm: React.FC<BreachReportFormProps>;
@@ -1,50 +0,0 @@
1
- import React from 'react';
2
- import { BreachReport, RiskAssessment } from '../../types/breach';
3
- export interface BreachRiskAssessmentProps {
4
- /**
5
- * The breach data to assess
6
- */
7
- breachData: BreachReport;
8
- /**
9
- * Initial assessment data (if editing an existing assessment)
10
- */
11
- initialAssessment?: Partial<RiskAssessment>;
12
- /**
13
- * Callback function called when assessment is completed
14
- */
15
- onComplete: (assessment: RiskAssessment) => void;
16
- /**
17
- * Title displayed on the assessment form
18
- * @default "Breach Risk Assessment"
19
- */
20
- title?: string;
21
- /**
22
- * Description text displayed on the assessment form
23
- * @default "Assess the risk level of this data breach to determine notification requirements."
24
- */
25
- description?: string;
26
- /**
27
- * Text for the submit button
28
- * @default "Complete Assessment"
29
- */
30
- submitButtonText?: string;
31
- /**
32
- * Custom CSS class for the form
33
- */
34
- className?: string;
35
- /**
36
- * Custom CSS class for the submit button
37
- */
38
- buttonClassName?: string;
39
- /**
40
- * Whether to show the breach summary
41
- * @default true
42
- */
43
- showBreachSummary?: boolean;
44
- /**
45
- * Whether to show notification requirements after assessment
46
- * @default true
47
- */
48
- showNotificationRequirements?: boolean;
49
- }
50
- export declare const BreachRiskAssessment: React.FC<BreachRiskAssessmentProps>;
@@ -1,94 +0,0 @@
1
- import React from 'react';
2
- import { BreachReport, RiskAssessment, RegulatoryNotification } from '../../types/breach';
3
- export interface OrganizationInfo {
4
- /**
5
- * Name of the organization
6
- */
7
- name: string;
8
- /**
9
- * Registration number or business ID
10
- */
11
- registrationNumber?: string;
12
- /**
13
- * Physical address of the organization
14
- */
15
- address: string;
16
- /**
17
- * Website URL
18
- */
19
- website?: string;
20
- /**
21
- * Name of the Data Protection Officer
22
- */
23
- dpoName: string;
24
- /**
25
- * Email of the Data Protection Officer
26
- */
27
- dpoEmail: string;
28
- /**
29
- * Phone number of the Data Protection Officer
30
- */
31
- dpoPhone?: string;
32
- }
33
- export interface RegulatoryReportGeneratorProps {
34
- /**
35
- * The breach data to include in the report
36
- */
37
- breachData: BreachReport;
38
- /**
39
- * The risk assessment data
40
- */
41
- assessmentData?: RiskAssessment;
42
- /**
43
- * Organization information to include in the report
44
- */
45
- organizationInfo: OrganizationInfo;
46
- /**
47
- * Callback function called when the report is generated
48
- */
49
- onGenerate: (report: RegulatoryNotification) => void;
50
- /**
51
- * Title displayed on the generator form
52
- * @default "Generate NITDA Notification Report"
53
- */
54
- title?: string;
55
- /**
56
- * Description text displayed on the generator form
57
- * @default "Generate a report for submission to NITDA in compliance with the NDPR breach notification requirements."
58
- */
59
- description?: string;
60
- /**
61
- * Text for the generate button
62
- * @default "Generate Report"
63
- */
64
- generateButtonText?: string;
65
- /**
66
- * Custom CSS class for the form
67
- */
68
- className?: string;
69
- /**
70
- * Custom CSS class for the buttons
71
- */
72
- buttonClassName?: string;
73
- /**
74
- * Whether to show a preview of the generated report
75
- * @default true
76
- */
77
- showPreview?: boolean;
78
- /**
79
- * Whether to allow editing the report content
80
- * @default true
81
- */
82
- allowEditing?: boolean;
83
- /**
84
- * Whether to allow downloading the report
85
- * @default true
86
- */
87
- allowDownload?: boolean;
88
- /**
89
- * Format for downloading the report
90
- * @default "pdf"
91
- */
92
- downloadFormat?: 'pdf' | 'docx' | 'html';
93
- }
94
- export declare const RegulatoryReportGenerator: React.FC<RegulatoryReportGeneratorProps>;