@tantainnovative/ndpr-toolkit 2.1.0 → 2.1.2

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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +14 -10
  3. package/dist/{breach-D5zJYNph.d.mts → breach-6z0r-KuE.d.mts} +1 -1
  4. package/dist/{breach-D7NgrdMX.d.ts → breach-BFfnvtRk.d.ts} +1 -1
  5. package/dist/{breach-BpSBPrdk.d.mts → breach-BtFbDOmV.d.mts} +1 -1
  6. package/dist/{breach-BpSBPrdk.d.ts → breach-BtFbDOmV.d.ts} +1 -1
  7. package/dist/breach.d.mts +4 -4
  8. package/dist/breach.d.ts +4 -4
  9. package/dist/chunk-3YCV2BA6.js +2 -0
  10. package/dist/chunk-6GGGTRDZ.mjs +2 -0
  11. package/dist/core.d.mts +2 -2
  12. package/dist/core.d.ts +2 -2
  13. package/dist/dpia.js +1 -1
  14. package/dist/dpia.mjs +1 -1
  15. package/dist/hooks.d.mts +2 -2
  16. package/dist/hooks.d.ts +2 -2
  17. package/dist/hooks.js +1 -1
  18. package/dist/hooks.mjs +1 -1
  19. package/dist/index.d.mts +3 -3
  20. package/dist/index.d.ts +3 -3
  21. package/dist/index.js +1 -1
  22. package/dist/index.mjs +1 -1
  23. package/dist/{useBreach-DRKnexsk.d.mts → useBreach-WrZzJilM.d.mts} +1 -1
  24. package/dist/{useBreach-DuT0N0K1.d.ts → useBreach-vrh_XMpI.d.ts} +1 -1
  25. package/package.json +18 -7
  26. package/dist/breach.js.map +0 -1
  27. package/dist/breach.mjs.map +0 -1
  28. package/dist/chunk-2SYNHRP6.mjs.map +0 -1
  29. package/dist/chunk-2XHD22J7.mjs.map +0 -1
  30. package/dist/chunk-4A354HL3.js.map +0 -1
  31. package/dist/chunk-4DKT6IB6.js.map +0 -1
  32. package/dist/chunk-5ZBO2UPH.js.map +0 -1
  33. package/dist/chunk-6JFTAYXV.mjs.map +0 -1
  34. package/dist/chunk-6JVYYLS7.js.map +0 -1
  35. package/dist/chunk-6SGG6WPA.mjs.map +0 -1
  36. package/dist/chunk-AQEGDEQM.js.map +0 -1
  37. package/dist/chunk-C2IJWCZQ.mjs.map +0 -1
  38. package/dist/chunk-CMZTI7SG.js.map +0 -1
  39. package/dist/chunk-DB3JH4DS.mjs.map +0 -1
  40. package/dist/chunk-EWOZKYLY.mjs +0 -2
  41. package/dist/chunk-EWOZKYLY.mjs.map +0 -1
  42. package/dist/chunk-FFW7RUAG.mjs.map +0 -1
  43. package/dist/chunk-FK3CSFLJ.js.map +0 -1
  44. package/dist/chunk-GIV2OHE6.mjs.map +0 -1
  45. package/dist/chunk-GMLNWS2N.mjs.map +0 -1
  46. package/dist/chunk-IQF726GS.js.map +0 -1
  47. package/dist/chunk-IWUUVRLJ.js.map +0 -1
  48. package/dist/chunk-JUN6YPLL.mjs.map +0 -1
  49. package/dist/chunk-L3FKTBGV.js.map +0 -1
  50. package/dist/chunk-L52PDW6O.mjs.map +0 -1
  51. package/dist/chunk-LI6WJ3LZ.js.map +0 -1
  52. package/dist/chunk-LXRXDTPI.js.map +0 -1
  53. package/dist/chunk-MQFZHA2D.js.map +0 -1
  54. package/dist/chunk-OITITR6K.mjs.map +0 -1
  55. package/dist/chunk-PDJGTQMY.mjs.map +0 -1
  56. package/dist/chunk-PGSA2O5P.mjs.map +0 -1
  57. package/dist/chunk-PM7CMTMB.js.map +0 -1
  58. package/dist/chunk-PYEX7DFR.mjs.map +0 -1
  59. package/dist/chunk-QKK5S54L.mjs.map +0 -1
  60. package/dist/chunk-RB26MIRI.js.map +0 -1
  61. package/dist/chunk-RGYK4VAY.mjs.map +0 -1
  62. package/dist/chunk-RHWW5FDP.js.map +0 -1
  63. package/dist/chunk-RYZEIDNR.js.map +0 -1
  64. package/dist/chunk-SLNMKGQ2.mjs.map +0 -1
  65. package/dist/chunk-SSGJREE3.js.map +0 -1
  66. package/dist/chunk-SWF3YVE5.js.map +0 -1
  67. package/dist/chunk-T44JQT2O.mjs.map +0 -1
  68. package/dist/chunk-TDDAYVKK.js.map +0 -1
  69. package/dist/chunk-TXBZPCGF.mjs.map +0 -1
  70. package/dist/chunk-U2CGMEWB.js +0 -2
  71. package/dist/chunk-U2CGMEWB.js.map +0 -1
  72. package/dist/chunk-UUWVBENC.js.map +0 -1
  73. package/dist/chunk-UYP64PV7.mjs.map +0 -1
  74. package/dist/chunk-VMJBW3EF.mjs.map +0 -1
  75. package/dist/chunk-WW3X3ELF.js.map +0 -1
  76. package/dist/chunk-WWT2ZSNU.mjs.map +0 -1
  77. package/dist/chunk-XMKA6GVK.mjs.map +0 -1
  78. package/dist/chunk-Y34DQYS7.js.map +0 -1
  79. package/dist/chunk-ZU73VG3X.js.map +0 -1
  80. package/dist/consent.js.map +0 -1
  81. package/dist/consent.mjs.map +0 -1
  82. package/dist/core.js.map +0 -1
  83. package/dist/core.mjs.map +0 -1
  84. package/dist/cross-border.js.map +0 -1
  85. package/dist/cross-border.mjs.map +0 -1
  86. package/dist/dpia.js.map +0 -1
  87. package/dist/dpia.mjs.map +0 -1
  88. package/dist/dsr.js.map +0 -1
  89. package/dist/dsr.mjs.map +0 -1
  90. package/dist/hooks.js.map +0 -1
  91. package/dist/hooks.mjs.map +0 -1
  92. package/dist/index.js.map +0 -1
  93. package/dist/index.mjs.map +0 -1
  94. package/dist/lawful-basis.js.map +0 -1
  95. package/dist/lawful-basis.mjs.map +0 -1
  96. package/dist/policy.js.map +0 -1
  97. package/dist/policy.mjs.map +0 -1
  98. package/dist/ropa.js.map +0 -1
  99. package/dist/ropa.mjs.map +0 -1
  100. package/dist/unstyled.js.map +0 -1
  101. package/dist/unstyled.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx","../packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx","../packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx"],"names":["ConsentBanner","options","onSave","title","description","acceptAllButtonText","rejectAllButtonText","customizeButtonText","saveButtonText","position","version","show","storageKey","className","buttonClassName","primaryButtonClassName","secondaryButtonClassName","isOpen","setIsOpen","useState","showCustomize","setShowCustomize","consents","setConsents","useEffect","initialConsents","option","savedConsent","handleAcceptAll","allConsents","saveConsent","handleRejectAll","rejectedConsents","handleToggleConsent","id","value","prev","__spreadProps","__spreadValues","handleSavePreferences","consentValues","settings","React","e","ConsentManager","resetButtonText","showSuccessMessage","successMessage","successMessageDuration","showSuccess","setShowSuccess","handleSave","newSettings","handleReset","defaultConsents","ConsentStorage","storageOptions","onLoad","autoSave","autoLoad","children","storageType","cookieOptions","loaded","setLoaded","loadSettings","saveSettings","loadedSettings","savedData","consentCookie","cookie","cookieValue","error","settingsToSave","settingsString","domain","path","expires","secure","sameSite","expiryDate","cookieString","clearSettings"],"mappings":"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","file":"chunk-SLNMKGQ2.mjs","sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { ConsentOption, ConsentSettings } from '../../types/consent';\n\nexport interface ConsentBannerProps {\n /**\n * Array of consent options to display\n */\n options: ConsentOption[];\n \n /**\n * Callback function called when user saves their consent choices\n */\n onSave: (settings: ConsentSettings) => void;\n \n /**\n * Title displayed on the banner\n * @default \"We Value Your Privacy\"\n */\n title?: string;\n \n /**\n * Description text displayed on the banner\n * @default \"We use cookies and similar technologies to provide our services and enhance your experience.\"\n */\n description?: string;\n \n /**\n * Text for the accept all button\n * @default \"Accept All\"\n */\n acceptAllButtonText?: string;\n \n /**\n * Text for the reject all button\n * @default \"Reject All\"\n */\n rejectAllButtonText?: string;\n \n /**\n * Text for the customize button\n * @default \"Customize\"\n */\n customizeButtonText?: string;\n \n /**\n * Text for the save button\n * @default \"Save Preferences\"\n */\n saveButtonText?: string;\n \n /**\n * Position of the banner\n * @default \"bottom\"\n */\n position?: 'top' | 'bottom' | 'center';\n \n /**\n * Version of the consent form\n * @default \"1.0\"\n */\n version?: string;\n \n /**\n * Whether to show the banner\n * If not provided, the banner will be shown if no consent has been saved\n */\n show?: boolean;\n \n /**\n * Storage key for consent settings\n * @default \"ndpr_consent\"\n */\n storageKey?: string;\n \n /**\n * Custom CSS class for the banner\n */\n className?: string;\n \n /**\n * Custom CSS class for the buttons\n */\n buttonClassName?: string;\n \n /**\n * Custom CSS class for the primary button\n */\n primaryButtonClassName?: string;\n \n /**\n * Custom CSS class for the secondary button\n */\n secondaryButtonClassName?: string;\n}\n\nexport const ConsentBanner: React.FC<ConsentBannerProps> = ({\n options,\n onSave,\n title = \"We Value Your Privacy\",\n description = \"We use cookies and similar technologies to provide our services and enhance your experience.\",\n acceptAllButtonText = \"Accept All\",\n rejectAllButtonText = \"Reject All\",\n customizeButtonText = \"Customize\",\n saveButtonText = \"Save Preferences\",\n position = \"bottom\",\n version = \"1.0\",\n show,\n storageKey = \"ndpr_consent\",\n className = \"\",\n buttonClassName = \"\",\n primaryButtonClassName = \"\",\n secondaryButtonClassName = \"\"\n}) => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [showCustomize, setShowCustomize] = useState<boolean>(false);\n const [consents, setConsents] = useState<Record<string, boolean>>({});\n \n // Initialize consents from options\n useEffect(() => {\n const initialConsents: Record<string, boolean> = {};\n options.forEach(option => {\n initialConsents[option.id] = option.defaultValue || false;\n });\n setConsents(initialConsents);\n \n // Check if consent is already saved\n if (show === undefined) {\n const savedConsent = localStorage.getItem(storageKey);\n setIsOpen(!savedConsent);\n } else {\n setIsOpen(show);\n }\n }, [options, show, storageKey]);\n \n const handleAcceptAll = () => {\n const allConsents: Record<string, boolean> = {};\n options.forEach(option => {\n allConsents[option.id] = true;\n });\n saveConsent(allConsents);\n };\n \n const handleRejectAll = () => {\n const rejectedConsents: Record<string, boolean> = {};\n options.forEach(option => {\n rejectedConsents[option.id] = option.required || false;\n });\n saveConsent(rejectedConsents);\n };\n \n const handleToggleConsent = (id: string, value: boolean) => {\n setConsents(prev => ({\n ...prev,\n [id]: value\n }));\n };\n \n const handleSavePreferences = () => {\n saveConsent(consents);\n };\n \n const saveConsent = (consentValues: Record<string, boolean>) => {\n const settings: ConsentSettings = {\n consents: consentValues,\n timestamp: Date.now(),\n version,\n method: showCustomize ? 'customize' : 'banner',\n hasInteracted: true\n };\n \n // Save to localStorage\n localStorage.setItem(storageKey, JSON.stringify(settings));\n \n // Call onSave callback\n onSave(settings);\n \n // Close the banner\n setIsOpen(false);\n setShowCustomize(false);\n };\n \n if (!isOpen) {\n return null;\n }\n \n const positionClass = \n position === 'top' ? 'top-0 left-0 right-0' :\n position === 'center' ? 'top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 max-w-lg' :\n 'bottom-0 left-0 right-0';\n \n return (\n <div \n className={`fixed z-50 bg-white dark:bg-gray-800 shadow-lg p-4 border border-gray-200 dark:border-gray-700 ${positionClass} ${className}`}\n role=\"dialog\"\n aria-labelledby=\"consent-banner-title\"\n >\n <div className=\"max-w-6xl mx-auto\">\n <h2 id=\"consent-banner-title\" className=\"text-lg font-bold mb-2\">{title}</h2>\n <p className=\"mb-4\">{description}</p>\n \n {showCustomize ? (\n <div className=\"mb-4\">\n <div className=\"space-y-3\">\n {options.map(option => (\n <div key={option.id} className=\"flex items-start\">\n <div className=\"flex items-center h-5\">\n <input\n id={`consent-${option.id}`}\n type=\"checkbox\"\n checked={consents[option.id] || false}\n onChange={e => handleToggleConsent(option.id, e.target.checked)}\n disabled={option.required}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500\"\n />\n </div>\n <div className=\"ml-3 text-sm\">\n <label htmlFor={`consent-${option.id}`} className=\"font-medium\">\n {option.label} {option.required && <span className=\"text-red-500\">*</span>}\n </label>\n <p className=\"text-gray-500 dark:text-gray-400\">{option.description}</p>\n </div>\n </div>\n ))}\n </div>\n \n <div className=\"mt-4 flex flex-wrap gap-2\">\n <button\n onClick={handleSavePreferences}\n className={`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 ${buttonClassName} ${primaryButtonClassName}`}\n >\n {saveButtonText}\n </button>\n <button\n onClick={() => setShowCustomize(false)}\n className={`px-4 py-2 bg-gray-200 text-gray-800 dark:bg-gray-700 dark:text-white rounded hover:bg-gray-300 dark:hover:bg-gray-600 ${buttonClassName} ${secondaryButtonClassName}`}\n >\n Back\n </button>\n </div>\n </div>\n ) : (\n <div className=\"flex flex-wrap gap-2\">\n <button\n onClick={handleAcceptAll}\n className={`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 ${buttonClassName} ${primaryButtonClassName}`}\n >\n {acceptAllButtonText}\n </button>\n <button\n onClick={handleRejectAll}\n className={`px-4 py-2 bg-gray-200 text-gray-800 dark:bg-gray-700 dark:text-white rounded hover:bg-gray-300 dark:hover:bg-gray-600 ${buttonClassName} ${secondaryButtonClassName}`}\n >\n {rejectAllButtonText}\n </button>\n <button\n onClick={() => setShowCustomize(true)}\n className={`px-4 py-2 bg-transparent text-gray-800 dark:text-white hover:underline ${buttonClassName}`}\n >\n {customizeButtonText}\n </button>\n </div>\n )}\n \n <div className=\"mt-2 text-xs text-gray-500 dark:text-gray-400\">\n By clicking \"Accept All\", you agree to the use of ALL cookies. Visit our Cookie Policy to learn more.\n </div>\n </div>\n </div>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport { ConsentOption, ConsentSettings } from '../../types/consent';\n\nexport interface ConsentManagerProps {\n /**\n * Array of consent options to display\n */\n options: ConsentOption[];\n \n /**\n * Current consent settings\n */\n settings?: ConsentSettings;\n \n /**\n * Callback function called when user saves their consent choices\n */\n onSave: (settings: ConsentSettings) => void;\n \n /**\n * Title displayed in the manager\n * @default \"Manage Your Privacy Settings\"\n */\n title?: string;\n \n /**\n * Description text displayed in the manager\n * @default \"Update your consent preferences at any time. Required cookies cannot be disabled as they are necessary for the website to function.\"\n */\n description?: string;\n \n /**\n * Text for the save button\n * @default \"Save Preferences\"\n */\n saveButtonText?: string;\n \n /**\n * Text for the reset button\n * @default \"Reset to Defaults\"\n */\n resetButtonText?: string;\n \n /**\n * Version of the consent form\n * @default \"1.0\"\n */\n version?: string;\n \n /**\n * Custom CSS class for the manager\n */\n className?: string;\n \n /**\n * Custom CSS class for the buttons\n */\n buttonClassName?: string;\n \n /**\n * Custom CSS class for the primary button\n */\n primaryButtonClassName?: string;\n \n /**\n * Custom CSS class for the secondary button\n */\n secondaryButtonClassName?: string;\n \n /**\n * Whether to show a success message after saving\n * @default true\n */\n showSuccessMessage?: boolean;\n \n /**\n * Success message to display after saving\n * @default \"Your preferences have been saved.\"\n */\n successMessage?: string;\n \n /**\n * Duration to show the success message (in milliseconds)\n * @default 3000\n */\n successMessageDuration?: number;\n}\n\nexport const ConsentManager: React.FC<ConsentManagerProps> = ({\n options,\n settings,\n onSave,\n title = \"Manage Your Privacy Settings\",\n description = \"Update your consent preferences at any time. Required cookies cannot be disabled as they are necessary for the website to function.\",\n saveButtonText = \"Save Preferences\",\n resetButtonText = \"Reset to Defaults\",\n version = \"1.0\",\n className = \"\",\n buttonClassName = \"\",\n primaryButtonClassName = \"\",\n secondaryButtonClassName = \"\",\n showSuccessMessage = true,\n successMessage = \"Your preferences have been saved.\",\n successMessageDuration = 3000\n}) => {\n const [consents, setConsents] = useState<Record<string, boolean>>({});\n const [showSuccess, setShowSuccess] = useState<boolean>(false);\n \n // Initialize consents from settings or options\n useEffect(() => {\n if (settings && settings.consents) {\n setConsents(settings.consents);\n } else {\n const initialConsents: Record<string, boolean> = {};\n options.forEach(option => {\n initialConsents[option.id] = option.defaultValue || false;\n });\n setConsents(initialConsents);\n }\n }, [options, settings]);\n \n const handleToggleConsent = (id: string, value: boolean) => {\n setConsents(prev => ({\n ...prev,\n [id]: value\n }));\n };\n \n const handleSave = () => {\n const newSettings: ConsentSettings = {\n consents,\n timestamp: Date.now(),\n version,\n method: 'manager',\n hasInteracted: true\n };\n \n onSave(newSettings);\n \n if (showSuccessMessage) {\n setShowSuccess(true);\n setTimeout(() => {\n setShowSuccess(false);\n }, successMessageDuration);\n }\n };\n \n const handleReset = () => {\n const defaultConsents: Record<string, boolean> = {};\n options.forEach(option => {\n defaultConsents[option.id] = option.defaultValue || false;\n });\n setConsents(defaultConsents);\n };\n \n return (\n <div className={`bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 ${className}`}>\n <h2 className=\"text-xl font-bold mb-2\">{title}</h2>\n <p className=\"mb-6 text-gray-600 dark:text-gray-300\">{description}</p>\n \n <div className=\"space-y-6\">\n {options.map(option => (\n <div key={option.id} className=\"border-b border-gray-200 dark:border-gray-700 pb-4 last:border-0\">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"font-medium text-gray-900 dark:text-white\">{option.label}</h3>\n <p className=\"text-sm text-gray-500 dark:text-gray-400 mt-1\">{option.description}</p>\n </div>\n <div className=\"ml-4 flex-shrink-0\">\n <label className=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n className=\"sr-only peer\"\n checked={consents[option.id] || false}\n onChange={e => handleToggleConsent(option.id, e.target.checked)}\n disabled={option.required}\n />\n <div className={`w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600 ${option.required ? 'opacity-60' : ''}`}></div>\n <span className=\"ml-3 text-sm font-medium text-gray-900 dark:text-gray-300\">\n {consents[option.id] ? 'Enabled' : 'Disabled'}\n {option.required && <span className=\"text-xs text-red-500 ml-1\">(Required)</span>}\n </span>\n </label>\n </div>\n </div>\n </div>\n ))}\n </div>\n \n {showSuccess && (\n <div className=\"mt-4 p-3 bg-green-50 dark:bg-green-900/20 text-green-800 dark:text-green-200 rounded-md\">\n {successMessage}\n </div>\n )}\n \n <div className=\"mt-6 flex flex-wrap gap-3\">\n <button\n onClick={handleSave}\n className={`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 ${buttonClassName} ${primaryButtonClassName}`}\n >\n {saveButtonText}\n </button>\n <button\n onClick={handleReset}\n className={`px-4 py-2 bg-gray-200 text-gray-800 dark:bg-gray-700 dark:text-white rounded hover:bg-gray-300 dark:hover:bg-gray-600 ${buttonClassName} ${secondaryButtonClassName}`}\n >\n {resetButtonText}\n </button>\n </div>\n \n <div className=\"mt-4 text-xs text-gray-500 dark:text-gray-400\">\n <p>Last updated: {settings ? new Date(settings.timestamp).toLocaleString() : 'Never'}</p>\n <p>Version: {version}</p>\n </div>\n </div>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport { ConsentSettings, ConsentStorageOptions } from '../../types/consent';\n\nexport interface ConsentStorageProps {\n /**\n * Current consent settings\n */\n settings: ConsentSettings;\n \n /**\n * Storage options for consent settings\n */\n storageOptions?: ConsentStorageOptions;\n \n /**\n * Callback function called when settings are loaded from storage\n */\n onLoad?: (settings: ConsentSettings | null) => void;\n \n /**\n * Callback function called when settings are saved to storage\n */\n onSave?: (settings: ConsentSettings) => void;\n \n /**\n * Whether to automatically save settings to storage\n * @default true\n */\n autoSave?: boolean;\n \n /**\n * Whether to automatically load settings from storage on mount\n * @default true\n */\n autoLoad?: boolean;\n \n /**\n * Children to render\n * Can be either React nodes or a render prop function that receives storage methods\n */\n children?: React.ReactNode | ((props: {\n loadSettings: () => ConsentSettings | null;\n saveSettings: (settings: ConsentSettings) => void;\n clearSettings: () => void;\n loaded: boolean;\n }) => React.ReactNode);\n}\n\nexport const ConsentStorage = ({\n settings,\n storageOptions = {},\n onLoad,\n onSave,\n autoSave = true,\n autoLoad = true,\n children\n}: ConsentStorageProps): React.ReactElement | null => {\n const {\n storageKey = \"ndpr_consent\",\n storageType = \"localStorage\",\n cookieOptions = {}\n } = storageOptions;\n \n const [loaded, setLoaded] = useState<boolean>(false);\n \n // Load consent settings from storage on mount\n useEffect(() => {\n if (autoLoad && !loaded) {\n loadSettings();\n }\n }, [autoLoad, loaded]);\n \n // Save consent settings to storage when they change\n useEffect(() => {\n if (autoSave && loaded) {\n saveSettings(settings);\n }\n }, [settings, autoSave, loaded]);\n \n // Load settings from storage\n const loadSettings = (): ConsentSettings | null => {\n let loadedSettings: ConsentSettings | null = null;\n \n try {\n if (storageType === 'localStorage' && typeof window !== 'undefined') {\n const savedData = localStorage.getItem(storageKey);\n if (savedData) {\n loadedSettings = JSON.parse(savedData);\n }\n } else if (storageType === 'sessionStorage' && typeof window !== 'undefined') {\n const savedData = sessionStorage.getItem(storageKey);\n if (savedData) {\n loadedSettings = JSON.parse(savedData);\n }\n } else if (storageType === 'cookie' && typeof document !== 'undefined') {\n const cookies = document.cookie.split(';');\n const consentCookie = cookies.find(cookie => cookie.trim().startsWith(`${storageKey}=`));\n if (consentCookie) {\n const cookieValue = consentCookie.split('=')[1];\n loadedSettings = JSON.parse(decodeURIComponent(cookieValue));\n }\n }\n \n setLoaded(true);\n \n if (onLoad) {\n onLoad(loadedSettings);\n }\n } catch (error) {\n console.error('Error loading consent settings:', error);\n setLoaded(true);\n \n if (onLoad) {\n onLoad(null);\n }\n }\n \n return loadedSettings;\n };\n \n // Save settings to storage\n const saveSettings = (settingsToSave: ConsentSettings): boolean => {\n try {\n const settingsString = JSON.stringify(settingsToSave);\n \n if (storageType === 'localStorage' && typeof window !== 'undefined') {\n localStorage.setItem(storageKey, settingsString);\n } else if (storageType === 'sessionStorage' && typeof window !== 'undefined') {\n sessionStorage.setItem(storageKey, settingsString);\n } else if (storageType === 'cookie' && typeof document !== 'undefined') {\n const {\n domain,\n path = '/',\n expires = 365,\n secure = true,\n sameSite = 'Lax'\n } = cookieOptions;\n \n const expiryDate = new Date();\n expiryDate.setDate(expiryDate.getDate() + expires);\n \n let cookieString = `${storageKey}=${encodeURIComponent(settingsString)}; path=${path}; expires=${expiryDate.toUTCString()}`;\n \n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n \n if (secure) {\n cookieString += '; secure';\n }\n \n cookieString += `; samesite=${sameSite}`;\n \n document.cookie = cookieString;\n }\n \n if (onSave) {\n onSave(settingsToSave);\n }\n \n return true;\n } catch (error) {\n console.error('Error saving consent settings:', error);\n return false;\n }\n };\n \n // Clear settings from storage\n const clearSettings = (): boolean => {\n try {\n if (storageType === 'localStorage' && typeof window !== 'undefined') {\n localStorage.removeItem(storageKey);\n } else if (storageType === 'sessionStorage' && typeof window !== 'undefined') {\n sessionStorage.removeItem(storageKey);\n } else if (storageType === 'cookie' && typeof document !== 'undefined') {\n const { domain, path = '/' } = cookieOptions;\n \n let cookieString = `${storageKey}=; path=${path}; expires=Thu, 01 Jan 1970 00:00:00 GMT`;\n \n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n \n document.cookie = cookieString;\n }\n \n return true;\n } catch (error) {\n console.error('Error clearing consent settings:', error);\n return false;\n }\n };\n \n // If children is a function, call it with the storage methods\n if (typeof children === 'function') {\n return <>{children({\n loadSettings,\n saveSettings,\n clearSettings,\n loaded\n })}</>; \n }\n \n // Otherwise, just render the children\n return <>{children}</>;\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/dpia.ts"],"names":["assessDPIARisk","dpiaResult","riskCounts","highestRiskScore","unmitigatedHighRisks","risk","overallRiskLevel","requiresConsultation","canProceed","recommendations"],"mappings":"aAOO,SAASA,CAAAA,CAAeC,CAAAA,CAK7B,CAEA,IAAMC,EAAa,CACjB,GAAA,CAAK,CAAA,CACL,MAAA,CAAQ,CAAA,CACR,IAAA,CAAM,CAAA,CACN,QAAA,CAAU,CACZ,CAAA,CAGIC,CAAAA,CAAmB,CAAA,CAGjBC,CAAAA,CAAmC,EAAC,CAG1CH,CAAAA,CAAW,KAAA,CAAM,QAAQI,CAAAA,EAAQ,CAE/BH,CAAAA,CAAWG,CAAAA,CAAK,KAAK,CAAA,EAAA,CAGjBA,CAAAA,CAAK,KAAA,CAAQF,IACfA,CAAAA,CAAmBE,CAAAA,CAAK,KAAA,CAAA,CAAA,CAIrBA,CAAAA,CAAK,KAAA,GAAU,MAAA,EAAUA,CAAAA,CAAK,KAAA,GAAU,aAAe,CAACA,CAAAA,CAAK,SAAA,EAChED,CAAAA,CAAqB,IAAA,CAAKC,CAAI,EAElC,CAAC,EAGD,IAAIC,CAAAA,CAEAJ,CAAAA,CAAW,QAAA,CAAW,CAAA,CACxBI,CAAAA,CAAmB,UAAA,CACVJ,CAAAA,CAAW,KAAO,CAAA,EAAMA,CAAAA,CAAW,IAAA,CAAO,CAAA,EAAKA,CAAAA,CAAW,MAAA,CAAS,CAAA,CAC5EI,CAAAA,CAAmB,OACVJ,CAAAA,CAAW,IAAA,CAAO,CAAA,EAAKA,CAAAA,CAAW,MAAA,CAAS,CAAA,CACpDI,CAAAA,CAAmB,QAAA,CAEnBA,EAAmB,KAAA,CAKrB,IAAMC,CAAAA,CAAuBD,CAAAA,GAAqB,MAAA,EAAUA,CAAAA,GAAqB,UAAA,CAI3EE,CAAAA,CAAaJ,EAAqB,MAAA,GAAW,CAAA,CAG7CK,CAAAA,CAA4B,EAAC,CAEnC,OAAIL,CAAAA,CAAqB,MAAA,CAAS,GAChCK,CAAAA,CAAgB,IAAA,CACd,CAAA,8DAAA,EACEL,CAAAA,CAAqB,GAAA,CAAIC,CAAAA,EAAQA,CAAAA,CAAK,WAAW,EAAE,IAAA,CAAK,IAAI,CAC9D,CAAA,CACF,CAAA,CAGEE,CAAAA,EACFE,CAAAA,CAAgB,IAAA,CACd,6IACF,CAAA,CAGEP,CAAAA,CAAW,MAAA,CAAS,CAAA,EACtBO,CAAAA,CAAgB,IAAA,CACd,8EACF,CAAA,CAGEH,IAAqB,KAAA,CACvBG,CAAAA,CAAgB,IAAA,CACd,wGACF,CAAA,CAEAA,CAAAA,CAAgB,IAAA,CACd,uFACF,EAGK,CACL,gBAAA,CAAAH,CAAAA,CACA,oBAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CACA,eAAA,CAAAC,CACF,CACF","file":"chunk-SSGJREE3.js","sourcesContent":["import { DPIAResult, DPIARisk } from '../types/dpia';\n\n/**\n * Assesses the risk level of a DPIA based on the identified risks\n * @param dpiaResult The DPIA result containing risks to assess\n * @returns Assessment result with overall risk level and recommendations\n */\nexport function assessDPIARisk(dpiaResult: DPIAResult): {\n overallRiskLevel: 'low' | 'medium' | 'high' | 'critical';\n requiresConsultation: boolean;\n canProceed: boolean;\n recommendations: string[];\n} {\n // Count risks by level\n const riskCounts = {\n low: 0,\n medium: 0,\n high: 0,\n critical: 0\n };\n \n // Calculate the highest risk score\n let highestRiskScore = 0;\n \n // Track unmitigated high/critical risks\n const unmitigatedHighRisks: DPIARisk[] = [];\n \n // Analyze each risk\n dpiaResult.risks.forEach(risk => {\n // Count by level\n riskCounts[risk.level]++;\n \n // Track highest score\n if (risk.score > highestRiskScore) {\n highestRiskScore = risk.score;\n }\n \n // Track unmitigated high/critical risks\n if ((risk.level === 'high' || risk.level === 'critical') && !risk.mitigated) {\n unmitigatedHighRisks.push(risk);\n }\n });\n \n // Determine overall risk level\n let overallRiskLevel: 'low' | 'medium' | 'high' | 'critical';\n \n if (riskCounts.critical > 0) {\n overallRiskLevel = 'critical';\n } else if (riskCounts.high > 2 || (riskCounts.high > 0 && riskCounts.medium > 3)) {\n overallRiskLevel = 'high';\n } else if (riskCounts.high > 0 || riskCounts.medium > 1) {\n overallRiskLevel = 'medium';\n } else {\n overallRiskLevel = 'low';\n }\n \n // Determine if NDPC consultation is required\n // Under NDPA Section 39, prior consultation with the NDPC is required when residual risk is high\n const requiresConsultation = overallRiskLevel === 'high' || overallRiskLevel === 'critical';\n \n // Determine if processing can proceed\n // Processing can proceed if all high/critical risks are mitigated\n const canProceed = unmitigatedHighRisks.length === 0;\n \n // Generate recommendations\n const recommendations: string[] = [];\n \n if (unmitigatedHighRisks.length > 0) {\n recommendations.push(\n `Mitigate the following high/critical risks before proceeding: ${\n unmitigatedHighRisks.map(risk => risk.description).join(', ')\n }`\n );\n }\n \n if (requiresConsultation) {\n recommendations.push(\n 'Consult with the NDPC (Nigeria Data Protection Commission) before proceeding with this processing activity, as required by NDPA Section 39.'\n );\n }\n \n if (riskCounts.medium > 0) {\n recommendations.push(\n 'Implement additional safeguards to reduce medium-level risks where possible.'\n );\n }\n \n if (overallRiskLevel !== 'low') {\n recommendations.push(\n 'Schedule a review of this DPIA in 6 months to reassess risks and effectiveness of mitigation measures.'\n );\n } else {\n recommendations.push(\n 'Schedule a review of this DPIA in 12 months as part of regular compliance activities.'\n );\n }\n \n return {\n overallRiskLevel,\n requiresConsultation,\n canProceed,\n recommendations\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/ropa.ts"],"names":["ALL_LAWFUL_BASES","validateProcessingRecord","record","errors","generateROPASummary","ropa","byLawfulBasis","acc","basis","activeRecords","sensitiveDataRecords","crossBorderRecords","dpiaRequiredRecords","automatedDecisionRecords","recordsDueForReview","departmentCounts","now","topDepartments","department","count","b","escapeCSVField","value","formatTimestamp","timestamp","exportROPAToCSV","headers","rows","crossBorderSummary","t","field","h","row","identifyComplianceGaps","gaps","recordGaps","overdueBy","transfer"],"mappings":"aAwBA,IAAMA,CAAAA,CAAkC,CACtC,SAAA,CACA,UAAA,CACA,mBACA,iBAAA,CACA,iBAAA,CACA,sBACF,CAAA,CASO,SAASC,CAAAA,CACdC,EACsB,CACtB,IAAMC,EAAmB,EAAC,CAE1B,QAAI,CAACD,CAAAA,CAAO,EAAA,EAAMA,CAAAA,CAAO,EAAA,CAAG,IAAA,KAAW,EAAA,GACrCC,CAAAA,CAAO,KAAK,wBAAwB,CAAA,CAAA,CAGlC,CAACD,CAAAA,CAAO,IAAA,EAAQA,CAAAA,CAAO,IAAA,CAAK,IAAA,EAAK,GAAM,KACzCC,CAAAA,CAAO,IAAA,CAAK,uCAAuC,CAAA,CAAA,CAGjD,CAACD,CAAAA,CAAO,aAAeA,CAAAA,CAAO,WAAA,CAAY,IAAA,EAAK,GAAM,EAAA,GACvDC,CAAAA,CAAO,KAAK,qCAAqC,CAAA,CAG9CD,EAAO,iBAAA,EAAA,CAGN,CAACA,EAAO,iBAAA,CAAkB,IAAA,EAAQA,CAAAA,CAAO,iBAAA,CAAkB,IAAA,CAAK,IAAA,KAAW,EAAA,GAC7EC,CAAAA,CAAO,IAAA,CAAK,8BAA8B,CAAA,CAAA,CAExC,CAACD,EAAO,iBAAA,CAAkB,OAAA,EAAWA,CAAAA,CAAO,iBAAA,CAAkB,OAAA,CAAQ,IAAA,KAAW,EAAA,GACnFC,CAAAA,CAAO,KAAK,iCAAiC,CAAA,CAAA,CAE3C,CAACD,CAAAA,CAAO,iBAAA,CAAkB,OAAA,EAAWA,CAAAA,CAAO,iBAAA,CAAkB,OAAA,CAAQ,MAAK,GAAM,EAAA,GACnFC,CAAAA,CAAO,IAAA,CAAK,iCAAiC,CAAA,EAT/CA,EAAO,IAAA,CAAK,kCAAkC,CAAA,CAAA,CAa5C,CAACD,CAAAA,CAAO,WAAA,EAAe,CAACF,CAAAA,CAAiB,QAAA,CAASE,EAAO,WAAW,CAAA,GACtEC,EAAO,IAAA,CAAK,2DAA2D,CAAA,CAAA,CAGrE,CAACD,CAAAA,CAAO,wBAAA,EAA4BA,EAAO,wBAAA,CAAyB,IAAA,KAAW,EAAA,GACjFC,CAAAA,CAAO,KAAK,mEAAmE,CAAA,CAAA,CAG7E,CAACD,CAAAA,CAAO,QAAA,EAAYA,CAAAA,CAAO,SAAS,MAAA,GAAW,CAAA,GACjDC,EAAO,IAAA,CAAK,oDAAoD,GAG9D,CAACD,CAAAA,CAAO,cAAA,EAAkBA,CAAAA,CAAO,cAAA,CAAe,MAAA,GAAW,IAC7DC,CAAAA,CAAO,IAAA,CAAK,+CAA+C,CAAA,CAAA,CAGzD,CAACD,CAAAA,CAAO,uBAAyBA,CAAAA,CAAO,qBAAA,CAAsB,MAAA,GAAW,CAAA,GAC3EC,CAAAA,CAAO,IAAA,CAAK,uDAAuD,CAAA,CAAA,CAGjE,CAACD,EAAO,UAAA,EAAcA,CAAAA,CAAO,WAAW,MAAA,GAAW,CAAA,GACrDC,CAAAA,CAAO,IAAA,CAAK,qEAAqE,CAAA,CAAA,CAG/E,CAACD,CAAAA,CAAO,eAAA,EAAmBA,CAAAA,CAAO,eAAA,CAAgB,IAAA,EAAK,GAAM,KAC/DC,CAAAA,CAAO,IAAA,CAAK,qCAAqC,CAAA,CAAA,CAG/C,CAACD,CAAAA,CAAO,kBAAoBA,CAAAA,CAAO,gBAAA,CAAiB,SAAW,CAAA,GACjEC,CAAAA,CAAO,KAAK,mDAAmD,CAAA,CAG5DD,CAAAA,CAAO,UAAA,EACVC,CAAAA,CAAO,IAAA,CAAK,gCAAgC,CAAA,CAI5CD,CAAAA,CAAO,UAAA,GAAe,aAAA,GACrB,CAACA,CAAAA,CAAO,yBAA2BA,CAAAA,CAAO,uBAAA,CAAwB,IAAA,EAAK,GAAM,EAAA,CAAA,EAE9EC,CAAAA,CAAO,KAAK,4EAA4E,CAAA,CAIxFD,EAAO,uBAAA,GACN,CAACA,EAAO,8BAAA,EAAkCA,CAAAA,CAAO,8BAAA,CAA+B,IAAA,EAAK,GAAM,EAAA,CAAA,EAE5FC,EAAO,IAAA,CACL,4FACF,EAIAD,CAAAA,CAAO,YAAA,GACN,CAACA,CAAAA,CAAO,aAAA,EAAiBA,CAAAA,CAAO,aAAA,CAAc,IAAA,EAAK,GAAM,KAE1DC,CAAAA,CAAO,IAAA,CAAK,6DAA6D,CAAA,CAGpE,CACL,MAAOA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACzB,MAAA,CAAAA,CACF,CACF,CASO,SAASC,CAAAA,CACdC,CAAAA,CACa,CACb,IAAMC,CAAAA,CAAgBN,EAAiB,MAAA,CACrC,CAACO,CAAAA,CAAKC,CAAAA,IACJD,CAAAA,CAAIC,CAAK,EAAI,CAAA,CACND,CAAAA,CAAAA,CAET,EACF,CAAA,CAEIE,EAAgB,CAAA,CAChBC,CAAAA,CAAuB,CAAA,CACvBC,CAAAA,CAAqB,CAAA,CACrBC,CAAAA,CAAsB,EACtBC,CAAAA,CAA2B,CAAA,CACzBC,CAAAA,CAA0C,EAAC,CAC3CC,CAAAA,CAA2C,EAAC,CAE5CC,CAAAA,CAAM,IAAA,CAAK,GAAA,EAAI,CAErB,IAAA,IAAWd,KAAUG,CAAAA,CAAK,OAAA,CAEpBH,EAAO,WAAA,EAAeF,CAAAA,CAAiB,SAASE,CAAAA,CAAO,WAAW,CAAA,EACpEI,CAAAA,CAAcJ,CAAAA,CAAO,WAAW,IAI9BA,CAAAA,CAAO,MAAA,GAAW,QAAA,EACpBO,CAAAA,EAAAA,CAKAP,CAAAA,CAAO,uBAAA,EACPA,EAAO,uBAAA,CAAwB,MAAA,CAAS,CAAA,EAExCQ,CAAAA,EAAAA,CAIER,CAAAA,CAAO,oBAAA,EAAwBA,EAAO,oBAAA,CAAqB,MAAA,CAAS,GACtES,CAAAA,EAAAA,CAIET,CAAAA,CAAO,cACTU,CAAAA,EAAAA,CAIEV,CAAAA,CAAO,uBAAA,EACTW,CAAAA,EAAAA,CAIEX,CAAAA,CAAO,cAAA,EAAkBA,EAAO,cAAA,EAAkBc,CAAAA,EACpDF,EAAoB,IAAA,CAAKZ,CAAM,EAI7BA,CAAAA,CAAO,UAAA,GACTa,CAAAA,CAAiBb,CAAAA,CAAO,UAAU,CAAA,CAAA,CAC/Ba,EAAiBb,CAAAA,CAAO,UAAU,GAAK,CAAA,EAAK,CAAA,CAAA,CAKnD,IAAMe,CAAAA,CAAiB,MAAA,CAAO,OAAA,CAAQF,CAAgB,CAAA,CACnD,GAAA,CAAI,CAAC,CAACG,CAAAA,CAAYC,CAAK,CAAA,IAAO,CAAE,UAAA,CAAAD,EAAY,KAAA,CAAAC,CAAM,CAAA,CAAE,CAAA,CACpD,IAAA,CAAK,CAAC,EAAGC,CAAAA,GAAMA,CAAAA,CAAE,MAAQ,CAAA,CAAE,KAAK,EAChC,KAAA,CAAM,CAAA,CAAG,EAAE,CAAA,CAEd,OAAO,CACL,aAAcf,CAAAA,CAAK,OAAA,CAAQ,MAAA,CAC3B,aAAA,CAAAI,CAAAA,CACA,aAAA,CAAAH,EACA,oBAAA,CAAAI,CAAAA,CACA,kBAAA,CAAAC,CAAAA,CACA,mBAAA,CAAAC,CAAAA,CACA,yBAAAC,CAAAA,CACA,mBAAA,CAAAC,EACA,cAAA,CAAAG,CAAAA,CACA,YAAaZ,CAAAA,CAAK,WACpB,CACF,CAKA,SAASgB,CAAAA,CAAeC,EAAuB,CAC7C,OACEA,CAAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAClBA,EAAM,QAAA,CAAS,GAAG,CAAA,EAClBA,CAAAA,CAAM,QAAA,CAAS;AAAA,CAAI,CAAA,EACnBA,EAAM,QAAA,CAAS,IAAI,EAEZ,CAAA,CAAA,EAAIA,CAAAA,CAAM,OAAA,CAAQ,IAAA,CAAM,IAAI,CAAC,IAE/BA,CACT,CAKA,SAASC,CAAAA,CAAgBC,CAAAA,CAAuC,CAC9D,OAAKA,CAAAA,CACE,IAAI,IAAA,CAAKA,CAAS,CAAA,CAAE,WAAA,GADJ,EAEzB,CASO,SAASC,CAAAA,CAAgBpB,CAAAA,CAA4C,CAC1E,IAAMqB,CAAAA,CAAU,CACd,IAAA,CACA,MAAA,CACA,aAAA,CACA,iBAAA,CACA,qBACA,cAAA,CACA,4BAAA,CACA,UAAA,CACA,iBAAA,CACA,2BAAA,CACA,yBAAA,CACA,aACA,wBAAA,CACA,kBAAA,CACA,mBAAA,CACA,aAAA,CACA,eAAA,CACA,gBAAA,CACA,4BACA,QAAA,CACA,YAAA,CACA,cAAA,CACA,YAAA,CACA,YAAA,CACA,kBAAA,CACA,kBACF,CAAA,CAEMC,CAAAA,CAAOtB,CAAAA,CAAK,OAAA,CAAQ,GAAA,CAAKH,CAAAA,EAAW,CACxC,IAAM0B,CAAAA,CAAqB1B,CAAAA,CAAO,oBAAA,CAC9BA,CAAAA,CAAO,oBAAA,CACJ,IACE2B,CAAAA,EACC,CAAA,EAAGA,CAAAA,CAAE,kBAAkB,CAAA,EAAA,EAAKA,CAAAA,CAAE,iBAAiB,CAAA,EAAA,EAAKA,CAAAA,CAAE,UAAU,CAAA,CAAA,CACpE,CAAA,CACC,IAAA,CAAK,IAAI,CAAA,CACZ,EAAA,CAEJ,OAAO,CACL3B,CAAAA,CAAO,EAAA,CACPA,EAAO,IAAA,CACPA,CAAAA,CAAO,WAAA,CACPA,CAAAA,CAAO,iBAAA,CAAkB,IAAA,CACzBA,EAAO,iBAAA,CAAkB,OAAA,CACzBA,CAAAA,CAAO,WAAA,CACPA,CAAAA,CAAO,wBAAA,CACPA,EAAO,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,CACzBA,CAAAA,CAAO,eAAe,IAAA,CAAK,IAAI,CAAA,CAAA,CAC9BA,CAAAA,CAAO,uBAAA,EAA2B,IAAI,IAAA,CAAK,IAAI,CAAA,CAChDA,CAAAA,CAAO,qBAAA,CAAsB,IAAA,CAAK,IAAI,CAAA,CACtCA,CAAAA,CAAO,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,CAC3B0B,EACA1B,CAAAA,CAAO,eAAA,CACPA,CAAAA,CAAO,gBAAA,CAAiB,IAAA,CAAK,IAAI,EACjCA,CAAAA,CAAO,UAAA,CACPA,CAAAA,CAAO,YAAA,CAAe,KAAA,CAAQ,IAAA,CAC9BA,EAAO,aAAA,EAAiB,EAAA,CACxBA,CAAAA,CAAO,uBAAA,CAA0B,KAAA,CAAQ,IAAA,CACzCA,EAAO,MAAA,CACPA,CAAAA,CAAO,UAAA,EAAc,EAAA,CAAA,CACpBA,CAAAA,CAAO,WAAA,EAAe,EAAC,EAAG,IAAA,CAAK,IAAI,CAAA,CACpCqB,CAAAA,CAAgBrB,CAAAA,CAAO,SAAS,CAAA,CAChCqB,CAAAA,CAAgBrB,CAAAA,CAAO,SAAS,CAAA,CAChCqB,CAAAA,CAAgBrB,EAAO,cAAc,CAAA,CACrCqB,CAAAA,CAAgBrB,CAAAA,CAAO,cAAc,CACvC,EAAE,GAAA,CAAK4B,CAAAA,EAAUT,CAAAA,CAAe,MAAA,CAAOS,CAAK,CAAC,CAAC,CAChD,CAAC,CAAA,CAOD,OALiB,CACfJ,CAAAA,CAAQ,IAAKK,CAAAA,EAAMV,CAAAA,CAAeU,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAC9C,GAAGJ,CAAAA,CAAK,GAAA,CAAKK,CAAAA,EAAQA,CAAAA,CAAI,KAAK,GAAG,CAAC,CACpC,CAAA,CAEgB,IAAA,CAAK;AAAA,CAAI,CAC3B,CASO,SAASC,CAAAA,CACd5B,EACqB,CACrB,IAAM6B,CAAAA,CAA4B,EAAC,CAC7BlB,CAAAA,CAAM,KAAK,GAAA,EAAI,CAErB,QAAWd,CAAAA,IAAUG,CAAAA,CAAK,QAAS,CACjC,IAAM8B,CAAAA,CAAuB,EAAC,CA2B9B,GAAA,CAvBE,CAACjC,CAAAA,CAAO,wBAAA,EACRA,EAAO,wBAAA,CAAyB,IAAA,KAAW,EAAA,GAE3CiC,CAAAA,CAAW,IAAA,CACT,yFACF,CAAA,CAAA,CAIE,CAACjC,EAAO,eAAA,EAAmBA,CAAAA,CAAO,gBAAgB,IAAA,EAAK,GAAM,KAC/DiC,CAAAA,CAAW,IAAA,CACT,yEACF,CAAA,CAAA,CAIE,CAACjC,CAAAA,CAAO,kBAAoBA,CAAAA,CAAO,gBAAA,CAAiB,SAAW,CAAA,GACjEiC,CAAAA,CAAW,KACT,oGACF,CAAA,CAIEjC,CAAAA,CAAO,cAAA,EAAkBA,CAAAA,CAAO,cAAA,EAAkBc,EAAK,CACzD,IAAMoB,EAAY,IAAA,CAAK,IAAA,CAAA,CACpBpB,EAAMd,CAAAA,CAAO,cAAA,EAAmB,KACnC,CAAA,CACAiC,CAAAA,CAAW,IAAA,CACT,wBAAwBC,CAAS,CAAA,IAAA,EAAOA,IAAc,CAAA,CAAI,GAAA,CAAM,EAAE,CAAA,CAAA,CACpE,EACF,CAwBA,GApBElC,CAAAA,CAAO,YAAA,GACN,CAACA,CAAAA,CAAO,aAAA,EAAiBA,CAAAA,CAAO,aAAA,CAAc,IAAA,EAAK,GAAM,KAE1DiC,CAAAA,CAAW,IAAA,CACT,qEACF,CAAA,CAKAjC,CAAAA,CAAO,uBAAA,GACN,CAACA,CAAAA,CAAO,8BAAA,EACPA,EAAO,8BAAA,CAA+B,IAAA,KAAW,EAAA,CAAA,EAEnDiC,CAAAA,CAAW,IAAA,CACT,qEACF,CAAA,CAIEjC,CAAAA,CAAO,qBACT,IAAA,IAAWmC,CAAAA,IAAYnC,EAAO,oBAAA,CAAA,CACxB,CAACmC,EAAS,UAAA,EAAcA,CAAAA,CAAS,UAAA,CAAW,IAAA,EAAK,GAAM,EAAA,GACzDF,EAAW,IAAA,CACT,CAAA,yBAAA,EAA4BE,EAAS,kBAAkB,CAAA,oCAAA,CACzD,GAGA,CAACA,CAAAA,CAAS,iBAAA,EACVA,CAAAA,CAAS,iBAAA,CAAkB,IAAA,KAAW,EAAA,GAEtCF,CAAAA,CAAW,KACT,CAAA,yBAAA,EAA4BE,CAAAA,CAAS,kBAAkB,CAAA,+BAAA,CACzD,CAAA,CAOJnC,CAAAA,CAAO,UAAA,GAAe,aAAA,GACrB,CAACA,EAAO,uBAAA,EACPA,CAAAA,CAAO,wBAAwB,IAAA,EAAK,GAAM,KAE5CiC,CAAAA,CAAW,IAAA,CACT,kEACF,CAAA,CAAA,CAIE,CAACjC,CAAAA,CAAO,UAAYA,CAAAA,CAAO,QAAA,CAAS,SAAW,CAAA,GACjDiC,CAAAA,CAAW,KAAK,mCAAmC,CAAA,CAAA,CAIjD,CAACjC,CAAAA,CAAO,UAAA,EAAcA,CAAAA,CAAO,WAAW,MAAA,GAAW,CAAA,GACrDiC,EAAW,IAAA,CAAK,sDAAsD,EAGpEA,CAAAA,CAAW,MAAA,CAAS,CAAA,EACtBD,CAAAA,CAAK,IAAA,CAAK,CACR,SAAUhC,CAAAA,CAAO,EAAA,CACjB,UAAA,CAAYA,CAAAA,CAAO,IAAA,CACnB,IAAA,CAAMiC,CACR,CAAC,EAEL,CAEA,OAAOD,CACT","file":"chunk-SWF3YVE5.js","sourcesContent":["import type { LawfulBasis } from '../types/lawful-basis';\nimport type {\n ProcessingRecord,\n RecordOfProcessingActivities,\n ROPASummary,\n} from '../types/ropa';\n\n/**\n * Compliance gap found in a processing record\n */\nexport interface ROPAComplianceGap {\n recordId: string;\n recordName: string;\n gaps: string[];\n}\n\n/**\n * Validation result for a processing record\n */\nexport interface ROPAValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nconst ALL_LAWFUL_BASES: LawfulBasis[] = [\n 'consent',\n 'contract',\n 'legal_obligation',\n 'vital_interests',\n 'public_interest',\n 'legitimate_interests',\n];\n\n/**\n * Validates a processing record to ensure all required fields are present\n * and properly filled per NDPA 2023 requirements.\n *\n * @param record - The processing record to validate\n * @returns Validation result with any errors found\n */\nexport function validateProcessingRecord(\n record: ProcessingRecord\n): ROPAValidationResult {\n const errors: string[] = [];\n\n if (!record.id || record.id.trim() === '') {\n errors.push('Record ID is required.');\n }\n\n if (!record.name || record.name.trim() === '') {\n errors.push('Processing activity name is required.');\n }\n\n if (!record.description || record.description.trim() === '') {\n errors.push('Processing description is required.');\n }\n\n if (!record.controllerDetails) {\n errors.push('Controller details are required.');\n } else {\n if (!record.controllerDetails.name || record.controllerDetails.name.trim() === '') {\n errors.push('Controller name is required.');\n }\n if (!record.controllerDetails.contact || record.controllerDetails.contact.trim() === '') {\n errors.push('Controller contact is required.');\n }\n if (!record.controllerDetails.address || record.controllerDetails.address.trim() === '') {\n errors.push('Controller address is required.');\n }\n }\n\n if (!record.lawfulBasis || !ALL_LAWFUL_BASES.includes(record.lawfulBasis)) {\n errors.push('A valid lawful basis must be specified (NDPA Section 25).');\n }\n\n if (!record.lawfulBasisJustification || record.lawfulBasisJustification.trim() === '') {\n errors.push('Lawful basis justification is required to demonstrate compliance.');\n }\n\n if (!record.purposes || record.purposes.length === 0) {\n errors.push('At least one processing purpose must be specified.');\n }\n\n if (!record.dataCategories || record.dataCategories.length === 0) {\n errors.push('At least one data category must be specified.');\n }\n\n if (!record.dataSubjectCategories || record.dataSubjectCategories.length === 0) {\n errors.push('At least one data subject category must be specified.');\n }\n\n if (!record.recipients || record.recipients.length === 0) {\n errors.push('At least one recipient or category of recipients must be specified.');\n }\n\n if (!record.retentionPeriod || record.retentionPeriod.trim() === '') {\n errors.push('Retention period must be specified.');\n }\n\n if (!record.securityMeasures || record.securityMeasures.length === 0) {\n errors.push('At least one security measure must be documented.');\n }\n\n if (!record.dataSource) {\n errors.push('Data source must be specified.');\n }\n\n if (\n record.dataSource === 'third_party' &&\n (!record.thirdPartySourceDetails || record.thirdPartySourceDetails.trim() === '')\n ) {\n errors.push('Third-party source details are required when data source is \"third_party\".');\n }\n\n if (\n record.automatedDecisionMaking &&\n (!record.automatedDecisionMakingDetails || record.automatedDecisionMakingDetails.trim() === '')\n ) {\n errors.push(\n 'Automated decision-making details are required when automated decision-making is involved.'\n );\n }\n\n if (\n record.dpiaRequired &&\n (!record.dpiaReference || record.dpiaReference.trim() === '')\n ) {\n errors.push('DPIA reference is required when DPIA is marked as required.');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Generates a summary of the Record of Processing Activities.\n * Provides statistics and identifies records that are due for review.\n *\n * @param ropa - The full Record of Processing Activities\n * @returns Summary statistics for the ROPA\n */\nexport function generateROPASummary(\n ropa: RecordOfProcessingActivities\n): ROPASummary {\n const byLawfulBasis = ALL_LAWFUL_BASES.reduce(\n (acc, basis) => {\n acc[basis] = 0;\n return acc;\n },\n {} as Record<LawfulBasis, number>\n );\n\n let activeRecords = 0;\n let sensitiveDataRecords = 0;\n let crossBorderRecords = 0;\n let dpiaRequiredRecords = 0;\n let automatedDecisionRecords = 0;\n const recordsDueForReview: ProcessingRecord[] = [];\n const departmentCounts: Record<string, number> = {};\n\n const now = Date.now();\n\n for (const record of ropa.records) {\n // Count by lawful basis\n if (record.lawfulBasis && ALL_LAWFUL_BASES.includes(record.lawfulBasis)) {\n byLawfulBasis[record.lawfulBasis]++;\n }\n\n // Count active records\n if (record.status === 'active') {\n activeRecords++;\n }\n\n // Count sensitive data records\n if (\n record.sensitiveDataCategories &&\n record.sensitiveDataCategories.length > 0\n ) {\n sensitiveDataRecords++;\n }\n\n // Count cross-border transfer records\n if (record.crossBorderTransfers && record.crossBorderTransfers.length > 0) {\n crossBorderRecords++;\n }\n\n // Count DPIA-required records\n if (record.dpiaRequired) {\n dpiaRequiredRecords++;\n }\n\n // Count automated decision-making records\n if (record.automatedDecisionMaking) {\n automatedDecisionRecords++;\n }\n\n // Identify records due for review\n if (record.nextReviewDate && record.nextReviewDate <= now) {\n recordsDueForReview.push(record);\n }\n\n // Track department counts\n if (record.department) {\n departmentCounts[record.department] =\n (departmentCounts[record.department] || 0) + 1;\n }\n }\n\n // Sort departments by count and take the top ones\n const topDepartments = Object.entries(departmentCounts)\n .map(([department, count]) => ({ department, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n return {\n totalRecords: ropa.records.length,\n activeRecords,\n byLawfulBasis,\n sensitiveDataRecords,\n crossBorderRecords,\n dpiaRequiredRecords,\n automatedDecisionRecords,\n recordsDueForReview,\n topDepartments,\n lastUpdated: ropa.lastUpdated,\n };\n}\n\n/**\n * Escapes a string value for safe inclusion in CSV output\n */\nfunction escapeCSVField(value: string): string {\n if (\n value.includes(',') ||\n value.includes('\"') ||\n value.includes('\\n') ||\n value.includes('\\r')\n ) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\n/**\n * Formats a timestamp as an ISO date string for CSV export\n */\nfunction formatTimestamp(timestamp: number | undefined): string {\n if (!timestamp) return '';\n return new Date(timestamp).toISOString();\n}\n\n/**\n * Exports the Record of Processing Activities to a CSV string.\n * The CSV includes all key fields from each processing record.\n *\n * @param ropa - The full Record of Processing Activities\n * @returns CSV-formatted string\n */\nexport function exportROPAToCSV(ropa: RecordOfProcessingActivities): string {\n const headers = [\n 'ID',\n 'Name',\n 'Description',\n 'Controller Name',\n 'Controller Contact',\n 'Lawful Basis',\n 'Lawful Basis Justification',\n 'Purposes',\n 'Data Categories',\n 'Sensitive Data Categories',\n 'Data Subject Categories',\n 'Recipients',\n 'Cross-Border Transfers',\n 'Retention Period',\n 'Security Measures',\n 'Data Source',\n 'DPIA Required',\n 'DPIA Reference',\n 'Automated Decision-Making',\n 'Status',\n 'Department',\n 'Systems Used',\n 'Created At',\n 'Updated At',\n 'Last Reviewed At',\n 'Next Review Date',\n ];\n\n const rows = ropa.records.map((record) => {\n const crossBorderSummary = record.crossBorderTransfers\n ? record.crossBorderTransfers\n .map(\n (t) =>\n `${t.destinationCountry} (${t.transferMechanism}: ${t.safeguards})`\n )\n .join('; ')\n : '';\n\n return [\n record.id,\n record.name,\n record.description,\n record.controllerDetails.name,\n record.controllerDetails.contact,\n record.lawfulBasis,\n record.lawfulBasisJustification,\n record.purposes.join('; '),\n record.dataCategories.join('; '),\n (record.sensitiveDataCategories || []).join('; '),\n record.dataSubjectCategories.join('; '),\n record.recipients.join('; '),\n crossBorderSummary,\n record.retentionPeriod,\n record.securityMeasures.join('; '),\n record.dataSource,\n record.dpiaRequired ? 'Yes' : 'No',\n record.dpiaReference || '',\n record.automatedDecisionMaking ? 'Yes' : 'No',\n record.status,\n record.department || '',\n (record.systemsUsed || []).join('; '),\n formatTimestamp(record.createdAt),\n formatTimestamp(record.updatedAt),\n formatTimestamp(record.lastReviewedAt),\n formatTimestamp(record.nextReviewDate),\n ].map((field) => escapeCSVField(String(field)));\n });\n\n const csvLines = [\n headers.map((h) => escapeCSVField(h)).join(','),\n ...rows.map((row) => row.join(',')),\n ];\n\n return csvLines.join('\\n');\n}\n\n/**\n * Identifies compliance gaps in the Record of Processing Activities.\n * Finds records that are missing required information per NDPA 2023.\n *\n * @param ropa - The full Record of Processing Activities\n * @returns Array of compliance gaps grouped by record\n */\nexport function identifyComplianceGaps(\n ropa: RecordOfProcessingActivities\n): ROPAComplianceGap[] {\n const gaps: ROPAComplianceGap[] = [];\n const now = Date.now();\n\n for (const record of ropa.records) {\n const recordGaps: string[] = [];\n\n // Check lawful basis justification\n if (\n !record.lawfulBasisJustification ||\n record.lawfulBasisJustification.trim() === ''\n ) {\n recordGaps.push(\n 'Missing lawful basis justification (NDPA Section 25 requires documented justification).'\n );\n }\n\n // Check retention period\n if (!record.retentionPeriod || record.retentionPeriod.trim() === '') {\n recordGaps.push(\n 'Missing retention period (data must not be kept longer than necessary).'\n );\n }\n\n // Check security measures\n if (!record.securityMeasures || record.securityMeasures.length === 0) {\n recordGaps.push(\n 'No security measures documented (NDPA requires appropriate technical and organizational measures).'\n );\n }\n\n // Check for overdue review\n if (record.nextReviewDate && record.nextReviewDate <= now) {\n const overdueBy = Math.ceil(\n (now - record.nextReviewDate) / (24 * 60 * 60 * 1000)\n );\n recordGaps.push(\n `Review is overdue by ${overdueBy} day${overdueBy !== 1 ? 's' : ''}.`\n );\n }\n\n // Check DPIA reference when required\n if (\n record.dpiaRequired &&\n (!record.dpiaReference || record.dpiaReference.trim() === '')\n ) {\n recordGaps.push(\n 'DPIA is required but no reference to a completed DPIA was provided.'\n );\n }\n\n // Check automated decision-making documentation\n if (\n record.automatedDecisionMaking &&\n (!record.automatedDecisionMakingDetails ||\n record.automatedDecisionMakingDetails.trim() === '')\n ) {\n recordGaps.push(\n 'Automated decision-making is flagged but no details are documented.'\n );\n }\n\n // Check cross-border transfer safeguards\n if (record.crossBorderTransfers) {\n for (const transfer of record.crossBorderTransfers) {\n if (!transfer.safeguards || transfer.safeguards.trim() === '') {\n recordGaps.push(\n `Cross-border transfer to ${transfer.destinationCountry} is missing safeguard documentation.`\n );\n }\n if (\n !transfer.transferMechanism ||\n transfer.transferMechanism.trim() === ''\n ) {\n recordGaps.push(\n `Cross-border transfer to ${transfer.destinationCountry} is missing transfer mechanism.`\n );\n }\n }\n }\n\n // Check third-party source details\n if (\n record.dataSource === 'third_party' &&\n (!record.thirdPartySourceDetails ||\n record.thirdPartySourceDetails.trim() === '')\n ) {\n recordGaps.push(\n 'Data source is \"third_party\" but no source details are provided.'\n );\n }\n\n // Check missing purposes\n if (!record.purposes || record.purposes.length === 0) {\n recordGaps.push('No processing purposes specified.');\n }\n\n // Check missing recipients\n if (!record.recipients || record.recipients.length === 0) {\n recordGaps.push('No recipients or categories of recipients specified.');\n }\n\n if (recordGaps.length > 0) {\n gaps.push({\n recordId: record.id,\n recordName: record.name,\n gaps: recordGaps,\n });\n }\n }\n\n return gaps;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/hooks/useROPA.ts"],"names":["useROPA","initialData","onRecordAdd","onRecordUpdate","onRecordArchive","ropa","setROPA","useState","addRecord","useCallback","record","prev","__spreadProps","__spreadValues","updateRecord","id","updates","archiveRecord","getRecord","getSummary","generateROPASummary","exportCSV","exportROPAToCSV","getComplianceGaps","identifyComplianceGaps"],"mappings":"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","file":"chunk-T44JQT2O.mjs","sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport type {\n ProcessingRecord,\n RecordOfProcessingActivities,\n ROPASummary,\n} from '../types/ropa';\nimport {\n generateROPASummary,\n exportROPAToCSV,\n identifyComplianceGaps,\n type ROPAComplianceGap,\n} from '../utils/ropa';\n\nexport interface UseROPAOptions {\n /**\n * Initial ROPA state\n */\n initialData: RecordOfProcessingActivities;\n\n /**\n * Callback when a record is added\n */\n onRecordAdd?: (record: ProcessingRecord) => void;\n\n /**\n * Callback when a record is updated\n */\n onRecordUpdate?: (id: string, updates: Partial<ProcessingRecord>) => void;\n\n /**\n * Callback when a record is archived\n */\n onRecordArchive?: (id: string) => void;\n}\n\nexport interface UseROPAReturn {\n /**\n * Current state of the Record of Processing Activities\n */\n ropa: RecordOfProcessingActivities;\n\n /**\n * Add a new processing record\n */\n addRecord: (record: ProcessingRecord) => void;\n\n /**\n * Update an existing processing record\n */\n updateRecord: (id: string, updates: Partial<ProcessingRecord>) => void;\n\n /**\n * Archive a processing record by setting its status to 'archived'\n */\n archiveRecord: (id: string) => void;\n\n /**\n * Get a single processing record by ID\n */\n getRecord: (id: string) => ProcessingRecord | undefined;\n\n /**\n * Get a summary of the ROPA including statistics\n */\n getSummary: () => ROPASummary;\n\n /**\n * Export the ROPA as a CSV string\n */\n exportCSV: () => string;\n\n /**\n * Identify compliance gaps across all records\n */\n getComplianceGaps: () => ROPAComplianceGap[];\n}\n\n/**\n * Hook for managing a Record of Processing Activities (ROPA)\n * in compliance with NDPA 2023 requirements.\n *\n * Provides state management and utility functions for maintaining\n * a comprehensive register of all data processing activities.\n */\nexport function useROPA({\n initialData,\n onRecordAdd,\n onRecordUpdate,\n onRecordArchive,\n}: UseROPAOptions): UseROPAReturn {\n const [ropa, setROPA] = useState<RecordOfProcessingActivities>(initialData);\n\n const addRecord = useCallback(\n (record: ProcessingRecord) => {\n setROPA((prev) => ({\n ...prev,\n records: [...prev.records, record],\n lastUpdated: Date.now(),\n }));\n onRecordAdd?.(record);\n },\n [onRecordAdd]\n );\n\n const updateRecord = useCallback(\n (id: string, updates: Partial<ProcessingRecord>) => {\n setROPA((prev) => ({\n ...prev,\n records: prev.records.map((record) =>\n record.id === id\n ? { ...record, ...updates, updatedAt: Date.now() }\n : record\n ),\n lastUpdated: Date.now(),\n }));\n onRecordUpdate?.(id, updates);\n },\n [onRecordUpdate]\n );\n\n const archiveRecord = useCallback(\n (id: string) => {\n setROPA((prev) => ({\n ...prev,\n records: prev.records.map((record) =>\n record.id === id\n ? { ...record, status: 'archived' as const, updatedAt: Date.now() }\n : record\n ),\n lastUpdated: Date.now(),\n }));\n onRecordArchive?.(id);\n },\n [onRecordArchive]\n );\n\n const getRecord = useCallback(\n (id: string): ProcessingRecord | undefined => {\n return ropa.records.find((record) => record.id === id);\n },\n [ropa.records]\n );\n\n const getSummary = useCallback((): ROPASummary => {\n return generateROPASummary(ropa);\n }, [ropa]);\n\n const exportCSV = useCallback((): string => {\n return exportROPAToCSV(ropa);\n }, [ropa]);\n\n const getComplianceGaps = useCallback((): ROPAComplianceGap[] => {\n return identifyComplianceGaps(ropa);\n }, [ropa]);\n\n return {\n ropa,\n addRecord,\n updateRecord,\n archiveRecord,\n getRecord,\n getSummary,\n exportCSV,\n getComplianceGaps,\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/lawful-basis.ts"],"names":["validateProcessingActivity","activity","errors","warnings","getLawfulBasisDescription","basis","assessComplianceGaps","activities","gaps","generateLawfulBasisSummary","byBasis","sensitiveDataActivities","crossBorderActivities","activitiesDueForReview","activitiesWithoutApproval","a"],"mappings":"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","file":"chunk-TDDAYVKK.js","sourcesContent":["import {\n LawfulBasis,\n ProcessingActivity,\n LawfulBasisSummary,\n} from '../types/lawful-basis';\n\n/**\n * Validation result for a processing activity\n */\nexport interface LawfulBasisValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Compliance gap identified across processing activities\n */\nexport interface LawfulBasisComplianceGap {\n activityId: string;\n activityName: string;\n type: 'missing_approval' | 'overdue_review' | 'missing_justification' | 'missing_lia' | 'missing_sensitive_condition' | 'missing_retention' | 'missing_data_categories' | 'missing_purposes';\n severity: 'high' | 'medium' | 'low';\n description: string;\n}\n\n/**\n * Validates that all required fields are present on a processing activity\n * and that the lawful basis is properly documented.\n *\n * If lawfulBasis is 'legitimate_interests', ensures a LIA justification exists.\n * If involvesSensitiveData is true, ensures sensitiveDataCondition is set.\n *\n * @param activity The processing activity to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateProcessingActivity(activity: ProcessingActivity): LawfulBasisValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Required fields\n if (!activity.id) {\n errors.push('Activity ID is required.');\n }\n\n if (!activity.name || activity.name.trim() === '') {\n errors.push('Activity name is required.');\n }\n\n if (!activity.description || activity.description.trim() === '') {\n errors.push('Activity description is required.');\n }\n\n if (!activity.lawfulBasis) {\n errors.push('Lawful basis is required per NDPA Section 25.');\n }\n\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n errors.push('Justification for the lawful basis is required.');\n }\n\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n errors.push('At least one data category must be specified.');\n }\n\n if (!activity.dataSubjectCategories || activity.dataSubjectCategories.length === 0) {\n errors.push('At least one data subject category must be specified.');\n }\n\n if (!activity.purposes || activity.purposes.length === 0) {\n errors.push('At least one processing purpose must be specified.');\n }\n\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n errors.push('Data retention period is required.');\n }\n\n // Legitimate interests requires additional justification (LIA)\n if (activity.lawfulBasis === 'legitimate_interests') {\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20) {\n errors.push(\n 'Legitimate interests requires a detailed Legitimate Interest Assessment (LIA) justification (NDPA Section 25(1)(f)).'\n );\n }\n }\n\n // Sensitive data requires a specific condition per NDPA Section 27\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n errors.push(\n 'Processing sensitive personal data requires specifying a condition under NDPA Section 27.'\n );\n }\n\n // Warnings for best practices\n if (!activity.dpoApproval) {\n warnings.push('Activity has not been approved by the DPO.');\n } else if (!activity.dpoApproval.approved) {\n warnings.push('Activity has a DPO review but has not been approved.');\n }\n\n if (!activity.reviewDate) {\n warnings.push('No review date has been set. Regular reviews are recommended.');\n } else if (activity.reviewDate < Date.now()) {\n warnings.push('Activity is overdue for review.');\n }\n\n if (!activity.retentionJustification) {\n warnings.push('Consider documenting the justification for the retention period.');\n }\n\n if (activity.crossBorderTransfer && (!activity.recipients || activity.recipients.length === 0)) {\n warnings.push(\n 'Cross-border transfer is indicated but no recipients are listed. Document the recipients or categories of recipients.'\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Returns a human-readable description of a lawful basis with the relevant\n * NDPA section reference.\n *\n * @param basis The lawful basis to describe\n * @returns Description string including NDPA section reference\n */\nexport function getLawfulBasisDescription(basis: LawfulBasis): string {\n const descriptions: Record<LawfulBasis, string> = {\n consent:\n 'Consent (NDPA Section 25(1)(a)) - The data subject has given consent to the processing of their personal data for one or more specific purposes.',\n contract:\n 'Contract (NDPA Section 25(1)(b)) - Processing is necessary for the performance of a contract to which the data subject is a party, or in order to take steps at the request of the data subject prior to entering into a contract.',\n legal_obligation:\n 'Legal Obligation (NDPA Section 25(1)(c)) - Processing is necessary for compliance with a legal obligation to which the data controller is subject.',\n vital_interests:\n 'Vital Interests (NDPA Section 25(1)(d)) - Processing is necessary to protect the vital interests of the data subject or another natural person.',\n public_interest:\n 'Public Interest (NDPA Section 25(1)(e)) - Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the data controller.',\n legitimate_interests:\n 'Legitimate Interests (NDPA Section 25(1)(f)) - Processing is necessary for the purposes of the legitimate interests pursued by the data controller or a third party, except where such interests are overridden by the interests, rights, or freedoms of the data subject.',\n };\n\n return descriptions[basis];\n}\n\n/**\n * Analyzes all processing activities and returns compliance gaps including\n * missing DPO approval, overdue reviews, undocumented justifications,\n * missing LIA for legitimate interests, and other documentation issues.\n *\n * @param activities Array of processing activities to analyze\n * @returns Array of identified compliance gaps\n */\nexport function assessComplianceGaps(activities: ProcessingActivity[]): LawfulBasisComplianceGap[] {\n const gaps: LawfulBasisComplianceGap[] = [];\n\n for (const activity of activities) {\n // Skip archived activities\n if (activity.status === 'archived') {\n continue;\n }\n\n // Missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_approval',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" has not been approved by the DPO.`,\n });\n }\n\n // Overdue review\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'overdue_review',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" was due for review on ${new Date(activity.reviewDate).toLocaleDateString()}.`,\n });\n }\n\n // Missing justification\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_justification',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" is missing the lawful basis justification.`,\n });\n }\n\n // Missing LIA for legitimate interests\n if (\n activity.lawfulBasis === 'legitimate_interests' &&\n (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20)\n ) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_lia',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" relies on legitimate interests but lacks a detailed Legitimate Interest Assessment (NDPA Section 25(1)(f)).`,\n });\n }\n\n // Missing sensitive data condition\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_sensitive_condition',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" involves sensitive data but no condition under NDPA Section 27 has been specified.`,\n });\n }\n\n // Missing retention period\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_retention',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" is missing a documented retention period.`,\n });\n }\n\n // Missing data categories\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_data_categories',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented data categories.`,\n });\n }\n\n // Missing purposes\n if (!activity.purposes || activity.purposes.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_purposes',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented processing purposes.`,\n });\n }\n }\n\n return gaps;\n}\n\n/**\n * Generates a summary of all lawful basis documentation across processing activities.\n *\n * @param activities Array of processing activities to summarize\n * @returns LawfulBasisSummary with counts, breakdowns, and flagged activities\n */\nexport function generateLawfulBasisSummary(activities: ProcessingActivity[]): LawfulBasisSummary {\n const byBasis: Record<LawfulBasis, number> = {\n consent: 0,\n contract: 0,\n legal_obligation: 0,\n vital_interests: 0,\n public_interest: 0,\n legitimate_interests: 0,\n };\n\n let sensitiveDataActivities = 0;\n let crossBorderActivities = 0;\n const activitiesDueForReview: ProcessingActivity[] = [];\n const activitiesWithoutApproval: ProcessingActivity[] = [];\n\n for (const activity of activities) {\n if (activity.status === 'archived') {\n continue;\n }\n\n // Count by lawful basis\n if (activity.lawfulBasis in byBasis) {\n byBasis[activity.lawfulBasis]++;\n }\n\n // Count sensitive data activities\n if (activity.involvesSensitiveData) {\n sensitiveDataActivities++;\n }\n\n // Count cross-border transfers\n if (activity.crossBorderTransfer) {\n crossBorderActivities++;\n }\n\n // Check for overdue reviews\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n activitiesDueForReview.push(activity);\n }\n\n // Check for missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n activitiesWithoutApproval.push(activity);\n }\n }\n\n return {\n totalActivities: activities.filter(a => a.status !== 'archived').length,\n byBasis,\n sensitiveDataActivities,\n crossBorderActivities,\n activitiesDueForReview,\n activitiesWithoutApproval,\n lastUpdated: Date.now(),\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/lawful-basis.ts"],"names":["validateProcessingActivity","activity","errors","warnings","getLawfulBasisDescription","basis","assessComplianceGaps","activities","gaps","generateLawfulBasisSummary","byBasis","sensitiveDataActivities","crossBorderActivities","activitiesDueForReview","activitiesWithoutApproval","a"],"mappings":"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","file":"chunk-TXBZPCGF.mjs","sourcesContent":["import {\n LawfulBasis,\n ProcessingActivity,\n LawfulBasisSummary,\n} from '../types/lawful-basis';\n\n/**\n * Validation result for a processing activity\n */\nexport interface LawfulBasisValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Compliance gap identified across processing activities\n */\nexport interface LawfulBasisComplianceGap {\n activityId: string;\n activityName: string;\n type: 'missing_approval' | 'overdue_review' | 'missing_justification' | 'missing_lia' | 'missing_sensitive_condition' | 'missing_retention' | 'missing_data_categories' | 'missing_purposes';\n severity: 'high' | 'medium' | 'low';\n description: string;\n}\n\n/**\n * Validates that all required fields are present on a processing activity\n * and that the lawful basis is properly documented.\n *\n * If lawfulBasis is 'legitimate_interests', ensures a LIA justification exists.\n * If involvesSensitiveData is true, ensures sensitiveDataCondition is set.\n *\n * @param activity The processing activity to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateProcessingActivity(activity: ProcessingActivity): LawfulBasisValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Required fields\n if (!activity.id) {\n errors.push('Activity ID is required.');\n }\n\n if (!activity.name || activity.name.trim() === '') {\n errors.push('Activity name is required.');\n }\n\n if (!activity.description || activity.description.trim() === '') {\n errors.push('Activity description is required.');\n }\n\n if (!activity.lawfulBasis) {\n errors.push('Lawful basis is required per NDPA Section 25.');\n }\n\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n errors.push('Justification for the lawful basis is required.');\n }\n\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n errors.push('At least one data category must be specified.');\n }\n\n if (!activity.dataSubjectCategories || activity.dataSubjectCategories.length === 0) {\n errors.push('At least one data subject category must be specified.');\n }\n\n if (!activity.purposes || activity.purposes.length === 0) {\n errors.push('At least one processing purpose must be specified.');\n }\n\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n errors.push('Data retention period is required.');\n }\n\n // Legitimate interests requires additional justification (LIA)\n if (activity.lawfulBasis === 'legitimate_interests') {\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20) {\n errors.push(\n 'Legitimate interests requires a detailed Legitimate Interest Assessment (LIA) justification (NDPA Section 25(1)(f)).'\n );\n }\n }\n\n // Sensitive data requires a specific condition per NDPA Section 27\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n errors.push(\n 'Processing sensitive personal data requires specifying a condition under NDPA Section 27.'\n );\n }\n\n // Warnings for best practices\n if (!activity.dpoApproval) {\n warnings.push('Activity has not been approved by the DPO.');\n } else if (!activity.dpoApproval.approved) {\n warnings.push('Activity has a DPO review but has not been approved.');\n }\n\n if (!activity.reviewDate) {\n warnings.push('No review date has been set. Regular reviews are recommended.');\n } else if (activity.reviewDate < Date.now()) {\n warnings.push('Activity is overdue for review.');\n }\n\n if (!activity.retentionJustification) {\n warnings.push('Consider documenting the justification for the retention period.');\n }\n\n if (activity.crossBorderTransfer && (!activity.recipients || activity.recipients.length === 0)) {\n warnings.push(\n 'Cross-border transfer is indicated but no recipients are listed. Document the recipients or categories of recipients.'\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Returns a human-readable description of a lawful basis with the relevant\n * NDPA section reference.\n *\n * @param basis The lawful basis to describe\n * @returns Description string including NDPA section reference\n */\nexport function getLawfulBasisDescription(basis: LawfulBasis): string {\n const descriptions: Record<LawfulBasis, string> = {\n consent:\n 'Consent (NDPA Section 25(1)(a)) - The data subject has given consent to the processing of their personal data for one or more specific purposes.',\n contract:\n 'Contract (NDPA Section 25(1)(b)) - Processing is necessary for the performance of a contract to which the data subject is a party, or in order to take steps at the request of the data subject prior to entering into a contract.',\n legal_obligation:\n 'Legal Obligation (NDPA Section 25(1)(c)) - Processing is necessary for compliance with a legal obligation to which the data controller is subject.',\n vital_interests:\n 'Vital Interests (NDPA Section 25(1)(d)) - Processing is necessary to protect the vital interests of the data subject or another natural person.',\n public_interest:\n 'Public Interest (NDPA Section 25(1)(e)) - Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the data controller.',\n legitimate_interests:\n 'Legitimate Interests (NDPA Section 25(1)(f)) - Processing is necessary for the purposes of the legitimate interests pursued by the data controller or a third party, except where such interests are overridden by the interests, rights, or freedoms of the data subject.',\n };\n\n return descriptions[basis];\n}\n\n/**\n * Analyzes all processing activities and returns compliance gaps including\n * missing DPO approval, overdue reviews, undocumented justifications,\n * missing LIA for legitimate interests, and other documentation issues.\n *\n * @param activities Array of processing activities to analyze\n * @returns Array of identified compliance gaps\n */\nexport function assessComplianceGaps(activities: ProcessingActivity[]): LawfulBasisComplianceGap[] {\n const gaps: LawfulBasisComplianceGap[] = [];\n\n for (const activity of activities) {\n // Skip archived activities\n if (activity.status === 'archived') {\n continue;\n }\n\n // Missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_approval',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" has not been approved by the DPO.`,\n });\n }\n\n // Overdue review\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'overdue_review',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" was due for review on ${new Date(activity.reviewDate).toLocaleDateString()}.`,\n });\n }\n\n // Missing justification\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_justification',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" is missing the lawful basis justification.`,\n });\n }\n\n // Missing LIA for legitimate interests\n if (\n activity.lawfulBasis === 'legitimate_interests' &&\n (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20)\n ) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_lia',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" relies on legitimate interests but lacks a detailed Legitimate Interest Assessment (NDPA Section 25(1)(f)).`,\n });\n }\n\n // Missing sensitive data condition\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_sensitive_condition',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" involves sensitive data but no condition under NDPA Section 27 has been specified.`,\n });\n }\n\n // Missing retention period\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_retention',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" is missing a documented retention period.`,\n });\n }\n\n // Missing data categories\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_data_categories',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented data categories.`,\n });\n }\n\n // Missing purposes\n if (!activity.purposes || activity.purposes.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_purposes',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented processing purposes.`,\n });\n }\n }\n\n return gaps;\n}\n\n/**\n * Generates a summary of all lawful basis documentation across processing activities.\n *\n * @param activities Array of processing activities to summarize\n * @returns LawfulBasisSummary with counts, breakdowns, and flagged activities\n */\nexport function generateLawfulBasisSummary(activities: ProcessingActivity[]): LawfulBasisSummary {\n const byBasis: Record<LawfulBasis, number> = {\n consent: 0,\n contract: 0,\n legal_obligation: 0,\n vital_interests: 0,\n public_interest: 0,\n legitimate_interests: 0,\n };\n\n let sensitiveDataActivities = 0;\n let crossBorderActivities = 0;\n const activitiesDueForReview: ProcessingActivity[] = [];\n const activitiesWithoutApproval: ProcessingActivity[] = [];\n\n for (const activity of activities) {\n if (activity.status === 'archived') {\n continue;\n }\n\n // Count by lawful basis\n if (activity.lawfulBasis in byBasis) {\n byBasis[activity.lawfulBasis]++;\n }\n\n // Count sensitive data activities\n if (activity.involvesSensitiveData) {\n sensitiveDataActivities++;\n }\n\n // Count cross-border transfers\n if (activity.crossBorderTransfer) {\n crossBorderActivities++;\n }\n\n // Check for overdue reviews\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n activitiesDueForReview.push(activity);\n }\n\n // Check for missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n activitiesWithoutApproval.push(activity);\n }\n }\n\n return {\n totalActivities: activities.filter(a => a.status !== 'archived').length,\n byBasis,\n sensitiveDataActivities,\n crossBorderActivities,\n activitiesDueForReview,\n activitiesWithoutApproval,\n lastUpdated: Date.now(),\n };\n}\n"]}
