@tantainnovative/ndpr-toolkit 1.0.10 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +293 -136
  3. package/dist/breach-6z0r-KuE.d.mts +17 -0
  4. package/dist/breach-BFfnvtRk.d.ts +17 -0
  5. package/dist/breach-BtFbDOmV.d.mts +185 -0
  6. package/dist/breach-BtFbDOmV.d.ts +185 -0
  7. package/dist/breach.d.mts +275 -0
  8. package/dist/breach.d.ts +275 -0
  9. package/dist/breach.js +2 -0
  10. package/dist/breach.js.map +1 -0
  11. package/dist/breach.mjs +2 -0
  12. package/dist/breach.mjs.map +1 -0
  13. package/dist/chunk-2SYNHRP6.mjs +2 -0
  14. package/dist/chunk-2SYNHRP6.mjs.map +1 -0
  15. package/dist/chunk-2XHD22J7.mjs +7 -0
  16. package/dist/chunk-2XHD22J7.mjs.map +1 -0
  17. package/dist/chunk-3YCV2BA6.js +2 -0
  18. package/dist/chunk-3YCV2BA6.js.map +1 -0
  19. package/dist/chunk-4A354HL3.js +2 -0
  20. package/dist/chunk-4A354HL3.js.map +1 -0
  21. package/dist/chunk-4DKT6IB6.js +94 -0
  22. package/dist/chunk-4DKT6IB6.js.map +1 -0
  23. package/dist/chunk-5ZBO2UPH.js +2 -0
  24. package/dist/chunk-5ZBO2UPH.js.map +1 -0
  25. package/dist/chunk-6GGGTRDZ.mjs +2 -0
  26. package/dist/chunk-6GGGTRDZ.mjs.map +1 -0
  27. package/dist/chunk-6JFTAYXV.mjs +2 -0
  28. package/dist/chunk-6JFTAYXV.mjs.map +1 -0
  29. package/dist/chunk-6JVYYLS7.js +2 -0
  30. package/dist/chunk-6JVYYLS7.js.map +1 -0
  31. package/dist/chunk-6SGG6WPA.mjs +2 -0
  32. package/dist/chunk-6SGG6WPA.mjs.map +1 -0
  33. package/dist/chunk-AQEGDEQM.js +7 -0
  34. package/dist/chunk-AQEGDEQM.js.map +1 -0
  35. package/dist/chunk-C2IJWCZQ.mjs +2 -0
  36. package/dist/chunk-C2IJWCZQ.mjs.map +1 -0
  37. package/dist/chunk-CMZTI7SG.js +2 -0
  38. package/dist/chunk-CMZTI7SG.js.map +1 -0
  39. package/dist/chunk-DB3JH4DS.mjs +2 -0
  40. package/dist/chunk-DB3JH4DS.mjs.map +1 -0
  41. package/dist/chunk-FFW7RUAG.mjs +94 -0
  42. package/dist/chunk-FFW7RUAG.mjs.map +1 -0
  43. package/dist/chunk-FK3CSFLJ.js +2 -0
  44. package/dist/chunk-FK3CSFLJ.js.map +1 -0
  45. package/dist/chunk-GIV2OHE6.mjs +2 -0
  46. package/dist/chunk-GIV2OHE6.mjs.map +1 -0
  47. package/dist/chunk-GMLNWS2N.mjs +2 -0
  48. package/dist/chunk-GMLNWS2N.mjs.map +1 -0
  49. package/dist/chunk-IQF726GS.js +2 -0
  50. package/dist/chunk-IQF726GS.js.map +1 -0
  51. package/dist/chunk-IWUUVRLJ.js +2 -0
  52. package/dist/chunk-IWUUVRLJ.js.map +1 -0
  53. package/dist/chunk-JUN6YPLL.mjs +72 -0
  54. package/dist/chunk-JUN6YPLL.mjs.map +1 -0
  55. package/dist/chunk-L3FKTBGV.js +72 -0
  56. package/dist/chunk-L3FKTBGV.js.map +1 -0
  57. package/dist/chunk-L52PDW6O.mjs +2 -0
  58. package/dist/chunk-L52PDW6O.mjs.map +1 -0
  59. package/dist/chunk-LI6WJ3LZ.js +2 -0
  60. package/dist/chunk-LI6WJ3LZ.js.map +1 -0
  61. package/dist/chunk-LXRXDTPI.js +2 -0
  62. package/dist/chunk-LXRXDTPI.js.map +1 -0
  63. package/dist/chunk-MQFZHA2D.js +2 -0
  64. package/dist/chunk-MQFZHA2D.js.map +1 -0
  65. package/dist/chunk-OITITR6K.mjs +2 -0
  66. package/dist/chunk-OITITR6K.mjs.map +1 -0
  67. package/dist/chunk-PDJGTQMY.mjs +2 -0
  68. package/dist/chunk-PDJGTQMY.mjs.map +1 -0
  69. package/dist/chunk-PGSA2O5P.mjs +2 -0
  70. package/dist/chunk-PGSA2O5P.mjs.map +1 -0
  71. package/dist/chunk-PM7CMTMB.js +4 -0
  72. package/dist/chunk-PM7CMTMB.js.map +1 -0
  73. package/dist/chunk-PYEX7DFR.mjs +4 -0
  74. package/dist/chunk-PYEX7DFR.mjs.map +1 -0
  75. package/dist/chunk-QKK5S54L.mjs +2 -0
  76. package/dist/chunk-QKK5S54L.mjs.map +1 -0
  77. package/dist/chunk-RB26MIRI.js +2 -0
  78. package/dist/chunk-RB26MIRI.js.map +1 -0
  79. package/dist/chunk-RGYK4VAY.mjs +2 -0
  80. package/dist/chunk-RGYK4VAY.mjs.map +1 -0
  81. package/dist/chunk-RHWW5FDP.js +16 -0
  82. package/dist/chunk-RHWW5FDP.js.map +1 -0
  83. package/dist/chunk-RYZEIDNR.js +2 -0
  84. package/dist/chunk-RYZEIDNR.js.map +1 -0
  85. package/dist/chunk-SLNMKGQ2.mjs +2 -0
  86. package/dist/chunk-SLNMKGQ2.mjs.map +1 -0
  87. package/dist/chunk-SSGJREE3.js +2 -0
  88. package/dist/chunk-SSGJREE3.js.map +1 -0
  89. package/dist/chunk-SWF3YVE5.js +4 -0
  90. package/dist/chunk-SWF3YVE5.js.map +1 -0
  91. package/dist/chunk-T44JQT2O.mjs +2 -0
  92. package/dist/chunk-T44JQT2O.mjs.map +1 -0
  93. package/dist/chunk-TDDAYVKK.js +2 -0
  94. package/dist/chunk-TDDAYVKK.js.map +1 -0
  95. package/dist/chunk-TXBZPCGF.mjs +2 -0
  96. package/dist/chunk-TXBZPCGF.mjs.map +1 -0
  97. package/dist/chunk-UUWVBENC.js +2 -0
  98. package/dist/chunk-UUWVBENC.js.map +1 -0
  99. package/dist/chunk-UYP64PV7.mjs +4 -0
  100. package/dist/chunk-UYP64PV7.mjs.map +1 -0
  101. package/dist/chunk-VMJBW3EF.mjs +2 -0
  102. package/dist/chunk-VMJBW3EF.mjs.map +1 -0
  103. package/dist/chunk-WW3X3ELF.js +2 -0
  104. package/dist/chunk-WW3X3ELF.js.map +1 -0
  105. package/dist/chunk-WWT2ZSNU.mjs +2 -0
  106. package/dist/chunk-WWT2ZSNU.mjs.map +1 -0
  107. package/dist/chunk-XMKA6GVK.mjs +16 -0
  108. package/dist/chunk-XMKA6GVK.mjs.map +1 -0
  109. package/dist/chunk-Y34DQYS7.js +2 -0
  110. package/dist/chunk-Y34DQYS7.js.map +1 -0
  111. package/dist/chunk-ZU73VG3X.js +2 -0
  112. package/dist/chunk-ZU73VG3X.js.map +1 -0
  113. package/dist/consent-CmVzqZUk.d.mts +99 -0
  114. package/dist/consent-CmVzqZUk.d.ts +99 -0
  115. package/dist/consent-DCc5zjXI.d.mts +24 -0
  116. package/dist/consent-DLWb5ota.d.ts +24 -0
  117. package/dist/consent.d.mts +197 -0
  118. package/dist/consent.d.ts +197 -0
  119. package/dist/consent.js +2 -0
  120. package/dist/consent.js.map +1 -0
  121. package/dist/consent.mjs +2 -0
  122. package/dist/consent.mjs.map +1 -0
  123. package/dist/core.d.mts +14 -0
  124. package/dist/core.d.ts +14 -0
  125. package/dist/core.js +2 -0
  126. package/dist/core.js.map +1 -0
  127. package/dist/core.mjs +2 -0
  128. package/dist/core.mjs.map +1 -0
  129. package/dist/cross-border-BrIy1ieh.d.mts +192 -0
  130. package/dist/cross-border-BrIy1ieh.d.ts +192 -0
  131. package/dist/cross-border.d.mts +58 -0
  132. package/dist/cross-border.d.ts +58 -0
  133. package/dist/cross-border.js +2 -0
  134. package/dist/cross-border.js.map +1 -0
  135. package/dist/cross-border.mjs +2 -0
  136. package/dist/cross-border.mjs.map +1 -0
  137. package/dist/dpia-B9ZZJG5a.d.mts +15 -0
  138. package/dist/dpia-fdtTd2DI.d.ts +15 -0
  139. package/dist/dpia-vWfE_9bO.d.mts +137 -0
  140. package/dist/dpia-vWfE_9bO.d.ts +137 -0
  141. package/dist/dpia.d.mts +179 -0
  142. package/dist/dpia.d.ts +179 -0
  143. package/dist/dpia.js +2 -0
  144. package/dist/dpia.js.map +1 -0
  145. package/dist/dpia.mjs +2 -0
  146. package/dist/dpia.mjs.map +1 -0
  147. package/dist/dsr-jq5NUEdz.d.ts +14 -0
  148. package/dist/dsr-pQzQ3H1O.d.mts +128 -0
  149. package/dist/dsr-pQzQ3H1O.d.ts +128 -0
  150. package/dist/dsr-whPkiI0_.d.mts +14 -0
  151. package/dist/dsr.d.mts +192 -0
  152. package/dist/dsr.d.ts +192 -0
  153. package/dist/dsr.js +2 -0
  154. package/dist/dsr.js.map +1 -0
  155. package/dist/dsr.mjs +2 -0
  156. package/dist/dsr.mjs.map +1 -0
  157. package/dist/hooks.d.mts +17 -0
  158. package/dist/hooks.d.ts +17 -0
  159. package/dist/hooks.js +2 -0
  160. package/dist/hooks.js.map +1 -0
  161. package/dist/hooks.mjs +2 -0
  162. package/dist/hooks.mjs.map +1 -0
  163. package/dist/index.d.mts +31 -448
  164. package/dist/index.d.ts +31 -448
  165. package/dist/index.js +1 -190
  166. package/dist/index.js.map +1 -1
  167. package/dist/index.mjs +1 -190
  168. package/dist/index.mjs.map +1 -1
  169. package/dist/lawful-basis-CWtvDG1x.d.mts +112 -0
  170. package/dist/lawful-basis-CWtvDG1x.d.ts +112 -0
  171. package/dist/lawful-basis-D-oXFizg.d.mts +57 -0
  172. package/dist/lawful-basis-v04AhbK2.d.ts +57 -0
  173. package/dist/lawful-basis.d.mts +55 -0
  174. package/dist/lawful-basis.d.ts +55 -0
  175. package/dist/lawful-basis.js +2 -0
  176. package/dist/lawful-basis.js.map +1 -0
  177. package/dist/lawful-basis.mjs +2 -0
  178. package/dist/lawful-basis.mjs.map +1 -0
  179. package/dist/policy.d.mts +195 -0
  180. package/dist/policy.d.ts +195 -0
  181. package/dist/policy.js +2 -0
  182. package/dist/policy.js.map +1 -0
  183. package/dist/policy.mjs +2 -0
  184. package/dist/policy.mjs.map +1 -0
  185. package/dist/privacy-9FcJceMr.d.mts +15 -0
  186. package/dist/privacy-BXz7O2ej.d.ts +15 -0
  187. package/dist/privacy-Ca6te9Ir.d.mts +138 -0
  188. package/dist/privacy-Ca6te9Ir.d.ts +138 -0
  189. package/dist/ropa-BebGfqKQ.d.ts +200 -0
  190. package/dist/ropa-Rb4dsFSz.d.mts +200 -0
  191. package/dist/ropa.d.mts +45 -0
  192. package/dist/ropa.d.ts +45 -0
  193. package/dist/ropa.js +2 -0
  194. package/dist/ropa.js.map +1 -0
  195. package/dist/ropa.mjs +2 -0
  196. package/dist/ropa.mjs.map +1 -0
  197. package/dist/unstyled.d.mts +4 -4
  198. package/dist/unstyled.d.ts +4 -4
  199. package/dist/unstyled.js +1 -1
  200. package/dist/unstyled.js.map +1 -1
  201. package/dist/unstyled.mjs +1 -1
  202. package/dist/unstyled.mjs.map +1 -1
  203. package/dist/useBreach-WrZzJilM.d.mts +99 -0
  204. package/dist/useBreach-vrh_XMpI.d.ts +99 -0
  205. package/dist/useConsent-D0pAfTlb.d.ts +65 -0
  206. package/dist/useConsent-DOt2Njst.d.mts +65 -0
  207. package/dist/useCrossBorderTransfer-D4FQYfFt.d.ts +66 -0
  208. package/dist/useCrossBorderTransfer-TVnY8_UX.d.mts +66 -0
  209. package/dist/useDPIA-DFDHBLSa.d.ts +94 -0
  210. package/dist/useDPIA-FqPofFaV.d.mts +94 -0
  211. package/dist/useDSR-DAqqOBXb.d.ts +74 -0
  212. package/dist/useDSR-OXM5Q9rf.d.mts +74 -0
  213. package/dist/useLawfulBasis-DNQ8YszQ.d.mts +68 -0
  214. package/dist/useLawfulBasis-RILM_xsx.d.ts +68 -0
  215. package/dist/usePrivacyPolicy-CfySfBLS.d.ts +89 -0
  216. package/dist/usePrivacyPolicy-Dit2sFuV.d.mts +89 -0
  217. package/dist/useROPA-Bcs6cRdi.d.ts +64 -0
  218. package/dist/useROPA-nmcSiUYv.d.mts +64 -0
  219. package/package.json +146 -20
