@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.
- package/README.md +113 -402
- package/dist/index.d.mts +448 -0
- package/dist/index.d.ts +448 -31
- package/dist/index.js +191 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +191 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +38 -0
- package/dist/unstyled.d.mts +22 -0
- package/dist/unstyled.d.ts +22 -0
- package/dist/unstyled.js +2 -0
- package/dist/unstyled.js.map +1 -0
- package/dist/unstyled.mjs +2 -0
- package/dist/unstyled.mjs.map +1 -0
- package/package.json +88 -46
- package/dist/components/breach/BreachNotificationManager.d.ts +0 -62
- package/dist/components/breach/BreachReportForm.d.ts +0 -66
- package/dist/components/breach/BreachRiskAssessment.d.ts +0 -50
- package/dist/components/breach/RegulatoryReportGenerator.d.ts +0 -94
- package/dist/components/consent/ConsentBanner.d.ts +0 -79
- package/dist/components/consent/ConsentManager.d.ts +0 -73
- package/dist/components/consent/ConsentStorage.d.ts +0 -41
- package/dist/components/dpia/DPIAQuestionnaire.d.ts +0 -70
- package/dist/components/dpia/DPIAReport.d.ts +0 -40
- package/dist/components/dpia/StepIndicator.d.ts +0 -64
- package/dist/components/dsr/DSRDashboard.d.ts +0 -58
- package/dist/components/dsr/DSRRequestForm.d.ts +0 -74
- package/dist/components/dsr/DSRTracker.d.ts +0 -56
- package/dist/components/policy/PolicyExporter.d.ts +0 -65
- package/dist/components/policy/PolicyGenerator.d.ts +0 -54
- package/dist/components/policy/PolicyPreview.d.ts +0 -71
- package/dist/hooks/useBreach.d.ts +0 -97
- package/dist/hooks/useConsent.d.ts +0 -63
- package/dist/hooks/useDPIA.d.ts +0 -92
- package/dist/hooks/useDSR.d.ts +0 -72
- package/dist/hooks/usePrivacyPolicy.d.ts +0 -87
- package/dist/index.esm.js +0 -2
- package/dist/index.esm.js.map +0 -1
- package/dist/setupTests.d.ts +0 -2
- package/dist/types/breach.d.ts +0 -239
- package/dist/types/consent.d.ts +0 -95
- package/dist/types/dpia.d.ts +0 -196
- package/dist/types/dsr.d.ts +0 -162
- package/dist/types/index.d.ts +0 -35
- package/dist/types/privacy.d.ts +0 -204
- package/dist/utils/breach.d.ts +0 -14
- package/dist/utils/consent.d.ts +0 -10
- package/dist/utils/dpia.d.ts +0 -12
- package/dist/utils/dsr.d.ts +0 -11
- package/dist/utils/privacy.d.ts +0 -12
package/dist/styles.css
ADDED
|
@@ -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 };
|
package/dist/unstyled.js
ADDED
|
@@ -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.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
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
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
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
|
-
"
|
|
24
|
-
"
|
|
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
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@testing-library/
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
52
|
-
"
|
|
53
|
-
"
|
|
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
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"jest
|
|
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
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
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>;
|