@@ -1,2 +0,0 @@
1
- 'use strict';var chunkSSGJREE3_js=require('./chunk-SSGJREE3.js'),chunkMQFZHA2D_js=require('./chunk-MQFZHA2D.js'),react=require('react');function N({sections:d,initialAnswers:Q={},storageKey:f="ndpr_dpia_data",useLocalStorage:m=true,onComplete:I}){let[l,c]=react.useState(0),[i,g]=react.useState(Q);react.useEffect(()=>{if(m&&typeof window!="undefined")try{let r=localStorage.getItem(f);if(r){let{answers:t,sectionIndex:e}=JSON.parse(r);g(t||{}),c(e||0);}}catch(r){console.error("Error loading DPIA data:",r);}},[f,m]),react.useEffect(()=>{if(m&&typeof window!="undefined")try{localStorage.setItem(f,JSON.stringify({answers:i,sectionIndex:l}));}catch(r){console.error("Error saving DPIA data:",r);}},[i,l,f,m]);let p=d[l]||null,E=(r,t)=>{g(e=>chunkMQFZHA2D_js.b(chunkMQFZHA2D_js.a({},e),{[r]:t}));},v=r=>r.showWhen?r.showWhen.every(t=>{let e=i[t.questionId];switch(t.operator){case "equals":return e===t.value;case "contains":return Array.isArray(e)?e.includes(t.value):false;case "greaterThan":return typeof e=="number"?e>t.value:false;case "lessThan":return typeof e=="number"?e<t.value:false;default:return true}}):true,A=()=>p?p.questions.filter(v):[],h=()=>p?A().every(t=>{if(!t.required)return true;let e=i[t.id];return !(e==null||typeof e=="string"&&e.trim()===""||Array.isArray(e)&&e.length===0)}):false,x=()=>{let r={};return p&&A().forEach(e=>{if(!e.required)return;let s=i[e.id];s==null||typeof s=="string"&&s.trim()===""?r[e.id]="This question is required":Array.isArray(s)&&s.length===0&&(r[e.id]="At least one option must be selected");}),r},C=()=>h()&&l<d.length-1?(c(r=>r+1),true):false,L=()=>l>0?(c(r=>r-1),true):false,O=r=>r>=0&&r<d.length?(c(r),true):false,T=()=>d.every((r,t)=>{c(t);let e=h();return c(l),e}),_=()=>{let r=[];return d.forEach(t=>{t.questions.forEach(e=>{let s=i[e.id];if(s!=null&&e.riskLevel)if(["select","radio","checkbox"].includes(e.type)&&e.options)(Array.isArray(s)?s:[s]).forEach(o=>{var w;let a=(w=e.options)==null?void 0:w.find(u=>u.value===o);if(a!=null&&a.riskLevel){let u=a.riskLevel,D=u==="low"?1:u==="medium"?3:5,P=u==="low"?1:u==="medium"?3:5;r.push({id:`risk_${r.length+1}`,description:`${e.text} - ${a.label}`,likelihood:D,impact:P,score:D*P,level:u,mitigated:false,relatedQuestionIds:[e.id]});}});else {let n=e.riskLevel,o=n==="low"?1:n==="medium"?3:5,a=n==="low"?1:n==="medium"?3:5;r.push({id:`risk_${r.length+1}`,description:e.text,likelihood:o,impact:a,score:o*a,level:n,mitigated:false,relatedQuestionIds:[e.id]});}});}),r},$=(r,t,e)=>{let s=_(),n={id:`dpia_${Date.now()}`,title:t,processingDescription:e,startedAt:Date.now(),completedAt:Date.now(),assessor:r,answers:i,risks:s,overallRiskLevel:"low",canProceed:true,conclusion:"",version:"1.0"},o=chunkSSGJREE3_js.a(n);return n.overallRiskLevel=o.overallRiskLevel,n.canProceed=o.canProceed,n.conclusion=o.canProceed?"Based on the assessment, the processing can proceed with appropriate safeguards.":"Based on the assessment, the processing should not proceed without further mitigation measures.",n.recommendations=o.recommendations,I&&I(n),n},U=()=>{g({}),c(0),m&&typeof window!="undefined"&&localStorage.removeItem(f);},V=(()=>{let r=0,t=0;return d.forEach(e=>{e.questions.forEach(s=>{if(s.required&&v(s)){t++;let n=i[s.id];n!=null&&!(typeof n=="string"&&n.trim()==="")&&!(Array.isArray(n)&&n.length===0)&&r++;}});}),t>0?Math.round(r/t*100):0})();return {currentSectionIndex:l,currentSection:p,answers:i,updateAnswer:E,nextSection:C,prevSection:L,goToSection:O,isCurrentSectionValid:h,getCurrentSectionErrors:x,isComplete:T,completeDPIA:$,getVisibleQuestions:A,resetDPIA:U,progress:V}}exports.a=N;//# sourceMappingURL=chunk-U2CGMEWB.js.map
2
- //# sourceMappingURL=chunk-U2CGMEWB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/hooks/useDPIA.ts"],"names":["useDPIA","sections","initialAnswers","storageKey","useLocalStorage","onComplete","currentSectionIndex","setCurrentSectionIndex","useState","answers","setAnswers","useEffect","savedData","savedAnswers","sectionIndex","error","currentSection","updateAnswer","questionId","value","prevAnswers","__spreadProps","__spreadValues","shouldShowQuestion","question","condition","answer","getVisibleQuestions","isCurrentSectionValid","getCurrentSectionErrors","errors","nextSection","prevIndex","prevSection","goToSection","index","isComplete","section","valid","identifyRisks","risks","selectedOption","_a","option","opt","riskLevel","likelihood","impact","completeDPIA","assessorInfo","title","processingDescription","result","assessment","assessDPIARisk","resetDPIA","progress","answeredQuestions","totalRequiredQuestions"],"mappings":"wIA4GO,SAASA,CAAAA,CAAQ,CACtB,QAAA,CAAAC,CAAAA,CACA,eAAAC,CAAAA,CAAiB,GACjB,UAAA,CAAAC,CAAAA,CAAa,iBACb,eAAA,CAAAC,CAAAA,CAAkB,KAClB,UAAA,CAAAC,CACF,EAAkC,CAChC,GAAM,CAACC,CAAAA,CAAqBC,CAAsB,EAAIC,cAAAA,CAAiB,CAAC,EAClE,CAACC,CAAAA,CAASC,CAAU,CAAA,CAAIF,cAAAA,CAA8BN,CAAc,CAAA,CAG1ES,eAAAA,CAAU,IAAM,CACd,GAAIP,GAAmB,OAAO,MAAA,EAAW,YACvC,GAAI,CACF,IAAMQ,CAAAA,CAAY,YAAA,CAAa,QAAQT,CAAU,CAAA,CACjD,GAAIS,CAAAA,CAAW,CACb,GAAM,CAAE,OAAA,CAASC,EAAc,YAAA,CAAAC,CAAa,EAAI,IAAA,CAAK,KAAA,CAAMF,CAAS,CAAA,CACpEF,CAAAA,CAAWG,GAAgB,EAAE,EAC7BN,CAAAA,CAAuBO,CAAAA,EAAgB,CAAC,EAC1C,CACF,OAASC,CAAAA,CAAO,CACd,QAAQ,KAAA,CAAM,0BAAA,CAA4BA,CAAK,EACjD,CAEJ,EAAG,CAACZ,CAAAA,CAAYC,CAAe,CAAC,CAAA,CAGhCO,gBAAU,IAAM,CACd,GAAIP,CAAAA,EAAmB,OAAO,QAAW,WAAA,CACvC,GAAI,CACF,YAAA,CAAa,OAAA,CAAQD,EAAY,IAAA,CAAK,SAAA,CAAU,CAC9C,OAAA,CAAAM,CAAAA,CACA,aAAcH,CAChB,CAAC,CAAC,EACJ,CAAA,MAASS,EAAO,CACd,OAAA,CAAQ,MAAM,yBAAA,CAA2BA,CAAK,EAChD,CAEJ,CAAA,CAAG,CAACN,CAAAA,CAASH,CAAAA,CAAqBH,EAAYC,CAAe,CAAC,EAG9D,IAAMY,CAAAA,CAAiBf,EAASK,CAAmB,CAAA,EAAK,KAGlDW,CAAAA,CAAe,CAACC,EAAoBC,CAAAA,GAAe,CACvDT,EAAWU,CAAAA,EAAgBC,kBAAAA,CAAAC,mBAAA,EAAA,CACtBF,CAAAA,CAAAA,CADsB,CAEzB,CAACF,CAAU,EAAGC,CAChB,CAAA,CAAE,EACJ,CAAA,CAGMI,CAAAA,CAAsBC,GACrBA,CAAAA,CAAS,QAAA,CAIPA,EAAS,QAAA,CAAS,KAAA,CAAMC,GAAa,CAC1C,IAAMC,EAASjB,CAAAA,CAAQgB,CAAAA,CAAU,UAAU,CAAA,CAE3C,OAAQA,EAAU,QAAA,EAChB,KAAK,QAAA,CACH,OAAOC,IAAWD,CAAAA,CAAU,KAAA,CAC9B,KAAK,UAAA,CACH,OAAO,MAAM,OAAA,CAAQC,CAAM,EAAIA,CAAAA,CAAO,QAAA,CAASD,EAAU,KAAK,CAAA,CAAI,MACpE,KAAK,aAAA,CACH,OAAO,OAAOC,CAAAA,EAAW,SAAWA,CAAAA,CAASD,CAAAA,CAAU,MAAQ,KAAA,CACjE,KAAK,WACH,OAAO,OAAOC,GAAW,QAAA,CAAWA,CAAAA,CAASD,EAAU,KAAA,CAAQ,KAAA,CACjE,QACE,OAAO,KACX,CACF,CAAC,CAAA,CAlBQ,KAsBLE,CAAAA,CAAsB,IACrBX,EAIEA,CAAAA,CAAe,SAAA,CAAU,OAAOO,CAAkB,CAAA,CAHhD,EAAC,CAONK,CAAAA,CAAwB,IACvBZ,CAAAA,CAIoBW,CAAAA,GAED,KAAA,CAAMH,CAAAA,EAAY,CACxC,GAAI,CAACA,EAAS,QAAA,CACZ,OAAO,MAGT,IAAME,CAAAA,CAASjB,EAAQe,CAAAA,CAAS,EAAE,EAUlC,OARI,EAAwBE,GAAW,IAAA,EAInC,OAAOA,GAAW,QAAA,EAAYA,CAAAA,CAAO,MAAK,GAAM,EAAA,EAIhD,MAAM,OAAA,CAAQA,CAAM,GAAKA,CAAAA,CAAO,MAAA,GAAW,EAKjD,CAAC,CAAA,CAzBQ,MA6BLG,CAAAA,CAA0B,IAA8B,CAC5D,IAAMC,CAAAA,CAAiC,EAAC,CAExC,OAAKd,GAIoBW,CAAAA,EAAoB,CAE5B,QAAQH,CAAAA,EAAY,CACnC,GAAI,CAACA,CAAAA,CAAS,SACZ,OAGF,IAAME,EAASjB,CAAAA,CAAQe,CAAAA,CAAS,EAAE,CAAA,CAENE,CAAAA,EAAW,MAE5B,OAAOA,CAAAA,EAAW,UAAYA,CAAAA,CAAO,IAAA,KAAW,EAAA,CADzDI,CAAAA,CAAON,EAAS,EAAE,CAAA,CAAI,4BAGb,KAAA,CAAM,OAAA,CAAQE,CAAM,CAAA,EAAKA,CAAAA,CAAO,SAAW,CAAA,GACpDI,CAAAA,CAAON,EAAS,EAAE,CAAA,CAAI,wCAE1B,CAAC,CAAA,CAEMM,CACT,CAAA,CAGMC,CAAAA,CAAc,IACbH,CAAAA,EAAsB,EAIvBtB,EAAsBL,CAAAA,CAAS,MAAA,CAAS,GAC1CM,CAAAA,CAAuByB,CAAAA,EAAaA,EAAY,CAAC,CAAA,CAC1C,MALA,KAAA,CAYLC,CAAAA,CAAc,IACd3B,CAAAA,CAAsB,CAAA,EACxBC,EAAuByB,CAAAA,EAAaA,CAAAA,CAAY,CAAC,CAAA,CAC1C,IAAA,EAGF,MAIHE,CAAAA,CAAeC,CAAAA,EACfA,GAAS,CAAA,EAAKA,CAAAA,CAAQlC,EAAS,MAAA,EACjCM,CAAAA,CAAuB4B,CAAK,CAAA,CACrB,IAAA,EAGF,MAIHC,CAAAA,CAAa,IACVnC,EAAS,KAAA,CAAM,CAACoC,EAASF,CAAAA,GAAU,CAExC5B,EAAuB4B,CAAK,CAAA,CAC5B,IAAMG,CAAAA,CAAQV,CAAAA,EAAsB,CAEpC,OAAArB,CAAAA,CAAuBD,CAAmB,EACnCgC,CACT,CAAC,EAIGC,CAAAA,CAAgB,IAAkB,CACtC,IAAMC,CAAAA,CAAoB,EAAC,CAG3B,OAAAvC,EAAS,OAAA,CAAQoC,CAAAA,EAAW,CAC1BA,CAAAA,CAAQ,SAAA,CAAU,QAAQb,CAAAA,EAAY,CACpC,IAAME,CAAAA,CAASjB,CAAAA,CAAQe,EAAS,EAAE,CAAA,CAGlC,GAA4BE,CAAAA,EAAW,IAAA,EAKnCF,EAAS,SAAA,CAEX,GAAI,CAAC,QAAA,CAAU,OAAA,CAAS,UAAU,CAAA,CAAE,QAAA,CAASA,EAAS,IAAI,CAAA,EAAKA,EAAS,OAAA,CAAA,CAC9C,KAAA,CAAM,QAAQE,CAAM,CAAA,CAAIA,EAAS,CAACA,CAAM,GAEhD,OAAA,CAAQe,CAAAA,EAAkB,CA9TtD,IAAAC,CAAAA,CA+Tc,IAAMC,CAAAA,CAAAA,CAASD,CAAAA,CAAAlB,EAAS,OAAA,GAAT,IAAA,CAAA,MAAA,CAAAkB,EAAkB,IAAA,CAAKE,CAAAA,EAAOA,EAAI,KAAA,GAAUH,CAAAA,CAAAA,CAE3D,GAAIE,CAAAA,EAAA,IAAA,EAAAA,EAAQ,SAAA,CAAW,CACrB,IAAME,CAAAA,CAAYF,CAAAA,CAAO,UACnBG,CAAAA,CAAaD,CAAAA,GAAc,MAAQ,CAAA,CAAIA,CAAAA,GAAc,SAAW,CAAA,CAAI,CAAA,CACpEE,EAASF,CAAAA,GAAc,KAAA,CAAQ,EAAIA,CAAAA,GAAc,QAAA,CAAW,EAAI,CAAA,CAEtEL,CAAAA,CAAM,KAAK,CACT,EAAA,CAAI,QAAQA,CAAAA,CAAM,MAAA,CAAS,CAAC,CAAA,CAAA,CAC5B,WAAA,CAAa,GAAGhB,CAAAA,CAAS,IAAI,MAAMmB,CAAAA,CAAO,KAAK,GAC/C,UAAA,CAAAG,CAAAA,CACA,OAAAC,CAAAA,CACA,KAAA,CAAOD,EAAaC,CAAAA,CACpB,KAAA,CAAOF,EACP,SAAA,CAAW,KAAA,CACX,mBAAoB,CAACrB,CAAAA,CAAS,EAAE,CAClC,CAAC,EACH,CACF,CAAC,OACI,CAEL,IAAMqB,EAAYrB,CAAAA,CAAS,SAAA,CACrBsB,EAAaD,CAAAA,GAAc,KAAA,CAAQ,EAAIA,CAAAA,GAAc,QAAA,CAAW,EAAI,CAAA,CACpEE,CAAAA,CAASF,IAAc,KAAA,CAAQ,CAAA,CAAIA,IAAc,QAAA,CAAW,CAAA,CAAI,EAEtEL,CAAAA,CAAM,IAAA,CAAK,CACT,EAAA,CAAI,CAAA,KAAA,EAAQA,EAAM,MAAA,CAAS,CAAC,GAC5B,WAAA,CAAahB,CAAAA,CAAS,KACtB,UAAA,CAAAsB,CAAAA,CACA,OAAAC,CAAAA,CACA,KAAA,CAAOD,EAAaC,CAAAA,CACpB,KAAA,CAAOF,EACP,SAAA,CAAW,KAAA,CACX,mBAAoB,CAACrB,CAAAA,CAAS,EAAE,CAClC,CAAC,EACH,CAEJ,CAAC,EACH,CAAC,CAAA,CAEMgB,CACT,EAGMQ,CAAAA,CAAe,CACnBC,EACAC,CAAAA,CACAC,CAAAA,GACe,CACf,IAAMX,CAAAA,CAAQD,GAAc,CAEtBa,CAAAA,CAAqB,CACzB,EAAA,CAAI,CAAA,KAAA,EAAQ,KAAK,GAAA,EAAK,GACtB,KAAA,CAAAF,CAAAA,CACA,sBAAAC,CAAAA,CACA,SAAA,CAAW,KAAK,GAAA,EAAI,CACpB,YAAa,IAAA,CAAK,GAAA,GAClB,QAAA,CAAUF,CAAAA,CACV,QAAAxC,CAAAA,CACA,KAAA,CAAA+B,EACA,gBAAA,CAAkB,KAAA,CAClB,WAAY,IAAA,CACZ,UAAA,CAAY,GACZ,OAAA,CAAS,KACX,EAGMa,CAAAA,CAAaC,kBAAAA,CAAeF,CAAM,CAAA,CAExC,OAAAA,EAAO,gBAAA,CAAmBC,CAAAA,CAAW,iBACrCD,CAAAA,CAAO,UAAA,CAAaC,EAAW,UAAA,CAC/BD,CAAAA,CAAO,WAAaC,CAAAA,CAAW,UAAA,CAC3B,mFACA,iGAAA,CACJD,CAAAA,CAAO,gBAAkBC,CAAAA,CAAW,eAAA,CAEhChD,GACFA,CAAAA,CAAW+C,CAAM,EAGZA,CACT,CAAA,CAGMG,EAAY,IAAM,CACtB7C,EAAW,EAAE,EACbH,CAAAA,CAAuB,CAAC,EAEpBH,CAAAA,EAAmB,OAAO,QAAW,WAAA,EACvC,YAAA,CAAa,WAAWD,CAAU,EAEtC,EAGMqD,CAAAA,CAAAA,CAAY,IAAM,CACtB,IAAIC,CAAAA,CAAoB,EACpBC,CAAAA,CAAyB,CAAA,CAE7B,OAAAzD,CAAAA,CAAS,OAAA,CAAQoC,GAAW,CAC1BA,CAAAA,CAAQ,UAAU,OAAA,CAAQb,CAAAA,EAAY,CACpC,GAAIA,CAAAA,CAAS,UAAYD,CAAAA,CAAmBC,CAAQ,EAAG,CACrDkC,CAAAA,EAAAA,CAEA,IAAMhC,CAAAA,CAASjB,CAAAA,CAAQe,EAAS,EAAE,CAAA,CAGhCE,GAAW,IAAA,EACX,EAAE,OAAOA,CAAAA,EAAW,QAAA,EAAYA,EAAO,IAAA,EAAK,GAAM,KAClD,EAAE,KAAA,CAAM,QAAQA,CAAM,CAAA,EAAKA,EAAO,MAAA,GAAW,CAAA,CAAA,EAE7C+B,IAEJ,CACF,CAAC,EACH,CAAC,CAAA,CAEMC,EAAyB,CAAA,CAC5B,IAAA,CAAK,MAAOD,CAAAA,CAAoBC,CAAAA,CAA0B,GAAG,CAAA,CAC7D,CACN,IAAG,CAEH,OAAO,CACL,mBAAA,CAAApD,CAAAA,CACA,eAAAU,CAAAA,CACA,OAAA,CAAAP,EACA,YAAA,CAAAQ,CAAAA,CACA,YAAAc,CAAAA,CACA,WAAA,CAAAE,EACA,WAAA,CAAAC,CAAAA,CACA,sBAAAN,CAAAA,CACA,uBAAA,CAAAC,EACA,UAAA,CAAAO,CAAAA,CACA,aAAAY,CAAAA,CACA,mBAAA,CAAArB,EACA,SAAA,CAAA4B,CAAAA,CACA,QAAA,CAAAC,CACF,CACF","file":"chunk-U2CGMEWB.js","sourcesContent":["import { useState, useEffect } from 'react';\nimport { DPIAQuestion, DPIASection, DPIAResult, DPIARisk } from '../types/dpia';\nimport { assessDPIARisk } from '../utils/dpia';\n\ninterface UseDPIAOptions {\n /**\n * Sections of the DPIA questionnaire\n */\n sections: DPIASection[];\n \n /**\n * Initial answers (if resuming a DPIA)\n */\n initialAnswers?: Record<string, any>;\n \n /**\n * Storage key for DPIA data\n * @default \"ndpr_dpia_data\"\n */\n storageKey?: string;\n \n /**\n * Whether to use local storage to persist DPIA data\n * @default true\n */\n useLocalStorage?: boolean;\n \n /**\n * Callback function called when the DPIA is completed\n */\n onComplete?: (result: DPIAResult) => void;\n}\n\ninterface UseDPIAReturn {\n /**\n * Current section index\n */\n currentSectionIndex: number;\n \n /**\n * Current section\n */\n currentSection: DPIASection | null;\n \n /**\n * All answers\n */\n answers: Record<string, any>;\n \n /**\n * Update an answer\n */\n updateAnswer: (questionId: string, value: any) => void;\n \n /**\n * Go to the next section\n */\n nextSection: () => boolean;\n \n /**\n * Go to the previous section\n */\n prevSection: () => boolean;\n \n /**\n * Go to a specific section\n */\n goToSection: (index: number) => boolean;\n \n /**\n * Check if the current section is valid\n */\n isCurrentSectionValid: () => boolean;\n \n /**\n * Get validation errors for the current section\n */\n getCurrentSectionErrors: () => Record<string, string>;\n \n /**\n * Check if the DPIA is complete\n */\n isComplete: () => boolean;\n \n /**\n * Complete the DPIA and generate a result\n */\n completeDPIA: (assessorInfo: { name: string; role: string; email: string; }, title: string, processingDescription: string) => DPIAResult;\n \n /**\n * Get the visible questions for the current section\n */\n getVisibleQuestions: () => DPIAQuestion[];\n \n /**\n * Reset the DPIA\n */\n resetDPIA: () => void;\n \n /**\n * Progress percentage\n */\n progress: number;\n}\n\n/**\n * Hook for conducting Data Protection Impact Assessments in compliance with the NDPA 2023\n */\nexport function useDPIA({\n sections,\n initialAnswers = {},\n storageKey = \"ndpr_dpia_data\",\n useLocalStorage = true,\n onComplete\n}: UseDPIAOptions): UseDPIAReturn {\n const [currentSectionIndex, setCurrentSectionIndex] = useState<number>(0);\n const [answers, setAnswers] = useState<Record<string, any>>(initialAnswers);\n \n // Load DPIA data from storage on mount\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined') {\n try {\n const savedData = localStorage.getItem(storageKey);\n if (savedData) {\n const { answers: savedAnswers, sectionIndex } = JSON.parse(savedData);\n setAnswers(savedAnswers || {});\n setCurrentSectionIndex(sectionIndex || 0);\n }\n } catch (error) {\n console.error('Error loading DPIA data:', error);\n }\n }\n }, [storageKey, useLocalStorage]);\n \n // Save DPIA data to storage when it changes\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined') {\n try {\n localStorage.setItem(storageKey, JSON.stringify({\n answers,\n sectionIndex: currentSectionIndex\n }));\n } catch (error) {\n console.error('Error saving DPIA data:', error);\n }\n }\n }, [answers, currentSectionIndex, storageKey, useLocalStorage]);\n \n // Get the current section\n const currentSection = sections[currentSectionIndex] || null;\n \n // Update an answer\n const updateAnswer = (questionId: string, value: any) => {\n setAnswers(prevAnswers => ({\n ...prevAnswers,\n [questionId]: value\n }));\n };\n \n // Check if a question should be shown based on its conditions\n const shouldShowQuestion = (question: DPIAQuestion): boolean => {\n if (!question.showWhen) {\n return true;\n }\n \n return question.showWhen.every(condition => {\n const answer = answers[condition.questionId];\n \n switch (condition.operator) {\n case 'equals':\n return answer === condition.value;\n case 'contains':\n return Array.isArray(answer) ? answer.includes(condition.value) : false;\n case 'greaterThan':\n return typeof answer === 'number' ? answer > condition.value : false;\n case 'lessThan':\n return typeof answer === 'number' ? answer < condition.value : false;\n default:\n return true;\n }\n });\n };\n \n // Get the visible questions for the current section\n const getVisibleQuestions = (): DPIAQuestion[] => {\n if (!currentSection) {\n return [];\n }\n \n return currentSection.questions.filter(shouldShowQuestion);\n };\n \n // Check if the current section is valid\n const isCurrentSectionValid = (): boolean => {\n if (!currentSection) {\n return false;\n }\n \n const visibleQuestions = getVisibleQuestions();\n \n return visibleQuestions.every(question => {\n if (!question.required) {\n return true;\n }\n \n const answer = answers[question.id];\n \n if (answer === undefined || answer === null) {\n return false;\n }\n \n if (typeof answer === 'string' && answer.trim() === '') {\n return false;\n }\n \n if (Array.isArray(answer) && answer.length === 0) {\n return false;\n }\n \n return true;\n });\n };\n \n // Get validation errors for the current section\n const getCurrentSectionErrors = (): Record<string, string> => {\n const errors: Record<string, string> = {};\n \n if (!currentSection) {\n return errors;\n }\n \n const visibleQuestions = getVisibleQuestions();\n \n visibleQuestions.forEach(question => {\n if (!question.required) {\n return;\n }\n \n const answer = answers[question.id];\n \n if (answer === undefined || answer === null) {\n errors[question.id] = 'This question is required';\n } else if (typeof answer === 'string' && answer.trim() === '') {\n errors[question.id] = 'This question is required';\n } else if (Array.isArray(answer) && answer.length === 0) {\n errors[question.id] = 'At least one option must be selected';\n }\n });\n \n return errors;\n };\n \n // Go to the next section\n const nextSection = (): boolean => {\n if (!isCurrentSectionValid()) {\n return false;\n }\n \n if (currentSectionIndex < sections.length - 1) {\n setCurrentSectionIndex(prevIndex => prevIndex + 1);\n return true;\n }\n \n return false;\n };\n \n // Go to the previous section\n const prevSection = (): boolean => {\n if (currentSectionIndex > 0) {\n setCurrentSectionIndex(prevIndex => prevIndex - 1);\n return true;\n }\n \n return false;\n };\n \n // Go to a specific section\n const goToSection = (index: number): boolean => {\n if (index >= 0 && index < sections.length) {\n setCurrentSectionIndex(index);\n return true;\n }\n \n return false;\n };\n \n // Check if the DPIA is complete\n const isComplete = (): boolean => {\n return sections.every((section, index) => {\n // Temporarily set the current section to check ifit&apos;s valid\n setCurrentSectionIndex(index);\n const valid = isCurrentSectionValid();\n // Restore the current section\n setCurrentSectionIndex(currentSectionIndex);\n return valid;\n });\n };\n \n // Identify risks based on answers\n const identifyRisks = (): DPIARisk[] => {\n const risks: DPIARisk[] = [];\n \n // Check each question for risk indicators\n sections.forEach(section => {\n section.questions.forEach(question => {\n const answer = answers[question.id];\n \n // Skip if no answer\n if (answer === undefined || answer === null) {\n return;\n }\n \n // Check if the question has a risk level\n if (question.riskLevel) {\n // For select/radio/checkbox questions, check if the selected option has a risk level\n if (['select', 'radio', 'checkbox'].includes(question.type) && question.options) {\n const selectedOptions = Array.isArray(answer) ? answer : [answer];\n \n selectedOptions.forEach(selectedOption => {\n const option = question.options?.find(opt => opt.value === selectedOption);\n \n if (option?.riskLevel) {\n const riskLevel = option.riskLevel;\n const likelihood = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n const impact = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n \n risks.push({\n id: `risk_${risks.length + 1}`,\n description: `${question.text} - ${option.label}`,\n likelihood,\n impact,\n score: likelihood * impact,\n level: riskLevel,\n mitigated: false,\n relatedQuestionIds: [question.id]\n });\n }\n });\n } else {\n // For other question types, use the question's risk level\n const riskLevel = question.riskLevel;\n const likelihood = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n const impact = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n \n risks.push({\n id: `risk_${risks.length + 1}`,\n description: question.text,\n likelihood,\n impact,\n score: likelihood * impact,\n level: riskLevel,\n mitigated: false,\n relatedQuestionIds: [question.id]\n });\n }\n }\n });\n });\n \n return risks;\n };\n \n // Complete the DPIA and generate a result\n const completeDPIA = (\n assessorInfo: { name: string; role: string; email: string; },\n title: string,\n processingDescription: string\n ): DPIAResult => {\n const risks = identifyRisks();\n \n const result: DPIAResult = {\n id: `dpia_${Date.now()}`,\n title,\n processingDescription,\n startedAt: Date.now(),\n completedAt: Date.now(),\n assessor: assessorInfo,\n answers,\n risks,\n overallRiskLevel: 'low',\n canProceed: true,\n conclusion: '',\n version: '1.0'\n };\n \n // Assess the risks\n const assessment = assessDPIARisk(result);\n \n result.overallRiskLevel = assessment.overallRiskLevel;\n result.canProceed = assessment.canProceed;\n result.conclusion = assessment.canProceed\n ? 'Based on the assessment, the processing can proceed with appropriate safeguards.'\n : 'Based on the assessment, the processing should not proceed without further mitigation measures.';\n result.recommendations = assessment.recommendations;\n \n if (onComplete) {\n onComplete(result);\n }\n \n return result;\n };\n \n // Reset the DPIA\n const resetDPIA = () => {\n setAnswers({});\n setCurrentSectionIndex(0);\n \n if (useLocalStorage && typeof window !== 'undefined') {\n localStorage.removeItem(storageKey);\n }\n };\n \n // Calculate progress percentage\n const progress = (() => {\n let answeredQuestions = 0;\n let totalRequiredQuestions = 0;\n \n sections.forEach(section => {\n section.questions.forEach(question => {\n if (question.required && shouldShowQuestion(question)) {\n totalRequiredQuestions++;\n \n const answer = answers[question.id];\n if (\n answer !== undefined && \n answer !== null && \n !(typeof answer === 'string' && answer.trim() === '') &&\n !(Array.isArray(answer) && answer.length === 0)\n ) {\n answeredQuestions++;\n }\n }\n });\n });\n \n return totalRequiredQuestions > 0 \n ? Math.round((answeredQuestions / totalRequiredQuestions) * 100) \n : 0;\n })();\n \n return {\n currentSectionIndex,\n currentSection,\n answers,\n updateAnswer,\n nextSection,\n prevSection,\n goToSection,\n isCurrentSectionValid,\n getCurrentSectionErrors,\n isComplete,\n completeDPIA,\n getVisibleQuestions,\n resetDPIA,\n progress\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/components/ropa/ROPAManager.tsx"],"names":["LAWFUL_BASIS_OPTIONS","STATUS_OPTIONS","DATA_SOURCE_OPTIONS","createEmptyRecord","now","formatDate","timestamp","ROPAManager","ropa","onAddRecord","onUpdateRecord","onArchiveRecord","title","description","className","buttonClassName","viewMode","setViewMode","useState","searchTerm","setSearchTerm","statusFilter","setStatusFilter","basisFilter","setBasisFilter","editingRecord","setEditingRecord","formErrors","setFormErrors","purposesInput","setPurposesInput","dataCategoriesInput","setDataCategoriesInput","sensitiveDataInput","setSensitiveDataInput","subjectCategoriesInput","setSubjectCategoriesInput","recipientsInput","setRecipientsInput","securityMeasuresInput","setSecurityMeasuresInput","systemsUsedInput","setSystemsUsedInput","summary","useMemo","generateROPASummary","complianceGaps","identifyComplianceGaps","filteredRecords","filtered","r","term","c","useEffect","handleNewRecord","newRecord","handleEditRecord","record","__spreadValues","parseCommaSeparated","value","s","handleSaveRecord","recordToSave","__spreadProps","validation","validateProcessingRecord","handleArchiveRecord","id","handleExportCSV","csv","exportROPAToCSV","blob","url","link","handleCancelForm","updateEditingField","field","prev","updateControllerField","isReviewOverdue","renderStatusBadge","status","colorClasses","labels","React","renderBasisBadge","basis","renderOrganizationHeader","renderSummaryDashboard","option","dept","gap","g","i","renderRecordsTable","e","opt","overdue","hasGaps","renderForm","isNew","error","renderViewTabs"],"mappings":"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","file":"chunk-UUWVBENC.js","sourcesContent":["import React, { useState, useEffect, useMemo } from 'react';\nimport type { LawfulBasis } from '../../types/lawful-basis';\nimport type {\n ProcessingRecord,\n RecordOfProcessingActivities,\n ROPASummary,\n} from '../../types/ropa';\nimport type { ROPAComplianceGap } from '../../utils/ropa';\nimport {\n validateProcessingRecord,\n generateROPASummary,\n exportROPAToCSV,\n identifyComplianceGaps,\n} from '../../utils/ropa';\n\nexport interface ROPAManagerProps {\n /**\n * The full Record of Processing Activities\n */\n ropa: RecordOfProcessingActivities;\n\n /**\n * Callback when a new record is added\n */\n onAddRecord?: (record: ProcessingRecord) => void;\n\n /**\n * Callback when a record is updated\n */\n onUpdateRecord?: (id: string, updates: Partial<ProcessingRecord>) => void;\n\n /**\n * Callback when a record is archived\n */\n onArchiveRecord?: (id: string) => void;\n\n /**\n * Title displayed on the manager\n * @default \"Record of Processing Activities (ROPA)\"\n */\n title?: string;\n\n /**\n * Description text\n * @default \"Maintain a comprehensive record of all data processing activities as required by the NDPA 2023.\"\n */\n description?: string;\n\n /**\n * Custom CSS class\n */\n className?: string;\n\n /**\n * Custom CSS class for buttons\n */\n buttonClassName?: string;\n}\n\nconst LAWFUL_BASIS_OPTIONS: Array<{ value: LawfulBasis; label: string }> = [\n { value: 'consent', label: 'Consent (Section 25(1)(a))' },\n { value: 'contract', label: 'Contract (Section 25(1)(b))' },\n { value: 'legal_obligation', label: 'Legal Obligation (Section 25(1)(c))' },\n { value: 'vital_interests', label: 'Vital Interests (Section 25(1)(d))' },\n { value: 'public_interest', label: 'Public Interest (Section 25(1)(e))' },\n { value: 'legitimate_interests', label: 'Legitimate Interests (Section 25(1)(f))' },\n];\n\nconst STATUS_OPTIONS: Array<{ value: ProcessingRecord['status']; label: string }> = [\n { value: 'active', label: 'Active' },\n { value: 'inactive', label: 'Inactive' },\n { value: 'archived', label: 'Archived' },\n];\n\nconst DATA_SOURCE_OPTIONS: Array<{ value: ProcessingRecord['dataSource']; label: string }> = [\n { value: 'data_subject', label: 'Directly from Data Subject' },\n { value: 'third_party', label: 'Third Party' },\n { value: 'public_source', label: 'Public Source' },\n { value: 'other', label: 'Other' },\n];\n\ntype ViewMode = 'list' | 'form' | 'summary';\n\nfunction createEmptyRecord(): ProcessingRecord {\n const now = Date.now();\n return {\n id: `proc_${now}_${Math.random().toString(36).substring(2, 11)}`,\n name: '',\n description: '',\n controllerDetails: { name: '', contact: '', address: '' },\n lawfulBasis: 'consent',\n lawfulBasisJustification: '',\n purposes: [],\n dataCategories: [],\n dataSubjectCategories: [],\n recipients: [],\n retentionPeriod: '',\n securityMeasures: [],\n dataSource: 'data_subject',\n dpiaRequired: false,\n automatedDecisionMaking: false,\n status: 'active',\n createdAt: now,\n updatedAt: now,\n };\n}\n\nfunction formatDate(timestamp: number | undefined): string {\n if (!timestamp) return 'N/A';\n return new Date(timestamp).toLocaleDateString();\n}\n\nexport const ROPAManager: React.FC<ROPAManagerProps> = ({\n ropa,\n onAddRecord,\n onUpdateRecord,\n onArchiveRecord,\n title = 'Record of Processing Activities (ROPA)',\n description = 'Maintain a comprehensive record of all data processing activities as required by the NDPA 2023.',\n className = '',\n buttonClassName = '',\n}) => {\n const [viewMode, setViewMode] = useState<ViewMode>('list');\n const [searchTerm, setSearchTerm] = useState('');\n const [statusFilter, setStatusFilter] = useState<string>('all');\n const [basisFilter, setBasisFilter] = useState<string>('all');\n const [editingRecord, setEditingRecord] = useState<ProcessingRecord | null>(null);\n const [formErrors, setFormErrors] = useState<string[]>([]);\n\n // Temporary field values for comma-separated list inputs\n const [purposesInput, setPurposesInput] = useState('');\n const [dataCategoriesInput, setDataCategoriesInput] = useState('');\n const [sensitiveDataInput, setSensitiveDataInput] = useState('');\n const [subjectCategoriesInput, setSubjectCategoriesInput] = useState('');\n const [recipientsInput, setRecipientsInput] = useState('');\n const [securityMeasuresInput, setSecurityMeasuresInput] = useState('');\n const [systemsUsedInput, setSystemsUsedInput] = useState('');\n\n const summary = useMemo(() => generateROPASummary(ropa), [ropa]);\n const complianceGaps = useMemo(() => identifyComplianceGaps(ropa), [ropa]);\n\n // Filter records\n const filteredRecords = useMemo(() => {\n let filtered = [...ropa.records];\n\n if (statusFilter !== 'all') {\n filtered = filtered.filter((r) => r.status === statusFilter);\n }\n\n if (basisFilter !== 'all') {\n filtered = filtered.filter((r) => r.lawfulBasis === basisFilter);\n }\n\n if (searchTerm) {\n const term = searchTerm.toLowerCase();\n filtered = filtered.filter(\n (r) =>\n r.name.toLowerCase().includes(term) ||\n r.description.toLowerCase().includes(term) ||\n r.dataCategories.some((c) => c.toLowerCase().includes(term)) ||\n (r.department && r.department.toLowerCase().includes(term))\n );\n }\n\n return filtered;\n }, [ropa.records, statusFilter, basisFilter, searchTerm]);\n\n // Sync form inputs when editing record changes\n useEffect(() => {\n if (editingRecord) {\n setPurposesInput(editingRecord.purposes.join(', '));\n setDataCategoriesInput(editingRecord.dataCategories.join(', '));\n setSensitiveDataInput((editingRecord.sensitiveDataCategories || []).join(', '));\n setSubjectCategoriesInput(editingRecord.dataSubjectCategories.join(', '));\n setRecipientsInput(editingRecord.recipients.join(', '));\n setSecurityMeasuresInput(editingRecord.securityMeasures.join(', '));\n setSystemsUsedInput((editingRecord.systemsUsed || []).join(', '));\n }\n }, [editingRecord?.id]);\n\n const handleNewRecord = () => {\n const newRecord = createEmptyRecord();\n // Prefill controller details from the organization\n newRecord.controllerDetails.name = ropa.organizationName;\n newRecord.controllerDetails.contact = ropa.organizationContact;\n newRecord.controllerDetails.address = ropa.organizationAddress;\n if (ropa.ndpcRegistrationNumber) {\n newRecord.controllerDetails.registrationNumber = ropa.ndpcRegistrationNumber;\n }\n if (ropa.dpoDetails) {\n newRecord.controllerDetails.dpoContact = ropa.dpoDetails.email;\n }\n setEditingRecord(newRecord);\n setFormErrors([]);\n setViewMode('form');\n };\n\n const handleEditRecord = (record: ProcessingRecord) => {\n setEditingRecord({ ...record });\n setFormErrors([]);\n setViewMode('form');\n };\n\n const parseCommaSeparated = (value: string): string[] => {\n return value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n };\n\n const handleSaveRecord = () => {\n if (!editingRecord) return;\n\n // Apply comma-separated inputs to the record\n const recordToSave: ProcessingRecord = {\n ...editingRecord,\n purposes: parseCommaSeparated(purposesInput),\n dataCategories: parseCommaSeparated(dataCategoriesInput),\n sensitiveDataCategories: parseCommaSeparated(sensitiveDataInput),\n dataSubjectCategories: parseCommaSeparated(subjectCategoriesInput),\n recipients: parseCommaSeparated(recipientsInput),\n securityMeasures: parseCommaSeparated(securityMeasuresInput),\n systemsUsed: parseCommaSeparated(systemsUsedInput),\n updatedAt: Date.now(),\n };\n\n // Remove empty sensitive data categories\n if (\n recordToSave.sensitiveDataCategories &&\n recordToSave.sensitiveDataCategories.length === 0\n ) {\n recordToSave.sensitiveDataCategories = undefined;\n }\n\n // Remove empty systems used\n if (recordToSave.systemsUsed && recordToSave.systemsUsed.length === 0) {\n recordToSave.systemsUsed = undefined;\n }\n\n const validation = validateProcessingRecord(recordToSave);\n if (!validation.valid) {\n setFormErrors(validation.errors);\n return;\n }\n\n // Check if this is a new record or an update\n const existingRecord = ropa.records.find((r) => r.id === recordToSave.id);\n if (existingRecord) {\n onUpdateRecord?.(recordToSave.id, recordToSave);\n } else {\n onAddRecord?.(recordToSave);\n }\n\n setEditingRecord(null);\n setFormErrors([]);\n setViewMode('list');\n };\n\n const handleArchiveRecord = (id: string) => {\n onArchiveRecord?.(id);\n };\n\n const handleExportCSV = () => {\n const csv = exportROPAToCSV(ropa);\n const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `ropa_${ropa.organizationName.replace(/\\s+/g, '_').toLowerCase()}_${new Date().toISOString().slice(0, 10)}.csv`;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 100);\n };\n\n const handleCancelForm = () => {\n setEditingRecord(null);\n setFormErrors([]);\n setViewMode('list');\n };\n\n const updateEditingField = (field: string, value: any) => {\n if (!editingRecord) return;\n setEditingRecord((prev) => (prev ? { ...prev, [field]: value } : prev));\n };\n\n const updateControllerField = (field: string, value: string) => {\n if (!editingRecord) return;\n setEditingRecord((prev) =>\n prev\n ? {\n ...prev,\n controllerDetails: { ...prev.controllerDetails, [field]: value },\n }\n : prev\n );\n };\n\n const isReviewOverdue = (record: ProcessingRecord): boolean => {\n return !!record.nextReviewDate && record.nextReviewDate <= Date.now();\n };\n\n // Status badge rendering\n const renderStatusBadge = (status: ProcessingRecord['status']) => {\n const colorClasses: Record<ProcessingRecord['status'], string> = {\n active: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',\n inactive: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',\n archived: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300',\n };\n\n const labels: Record<ProcessingRecord['status'], string> = {\n active: 'Active',\n inactive: 'Inactive',\n archived: 'Archived',\n };\n\n return (\n <span className={`px-2 py-1 rounded text-xs font-medium ${colorClasses[status]}`}>\n {labels[status]}\n </span>\n );\n };\n\n // Lawful basis badge rendering\n const renderBasisBadge = (basis: LawfulBasis) => {\n const labels: Record<LawfulBasis, string> = {\n consent: 'Consent',\n contract: 'Contract',\n legal_obligation: 'Legal Obligation',\n vital_interests: 'Vital Interests',\n public_interest: 'Public Interest',\n legitimate_interests: 'Legitimate Interests',\n };\n\n return (\n <span className=\"px-2 py-1 rounded text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200\">\n {labels[basis]}\n </span>\n );\n };\n\n // Render organization header\n const renderOrganizationHeader = () => (\n <div className=\"mb-6 p-4 bg-gray-50 dark:bg-gray-700 rounded-md\">\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div>\n <p className=\"text-sm font-medium text-gray-500 dark:text-gray-400\">Organization</p>\n <p className=\"text-sm font-semibold\">{ropa.organizationName}</p>\n </div>\n {ropa.dpoDetails && (\n <div>\n <p className=\"text-sm font-medium text-gray-500 dark:text-gray-400\">\n Data Protection Officer\n </p>\n <p className=\"text-sm font-semibold\">{ropa.dpoDetails.name}</p>\n <p className=\"text-xs text-gray-500 dark:text-gray-400\">{ropa.dpoDetails.email}</p>\n </div>\n )}\n {ropa.ndpcRegistrationNumber && (\n <div>\n <p className=\"text-sm font-medium text-gray-500 dark:text-gray-400\">\n NDPC Registration No.\n </p>\n <p className=\"text-sm font-semibold\">{ropa.ndpcRegistrationNumber}</p>\n </div>\n )}\n </div>\n <div className=\"mt-2 text-xs text-gray-500 dark:text-gray-400\">\n Version {ropa.version} | Last Updated: {formatDate(ropa.lastUpdated)}\n </div>\n </div>\n );\n\n // Render compliance summary dashboard\n const renderSummaryDashboard = () => (\n <div className=\"mb-6\">\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-4\">\n <div className=\"p-4 bg-blue-50 dark:bg-blue-900/20 rounded-md text-center\">\n <p className=\"text-2xl font-bold text-blue-700 dark:text-blue-300\">\n {summary.totalRecords}\n </p>\n <p className=\"text-xs text-blue-600 dark:text-blue-400\">Total Records</p>\n </div>\n <div className=\"p-4 bg-green-50 dark:bg-green-900/20 rounded-md text-center\">\n <p className=\"text-2xl font-bold text-green-700 dark:text-green-300\">\n {summary.activeRecords}\n </p>\n <p className=\"text-xs text-green-600 dark:text-green-400\">Active</p>\n </div>\n <div className=\"p-4 bg-purple-50 dark:bg-purple-900/20 rounded-md text-center\">\n <p className=\"text-2xl font-bold text-purple-700 dark:text-purple-300\">\n {summary.crossBorderRecords}\n </p>\n <p className=\"text-xs text-purple-600 dark:text-purple-400\">Cross-Border</p>\n </div>\n <div className=\"p-4 bg-orange-50 dark:bg-orange-900/20 rounded-md text-center\">\n <p className=\"text-2xl font-bold text-orange-700 dark:text-orange-300\">\n {complianceGaps.length}\n </p>\n <p className=\"text-xs text-orange-600 dark:text-orange-400\">Records with Gaps</p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-3 gap-4 mb-4\">\n <div className=\"p-3 bg-gray-50 dark:bg-gray-700 rounded-md\">\n <p className=\"text-sm font-medium mb-2\">By Lawful Basis</p>\n {LAWFUL_BASIS_OPTIONS.map((option) => (\n <div key={option.value} className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-gray-600 dark:text-gray-400\">{option.label.split(' (')[0]}</span>\n <span className=\"font-medium\">{summary.byLawfulBasis[option.value] || 0}</span>\n </div>\n ))}\n </div>\n <div className=\"p-3 bg-gray-50 dark:bg-gray-700 rounded-md\">\n <p className=\"text-sm font-medium mb-2\">Risk Indicators</p>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-gray-600 dark:text-gray-400\">Sensitive Data</span>\n <span className=\"font-medium\">{summary.sensitiveDataRecords}</span>\n </div>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-gray-600 dark:text-gray-400\">DPIA Required</span>\n <span className=\"font-medium\">{summary.dpiaRequiredRecords}</span>\n </div>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-gray-600 dark:text-gray-400\">Automated Decisions</span>\n <span className=\"font-medium\">{summary.automatedDecisionRecords}</span>\n </div>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-gray-600 dark:text-gray-400\">Due for Review</span>\n <span className={`font-medium ${summary.recordsDueForReview.length > 0 ? 'text-red-600 dark:text-red-400' : ''}`}>\n {summary.recordsDueForReview.length}\n </span>\n </div>\n </div>\n {summary.topDepartments.length > 0 && (\n <div className=\"p-3 bg-gray-50 dark:bg-gray-700 rounded-md\">\n <p className=\"text-sm font-medium mb-2\">Top Departments</p>\n {summary.topDepartments.slice(0, 5).map((dept) => (\n <div key={dept.department} className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-gray-600 dark:text-gray-400\">{dept.department}</span>\n <span className=\"font-medium\">{dept.count}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {complianceGaps.length > 0 && (\n <div className=\"p-3 bg-red-50 dark:bg-red-900/20 rounded-md\">\n <p className=\"text-sm font-medium text-red-800 dark:text-red-200 mb-2\">\n Compliance Gaps Detected\n </p>\n {complianceGaps.slice(0, 5).map((gap) => (\n <div key={gap.recordId} className=\"mb-2\">\n <p className=\"text-xs font-medium text-red-700 dark:text-red-300\">{gap.recordName}</p>\n <ul className=\"list-disc list-inside\">\n {gap.gaps.map((g, i) => (\n <li key={i} className=\"text-xs text-red-600 dark:text-red-400\">\n {g}\n </li>\n ))}\n </ul>\n </div>\n ))}\n {complianceGaps.length > 5 && (\n <p className=\"text-xs text-red-600 dark:text-red-400 mt-1\">\n ...and {complianceGaps.length - 5} more record(s) with gaps.\n </p>\n )}\n </div>\n )}\n </div>\n );\n\n // Render the records table\n const renderRecordsTable = () => (\n <div>\n {/* Filters */}\n <div className=\"mb-4 grid grid-cols-1 md:grid-cols-4 gap-4\">\n <div>\n <label htmlFor=\"ropaSearch\" className=\"block text-sm font-medium mb-1\">\n Search\n </label>\n <input\n type=\"text\"\n id=\"ropaSearch\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n placeholder=\"Search records...\"\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n <div>\n <label htmlFor=\"ropaStatusFilter\" className=\"block text-sm font-medium mb-1\">\n Status\n </label>\n <select\n id=\"ropaStatusFilter\"\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <option value=\"all\">All Statuses</option>\n {STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"ropaBasisFilter\" className=\"block text-sm font-medium mb-1\">\n Lawful Basis\n </label>\n <select\n id=\"ropaBasisFilter\"\n value={basisFilter}\n onChange={(e) => setBasisFilter(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <option value=\"all\">All Bases</option>\n {LAWFUL_BASIS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label.split(' (')[0]}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex items-end space-x-2\">\n <button\n onClick={handleNewRecord}\n className={`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 text-sm ${buttonClassName}`}\n >\n Add Record\n </button>\n <button\n onClick={handleExportCSV}\n className={`px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700 text-sm ${buttonClassName}`}\n >\n Export CSV\n </button>\n </div>\n </div>\n\n {/* Table */}\n {filteredRecords.length === 0 ? (\n <p className=\"text-gray-500 dark:text-gray-400 text-sm text-center py-8\">\n No processing records found.\n </p>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm text-left\">\n <thead className=\"text-xs uppercase bg-gray-50 dark:bg-gray-700\">\n <tr>\n <th className=\"px-4 py-3\">Name</th>\n <th className=\"px-4 py-3\">Lawful Basis</th>\n <th className=\"px-4 py-3\">Data Categories</th>\n <th className=\"px-4 py-3\">Status</th>\n <th className=\"px-4 py-3\">Last Reviewed</th>\n <th className=\"px-4 py-3\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {filteredRecords.map((record) => {\n const overdue = isReviewOverdue(record);\n const hasGaps = complianceGaps.some((g) => g.recordId === record.id);\n\n return (\n <tr\n key={record.id}\n className={`border-b dark:border-gray-600 ${\n overdue\n ? 'bg-red-50 dark:bg-red-900/10'\n : hasGaps\n ? 'bg-yellow-50 dark:bg-yellow-900/10'\n : 'bg-white dark:bg-gray-800'\n } hover:bg-gray-50 dark:hover:bg-gray-700`}\n >\n <td className=\"px-4 py-3\">\n <div>\n <p className=\"font-medium\">{record.name}</p>\n {record.department && (\n <p className=\"text-xs text-gray-500 dark:text-gray-400\">\n {record.department}\n </p>\n )}\n {overdue && (\n <span className=\"text-xs text-red-600 dark:text-red-400 font-medium\">\n Review Overdue\n </span>\n )}\n </div>\n </td>\n <td className=\"px-4 py-3\">{renderBasisBadge(record.lawfulBasis)}</td>\n <td className=\"px-4 py-3\">\n <p className=\"text-xs text-gray-600 dark:text-gray-300 max-w-xs truncate\">\n {record.dataCategories.join(', ')}\n </p>\n </td>\n <td className=\"px-4 py-3\">{renderStatusBadge(record.status)}</td>\n <td className=\"px-4 py-3 text-xs text-gray-500 dark:text-gray-400\">\n {formatDate(record.lastReviewedAt)}\n </td>\n <td className=\"px-4 py-3\">\n <div className=\"flex space-x-2\">\n <button\n onClick={() => handleEditRecord(record)}\n className=\"text-blue-600 dark:text-blue-400 hover:underline text-xs\"\n >\n Edit\n </button>\n {record.status !== 'archived' && (\n <button\n onClick={() => handleArchiveRecord(record.id)}\n className=\"text-gray-600 dark:text-gray-400 hover:underline text-xs\"\n >\n Archive\n </button>\n )}\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </div>\n );\n\n // Render the add/edit form\n const renderForm = () => {\n if (!editingRecord) return null;\n\n const isNew = !ropa.records.find((r) => r.id === editingRecord.id);\n\n return (\n <div>\n <div className=\"flex justify-between items-center mb-4\">\n <h3 className=\"text-lg font-medium\">\n {isNew ? 'Add Processing Record' : 'Edit Processing Record'}\n </h3>\n <button\n onClick={handleCancelForm}\n className=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 text-sm\"\n >\n Cancel\n </button>\n </div>\n\n {formErrors.length > 0 && (\n <div className=\"mb-4 p-3 bg-red-50 dark:bg-red-900/20 rounded-md\">\n <p className=\"text-sm font-medium text-red-800 dark:text-red-200 mb-1\">\n Please fix the following errors:\n </p>\n <ul className=\"list-disc list-inside\">\n {formErrors.map((error, i) => (\n <li key={i} className=\"text-xs text-red-600 dark:text-red-400\">\n {error}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n <div className=\"space-y-6\">\n {/* Basic Information */}\n <fieldset className=\"border border-gray-200 dark:border-gray-600 rounded-md p-4\">\n <legend className=\"text-sm font-medium px-2\">Basic Information</legend>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"recordName\" className=\"block text-sm font-medium mb-1\">\n Activity Name *\n </label>\n <input\n type=\"text\"\n id=\"recordName\"\n value={editingRecord.name}\n onChange={(e) => updateEditingField('name', e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Customer Account Management\"\n />\n </div>\n <div>\n <label htmlFor=\"recordDepartment\" className=\"block text-sm font-medium mb-1\">\n Department\n </label>\n <input\n type=\"text\"\n id=\"recordDepartment\"\n value={editingRecord.department || ''}\n onChange={(e) => updateEditingField('department', e.target.value || undefined)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Marketing\"\n />\n </div>\n <div className=\"md:col-span-2\">\n <label htmlFor=\"recordDescription\" className=\"block text-sm font-medium mb-1\">\n Description *\n </label>\n <textarea\n id=\"recordDescription\"\n value={editingRecord.description}\n onChange={(e) => updateEditingField('description', e.target.value)}\n rows={3}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"Describe what personal data processing is performed...\"\n />\n </div>\n <div>\n <label htmlFor=\"recordStatus\" className=\"block text-sm font-medium mb-1\">\n Status *\n </label>\n <select\n id=\"recordStatus\"\n value={editingRecord.status}\n onChange={(e) =>\n updateEditingField('status', e.target.value as ProcessingRecord['status'])\n }\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </fieldset>\n\n {/* Controller Details */}\n <fieldset className=\"border border-gray-200 dark:border-gray-600 rounded-md p-4\">\n <legend className=\"text-sm font-medium px-2\">Controller Details</legend>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"controllerName\" className=\"block text-sm font-medium mb-1\">\n Controller Name *\n </label>\n <input\n type=\"text\"\n id=\"controllerName\"\n value={editingRecord.controllerDetails.name}\n onChange={(e) => updateControllerField('name', e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n <div>\n <label htmlFor=\"controllerContact\" className=\"block text-sm font-medium mb-1\">\n Controller Contact *\n </label>\n <input\n type=\"text\"\n id=\"controllerContact\"\n value={editingRecord.controllerDetails.contact}\n onChange={(e) => updateControllerField('contact', e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n <div className=\"md:col-span-2\">\n <label htmlFor=\"controllerAddress\" className=\"block text-sm font-medium mb-1\">\n Controller Address *\n </label>\n <input\n type=\"text\"\n id=\"controllerAddress\"\n value={editingRecord.controllerDetails.address}\n onChange={(e) => updateControllerField('address', e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Lawful Basis */}\n <fieldset className=\"border border-gray-200 dark:border-gray-600 rounded-md p-4\">\n <legend className=\"text-sm font-medium px-2\">Lawful Basis (NDPA Section 25)</legend>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"lawfulBasis\" className=\"block text-sm font-medium mb-1\">\n Lawful Basis *\n </label>\n <select\n id=\"lawfulBasis\"\n value={editingRecord.lawfulBasis}\n onChange={(e) =>\n updateEditingField('lawfulBasis', e.target.value as LawfulBasis)\n }\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {LAWFUL_BASIS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"lawfulBasisJustification\" className=\"block text-sm font-medium mb-1\">\n Justification *\n </label>\n <textarea\n id=\"lawfulBasisJustification\"\n value={editingRecord.lawfulBasisJustification}\n onChange={(e) =>\n updateEditingField('lawfulBasisJustification', e.target.value)\n }\n rows={2}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"Explain why this lawful basis applies...\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Data Details */}\n <fieldset className=\"border border-gray-200 dark:border-gray-600 rounded-md p-4\">\n <legend className=\"text-sm font-medium px-2\">Data Details</legend>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"purposes\" className=\"block text-sm font-medium mb-1\">\n Purposes * (comma-separated)\n </label>\n <input\n type=\"text\"\n id=\"purposes\"\n value={purposesInput}\n onChange={(e) => setPurposesInput(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Account management, Service delivery\"\n />\n </div>\n <div>\n <label htmlFor=\"dataCategories\" className=\"block text-sm font-medium mb-1\">\n Data Categories * (comma-separated)\n </label>\n <input\n type=\"text\"\n id=\"dataCategories\"\n value={dataCategoriesInput}\n onChange={(e) => setDataCategoriesInput(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Name, Email, Phone number\"\n />\n </div>\n <div>\n <label htmlFor=\"sensitiveData\" className=\"block text-sm font-medium mb-1\">\n Sensitive Data Categories (comma-separated)\n </label>\n <input\n type=\"text\"\n id=\"sensitiveData\"\n value={sensitiveDataInput}\n onChange={(e) => setSensitiveDataInput(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Health data, Biometric data\"\n />\n </div>\n <div>\n <label htmlFor=\"subjectCategories\" className=\"block text-sm font-medium mb-1\">\n Data Subject Categories * (comma-separated)\n </label>\n <input\n type=\"text\"\n id=\"subjectCategories\"\n value={subjectCategoriesInput}\n onChange={(e) => setSubjectCategoriesInput(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Customers, Employees\"\n />\n </div>\n <div>\n <label htmlFor=\"recipients\" className=\"block text-sm font-medium mb-1\">\n Recipients * (comma-separated)\n </label>\n <input\n type=\"text\"\n id=\"recipients\"\n value={recipientsInput}\n onChange={(e) => setRecipientsInput(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Payment processors, Cloud service providers\"\n />\n </div>\n <div>\n <label htmlFor=\"dataSource\" className=\"block text-sm font-medium mb-1\">\n Data Source *\n </label>\n <select\n id=\"dataSource\"\n value={editingRecord.dataSource}\n onChange={(e) =>\n updateEditingField(\n 'dataSource',\n e.target.value as ProcessingRecord['dataSource']\n )\n }\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {DATA_SOURCE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n {editingRecord.dataSource === 'third_party' && (\n <div className=\"md:col-span-2\">\n <label\n htmlFor=\"thirdPartyDetails\"\n className=\"block text-sm font-medium mb-1\"\n >\n Third-Party Source Details *\n </label>\n <input\n type=\"text\"\n id=\"thirdPartyDetails\"\n value={editingRecord.thirdPartySourceDetails || ''}\n onChange={(e) =>\n updateEditingField('thirdPartySourceDetails', e.target.value || undefined)\n }\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"Describe the third-party data source...\"\n />\n </div>\n )}\n </div>\n </fieldset>\n\n {/* Retention and Security */}\n <fieldset className=\"border border-gray-200 dark:border-gray-600 rounded-md p-4\">\n <legend className=\"text-sm font-medium px-2\">Retention and Security</legend>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"retentionPeriod\" className=\"block text-sm font-medium mb-1\">\n Retention Period *\n </label>\n <input\n type=\"text\"\n id=\"retentionPeriod\"\n value={editingRecord.retentionPeriod}\n onChange={(e) => updateEditingField('retentionPeriod', e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., 5 years after account closure\"\n />\n </div>\n <div>\n <label htmlFor=\"retentionJustification\" className=\"block text-sm font-medium mb-1\">\n Retention Justification\n </label>\n <input\n type=\"text\"\n id=\"retentionJustification\"\n value={editingRecord.retentionJustification || ''}\n onChange={(e) =>\n updateEditingField('retentionJustification', e.target.value || undefined)\n }\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"Why this retention period is necessary...\"\n />\n </div>\n <div className=\"md:col-span-2\">\n <label htmlFor=\"securityMeasures\" className=\"block text-sm font-medium mb-1\">\n Security Measures * (comma-separated)\n </label>\n <input\n type=\"text\"\n id=\"securityMeasures\"\n value={securityMeasuresInput}\n onChange={(e) => setSecurityMeasuresInput(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., Encryption at rest, Access controls, Audit logging\"\n />\n </div>\n <div>\n <label htmlFor=\"systemsUsed\" className=\"block text-sm font-medium mb-1\">\n Systems Used (comma-separated)\n </label>\n <input\n type=\"text\"\n id=\"systemsUsed\"\n value={systemsUsedInput}\n onChange={(e) => setSystemsUsedInput(e.target.value)}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"e.g., CRM, ERP, Cloud Storage\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Risk Indicators */}\n <fieldset className=\"border border-gray-200 dark:border-gray-600 rounded-md p-4\">\n <legend className=\"text-sm font-medium px-2\">Risk Indicators</legend>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"dpiaRequired\"\n checked={editingRecord.dpiaRequired}\n onChange={(e) => updateEditingField('dpiaRequired', e.target.checked)}\n className=\"rounded border-gray-300 dark:border-gray-600\"\n />\n <label htmlFor=\"dpiaRequired\" className=\"text-sm font-medium\">\n DPIA Required\n </label>\n </div>\n {editingRecord.dpiaRequired && (\n <div>\n <label htmlFor=\"dpiaReference\" className=\"block text-sm font-medium mb-1\">\n DPIA Reference *\n </label>\n <input\n type=\"text\"\n id=\"dpiaReference\"\n value={editingRecord.dpiaReference || ''}\n onChange={(e) =>\n updateEditingField('dpiaReference', e.target.value || undefined)\n }\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"Reference to the completed DPIA\"\n />\n </div>\n )}\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"automatedDecisionMaking\"\n checked={editingRecord.automatedDecisionMaking}\n onChange={(e) =>\n updateEditingField('automatedDecisionMaking', e.target.checked)\n }\n className=\"rounded border-gray-300 dark:border-gray-600\"\n />\n <label htmlFor=\"automatedDecisionMaking\" className=\"text-sm font-medium\">\n Automated Decision-Making\n </label>\n </div>\n {editingRecord.automatedDecisionMaking && (\n <div>\n <label\n htmlFor=\"automatedDecisionMakingDetails\"\n className=\"block text-sm font-medium mb-1\"\n >\n Automated Decision-Making Details *\n </label>\n <textarea\n id=\"automatedDecisionMakingDetails\"\n value={editingRecord.automatedDecisionMakingDetails || ''}\n onChange={(e) =>\n updateEditingField(\n 'automatedDecisionMakingDetails',\n e.target.value || undefined\n )\n }\n rows={2}\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"Describe the automated decision-making process...\"\n />\n </div>\n )}\n </div>\n </fieldset>\n\n {/* Review Schedule */}\n <fieldset className=\"border border-gray-200 dark:border-gray-600 rounded-md p-4\">\n <legend className=\"text-sm font-medium px-2\">Review Schedule</legend>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"nextReviewDate\" className=\"block text-sm font-medium mb-1\">\n Next Review Date\n </label>\n <input\n type=\"date\"\n id=\"nextReviewDate\"\n value={\n editingRecord.nextReviewDate\n ? new Date(editingRecord.nextReviewDate).toISOString().slice(0, 10)\n : ''\n }\n onChange={(e) =>\n updateEditingField(\n 'nextReviewDate',\n e.target.value ? new Date(e.target.value).getTime() : undefined\n )\n }\n className=\"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Save / Cancel */}\n <div className=\"flex justify-end space-x-3\">\n <button\n onClick={handleCancelForm}\n className=\"px-4 py-2 border border-gray-300 dark:border-gray-600 rounded hover:bg-gray-50 dark:hover:bg-gray-700 text-sm\"\n >\n Cancel\n </button>\n <button\n onClick={handleSaveRecord}\n className={`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 text-sm ${buttonClassName}`}\n >\n {isNew ? 'Add Record' : 'Save Changes'}\n </button>\n </div>\n </div>\n </div>\n );\n };\n\n // View mode tabs\n const renderViewTabs = () => (\n <div className=\"flex space-x-4 mb-6 border-b border-gray-200 dark:border-gray-600\">\n <button\n onClick={() => setViewMode('list')}\n className={`pb-2 text-sm font-medium ${\n viewMode === 'list'\n ? 'border-b-2 border-blue-500 text-blue-600 dark:text-blue-400'\n : 'text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300'\n }`}\n >\n Processing Records\n </button>\n <button\n onClick={() => setViewMode('summary')}\n className={`pb-2 text-sm font-medium ${\n viewMode === 'summary'\n ? 'border-b-2 border-blue-500 text-blue-600 dark:text-blue-400'\n : 'text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300'\n }`}\n >\n Compliance Summary\n </button>\n </div>\n );\n\n return (\n <div className={`bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md ${className}`}>\n <h2 className=\"text-xl font-bold mb-2\">{title}</h2>\n <p className=\"mb-6 text-gray-600 dark:text-gray-300\">{description}</p>\n\n {renderOrganizationHeader()}\n\n {viewMode !== 'form' && renderViewTabs()}\n\n {viewMode === 'list' && renderRecordsTable()}\n {viewMode === 'summary' && renderSummaryDashboard()}\n {viewMode === 'form' && renderForm()}\n </div>\n );\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/privacy.ts"],"names":["generatePolicyText","sectionsOrTemplate","organizationInfoOrVariables","template","variableMap","result","variableRegex","match","variable","replacement","sections","organizationInfo","sectionTexts","missingVariables","section","a","b","content","contentVariables"],"mappings":"AAQO,SAASA,EACdC,CAAAA,CACAC,CAAAA,CAKA,CAEA,GAAI,OAAOD,CAAAA,EAAuB,QAAA,CAAU,CAC1C,IAAME,EAAWF,CAAAA,CACXG,CAAAA,CAAcF,EAGhBG,CAAAA,CAASF,CAAAA,CACPG,EAAgB,kBAAA,CAClBC,CAAAA,CAGJ,KAAA,CAAQA,CAAAA,CAAQD,EAAc,IAAA,CAAKH,CAAQ,CAAA,IAAO,IAAA,EAAM,CACtD,IAAMK,CAAAA,CAAWD,CAAAA,CAAM,CAAC,EAAE,IAAA,EAAK,CACzBE,EAAcL,CAAAA,CAAYI,CAAQ,GAAK,EAAA,CAG7CH,CAAAA,CAASA,CAAAA,CAAO,OAAA,CACd,IAAI,MAAA,CAAO,CAAA,UAAA,EAAaG,CAAQ,CAAA,UAAA,CAAA,CAAc,GAAG,CAAA,CACjDC,CACF,EACF,CAEA,OAAOJ,CACT,CAAA,KAEK,CACH,IAAMK,CAAAA,CAAWT,EACXU,CAAAA,CAAmBT,CAAAA,CACnBU,CAAAA,CAAuC,GACvCC,CAAAA,CAA6B,EAAC,CAGpC,OAAAH,EACG,MAAA,CAAOI,CAAAA,EAAWA,CAAAA,CAAQ,QAAQ,EAClC,IAAA,CAAK,CAACC,EAAGC,CAAAA,GAAAA,CAAOD,CAAAA,CAAE,OAAS,CAAA,GAAMC,CAAAA,CAAE,KAAA,EAAS,CAAA,CAAE,EAC9C,OAAA,CAAQF,CAAAA,EAAW,CAElB,IAAIG,EAAUH,CAAAA,CAAQ,QAAA,EAAYA,CAAAA,CAAQ,aAAA,EAAiBA,EAAQ,cAAA,EAAkB,EAAA,CAG/ER,EAAgB,kBAAA,CAClBC,CAAAA,CAGEW,EAA6B,EAAC,CACpC,KAAA,CAAQX,CAAAA,CAAQD,EAAc,IAAA,CAAKW,CAAO,CAAA,IAAO,IAAA,EAC/CC,EAAiB,IAAA,CAAKX,CAAAA,CAAM,CAAC,CAAA,CAAE,MAAM,CAAA,CAIvCW,EAAiB,OAAA,CAAQV,CAAAA,EAAY,CACnC,IAAIC,CAAAA,CAAc,EAAA,CAGdD,CAAAA,IAAYG,IACdF,CAAAA,CAAcE,CAAAA,CAAiBH,CAAkC,CAAA,EAAe,IAI7EC,CAAAA,EACHI,CAAAA,CAAiB,IAAA,CAAKL,CAAQ,EAIhCS,CAAAA,CAAUA,CAAAA,CAAQ,QAChB,IAAI,MAAA,CAAO,aAAaT,CAAQ,CAAA,UAAA,CAAA,CAAc,GAAG,CAAA,CACjDC,CACF,EACF,CAAC,CAAA,CAGDG,CAAAA,CAAaE,EAAQ,EAAE,CAAA,CAAIG,EAC7B,CAAC,EAKI,CACL,QAAA,CAHe,OAAO,MAAA,CAAOL,CAAY,EAAE,IAAA,CAAK;;AAAA,CAAM,CAAA,CAItD,YAAA,CAAAA,CAAAA,CACA,gBAAA,CAAkB,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAIC,CAAgB,CAAC,CACxD,CACF,CACF","file":"chunk-UYP64PV7.mjs","sourcesContent":["import { PolicySection, OrganizationInfo, PolicyVariable } from '../types/privacy';\n\n/**\n * Generates policy text by replacing variables in a template with organization-specific values\n * @param sectionsOrTemplate The policy sections or template string to generate text for\n * @param organizationInfoOrVariables The organization information or variable map to use for replacement\n * @returns The generated policy text or an object with the generated text and metadata\n */\nexport function generatePolicyText(\n sectionsOrTemplate: PolicySection[] | string,\n organizationInfoOrVariables: OrganizationInfo | Record<string, string>\n): string | {\n fullText: string;\n sectionTexts: Record<string, string>;\n missingVariables: string[];\n} {\n // Check if we're using the new API (template string and variable map)\n if (typeof sectionsOrTemplate === 'string') {\n const template = sectionsOrTemplate;\n const variableMap = organizationInfoOrVariables as Record<string, string>;\n \n // Replace variables in the template\n let result = template;\n const variableRegex = /\\{\\{([^}]+)\\}\\}/g;\n let match;\n \n // Find and replace all variables in the content\n while ((match = variableRegex.exec(template)) !== null) {\n const variable = match[1].trim();\n const replacement = variableMap[variable] || '';\n \n // Replace the variable in the content\n result = result.replace(\n new RegExp(`\\\\{\\\\{\\\\s*${variable}\\\\s*\\\\}\\\\}`, 'g'), \n replacement\n );\n }\n \n return result;\n } \n // Otherwise use the original API (sections array and organization info)\n else {\n const sections = sectionsOrTemplate;\n const organizationInfo = organizationInfoOrVariables as OrganizationInfo;\n const sectionTexts: Record<string, string> = {};\n const missingVariables: string[] = [];\n \n // Process each section\n sections\n .filter(section => section.included)\n .sort((a, b) => (a.order || 0) - (b.order || 0))\n .forEach(section => {\n // Use template if available, otherwise fall back to custom/default content\n let content = section.template || section.customContent || section.defaultContent || '';\n \n // Replace variables in the content\n const variableRegex = /\\{\\{([^}]+)\\}\\}/g;\n let match;\n \n // Find all variables in the content\n const contentVariables: string[] = [];\n while ((match = variableRegex.exec(content)) !== null) {\n contentVariables.push(match[1].trim());\n }\n \n // Replace each variable with its value\n contentVariables.forEach(variable => {\n let replacement = '';\n \n // Check if the variable exists in organizationInfo\n if (variable in organizationInfo) {\n replacement = organizationInfo[variable as keyof OrganizationInfo] as string || '';\n }\n \n // If replacement is empty, add to missing variables\n if (!replacement) {\n missingVariables.push(variable);\n }\n \n // Replace the variable in the content\n content = content.replace(\n new RegExp(`\\\\{\\\\{\\\\s*${variable}\\\\s*\\\\}\\\\}`, 'g'), \n replacement\n );\n });\n \n // Store the processed section text\n sectionTexts[section.id] = content;\n });\n \n // Combine all sections into full text\n const fullText = Object.values(sectionTexts).join('\\n\\n');\n \n return {\n fullText,\n sectionTexts,\n missingVariables: Array.from(new Set(missingVariables)) // Remove duplicates\n };\n }\n}\n"]}