@@ -0,0 +1,2 @@
1
+ import {c}from'./chunk-QKK5S54L.mjs';import {b,a}from'./chunk-WWT2ZSNU.mjs';import {useState,useEffect,useCallback}from'react';function J({initialTransfers:w=[],storageKey:c$1="ndpr_cross_border_transfers",useLocalStorage:u=true,onAdd:m,onUpdate:p,onRemove:C}={}){let[t,l]=useState(w);useEffect(()=>{if(u&&typeof window!="undefined")try{let r=localStorage.getItem(c$1);r&&l(JSON.parse(r));}catch(r){console.error("Error loading cross-border transfers:",r);}},[c$1,u]),useEffect(()=>{if(u&&typeof window!="undefined")try{localStorage.setItem(c$1,JSON.stringify(t));}catch(r){console.error("Error saving cross-border transfers:",r);}},[t,c$1,u]);let _=()=>"cbt_"+Date.now()+"_"+Math.random().toString(36).substring(2,11),b$1=useCallback(r=>{let n=Date.now(),s=b(a({},r),{id:_(),createdAt:n,updatedAt:n});return l(a=>[...a,s]),m&&m(s),s},[m]),A=useCallback((r,n)=>{let s=null;return l(a$1=>{let o=a$1.findIndex(g=>g.id===r);if(o===-1)return a$1;s=b(a(a({},a$1[o]),n),{updatedAt:Date.now()});let f=[...a$1];return f[o]=s,f}),s&&p&&p(s),s},[p]),S=useCallback(r=>{let n=false;return l(s=>s.findIndex(o=>o.id===r)===-1?s:(n=true,s.filter(o=>o.id!==r))),n&&C&&C(r),n},[C]),q=useCallback(r=>t.find(n=>n.id===r)||null,[t]),D=useCallback(()=>{let r=Date.now(),n=t.filter(e=>e.status==="active"),s=["adequacy_decision","standard_clauses","binding_corporate_rules","ndpc_authorization","explicit_consent","contract_performance","public_interest","legal_claims","vital_interests"],a={};for(let e of s)a[e]=n.filter(i=>i.transferMechanism===e).length;let o=["adequate","inadequate","pending_review","unknown"],f={};for(let e of o)f[e]=n.filter(i=>i.adequacyStatus===e).length;let g=t.filter(e=>{var i,v;return e.status==="pending_approval"||((i=e.ndpcApproval)==null?void 0:i.required)&&!((v=e.ndpcApproval)!=null&&v.approved)}),R=720*60*60*1e3,x=t.filter(e=>e.reviewDate&&e.reviewDate<=r+R&&e.status==="active"),I=t.filter(e=>!e.tiaCompleted&&e.status==="active"),O=t.filter(e=>e.riskLevel==="high"&&e.status==="active");return {totalActiveTransfers:n.length,byMechanism:a,byAdequacy:f,pendingApproval:g,dueForReview:x,missingTIA:I,highRiskTransfers:O,lastUpdated:r}},[t]),M=useCallback(r=>c(r),[]);return {transfers:t,addTransfer:b$1,updateTransfer:A,removeTransfer:S,getTransfer:q,getSummary:D,validateTransfer:M}}export{J as a};//# sourceMappingURL=chunk-VMJBW3EF.mjs.map
2
+ //# sourceMappingURL=chunk-VMJBW3EF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/hooks/useCrossBorderTransfer.ts"],"names":["useCrossBorderTransfer","initialTransfers","storageKey","useLocalStorage","onAdd","onUpdate","onRemove","transfers","setTransfers","useState","useEffect","savedData","error","generateId","addTransfer","useCallback","transferData","now","newTransfer","__spreadProps","__spreadValues","prev","updateTransfer","id","updates","updatedTransfer","index","t","newTransfers","removeTransfer","found","getTransfer","getSummary","activeTransfers","allMechanisms","byMechanism","mechanism","allStatuses","byAdequacy","status","pendingApproval","_a","_b","thirtyDaysMs","dueForReview","missingTIA","highRiskTransfers","validateTransfer","transfer"],"mappings":"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","file":"chunk-VMJBW3EF.mjs","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport {\n CrossBorderTransfer,\n CrossBorderSummary,\n TransferMechanism,\n AdequacyStatus,\n} from '../types/cross-border';\nimport {\n validateTransfer as validateTransferUtil,\n TransferValidationResult,\n} from '../utils/cross-border';\n\ninterface UseCrossBorderTransferOptions {\n /**\n * Initial transfers to load\n */\n initialTransfers?: CrossBorderTransfer[];\n\n /**\n * Storage key for transfer data\n * @default \"ndpr_cross_border_transfers\"\n */\n storageKey?: string;\n\n /**\n * Whether to use local storage to persist transfers\n * @default true\n */\n useLocalStorage?: boolean;\n\n /**\n * Callback function called when a transfer is added\n */\n onAdd?: (transfer: CrossBorderTransfer) => void;\n\n /**\n * Callback function called when a transfer is updated\n */\n onUpdate?: (transfer: CrossBorderTransfer) => void;\n\n /**\n * Callback function called when a transfer is removed\n */\n onRemove?: (id: string) => void;\n}\n\ninterface UseCrossBorderTransferReturn {\n /**\n * All cross-border transfers\n */\n transfers: CrossBorderTransfer[];\n\n /**\n * Add a new cross-border transfer\n */\n addTransfer: (\n transfer: Omit<CrossBorderTransfer, 'id' | 'createdAt' | 'updatedAt'>\n ) => CrossBorderTransfer;\n\n /**\n * Update an existing cross-border transfer\n */\n updateTransfer: (\n id: string,\n updates: Partial<CrossBorderTransfer>\n ) => CrossBorderTransfer | null;\n\n /**\n * Remove a cross-border transfer\n */\n removeTransfer: (id: string) => boolean;\n\n /**\n * Get a cross-border transfer by ID\n */\n getTransfer: (id: string) => CrossBorderTransfer | null;\n\n /**\n * Get a compliance summary of all cross-border transfers\n */\n getSummary: () => CrossBorderSummary;\n\n /**\n * Validate a cross-border transfer\n */\n validateTransfer: (transfer: CrossBorderTransfer) => TransferValidationResult;\n}\n\n/**\n * Hook for managing cross-border data transfers in compliance with NDPA Part VI (Sections 41-45)\n */\nexport function useCrossBorderTransfer({\n initialTransfers = [],\n storageKey = 'ndpr_cross_border_transfers',\n useLocalStorage = true,\n onAdd,\n onUpdate,\n onRemove,\n}: UseCrossBorderTransferOptions = {}): UseCrossBorderTransferReturn {\n const [transfers, setTransfers] = useState<CrossBorderTransfer[]>(initialTransfers);\n\n // Load transfers from storage on mount\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined') {\n try {\n const savedData = localStorage.getItem(storageKey);\n if (savedData) {\n setTransfers(JSON.parse(savedData));\n }\n } catch (error) {\n console.error('Error loading cross-border transfers:', error);\n }\n }\n }, [storageKey, useLocalStorage]);\n\n // Save transfers to storage when they change\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined') {\n try {\n localStorage.setItem(storageKey, JSON.stringify(transfers));\n } catch (error) {\n console.error('Error saving cross-border transfers:', error);\n }\n }\n }, [transfers, storageKey, useLocalStorage]);\n\n // Generate a unique ID\n const generateId = (): string => {\n return 'cbt_' + Date.now() + '_' + Math.random().toString(36).substring(2, 11);\n };\n\n // Add a new transfer\n const addTransfer = useCallback(\n (\n transferData: Omit<CrossBorderTransfer, 'id' | 'createdAt' | 'updatedAt'>\n ): CrossBorderTransfer => {\n const now = Date.now();\n const newTransfer: CrossBorderTransfer = {\n ...transferData,\n id: generateId(),\n createdAt: now,\n updatedAt: now,\n };\n\n setTransfers((prev) => [...prev, newTransfer]);\n\n if (onAdd) {\n onAdd(newTransfer);\n }\n\n return newTransfer;\n },\n [onAdd]\n );\n\n // Update an existing transfer\n const updateTransfer = useCallback(\n (id: string, updates: Partial<CrossBorderTransfer>): CrossBorderTransfer | null => {\n let updatedTransfer: CrossBorderTransfer | null = null;\n\n setTransfers((prev) => {\n const index = prev.findIndex((t) => t.id === id);\n if (index === -1) {\n return prev;\n }\n\n updatedTransfer = {\n ...prev[index],\n ...updates,\n updatedAt: Date.now(),\n };\n\n const newTransfers = [...prev];\n newTransfers[index] = updatedTransfer as CrossBorderTransfer;\n return newTransfers;\n });\n\n if (updatedTransfer && onUpdate) {\n onUpdate(updatedTransfer);\n }\n\n return updatedTransfer;\n },\n [onUpdate]\n );\n\n // Remove a transfer\n const removeTransfer = useCallback(\n (id: string): boolean => {\n let found = false;\n\n setTransfers((prev) => {\n const index = prev.findIndex((t) => t.id === id);\n if (index === -1) {\n return prev;\n }\n found = true;\n return prev.filter((t) => t.id !== id);\n });\n\n if (found && onRemove) {\n onRemove(id);\n }\n\n return found;\n },\n [onRemove]\n );\n\n // Get a transfer by ID\n const getTransfer = useCallback(\n (id: string): CrossBorderTransfer | null => {\n return transfers.find((t) => t.id === id) || null;\n },\n [transfers]\n );\n\n // Get compliance summary\n const getSummary = useCallback((): CrossBorderSummary => {\n const now = Date.now();\n const activeTransfers = transfers.filter((t) => t.status === 'active');\n\n // Breakdown by mechanism\n const allMechanisms: TransferMechanism[] = [\n 'adequacy_decision',\n 'standard_clauses',\n 'binding_corporate_rules',\n 'ndpc_authorization',\n 'explicit_consent',\n 'contract_performance',\n 'public_interest',\n 'legal_claims',\n 'vital_interests',\n ];\n const byMechanism = {} as Record<TransferMechanism, number>;\n for (const mechanism of allMechanisms) {\n byMechanism[mechanism] = activeTransfers.filter(\n (t) => t.transferMechanism === mechanism\n ).length;\n }\n\n // Breakdown by adequacy\n const allStatuses: AdequacyStatus[] = ['adequate', 'inadequate', 'pending_review', 'unknown'];\n const byAdequacy = {} as Record<AdequacyStatus, number>;\n for (const status of allStatuses) {\n byAdequacy[status] = activeTransfers.filter(\n (t) => t.adequacyStatus === status\n ).length;\n }\n\n // Transfers pending NDPC approval\n const pendingApproval = transfers.filter(\n (t) => t.status === 'pending_approval' || (t.ndpcApproval?.required && !t.ndpcApproval?.approved)\n );\n\n // Transfers due for review (within the next 30 days or overdue)\n const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000;\n const dueForReview = transfers.filter(\n (t) => t.reviewDate && t.reviewDate <= now + thirtyDaysMs && t.status === 'active'\n );\n\n // Transfers missing TIA\n const missingTIA = transfers.filter(\n (t) => !t.tiaCompleted && t.status === 'active'\n );\n\n // High-risk transfers\n const highRiskTransfers = transfers.filter(\n (t) => t.riskLevel === 'high' && t.status === 'active'\n );\n\n return {\n totalActiveTransfers: activeTransfers.length,\n byMechanism,\n byAdequacy,\n pendingApproval,\n dueForReview,\n missingTIA,\n highRiskTransfers,\n lastUpdated: now,\n };\n }, [transfers]);\n\n // Validate a transfer (wrapper around utility)\n const validateTransfer = useCallback(\n (transfer: CrossBorderTransfer): TransferValidationResult => {\n return validateTransferUtil(transfer);\n },\n []\n );\n\n return {\n transfers,\n addTransfer,\n updateTransfer,\n removeTransfer,\n getTransfer,\n getSummary,\n validateTransfer,\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkCMZTI7SG_js=require('./chunk-CMZTI7SG.js'),chunkMQFZHA2D_js=require('./chunk-MQFZHA2D.js'),react=require('react');function J({initialRequests:T=[],requestTypes:D,storageKey:R="ndpr_dsr_requests",useLocalStorage:r=true,onSubmit:c,onUpdate:l}){let[u,q]=react.useState(T);react.useEffect(()=>{if(r&&typeof window!="undefined")try{let e=localStorage.getItem(R);e&&q(JSON.parse(e));}catch(e){console.error("Error loading DSR requests:",e);}},[R,r]),react.useEffect(()=>{if(r&&typeof window!="undefined"&&u.length>0)try{localStorage.setItem(R,JSON.stringify(u));}catch(e){console.error("Error saving DSR requests:",e);}},[u,R,r]);let A=()=>"dsr_"+Date.now()+"_"+Math.random().toString(36).substr(2,9);return {requests:u,submitRequest:e=>{let t=D.find(S=>S.id===e.type),n=(t==null?void 0:t.estimatedCompletionTime)||30,s=Date.now(),i=s+n*24*60*60*1e3,f=e,{createdAt:p}=f,d=chunkMQFZHA2D_js.c(f,["createdAt"]),o=chunkMQFZHA2D_js.a({id:A(),status:"pending",createdAt:s,updatedAt:s,dueDate:i},d);return q(S=>[...S,o]),c&&c(o),o},updateRequest:(e,t)=>{let n=null;return q(s=>{let i=s.findIndex(o=>o.id===e);if(i===-1)return s;let p=s[i];n=chunkMQFZHA2D_js.b(chunkMQFZHA2D_js.a(chunkMQFZHA2D_js.a({},p),t),{updatedAt:Date.now()});let d=[...s];return d[i]=n,d}),n&&l&&l(n),n},getRequest:e=>u.find(t=>t.id===e)||null,getRequestsByStatus:e=>u.filter(t=>t.status===e),getRequestsByType:e=>u.filter(t=>t.type===e),getRequestType:e=>D.find(t=>t.id===e),formatRequest:e=>{let{formattedRequest:t}=chunkCMZTI7SG_js.a(e);return t},clearRequests:()=>{q([]),r&&typeof window!="undefined"&&localStorage.removeItem(R);}}}exports.a=J;//# sourceMappingURL=chunk-WW3X3ELF.js.map
2
+ //# sourceMappingURL=chunk-WW3X3ELF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/hooks/useDSR.ts"],"names":["useDSR","initialRequests","requestTypes","storageKey","useLocalStorage","onSubmit","onUpdate","requests","setRequests","useState","useEffect","savedRequests","error","generateId","requestData","requestType","type","estimatedCompletionDays","now","estimatedCompletionDate","_a","createdAt","restRequestData","__objRest","newRequest","__spreadValues","prevRequests","id","updates","updatedRequest","index","request","__spreadProps","newRequests","status","typeId","formattedRequest","formatDSRRequest"],"mappings":"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","file":"chunk-WW3X3ELF.js","sourcesContent":["import { useState, useEffect } from 'react';\nimport { DSRRequest, RequestStatus, RequestType } from '../types/dsr';\nimport { formatDSRRequest } from '../utils/dsr';\n\ninterface UseDSROptions {\n /**\n * Initial requests to load\n */\n initialRequests?: DSRRequest[];\n \n /**\n * Available request types\n */\n requestTypes: RequestType[];\n \n /**\n * Storage key for requests\n * @default \"ndpr_dsr_requests\"\n */\n storageKey?: string;\n \n /**\n * Whether to use local storage to persist requests\n * @default true\n */\n useLocalStorage?: boolean;\n \n /**\n * Callback function called when a request is submitted\n */\n onSubmit?: (request: DSRRequest) => void;\n \n /**\n * Callback function called when a request is updated\n */\n onUpdate?: (request: DSRRequest) => void;\n}\n\ninterface UseDSRReturn {\n /**\n * All requests\n */\n requests: DSRRequest[];\n \n /**\n * Submit a new request\n */\n submitRequest: (requestData: Omit<DSRRequest, 'id' | 'status' | 'submittedAt' | 'updatedAt' | 'estimatedCompletionDate'>) => DSRRequest;\n \n /**\n * Update an existing request\n */\n updateRequest: (id: string, updates: Partial<DSRRequest>) => DSRRequest | null;\n \n /**\n * Get a request by ID\n */\n getRequest: (id: string) => DSRRequest | null;\n \n /**\n * Get requests by status\n */\n getRequestsByStatus: (status: RequestStatus) => DSRRequest[];\n \n /**\n * Get requests by type\n */\n getRequestsByType: (type: string) => DSRRequest[];\n \n /**\n * Get the request type definition by ID\n */\n getRequestType: (typeId: string) => RequestType | undefined;\n \n /**\n * Format a request for display or submission\n */\n formatRequest: (request: DSRRequest) => Record<string, any>;\n \n /**\n * Clear all requests\n */\n clearRequests: () => void;\n}\n\n/**\n * Hook for managing Data Subject Requests in compliance with the NDPA\n */\nexport function useDSR({\n initialRequests = [],\n requestTypes,\n storageKey = \"ndpr_dsr_requests\",\n useLocalStorage = true,\n onSubmit,\n onUpdate\n}: UseDSROptions): UseDSRReturn {\n const [requests, setRequests] = useState<DSRRequest[]>(initialRequests);\n \n // Load requests from storage on mount\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined') {\n try {\n const savedRequests = localStorage.getItem(storageKey);\n if (savedRequests) {\n setRequests(JSON.parse(savedRequests));\n }\n } catch (error) {\n console.error('Error loading DSR requests:', error);\n }\n }\n }, [storageKey, useLocalStorage]);\n \n // Save requests to storage when they change\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined' && requests.length > 0) {\n try {\n localStorage.setItem(storageKey, JSON.stringify(requests));\n } catch (error) {\n console.error('Error saving DSR requests:', error);\n }\n }\n }, [requests, storageKey, useLocalStorage]);\n \n // Generate a unique ID\n const generateId = (): string => {\n return 'dsr_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);\n };\n \n // Submit a new request\n const submitRequest = (requestData: Omit<DSRRequest, 'id' | 'status' | 'submittedAt' | 'updatedAt' | 'estimatedCompletionDate'>): DSRRequest => {\n // Find the request type to get the estimated completion time\n const requestType = requestTypes.find(type => type.id === requestData.type);\n const estimatedCompletionDays = requestType?.estimatedCompletionTime || 30; // Default to 30 days\n \n const now = Date.now();\n const estimatedCompletionDate = now + (estimatedCompletionDays * 24 * 60 * 60 * 1000);\n \n // Extract any properties we want to override from requestData\n const { createdAt, ...restRequestData } = requestData as any;\n \n const newRequest: DSRRequest = {\n id: generateId(),\n status: 'pending',\n createdAt: now,\n updatedAt: now,\n dueDate: estimatedCompletionDate,\n ...restRequestData\n };\n \n setRequests(prevRequests => [...prevRequests, newRequest]);\n \n if (onSubmit) {\n onSubmit(newRequest);\n }\n \n return newRequest;\n };\n \n // Update an existing request\n const updateRequest = (id: string, updates: Partial<DSRRequest>): DSRRequest | null => {\n let updatedRequest: DSRRequest | null = null;\n \n setRequests(prevRequests => {\n const index = prevRequests.findIndex(request => request.id === id);\n \n if (index === -1) {\n return prevRequests;\n }\n \n const request = prevRequests[index];\n updatedRequest = {\n ...request,\n ...updates,\n updatedAt: Date.now()\n };\n \n const newRequests = [...prevRequests];\n newRequests[index] = updatedRequest as DSRRequest;\n \n return newRequests;\n });\n \n if (updatedRequest && onUpdate) {\n onUpdate(updatedRequest);\n }\n \n return updatedRequest;\n };\n \n // Get a request by ID\n const getRequest = (id: string): DSRRequest | null => {\n return requests.find(request => request.id === id) || null;\n };\n \n // Get requests by status\n const getRequestsByStatus = (status: RequestStatus): DSRRequest[] => {\n return requests.filter(request => request.status === status);\n };\n \n // Get requests by type\n const getRequestsByType = (type: string): DSRRequest[] => {\n return requests.filter(request => request.type === type);\n };\n \n // Get the request type definition by ID\n const getRequestType = (typeId: string): RequestType | undefined => {\n return requestTypes.find(type => type.id === typeId);\n };\n \n // Format a request for display or submission\n const formatRequest = (request: DSRRequest): Record<string, any> => {\n const { formattedRequest } = formatDSRRequest(request);\n return formattedRequest;\n };\n \n // Clear all requests\n const clearRequests = () => {\n setRequests([]);\n \n if (useLocalStorage && typeof window !== 'undefined') {\n localStorage.removeItem(storageKey);\n }\n };\n \n return {\n requests,\n submitRequest,\n updateRequest,\n getRequest,\n getRequestsByStatus,\n getRequestsByType,\n getRequestType,\n formatRequest,\n clearRequests\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var o=Object.defineProperty,p=Object.defineProperties;var q=Object.getOwnPropertyDescriptors;var f=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable;var j=(a,c,b)=>c in a?o(a,c,{enumerable:true,configurable:true,writable:true,value:b}):a[c]=b,r=(a,c)=>{for(var b in c||(c={}))k.call(c,b)&&j(a,b,c[b]);if(f)for(var b of f(c))l.call(c,b)&&j(a,b,c[b]);return a},s=(a,c)=>p(a,q(c));var t=(a,c)=>{var b={};for(var d in a)k.call(a,d)&&c.indexOf(d)<0&&(b[d]=a[d]);if(a!=null&&f)for(var d of f(a))c.indexOf(d)<0&&l.call(a,d)&&(b[d]=a[d]);return b};var u=(a,c,b)=>new Promise((d,i)=>{var m=e=>{try{g(b.next(e));}catch(h){i(h);}},n=e=>{try{g(b.throw(e));}catch(h){i(h);}},g=e=>e.done?d(e.value):Promise.resolve(e.value).then(m,n);g((b=b.apply(a,c)).next());});export{r as a,s as b,t as c,u as d};//# sourceMappingURL=chunk-WWT2ZSNU.mjs.map
2
+ //# sourceMappingURL=chunk-WWT2ZSNU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-WWT2ZSNU.mjs"}
@@ -0,0 +1,16 @@
1
+ import e from'react';var j=({sections:d,answers:b,onAnswerChange:g,currentSectionIndex:y,onNextSection:k,onPrevSection:h,validationErrors:N={},readOnly:o=false,className:v="",buttonClassName:c="",nextButtonText:n="Next",prevButtonText:f="Previous",submitButtonText:w="Submit",showProgress:P=true,progress:u})=>{let s=d[y],i=y===d.length-1,p=t=>t.showWhen?t.showWhen.every(x=>{let l=b[x.questionId];switch(x.operator){case "equals":return l===x.value;case "contains":return Array.isArray(l)?l.includes(x.value):false;case "greaterThan":return typeof l=="number"?l>x.value:false;case "lessThan":return typeof l=="number"?l<x.value:false;default:return true}}):true,A=t=>{if(!p(t))return null;let x=N[t.id],l=b[t.id];return e.createElement("div",{key:t.id,className:"mb-6"},e.createElement("div",{className:"mb-2"},e.createElement("label",{htmlFor:t.id,className:"block text-sm font-medium text-gray-900 dark:text-gray-100"},t.text,t.required&&e.createElement("span",{className:"text-red-500 ml-1"},"*")),t.guidance&&e.createElement("p",{className:"mt-1 text-sm text-gray-500 dark:text-gray-400"},t.guidance)),t.type==="text"&&e.createElement("input",{type:"text",id:t.id,value:l||"",onChange:a=>g(t.id,a.target.value),disabled:o,className:`w-full px-3 py-2 border rounded-md ${x?"border-red-500":"border-gray-300 dark:border-gray-600"} focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100`}),t.type==="textarea"&&e.createElement("textarea",{id:t.id,value:l||"",onChange:a=>g(t.id,a.target.value),disabled:o,rows:4,className:`w-full px-3 py-2 border rounded-md ${x?"border-red-500":"border-gray-300 dark:border-gray-600"} focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100`}),t.type==="select"&&t.options&&e.createElement("select",{id:t.id,value:l||"",onChange:a=>g(t.id,a.target.value),disabled:o,className:`w-full px-3 py-2 border rounded-md ${x?"border-red-500":"border-gray-300 dark:border-gray-600"} focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100`},e.createElement("option",{value:""},"Select an option"),t.options.map(a=>e.createElement("option",{key:a.value,value:a.value},a.label))),t.type==="radio"&&t.options&&e.createElement("div",{className:"space-y-2"},t.options.map(a=>e.createElement("div",{key:a.value,className:"flex items-center"},e.createElement("input",{type:"radio",id:`${t.id}_${a.value}`,name:t.id,value:a.value,checked:l===a.value,onChange:()=>g(t.id,a.value),disabled:o,className:"h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 dark:border-gray-600"}),e.createElement("label",{htmlFor:`${t.id}_${a.value}`,className:"ml-2 block text-sm text-gray-900 dark:text-gray-100"},a.label,a.riskLevel&&e.createElement("span",{className:`ml-2 text-xs px-2 py-1 rounded ${a.riskLevel==="low"?"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200":a.riskLevel==="medium"?"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200":"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"}`},a.riskLevel.charAt(0).toUpperCase()+a.riskLevel.slice(1)," Risk"))))),t.type==="checkbox"&&t.options&&e.createElement("div",{className:"space-y-2"},t.options.map(a=>e.createElement("div",{key:a.value,className:"flex items-center"},e.createElement("input",{type:"checkbox",id:`${t.id}_${a.value}`,value:a.value,checked:Array.isArray(l)?l.includes(a.value):false,onChange:$=>{let D=Array.isArray(l)?[...l]:[];$.target.checked?g(t.id,[...D,a.value]):g(t.id,D.filter(S=>S!==a.value));},disabled:o,className:"h-4 w-4 rounded text-blue-600 focus:ring-blue-500 border-gray-300 dark:border-gray-600"}),e.createElement("label",{htmlFor:`${t.id}_${a.value}`,className:"ml-2 block text-sm text-gray-900 dark:text-gray-100"},a.label)))),t.type==="scale"&&e.createElement("div",null,e.createElement("div",{className:"flex justify-between mb-2"},t.scaleLabels&&Object.entries(t.scaleLabels).map(([a,$])=>e.createElement("div",{key:a,className:"text-xs text-gray-500 dark:text-gray-400 text-center",style:{width:`${100/Object.keys(t.scaleLabels||{}).length}%`}},$))),e.createElement("input",{type:"range",id:t.id,min:t.minValue||1,max:t.maxValue||5,value:l||t.minValue||1,onChange:a=>g(t.id,parseInt(a.target.value,10)),disabled:o,className:"w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"}),e.createElement("div",{className:"mt-1 text-sm text-gray-500 dark:text-gray-400 text-center"},"Selected value: ",l||t.minValue||1)),x&&e.createElement("p",{className:"mt-1 text-sm text-red-500"},x))};return s?e.createElement("div",{className:`bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 ${v}`},P&&e.createElement("div",{className:"mb-6"},e.createElement("div",{className:"flex justify-between text-sm text-gray-500 dark:text-gray-400 mb-1"},e.createElement("span",null,"Section ",y+1," of ",d.length),e.createElement("span",null,u!==void 0?`${u}% Complete`:"")),e.createElement("div",{className:"w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"},e.createElement("div",{className:"bg-blue-600 h-2.5 rounded-full",style:{width:`${u!==void 0?u:(y+1)/d.length*100}%`}}))),e.createElement("h2",{className:"text-xl font-bold mb-2 text-gray-900 dark:text-white"},s.title),s.description&&e.createElement("p",{className:"mb-6 text-gray-600 dark:text-gray-300"},s.description),e.createElement("div",{className:"space-y-6"},s.questions.map(t=>A(t))),e.createElement("div",{className:"mt-8 flex justify-between"},e.createElement("button",{type:"button",onClick:h,disabled:y===0||o,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 disabled:opacity-50 disabled:cursor-not-allowed ${c}`},f),e.createElement("button",{type:"button",onClick:k,disabled:o,className:`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed ${c}`},i?w:n))):e.createElement("div",null,"No section found.")};var T=({result:d,sections:b,showFullReport:g=true,allowPrint:y=true,allowExport:k=true,onExport:h,className:N="",buttonClassName:o=""})=>{let v=s=>new Date(s).toLocaleDateString("en-GB",{day:"numeric",month:"long",year:"numeric"}),f=s=>{let i=d.answers[s];return i==null?"Not answered":typeof i=="boolean"?i?"Yes":"No":Array.isArray(i)?i.join(", "):String(i)},w=()=>{window.print();},P=s=>{h&&h(s);},u=s=>e.createElement("span",{className:`px-2 py-1 rounded text-xs font-medium ${{low:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",medium:"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200",high:"bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200",critical:"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"}[s]}`},s.charAt(0).toUpperCase()+s.slice(1));return e.createElement("div",{className:`bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 print:shadow-none print:p-0 ${N}`},e.createElement("div",{className:"mb-8 border-b border-gray-200 dark:border-gray-700 pb-6 print:pb-4"},e.createElement("div",{className:"flex justify-between items-start"},e.createElement("div",null,e.createElement("h1",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2"},"Data Protection Impact Assessment Report"),e.createElement("h2",{className:"text-xl text-gray-700 dark:text-gray-300 mb-4"},d.title)),(y||k)&&e.createElement("div",{className:"flex space-x-2 print:hidden"},y&&e.createElement("button",{onClick:w,className:`px-3 py-1 bg-gray-200 text-gray-800 dark:bg-gray-700 dark:text-white rounded hover:bg-gray-300 dark:hover:bg-gray-600 ${o}`},e.createElement("span",{className:"flex items-center"},e.createElement("svg",{className:"w-4 h-4 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"})),"Print")),k&&e.createElement("div",{className:"relative inline-block"},e.createElement("button",{onClick:()=>P("pdf"),className:`px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 ${o}`},e.createElement("span",{className:"flex items-center"},e.createElement("svg",{className:"w-4 h-4 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"})),"Export PDF"))))),e.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4"},e.createElement("div",null,e.createElement("p",{className:"text-sm text-gray-500 dark:text-gray-400"},e.createElement("span",{className:"font-medium"},"Assessor:")," ",d.assessor.name,", ",d.assessor.role),e.createElement("p",{className:"text-sm text-gray-500 dark:text-gray-400"},e.createElement("span",{className:"font-medium"},"Contact:")," ",d.assessor.email)),e.createElement("div",null,e.createElement("p",{className:"text-sm text-gray-500 dark:text-gray-400"},e.createElement("span",{className:"font-medium"},"Started:")," ",v(d.startedAt)),e.createElement("p",{className:"text-sm text-gray-500 dark:text-gray-400"},e.createElement("span",{className:"font-medium"},"Completed:")," ",d.completedAt?v(d.completedAt):"In progress"),e.createElement("p",{className:"text-sm text-gray-500 dark:text-gray-400"},e.createElement("span",{className:"font-medium"},"Next review:")," ",d.reviewDate?v(d.reviewDate):"Not scheduled")))),e.createElement("div",{className:"mb-8"},e.createElement("h2",{className:"text-xl font-bold text-gray-900 dark:text-white mb-4"},"Executive Summary"),e.createElement("div",{className:"bg-gray-50 dark:bg-gray-700 p-4 rounded-md mb-4"},e.createElement("div",{className:"flex items-center mb-2"},e.createElement("span",{className:"font-medium mr-2"},"Overall Risk Level:"),u(d.overallRiskLevel)),e.createElement("div",{className:"mb-2"},e.createElement("span",{className:"font-medium"},"Conclusion:")," ",d.conclusion),e.createElement("div",null,e.createElement("span",{className:"font-medium"},"Can Proceed:")," ",d.canProceed?"Yes":"No")),e.createElement("div",null,e.createElement("h3",{className:"font-medium text-gray-900 dark:text-white mb-2"},"Processing Activity Description"),e.createElement("p",{className:"text-gray-700 dark:text-gray-300 mb-4"},d.processingDescription),d.recommendations&&d.recommendations.length>0&&e.createElement("div",null,e.createElement("h3",{className:"font-medium text-gray-900 dark:text-white mb-2"},"Key Recommendations"),e.createElement("ul",{className:"list-disc pl-5 text-gray-700 dark:text-gray-300"},d.recommendations.map((s,i)=>e.createElement("li",{key:i},s)))))),e.createElement("div",{className:"mb-8"},e.createElement("h2",{className:"text-xl font-bold text-gray-900 dark:text-white mb-4"},"Identified Risks"),d.risks.length===0?e.createElement("p",{className:"text-gray-700 dark:text-gray-300"},"No risks identified."):e.createElement("div",{className:"overflow-x-auto"},e.createElement("table",{className:"min-w-full divide-y divide-gray-200 dark:divide-gray-700"},e.createElement("thead",{className:"bg-gray-50 dark:bg-gray-700"},e.createElement("tr",null,e.createElement("th",{scope:"col",className:"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"},"Risk"),e.createElement("th",{scope:"col",className:"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"},"Likelihood"),e.createElement("th",{scope:"col",className:"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"},"Impact"),e.createElement("th",{scope:"col",className:"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"},"Risk Level"),e.createElement("th",{scope:"col",className:"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"},"Mitigated"))),e.createElement("tbody",{className:"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700"},d.risks.map(s=>e.createElement("tr",{key:s.id},e.createElement("td",{className:"px-6 py-4 whitespace-normal text-sm text-gray-900 dark:text-gray-100"},s.description),e.createElement("td",{className:"px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"},s.likelihood," / 5"),e.createElement("td",{className:"px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"},s.impact," / 5"),e.createElement("td",{className:"px-6 py-4 whitespace-nowrap text-sm"},u(s.level)),e.createElement("td",{className:"px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"},s.mitigated?e.createElement("span",{className:"text-green-600 dark:text-green-400"},"Yes"):e.createElement("span",{className:"text-red-600 dark:text-red-400"},"No")))))))),g&&e.createElement("div",null,e.createElement("h2",{className:"text-xl font-bold text-gray-900 dark:text-white mb-4"},"Full Assessment Details"),b.map(s=>{let i=s.questions.filter(p=>d.answers[p.id]!==void 0);return i.length===0?null:e.createElement("div",{key:s.id,className:"mb-6"},e.createElement("h3",{className:"text-lg font-medium text-gray-900 dark:text-white mb-2"},s.title),e.createElement("div",{className:"overflow-x-auto"},e.createElement("table",{className:"min-w-full divide-y divide-gray-200 dark:divide-gray-700"},e.createElement("thead",{className:"bg-gray-50 dark:bg-gray-700"},e.createElement("tr",null,e.createElement("th",{scope:"col",className:"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"},"Question"),e.createElement("th",{scope:"col",className:"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider"},"Answer"))),e.createElement("tbody",{className:"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700"},i.map(p=>e.createElement("tr",{key:p.id},e.createElement("td",{className:"px-6 py-4 whitespace-normal text-sm text-gray-900 dark:text-gray-100"},p.text),e.createElement("td",{className:"px-6 py-4 whitespace-normal text-sm text-gray-500 dark:text-gray-400"},f(p.id))))))))})),e.createElement("div",{className:"mt-8 pt-4 border-t border-gray-200 dark:border-gray-700 text-sm text-gray-500 dark:text-gray-400"},e.createElement("p",null,"This DPIA was conducted in accordance with the Nigeria Data Protection Act (NDPA) 2023."),e.createElement("p",null,"DPIA Report Version: ",d.version),e.createElement("p",null,"Generated on: ",new Date().toLocaleDateString())))};var E=({steps:d,onStepClick:b,clickable:g=true,orientation:y="horizontal",className:k="",activeStepClassName:h="",completedStepClassName:N="",incompleteStepClassName:o=""})=>{let v=n=>{g&&b&&b(n);},c=y==="vertical";return e.createElement("div",{className:`${k} ${c?"flex flex-col space-y-4":"flex items-center justify-between"}`},d.map((n,f)=>{let w=f===d.length-1,P=n.active?`font-medium ${h||"text-blue-600 dark:text-blue-400"}`:n.completed?`${N||"text-green-600 dark:text-green-400"}`:`${o||"text-gray-500 dark:text-gray-400"}`;return e.createElement(e.Fragment,{key:n.id},e.createElement("div",{className:`
2
+ ${c?"flex items-start":"flex flex-col items-center"}
3
+ ${g?"cursor-pointer":""}
4
+ `,onClick:()=>v(n.id)},e.createElement("div",{className:`
5
+ flex items-center justify-center
6
+ ${c?"mr-4":""}
7
+ `},e.createElement("div",{className:`
8
+ flex items-center justify-center
9
+ w-8 h-8 rounded-full
10
+ ${n.active?"bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-400 border-2 border-blue-600 dark:border-blue-400":n.completed?"bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-400 border-2 border-green-600 dark:border-green-400":"bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 border-2 border-gray-300 dark:border-gray-600"}
11
+ `},n.icon?n.icon:n.completed?e.createElement("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",xmlns:"http://www.w3.org/2000/svg"},e.createElement("path",{fillRule:"evenodd",d:"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",clipRule:"evenodd"})):e.createElement("span",null,f+1))),e.createElement("div",{className:`
12
+ ${c?"flex-1":"mt-2 text-center"}
13
+ `},e.createElement("div",{className:`text-sm font-medium ${P}`},n.label),n.description&&e.createElement("div",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1"},n.description))),!w&&e.createElement("div",{className:`
14
+ ${c?"ml-4 h-8 border-l-2 border-gray-300 dark:border-gray-600":"w-full border-t-2 border-gray-300 dark:border-gray-600 hidden sm:block"}
15
+ `}))}))};export{j as a,T as b,E as c};//# sourceMappingURL=chunk-XMKA6GVK.mjs.map
16
+ //# sourceMappingURL=chunk-XMKA6GVK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx","../packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx","../packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx"],"names":["DPIAQuestionnaire","sections","answers","onAnswerChange","currentSectionIndex","onNextSection","onPrevSection","validationErrors","readOnly","className","buttonClassName","nextButtonText","prevButtonText","submitButtonText","showProgress","progress","currentSection","isLastSection","shouldShowQuestion","question","condition","answer","renderQuestion","error","value","React","e","option","currentValues","v","scaleValue","label","DPIAReport","result","showFullReport","allowPrint","allowExport","onExport","formatDate","timestamp","getAnswerText","questionId","handlePrint","handleExport","format","renderRiskLevelBadge","level","recommendation","index","risk","section","sectionQuestions","StepIndicator","steps","onStepClick","clickable","orientation","activeStepClassName","completedStepClassName","incompleteStepClassName","handleStepClick","stepId","isVertical","step","isLast","stepClassName"],"mappings":"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","file":"chunk-XMKA6GVK.mjs","sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { DPIASection, DPIAQuestion } from '../../types/dpia';\n\nexport interface DPIAQuestionnaireProps {\n /**\n * Sections of the DPIA questionnaire\n */\n sections: DPIASection[];\n \n /**\n * Current answers to the questionnaire\n */\n answers: Record<string, any>;\n \n /**\n * Callback function called when an answer is updated\n */\n onAnswerChange: (questionId: string, value: any) => void;\n \n /**\n * Current section index\n */\n currentSectionIndex: number;\n \n /**\n * Callback function called when user navigates to the next section\n */\n onNextSection?: () => void;\n \n /**\n * Callback function called when user navigates to the previous section\n */\n onPrevSection?: () => void;\n \n /**\n * Validation errors for the current section\n */\n validationErrors?: Record<string, string>;\n \n /**\n * Whether the questionnaire is in read-only mode\n * @default false\n */\n readOnly?: boolean;\n \n /**\n * Custom CSS class for the questionnaire\n */\n className?: string;\n \n /**\n * Custom CSS class for the buttons\n */\n buttonClassName?: string;\n \n /**\n * Text for the next button\n * @default \"Next\"\n */\n nextButtonText?: string;\n \n /**\n * Text for the previous button\n * @default \"Previous\"\n */\n prevButtonText?: string;\n \n /**\n * Text for the submit button (shown on the last section)\n * @default \"Submit\"\n */\n submitButtonText?: string;\n \n /**\n * Whether to show a progress indicator\n * @default true\n */\n showProgress?: boolean;\n \n /**\n * Current progress percentage (0-100)\n */\n progress?: number;\n}\n\nexport const DPIAQuestionnaire: React.FC<DPIAQuestionnaireProps> = ({\n sections,\n answers,\n onAnswerChange,\n currentSectionIndex,\n onNextSection,\n onPrevSection,\n validationErrors = {},\n readOnly = false,\n className = \"\",\n buttonClassName = \"\",\n nextButtonText = \"Next\",\n prevButtonText = \"Previous\",\n submitButtonText = \"Submit\",\n showProgress = true,\n progress\n}) => {\n const currentSection = sections[currentSectionIndex];\n const isLastSection = currentSectionIndex === sections.length - 1;\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 // Render a question based on its type\n const renderQuestion = (question: DPIAQuestion) => {\n if (!shouldShowQuestion(question)) {\n return null;\n }\n \n const error = validationErrors[question.id];\n const value = answers[question.id];\n \n return (\n <div key={question.id} className=\"mb-6\">\n <div className=\"mb-2\">\n <label htmlFor={question.id} className=\"block text-sm font-medium text-gray-900 dark:text-gray-100\">\n {question.text}\n {question.required && <span className=\"text-red-500 ml-1\">*</span>}\n </label>\n {question.guidance && (\n <p className=\"mt-1 text-sm text-gray-500 dark:text-gray-400\">{question.guidance}</p>\n )}\n </div>\n \n {question.type === 'text' && (\n <input\n type=\"text\"\n id={question.id}\n value={value || ''}\n onChange={e => onAnswerChange(question.id, e.target.value)}\n disabled={readOnly}\n className={`w-full px-3 py-2 border rounded-md ${\n error ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'\n } focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100`}\n />\n )}\n \n {question.type === 'textarea' && (\n <textarea\n id={question.id}\n value={value || ''}\n onChange={e => onAnswerChange(question.id, e.target.value)}\n disabled={readOnly}\n rows={4}\n className={`w-full px-3 py-2 border rounded-md ${\n error ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'\n } focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100`}\n />\n )}\n \n {question.type === 'select' && question.options && (\n <select\n id={question.id}\n value={value || ''}\n onChange={e => onAnswerChange(question.id, e.target.value)}\n disabled={readOnly}\n className={`w-full px-3 py-2 border rounded-md ${\n error ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'\n } focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100`}\n >\n <option value=\"\">Select an option</option>\n {question.options.map(option => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n \n {question.type === 'radio' && question.options && (\n <div className=\"space-y-2\">\n {question.options.map(option => (\n <div key={option.value} className=\"flex items-center\">\n <input\n type=\"radio\"\n id={`${question.id}_${option.value}`}\n name={question.id}\n value={option.value}\n checked={value === option.value}\n onChange={() => onAnswerChange(question.id, option.value)}\n disabled={readOnly}\n className=\"h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 dark:border-gray-600\"\n />\n <label\n htmlFor={`${question.id}_${option.value}`}\n className=\"ml-2 block text-sm text-gray-900 dark:text-gray-100\"\n >\n {option.label}\n {option.riskLevel && (\n <span className={`ml-2 text-xs px-2 py-1 rounded ${\n option.riskLevel === 'low' ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' :\n option.riskLevel === 'medium' ? 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200' :\n 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'\n }`}>\n {option.riskLevel.charAt(0).toUpperCase() + option.riskLevel.slice(1)} Risk\n </span>\n )}\n </label>\n </div>\n ))}\n </div>\n )}\n \n {question.type === 'checkbox' && question.options && (\n <div className=\"space-y-2\">\n {question.options.map(option => (\n <div key={option.value} className=\"flex items-center\">\n <input\n type=\"checkbox\"\n id={`${question.id}_${option.value}`}\n value={option.value}\n checked={Array.isArray(value) ? value.includes(option.value) : false}\n onChange={e => {\n const currentValues = Array.isArray(value) ? [...value] : [];\n if (e.target.checked) {\n onAnswerChange(question.id, [...currentValues, option.value]);\n } else {\n onAnswerChange(question.id, currentValues.filter(v => v !== option.value));\n }\n }}\n disabled={readOnly}\n className=\"h-4 w-4 rounded text-blue-600 focus:ring-blue-500 border-gray-300 dark:border-gray-600\"\n />\n <label\n htmlFor={`${question.id}_${option.value}`}\n className=\"ml-2 block text-sm text-gray-900 dark:text-gray-100\"\n >\n {option.label}\n </label>\n </div>\n ))}\n </div>\n )}\n \n {question.type === 'scale' && (\n <div>\n <div className=\"flex justify-between mb-2\">\n {question.scaleLabels && Object.entries(question.scaleLabels).map(([scaleValue, label]) => (\n <div key={scaleValue} className=\"text-xs text-gray-500 dark:text-gray-400 text-center\" style={{ width: `${100 / Object.keys(question.scaleLabels || {}).length}%` }}>\n {label}\n </div>\n ))}\n </div>\n <input\n type=\"range\"\n id={question.id}\n min={question.minValue || 1}\n max={question.maxValue || 5}\n value={value || (question.minValue || 1)}\n onChange={e => onAnswerChange(question.id, parseInt(e.target.value, 10))}\n disabled={readOnly}\n className=\"w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700\"\n />\n <div className=\"mt-1 text-sm text-gray-500 dark:text-gray-400 text-center\">\n Selected value: {value || (question.minValue || 1)}\n </div>\n </div>\n )}\n \n {error && <p className=\"mt-1 text-sm text-red-500\">{error}</p>}\n </div>\n );\n };\n \n if (!currentSection) {\n return <div>No section found.</div>;\n }\n \n return (\n <div className={`bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 ${className}`}>\n {showProgress && (\n <div className=\"mb-6\">\n <div className=\"flex justify-between text-sm text-gray-500 dark:text-gray-400 mb-1\">\n <span>Section {currentSectionIndex + 1} of {sections.length}</span>\n <span>{progress !== undefined ? `${progress}% Complete` : ''}</span>\n </div>\n <div className=\"w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700\">\n <div\n className=\"bg-blue-600 h-2.5 rounded-full\"\n style={{ width: `${progress !== undefined ? progress : ((currentSectionIndex + 1) / sections.length) * 100}%` }}\n ></div>\n </div>\n </div>\n )}\n \n <h2 className=\"text-xl font-bold mb-2 text-gray-900 dark:text-white\">{currentSection.title}</h2>\n {currentSection.description && (\n <p className=\"mb-6 text-gray-600 dark:text-gray-300\">{currentSection.description}</p>\n )}\n \n <div className=\"space-y-6\">\n {currentSection.questions.map(question => renderQuestion(question))}\n </div>\n \n <div className=\"mt-8 flex justify-between\">\n <button\n type=\"button\"\n onClick={onPrevSection}\n disabled={currentSectionIndex === 0 || readOnly}\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 disabled:opacity-50 disabled:cursor-not-allowed ${buttonClassName}`}\n >\n {prevButtonText}\n </button>\n \n <button\n type=\"button\"\n onClick={onNextSection}\n disabled={readOnly}\n className={`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed ${buttonClassName}`}\n >\n {isLastSection ? submitButtonText : nextButtonText}\n </button>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport { DPIAResult, DPIASection, DPIARisk } from '../../types/dpia';\n\nexport interface DPIAReportProps {\n /**\n * The DPIA result to display\n */\n result: DPIAResult;\n \n /**\n * The sections of the DPIA questionnaire\n */\n sections: DPIASection[];\n \n /**\n * Whether to show the full report or just a summary\n * @default true\n */\n showFullReport?: boolean;\n \n /**\n * Whether to allow printing the report\n * @default true\n */\n allowPrint?: boolean;\n \n /**\n * Whether to allow exporting the report as PDF\n * @default true\n */\n allowExport?: boolean;\n \n /**\n * Callback function called when the report is exported\n */\n onExport?: (format: 'pdf' | 'docx' | 'html') => void;\n \n /**\n * Custom CSS class for the report container\n */\n className?: string;\n \n /**\n * Custom CSS class for the buttons\n */\n buttonClassName?: string;\n}\n\nexport const DPIAReport: React.FC<DPIAReportProps> = ({\n result,\n sections,\n showFullReport = true,\n allowPrint = true,\n allowExport = true,\n onExport,\n className = '',\n buttonClassName = ''\n}) => {\n // Format a date from timestamp\n const formatDate = (timestamp: number): string => {\n return new Date(timestamp).toLocaleDateString('en-GB', {\n day: 'numeric',\n month: 'long',\n year: 'numeric'\n });\n };\n \n // Get the section title by ID\n const getSectionTitle = (sectionId: string): string => {\n const section = sections.find(s => s.id === sectionId);\n return section?.title || 'Unknown Section';\n };\n \n // Get the question text by ID\n const getQuestionText = (questionId: string): string => {\n let questionText = 'Unknown Question';\n \n sections.forEach(section => {\n const question = section.questions.find(q => q.id === questionId);\n if (question) {\n questionText = question.text;\n }\n });\n \n return questionText;\n };\n \n // Get the answer text for a question\n const getAnswerText = (questionId: string): string => {\n const answer = result.answers[questionId];\n \n if (answer === undefined || answer === null) {\n return 'Not answered';\n }\n \n if (typeof answer === 'boolean') {\n return answer ? 'Yes' : 'No';\n }\n \n if (Array.isArray(answer)) {\n return answer.join(', ');\n }\n \n return String(answer);\n };\n \n // Handle print button click\n const handlePrint = () => {\n window.print();\n };\n \n // Handle export button click\n const handleExport = (format: 'pdf' | 'docx' | 'html') => {\n if (onExport) {\n onExport(format);\n }\n };\n \n // Render risk level badge\n const renderRiskLevelBadge = (level: 'low' | 'medium' | 'high' | 'critical') => {\n const colorClasses = {\n low: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',\n medium: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',\n high: 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200',\n critical: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'\n };\n \n return (\n <span className={`px-2 py-1 rounded text-xs font-medium ${colorClasses[level]}`}>\n {level.charAt(0).toUpperCase() + level.slice(1)}\n </span>\n );\n };\n \n return (\n <div className={`bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 print:shadow-none print:p-0 ${className}`}>\n {/* Report Header */}\n <div className=\"mb-8 border-b border-gray-200 dark:border-gray-700 pb-6 print:pb-4\">\n <div className=\"flex justify-between items-start\">\n <div>\n <h1 className=\"text-2xl font-bold text-gray-900 dark:text-white mb-2\">\n Data Protection Impact Assessment Report\n </h1>\n <h2 className=\"text-xl text-gray-700 dark:text-gray-300 mb-4\">\n {result.title}\n </h2>\n </div>\n \n {(allowPrint || allowExport) && (\n <div className=\"flex space-x-2 print:hidden\">\n {allowPrint && (\n <button\n onClick={handlePrint}\n className={`px-3 py-1 bg-gray-200 text-gray-800 dark:bg-gray-700 dark:text-white rounded hover:bg-gray-300 dark:hover:bg-gray-600 ${buttonClassName}`}\n >\n <span className=\"flex items-center\">\n <svg className=\"w-4 h-4 mr-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z\" />\n </svg>\n Print\n </span>\n </button>\n )}\n \n {allowExport && (\n <div className=\"relative inline-block\">\n <button\n onClick={() => handleExport('pdf')}\n className={`px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 ${buttonClassName}`}\n >\n <span className=\"flex items-center\">\n <svg className=\"w-4 h-4 mr-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n </svg>\n Export PDF\n </span>\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n \n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4\">\n <div>\n <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n <span className=\"font-medium\">Assessor:</span> {result.assessor.name}, {result.assessor.role}\n </p>\n <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n <span className=\"font-medium\">Contact:</span> {result.assessor.email}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n <span className=\"font-medium\">Started:</span> {formatDate(result.startedAt)}\n </p>\n <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n <span className=\"font-medium\">Completed:</span> {result.completedAt ? formatDate(result.completedAt) : 'In progress'}\n </p>\n <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n <span className=\"font-medium\">Next review:</span> {result.reviewDate ? formatDate(result.reviewDate) : 'Not scheduled'}\n </p>\n </div>\n </div>\n </div>\n \n {/* Executive Summary */}\n <div className=\"mb-8\">\n <h2 className=\"text-xl font-bold text-gray-900 dark:text-white mb-4\">\n Executive Summary\n </h2>\n \n <div className=\"bg-gray-50 dark:bg-gray-700 p-4 rounded-md mb-4\">\n <div className=\"flex items-center mb-2\">\n <span className=\"font-medium mr-2\">Overall Risk Level:</span>\n {renderRiskLevelBadge(result.overallRiskLevel)}\n </div>\n \n <div className=\"mb-2\">\n <span className=\"font-medium\">Conclusion:</span> {result.conclusion}\n </div>\n \n <div>\n <span className=\"font-medium\">Can Proceed:</span> {result.canProceed ? 'Yes' : 'No'}\n </div>\n </div>\n \n <div>\n <h3 className=\"font-medium text-gray-900 dark:text-white mb-2\">\n Processing Activity Description\n </h3>\n <p className=\"text-gray-700 dark:text-gray-300 mb-4\">\n {result.processingDescription}\n </p>\n \n {result.recommendations && result.recommendations.length > 0 && (\n <div>\n <h3 className=\"font-medium text-gray-900 dark:text-white mb-2\">\n Key Recommendations\n </h3>\n <ul className=\"list-disc pl-5 text-gray-700 dark:text-gray-300\">\n {result.recommendations.map((recommendation, index) => (\n <li key={index}>{recommendation}</li>\n ))}\n </ul>\n </div>\n )}\n </div>\n </div>\n \n {/* Identified Risks */}\n <div className=\"mb-8\">\n <h2 className=\"text-xl font-bold text-gray-900 dark:text-white mb-4\">\n Identified Risks\n </h2>\n \n {result.risks.length === 0 ? (\n <p className=\"text-gray-700 dark:text-gray-300\">No risks identified.</p>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 dark:divide-gray-700\">\n <thead className=\"bg-gray-50 dark:bg-gray-700\">\n <tr>\n <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider\">\n Risk\n </th>\n <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider\">\n Likelihood\n </th>\n <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider\">\n Impact\n </th>\n <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider\">\n Risk Level\n </th>\n <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider\">\n Mitigated\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700\">\n {result.risks.map((risk) => (\n <tr key={risk.id}>\n <td className=\"px-6 py-4 whitespace-normal text-sm text-gray-900 dark:text-gray-100\">\n {risk.description}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400\">\n {risk.likelihood} / 5\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400\">\n {risk.impact} / 5\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm\">\n {renderRiskLevelBadge(risk.level)}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400\">\n {risk.mitigated ? (\n <span className=\"text-green-600 dark:text-green-400\">Yes</span>\n ) : (\n <span className=\"text-red-600 dark:text-red-400\">No</span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n \n {/* Full Assessment Details */}\n {showFullReport && (\n <div>\n <h2 className=\"text-xl font-bold text-gray-900 dark:text-white mb-4\">\n Full Assessment Details\n </h2>\n \n {sections.map((section) => {\n const sectionQuestions = section.questions.filter(question => \n result.answers[question.id] !== undefined\n );\n \n if (sectionQuestions.length === 0) {\n return null;\n }\n \n return (\n <div key={section.id} className=\"mb-6\">\n <h3 className=\"text-lg font-medium text-gray-900 dark:text-white mb-2\">\n {section.title}\n </h3>\n \n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 dark:divide-gray-700\">\n <thead className=\"bg-gray-50 dark:bg-gray-700\">\n <tr>\n <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider\">\n Question\n </th>\n <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider\">\n Answer\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700\">\n {sectionQuestions.map((question) => (\n <tr key={question.id}>\n <td className=\"px-6 py-4 whitespace-normal text-sm text-gray-900 dark:text-gray-100\">\n {question.text}\n </td>\n <td className=\"px-6 py-4 whitespace-normal text-sm text-gray-500 dark:text-gray-400\">\n {getAnswerText(question.id)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n })}\n </div>\n )}\n \n {/* Footer */}\n <div className=\"mt-8 pt-4 border-t border-gray-200 dark:border-gray-700 text-sm text-gray-500 dark:text-gray-400\">\n <p>This DPIA was conducted in accordance with the Nigeria Data Protection Act (NDPA) 2023.</p>\n <p>DPIA Report Version: {result.version}</p>\n <p>Generated on: {new Date().toLocaleDateString()}</p>\n </div>\n </div>\n );\n};\n","import React from 'react';\n\nexport interface Step {\n /**\n * Unique identifier for the step\n */\n id: string;\n \n /**\n * Display label for the step\n */\n label: string;\n \n /**\n * Optional description for the step\n */\n description?: string;\n \n /**\n * Whether the step is completed\n */\n completed: boolean;\n \n /**\n * Whether the step is the current active step\n */\n active: boolean;\n \n /**\n * Optional icon for the step\n */\n icon?: React.ReactNode;\n}\n\nexport interface StepIndicatorProps {\n /**\n * Array of steps to display\n */\n steps: Step[];\n \n /**\n * Callback function called when a step is clicked\n */\n onStepClick?: (stepId: string) => void;\n \n /**\n * Whether the steps are clickable\n * @default true\n */\n clickable?: boolean;\n \n /**\n * Orientation of the step indicator\n * @default \"horizontal\"\n */\n orientation?: 'horizontal' | 'vertical';\n \n /**\n * Custom CSS class for the container\n */\n className?: string;\n \n /**\n * Custom CSS class for the active step\n */\n activeStepClassName?: string;\n \n /**\n * Custom CSS class for completed steps\n */\n completedStepClassName?: string;\n \n /**\n * Custom CSS class for incomplete steps\n */\n incompleteStepClassName?: string;\n}\n\nexport const StepIndicator: React.FC<StepIndicatorProps> = ({\n steps,\n onStepClick,\n clickable = true,\n orientation = 'horizontal',\n className = '',\n activeStepClassName = '',\n completedStepClassName = '',\n incompleteStepClassName = ''\n}) => {\n const handleStepClick = (stepId: string) => {\n if (clickable && onStepClick) {\n onStepClick(stepId);\n }\n };\n \n const isVertical = orientation === 'vertical';\n \n return (\n <div \n className={`${className} ${\n isVertical \n ? 'flex flex-col space-y-4' \n : 'flex items-center justify-between'\n }`}\n >\n {steps.map((step, index) => {\n const isLast = index === steps.length - 1;\n const stepClassName = step.active \n ? `font-medium ${activeStepClassName || 'text-blue-600 dark:text-blue-400'}` \n : step.completed \n ? `${completedStepClassName || 'text-green-600 dark:text-green-400'}` \n : `${incompleteStepClassName || 'text-gray-500 dark:text-gray-400'}`;\n \n return (\n <React.Fragment key={step.id}>\n <div \n className={`\n ${isVertical ? 'flex items-start' : 'flex flex-col items-center'}\n ${clickable ? 'cursor-pointer' : ''}\n `}\n onClick={() => handleStepClick(step.id)}\n >\n <div className={`\n flex items-center justify-center\n ${isVertical ? 'mr-4' : ''}\n `}>\n <div className={`\n flex items-center justify-center\n w-8 h-8 rounded-full\n ${step.active \n ? 'bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-400 border-2 border-blue-600 dark:border-blue-400' \n : step.completed \n ? 'bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-400 border-2 border-green-600 dark:border-green-400' \n : 'bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 border-2 border-gray-300 dark:border-gray-600'\n }\n `}>\n {step.icon ? (\n step.icon\n ) : step.completed ? (\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fillRule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clipRule=\"evenodd\" />\n </svg>\n ) : (\n <span>{index + 1}</span>\n )}\n </div>\n </div>\n \n <div className={`\n ${isVertical ? 'flex-1' : 'mt-2 text-center'}\n `}>\n <div className={`text-sm font-medium ${stepClassName}`}>\n {step.label}\n </div>\n {step.description && (\n <div className=\"text-xs text-gray-500 dark:text-gray-400 mt-1\">\n {step.description}\n </div>\n )}\n </div>\n </div>\n \n {!isLast && (\n <div className={`\n ${isVertical \n ? 'ml-4 h-8 border-l-2 border-gray-300 dark:border-gray-600' \n : 'w-full border-t-2 border-gray-300 dark:border-gray-600 hidden sm:block'}\n `} />\n )}\n </React.Fragment>\n );\n })}\n </div>\n );\n};\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';function s(e){let n=[];(!e.consents||Object.keys(e.consents).length===0)&&n.push("Consent settings must include at least one consent option"),e.timestamp?(typeof e.timestamp!="number"||isNaN(e.timestamp))&&n.push("Consent timestamp must be a valid number"):n.push("Consent timestamp is required"),e.version||n.push("Consent version is required"),e.method||n.push("Consent collection method is required"),e.hasInteracted===void 0&&n.push("User interaction status is required");let t=Date.now()-390*24*60*60*1e3;return e.timestamp<t&&n.push("Consent is older than 13 months and should be refreshed"),{valid:n.length===0,errors:n}}function r(e){let n=[];return (!e||e.length===0)&&n.push("At least one consent option is required"),e==null||e.forEach(t=>{(!t.purpose||t.purpose.trim()==="")&&n.push(`Consent option "${t.id}" is missing a purpose. NDPA Section 26 requires consent to be specific to a stated purpose.`);}),{valid:n.length===0,errors:n}}exports.a=s;exports.b=r;//# sourceMappingURL=chunk-Y34DQYS7.js.map
2
+ //# sourceMappingURL=chunk-Y34DQYS7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/consent.ts"],"names":["validateConsent","settings","errors","thirteenMonthsAgo","validateConsentOptions","options","option"],"mappings":"aAOO,SAASA,CAAAA,CAAgBC,CAAAA,CAG9B,CACA,IAAMC,CAAAA,CAAmB,EAAC,CAAA,CAGtB,CAACD,CAAAA,CAAS,QAAA,EAAY,MAAA,CAAO,IAAA,CAAKA,EAAS,QAAQ,CAAA,CAAE,MAAA,GAAW,CAAA,GAClEC,CAAAA,CAAO,IAAA,CAAK,2DAA2D,CAAA,CAIpED,CAAAA,CAAS,SAAA,CAAA,CAEH,OAAOA,CAAAA,CAAS,SAAA,EAAc,QAAA,EAAY,KAAA,CAAMA,CAAAA,CAAS,SAAS,CAAA,GAC3EC,CAAAA,CAAO,IAAA,CAAK,0CAA0C,CAAA,CAFtDA,CAAAA,CAAO,IAAA,CAAK,+BAA+B,CAAA,CAMxCD,CAAAA,CAAS,OAAA,EACZC,CAAAA,CAAO,IAAA,CAAK,6BAA6B,CAAA,CAItCD,CAAAA,CAAS,QACZC,CAAAA,CAAO,IAAA,CAAK,uCAAuC,CAAA,CAIjDD,CAAAA,CAAS,aAAA,GAAkB,MAAA,EAC7BC,CAAAA,CAAO,IAAA,CAAK,qCAAqC,CAAA,CAInD,IAAMC,CAAAA,CAAoB,IAAA,CAAK,GAAA,EAAI,CAAK,IAAU,EAAA,CAAK,EAAA,CAAK,EAAA,CAAK,GAAA,CACjE,OAAIF,CAAAA,CAAS,SAAA,CAAYE,CAAAA,EACvBD,CAAAA,CAAO,IAAA,CAAK,yDAAyD,CAAA,CAGhE,CACL,KAAA,CAAOA,CAAAA,CAAO,MAAA,GAAW,EACzB,MAAA,CAAAA,CACF,CACF,CASO,SAASE,CAAAA,CAAuBC,CAAAA,CAGrC,CACA,IAAMH,CAAAA,CAAmB,EAAC,CAE1B,OAAA,CAAI,CAACG,CAAAA,EAAWA,CAAAA,CAAQ,SAAW,CAAA,GACjCH,CAAAA,CAAO,IAAA,CAAK,yCAAyC,CAAA,CAGvDG,CAAAA,EAAA,IAAA,EAAAA,CAAAA,CAAS,OAAA,CAASC,CAAAA,EAAW,CAAA,CACvB,CAACA,CAAAA,CAAO,OAAA,EAAWA,CAAAA,CAAO,OAAA,CAAQ,MAAK,GAAM,EAAA,GAC/CJ,CAAAA,CAAO,IAAA,CACL,CAAA,gBAAA,EAAmBI,CAAAA,CAAO,EAAE,CAAA,4FAAA,CAC9B,EAEJ,CAAA,CAAA,CAEO,CACL,KAAA,CAAOJ,CAAAA,CAAO,MAAA,GAAW,CAAA,CACzB,MAAA,CAAAA,CACF,CACF","file":"chunk-Y34DQYS7.js","sourcesContent":["import { ConsentOption, ConsentSettings } from '../types/consent';\n\n/**\n * Validates consent settings to ensure they meet NDPA requirements\n * @param settings The consent settings to validate\n * @returns An object containing validation result and any error messages\n */\nexport function validateConsent(settings: ConsentSettings): { \n valid: boolean; \n errors: string[] \n} {\n const errors: string[] = [];\n \n // Check if consents object exists\n if (!settings.consents || Object.keys(settings.consents).length === 0) {\n errors.push('Consent settings must include at least one consent option');\n }\n \n // Check if timestamp exists and is valid\n if (!settings.timestamp) {\n errors.push('Consent timestamp is required');\n } else if (typeof settings.timestamp !== 'number' || isNaN(settings.timestamp)) {\n errors.push('Consent timestamp must be a valid number');\n }\n \n // Check if version exists\n if (!settings.version) {\n errors.push('Consent version is required');\n }\n \n // Check if method exists\n if (!settings.method) {\n errors.push('Consent collection method is required');\n }\n \n // Check if hasInteracted is defined\n if (settings.hasInteracted === undefined) {\n errors.push('User interaction status is required');\n }\n \n // Check if consent is recent enough (within last 13 months for NDPA compliance)\n const thirteenMonthsAgo = Date.now() - (13 * 30 * 24 * 60 * 60 * 1000);\n if (settings.timestamp < thirteenMonthsAgo) {\n errors.push('Consent is older than 13 months and should be refreshed');\n }\n \n return {\n valid: errors.length === 0,\n errors\n };\n}\n\n/**\n * Validates that consent options meet NDPA Section 26 requirements.\n * Each consent option must specify a purpose for which data will be processed,\n * as consent must be specific and informed per the Nigeria Data Protection Act.\n * @param options The consent options to validate\n * @returns An object containing validation result and any error messages\n */\nexport function validateConsentOptions(options: ConsentOption[]): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n\n if (!options || options.length === 0) {\n errors.push('At least one consent option is required');\n }\n\n options?.forEach((option) => {\n if (!option.purpose || option.purpose.trim() === '') {\n errors.push(\n `Consent option \"${option.id}\" is missing a purpose. NDPA Section 26 requires consent to be specific to a stated purpose.`\n );\n }\n });\n\n return {\n valid: errors.length === 0,\n errors\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkY34DQYS7_js=require('./chunk-Y34DQYS7.js'),react=require('react');function T({options:h,storageOptions:d={},version:f="1.0",onChange:v}){let{storageKey:o="ndpr_consent",storageType:n="localStorage"}=d,[r,g]=react.useState(null),[y,a]=react.useState(true),[k,u]=react.useState(false),[I,p]=react.useState([]);react.useEffect(()=>{let t=null;try{if(n==="localStorage"&&typeof window!="undefined"){let e=localStorage.getItem(o);e&&(t=JSON.parse(e));}else if(n==="sessionStorage"&&typeof window!="undefined"){let e=sessionStorage.getItem(o);e&&(t=JSON.parse(e));}else if(n==="cookie"&&typeof document!="undefined"){let s=document.cookie.split(";").find(i=>i.trim().startsWith(`${o}=`));if(s){let i=s.split("=")[1];t=JSON.parse(decodeURIComponent(i));}}}catch(e){console.error("Error loading consent settings:",e);}if(t){g(t);let{valid:e,errors:s}=chunkY34DQYS7_js.a(t);u(e),p(s),a(!(e&&t.version===f));}else a(true);},[o,n,f]);let O=t=>{try{let e=JSON.stringify(t);if(n==="localStorage"&&typeof window!="undefined")localStorage.setItem(o,e);else if(n==="sessionStorage"&&typeof window!="undefined")sessionStorage.setItem(o,e);else if(n==="cookie"&&typeof document!="undefined"){let{cookieOptions:b={}}=d,{domain:w,path:$="/",expires:E=365,secure:R=!0,sameSite:x="Lax"}=b,m=new Date;m.setDate(m.getDate()+E);let c=`${o}=${encodeURIComponent(e)}; path=${$}; expires=${m.toUTCString()}`;w&&(c+=`; domain=${w}`),R&&(c+="; secure"),c+=`; samesite=${x}`,document.cookie=c;}let{valid:s,errors:i}=chunkY34DQYS7_js.a(t);u(s),p(i),v&&v(t);}catch(e){console.error("Error saving consent settings:",e);}},S=t=>{let e={consents:t,timestamp:Date.now(),version:f,method:"explicit",hasInteracted:true};g(e),O(e),a(false);};return {settings:r,hasConsent:t=>!!(r!=null&&r.consents[t]),updateConsent:S,acceptAll:()=>{let t={};h.forEach(e=>{t[e.id]=true;}),S(t);},rejectAll:()=>{let t={};h.forEach(e=>{t[e.id]=e.required||false;}),S(t);},shouldShowBanner:y,isValid:k,validationErrors:I,resetConsent:()=>{if(n==="localStorage"&&typeof window!="undefined")localStorage.removeItem(o);else if(n==="sessionStorage"&&typeof window!="undefined")sessionStorage.removeItem(o);else if(n==="cookie"&&typeof document!="undefined"){let{cookieOptions:t={}}=d,{domain:e,path:s="/"}=t,i=`${o}=; path=${s}; expires=Thu, 01 Jan 1970 00:00:00 GMT`;e&&(i+=`; domain=${e}`),document.cookie=i;}g(null),a(true),u(false),p([]);}}}exports.a=T;//# sourceMappingURL=chunk-ZU73VG3X.js.map
2
+ //# sourceMappingURL=chunk-ZU73VG3X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/hooks/useConsent.ts"],"names":["useConsent","options","storageOptions","version","onChange","storageKey","storageType","settings","setSettings","useState","shouldShowBanner","setShouldShowBanner","isValid","setIsValid","validationErrors","setValidationErrors","useEffect","savedSettings","savedData","consentCookie","cookie","cookieValue","error","valid","errors","validateConsent","saveSettings","newSettings","settingsString","cookieOptions","domain","path","expires","secure","sameSite","expiryDate","cookieString","updateConsent","consents","optionId","allConsents","option","rejectedConsents"],"mappings":"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","file":"chunk-ZU73VG3X.js","sourcesContent":["import { useState, useEffect } from 'react';\nimport { ConsentOption, ConsentSettings, ConsentStorageOptions } from '../types/consent';\nimport { validateConsent } from '../utils/consent';\n\ninterface UseConsentOptions {\n /**\n * Consent options to present to the user\n */\n options: ConsentOption[];\n \n /**\n * Storage options for consent settings\n */\n storageOptions?: ConsentStorageOptions;\n \n /**\n * Version of the consent form\n * @default \"1.0\"\n */\n version?: string;\n \n /**\n * Callback function called when consent settings change\n */\n onChange?: (settings: ConsentSettings) => void;\n}\n\ninterface UseConsentReturn {\n /**\n * Current consent settings\n */\n settings: ConsentSettings | null;\n \n /**\n * Whether consent has been given for a specific option\n */\n hasConsent: (optionId: string) => boolean;\n \n /**\n * Update consent settings\n */\n updateConsent: (consents: Record<string, boolean>) => void;\n \n /**\n * Accept all consent options\n */\n acceptAll: () => void;\n \n /**\n * Reject all non-required consent options\n */\n rejectAll: () => void;\n \n /**\n * Whether the consent banner should be shown\n */\n shouldShowBanner: boolean;\n \n /**\n * Whether consent settings are valid\n */\n isValid: boolean;\n \n /**\n * Validation errors (if any)\n */\n validationErrors: string[];\n \n /**\n * Reset consent settings (clear from storage)\n */\n resetConsent: () => void;\n}\n\n/**\n * Hook for managing user consent in compliance with NDPA\n */\nexport function useConsent({\n options,\n storageOptions = {},\n version = \"1.0\",\n onChange\n}: UseConsentOptions): UseConsentReturn {\n const {\n storageKey = \"ndpr_consent\",\n storageType = \"localStorage\"\n } = storageOptions;\n \n const [settings, setSettings] = useState<ConsentSettings | null>(null);\n const [shouldShowBanner, setShouldShowBanner] = useState<boolean>(true);\n const [isValid, setIsValid] = useState<boolean>(false);\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n \n // Load consent settings from storage on mount\n useEffect(() => {\n let savedSettings: ConsentSettings | null = null;\n \n try {\n if (storageType === 'localStorage' && typeof window !== 'undefined') {\n const savedData = localStorage.getItem(storageKey);\n if (savedData) {\n savedSettings = JSON.parse(savedData);\n }\n } else if (storageType === 'sessionStorage' && typeof window !== 'undefined') {\n const savedData = sessionStorage.getItem(storageKey);\n if (savedData) {\n savedSettings = 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 savedSettings = JSON.parse(decodeURIComponent(cookieValue));\n }\n }\n } catch (error) {\n console.error('Error loading consent settings:', error);\n }\n \n if (savedSettings) {\n setSettings(savedSettings);\n \n // Validate the saved settings\n const { valid, errors } = validateConsent(savedSettings);\n setIsValid(valid);\n setValidationErrors(errors);\n \n // Only hide banner if settings are valid and for the current version\n setShouldShowBanner(!(valid && savedSettings.version === version));\n } else {\n setShouldShowBanner(true);\n }\n }, [storageKey, storageType, version]);\n \n // Save settings to storage\n const saveSettings = (newSettings: ConsentSettings) => {\n try {\n const settingsString = JSON.stringify(newSettings);\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 { cookieOptions = {} } = storageOptions;\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 // Validate the new settings\n const { valid, errors } = validateConsent(newSettings);\n setIsValid(valid);\n setValidationErrors(errors);\n \n // Call onChange callback if provided\n if (onChange) {\n onChange(newSettings);\n }\n } catch (error) {\n console.error('Error saving consent settings:', error);\n }\n };\n \n // Update consent settings\n const updateConsent = (consents: Record<string, boolean>) => {\n const newSettings: ConsentSettings = {\n consents,\n timestamp: Date.now(),\n version,\n method: 'explicit',\n hasInteracted: true\n };\n \n setSettings(newSettings);\n saveSettings(newSettings);\n setShouldShowBanner(false);\n };\n \n // Accept all consent options\n const acceptAll = () => {\n const allConsents: Record<string, boolean> = {};\n options.forEach(option => {\n allConsents[option.id] = true;\n });\n \n updateConsent(allConsents);\n };\n \n // Reject all non-required consent options\n const rejectAll = () => {\n const rejectedConsents: Record<string, boolean> = {};\n options.forEach(option => {\n rejectedConsents[option.id] = option.required || false;\n });\n \n updateConsent(rejectedConsents);\n };\n \n // Check if consent has been given for a specific option\n const hasConsent = (optionId: string): boolean => {\n return !!settings?.consents[optionId];\n };\n \n // Reset consent settings\n const resetConsent = () => {\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 { cookieOptions = {} } = storageOptions;\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 setSettings(null);\n setShouldShowBanner(true);\n setIsValid(false);\n setValidationErrors([]);\n };\n \n return {\n settings,\n hasConsent,\n updateConsent,\n acceptAll,\n rejectAll,\n shouldShowBanner,\n isValid,\n validationErrors,\n resetConsent\n };\n}\n"]}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Consent types aligned with NDPA 2023 Section 25-26
3
+ * Consent must be freely given, specific, informed, and unambiguous
4
+ */
5
+ /**
6
+ * Represents a consent option that can be presented to users
7
+ */
8
+ interface ConsentOption {
9
+ /** Unique identifier for the consent option */
10
+ id: string;
11
+ /** Display label for the consent option */
12
+ label: string;
13
+ /** Detailed description of what this consent option covers */
14
+ description: string;
15
+ /** Whether this consent option is required (cannot be declined) */
16
+ required: boolean;
17
+ /**
18
+ * The specific purpose for which data will be processed
19
+ * NDPA Section 25(2) requires consent to be specific to each purpose
20
+ */
21
+ purpose: string;
22
+ /**
23
+ * Default state of the consent option
24
+ * @default false
25
+ */
26
+ defaultValue?: boolean;
27
+ /**
28
+ * Categories of personal data covered by this consent option
29
+ */
30
+ dataCategories?: string[];
31
+ }
32
+ /**
33
+ * Represents the user's consent settings
34
+ */
35
+ interface ConsentSettings {
36
+ /** Map of consent option IDs to boolean values indicating consent status */
37
+ consents: Record<string, boolean>;
38
+ /** Timestamp when consent was last updated */
39
+ timestamp: number;
40
+ /** Version of the consent form that was accepted */
41
+ version: string;
42
+ /** Method used to collect consent (e.g., "banner", "settings", "api") */
43
+ method: string;
44
+ /** Whether the user has actively made a choice (as opposed to default settings) */
45
+ hasInteracted: boolean;
46
+ /**
47
+ * The lawful basis under which processing is conducted
48
+ * Required by NDPA Section 25(1)
49
+ */
50
+ lawfulBasis?: LawfulBasisType;
51
+ }
52
+ /**
53
+ * Lawful basis for processing personal data per NDPA Section 25(1)
54
+ */
55
+ type LawfulBasisType = 'consent' | 'contract' | 'legal_obligation' | 'vital_interests' | 'public_interest' | 'legitimate_interests';
56
+ /**
57
+ * Represents the storage mechanism for consent settings
58
+ */
59
+ interface ConsentStorageOptions {
60
+ /**
61
+ * Storage key for consent settings
62
+ * @default "ndpr_consent"
63
+ */
64
+ storageKey?: string;
65
+ /**
66
+ * Storage type to use
67
+ * @default "localStorage"
68
+ */
69
+ storageType?: 'localStorage' | 'sessionStorage' | 'cookie';
70
+ /**
71
+ * Cookie options (only used when storageType is "cookie")
72
+ */
73
+ cookieOptions?: {
74
+ /** Domain for the cookie */
75
+ domain?: string;
76
+ /**
77
+ * Path for the cookie
78
+ * @default "/"
79
+ */
80
+ path?: string;
81
+ /**
82
+ * Expiration days for the cookie
83
+ * @default 365
84
+ */
85
+ expires?: number;
86
+ /**
87
+ * Whether the cookie should be secure
88
+ * @default true
89
+ */
90
+ secure?: boolean;
91
+ /**
92
+ * SameSite attribute for the cookie
93
+ * @default "Lax"
94
+ */
95
+ sameSite?: 'Strict' | 'Lax' | 'None';
96
+ };
97
+ }
98
+
99
+ export type { ConsentOption as C, LawfulBasisType as L, ConsentSettings as a, ConsentStorageOptions as b };
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Consent types aligned with NDPA 2023 Section 25-26
3
+ * Consent must be freely given, specific, informed, and unambiguous
4
+ */
5
+ /**
6
+ * Represents a consent option that can be presented to users
7
+ */
8
+ interface ConsentOption {
9
+ /** Unique identifier for the consent option */
10
+ id: string;
11
+ /** Display label for the consent option */
12
+ label: string;
13
+ /** Detailed description of what this consent option covers */
14
+ description: string;
15
+ /** Whether this consent option is required (cannot be declined) */
16
+ required: boolean;
17
+ /**
18
+ * The specific purpose for which data will be processed
19
+ * NDPA Section 25(2) requires consent to be specific to each purpose
20
+ */
21
+ purpose: string;
22
+ /**
23
+ * Default state of the consent option
24
+ * @default false
25
+ */
26
+ defaultValue?: boolean;
27
+ /**
28
+ * Categories of personal data covered by this consent option
29
+ */
30
+ dataCategories?: string[];
31
+ }
32
+ /**
33
+ * Represents the user's consent settings
34
+ */
35
+ interface ConsentSettings {
36
+ /** Map of consent option IDs to boolean values indicating consent status */
37
+ consents: Record<string, boolean>;
38
+ /** Timestamp when consent was last updated */
39
+ timestamp: number;
40
+ /** Version of the consent form that was accepted */
41
+ version: string;
42
+ /** Method used to collect consent (e.g., "banner", "settings", "api") */
43
+ method: string;
44
+ /** Whether the user has actively made a choice (as opposed to default settings) */
45
+ hasInteracted: boolean;
46
+ /**
47
+ * The lawful basis under which processing is conducted
48
+ * Required by NDPA Section 25(1)
49
+ */
50
+ lawfulBasis?: LawfulBasisType;
51
+ }
52
+ /**
53
+ * Lawful basis for processing personal data per NDPA Section 25(1)
54
+ */
55
+ type LawfulBasisType = 'consent' | 'contract' | 'legal_obligation' | 'vital_interests' | 'public_interest' | 'legitimate_interests';
56
+ /**
57
+ * Represents the storage mechanism for consent settings
58
+ */
59
+ interface ConsentStorageOptions {
60
+ /**
61
+ * Storage key for consent settings
62
+ * @default "ndpr_consent"
63
+ */
64
+ storageKey?: string;
65
+ /**
66
+ * Storage type to use
67
+ * @default "localStorage"
68
+ */
69
+ storageType?: 'localStorage' | 'sessionStorage' | 'cookie';
70
+ /**
71
+ * Cookie options (only used when storageType is "cookie")
72
+ */
73
+ cookieOptions?: {
74
+ /** Domain for the cookie */
75
+ domain?: string;
76
+ /**
77
+ * Path for the cookie
78
+ * @default "/"
79
+ */
80
+ path?: string;
81
+ /**
82
+ * Expiration days for the cookie
83
+ * @default 365
84
+ */
85
+ expires?: number;
86
+ /**
87
+ * Whether the cookie should be secure
88
+ * @default true
89
+ */
90
+ secure?: boolean;
91
+ /**
92
+ * SameSite attribute for the cookie
93
+ * @default "Lax"
94
+ */
95
+ sameSite?: 'Strict' | 'Lax' | 'None';
96
+ };
97
+ }
98
+
99
+ export type { ConsentOption as C, LawfulBasisType as L, ConsentSettings as a, ConsentStorageOptions as b };
@@ -0,0 +1,24 @@
1
+ import { a as ConsentSettings, C as ConsentOption } from './consent-CmVzqZUk.mjs';
2
+
3
+ /**
4
+ * Validates consent settings to ensure they meet NDPA requirements
5
+ * @param settings The consent settings to validate
6
+ * @returns An object containing validation result and any error messages
7
+ */
8
+ declare function validateConsent(settings: ConsentSettings): {
9
+ valid: boolean;
10
+ errors: string[];
11
+ };
12
+ /**
13
+ * Validates that consent options meet NDPA Section 26 requirements.
14
+ * Each consent option must specify a purpose for which data will be processed,
15
+ * as consent must be specific and informed per the Nigeria Data Protection Act.
16
+ * @param options The consent options to validate
17
+ * @returns An object containing validation result and any error messages
18
+ */
19
+ declare function validateConsentOptions(options: ConsentOption[]): {
20
+ valid: boolean;
21
+ errors: string[];
22
+ };
23
+
24
+ export { validateConsentOptions as a, validateConsent as v };
@@ -0,0 +1,24 @@
1
+ import { a as ConsentSettings, C as ConsentOption } from './consent-CmVzqZUk.js';
2
+
3
+ /**
4
+ * Validates consent settings to ensure they meet NDPA requirements
5
+ * @param settings The consent settings to validate
6
+ * @returns An object containing validation result and any error messages
7
+ */
8
+ declare function validateConsent(settings: ConsentSettings): {
9
+ valid: boolean;
10
+ errors: string[];
11
+ };
12
+ /**
13
+ * Validates that consent options meet NDPA Section 26 requirements.
14
+ * Each consent option must specify a purpose for which data will be processed,
15
+ * as consent must be specific and informed per the Nigeria Data Protection Act.
16
+ * @param options The consent options to validate
17
+ * @returns An object containing validation result and any error messages
18
+ */
19
+ declare function validateConsentOptions(options: ConsentOption[]): {
20
+ valid: boolean;
21
+ errors: string[];
22
+ };
23
+
24
+ export { validateConsentOptions as a, validateConsent as v };