@tantainnovative/ndpr-toolkit 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +14 -10
- package/dist/{breach-D5zJYNph.d.mts → breach-6z0r-KuE.d.mts} +1 -1
- package/dist/{breach-D7NgrdMX.d.ts → breach-BFfnvtRk.d.ts} +1 -1
- package/dist/{breach-BpSBPrdk.d.mts → breach-BtFbDOmV.d.mts} +1 -1
- package/dist/{breach-BpSBPrdk.d.ts → breach-BtFbDOmV.d.ts} +1 -1
- package/dist/breach.d.mts +4 -4
- package/dist/breach.d.ts +4 -4
- package/dist/chunk-3YCV2BA6.js +2 -0
- package/dist/chunk-6GGGTRDZ.mjs +2 -0
- package/dist/core.d.mts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/dpia.js +1 -1
- package/dist/dpia.mjs +1 -1
- package/dist/hooks.d.mts +2 -2
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +1 -1
- package/dist/hooks.mjs +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{useBreach-DRKnexsk.d.mts → useBreach-WrZzJilM.d.mts} +1 -1
- package/dist/{useBreach-DuT0N0K1.d.ts → useBreach-vrh_XMpI.d.ts} +1 -1
- package/package.json +18 -7
- package/dist/breach.js.map +0 -1
- package/dist/breach.mjs.map +0 -1
- package/dist/chunk-2SYNHRP6.mjs.map +0 -1
- package/dist/chunk-2XHD22J7.mjs.map +0 -1
- package/dist/chunk-4A354HL3.js.map +0 -1
- package/dist/chunk-4DKT6IB6.js.map +0 -1
- package/dist/chunk-5ZBO2UPH.js.map +0 -1
- package/dist/chunk-6JFTAYXV.mjs.map +0 -1
- package/dist/chunk-6JVYYLS7.js.map +0 -1
- package/dist/chunk-6SGG6WPA.mjs.map +0 -1
- package/dist/chunk-AQEGDEQM.js.map +0 -1
- package/dist/chunk-C2IJWCZQ.mjs.map +0 -1
- package/dist/chunk-CMZTI7SG.js.map +0 -1
- package/dist/chunk-DB3JH4DS.mjs.map +0 -1
- package/dist/chunk-EWOZKYLY.mjs +0 -2
- package/dist/chunk-EWOZKYLY.mjs.map +0 -1
- package/dist/chunk-FFW7RUAG.mjs.map +0 -1
- package/dist/chunk-FK3CSFLJ.js.map +0 -1
- package/dist/chunk-GIV2OHE6.mjs.map +0 -1
- package/dist/chunk-GMLNWS2N.mjs.map +0 -1
- package/dist/chunk-IQF726GS.js.map +0 -1
- package/dist/chunk-IWUUVRLJ.js.map +0 -1
- package/dist/chunk-JUN6YPLL.mjs.map +0 -1
- package/dist/chunk-L3FKTBGV.js.map +0 -1
- package/dist/chunk-L52PDW6O.mjs.map +0 -1
- package/dist/chunk-LI6WJ3LZ.js.map +0 -1
- package/dist/chunk-LXRXDTPI.js.map +0 -1
- package/dist/chunk-MQFZHA2D.js.map +0 -1
- package/dist/chunk-OITITR6K.mjs.map +0 -1
- package/dist/chunk-PDJGTQMY.mjs.map +0 -1
- package/dist/chunk-PGSA2O5P.mjs.map +0 -1
- package/dist/chunk-PM7CMTMB.js.map +0 -1
- package/dist/chunk-PYEX7DFR.mjs.map +0 -1
- package/dist/chunk-QKK5S54L.mjs.map +0 -1
- package/dist/chunk-RB26MIRI.js.map +0 -1
- package/dist/chunk-RGYK4VAY.mjs.map +0 -1
- package/dist/chunk-RHWW5FDP.js.map +0 -1
- package/dist/chunk-RYZEIDNR.js.map +0 -1
- package/dist/chunk-SLNMKGQ2.mjs.map +0 -1
- package/dist/chunk-SSGJREE3.js.map +0 -1
- package/dist/chunk-SWF3YVE5.js.map +0 -1
- package/dist/chunk-T44JQT2O.mjs.map +0 -1
- package/dist/chunk-TDDAYVKK.js.map +0 -1
- package/dist/chunk-TXBZPCGF.mjs.map +0 -1
- package/dist/chunk-U2CGMEWB.js +0 -2
- package/dist/chunk-U2CGMEWB.js.map +0 -1
- package/dist/chunk-UUWVBENC.js.map +0 -1
- package/dist/chunk-UYP64PV7.mjs.map +0 -1
- package/dist/chunk-VMJBW3EF.mjs.map +0 -1
- package/dist/chunk-WW3X3ELF.js.map +0 -1
- package/dist/chunk-WWT2ZSNU.mjs.map +0 -1
- package/dist/chunk-XMKA6GVK.mjs.map +0 -1
- package/dist/chunk-Y34DQYS7.js.map +0 -1
- package/dist/chunk-ZU73VG3X.js.map +0 -1
- package/dist/consent.js.map +0 -1
- package/dist/consent.mjs.map +0 -1
- package/dist/core.js.map +0 -1
- package/dist/core.mjs.map +0 -1
- package/dist/cross-border.js.map +0 -1
- package/dist/cross-border.mjs.map +0 -1
- package/dist/dpia.js.map +0 -1
- package/dist/dpia.mjs.map +0 -1
- package/dist/dsr.js.map +0 -1
- package/dist/dsr.mjs.map +0 -1
- package/dist/hooks.js.map +0 -1
- package/dist/hooks.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/lawful-basis.js.map +0 -1
- package/dist/lawful-basis.mjs.map +0 -1
- package/dist/policy.js.map +0 -1
- package/dist/policy.mjs.map +0 -1
- package/dist/ropa.js.map +0 -1
- package/dist/ropa.mjs.map +0 -1
- package/dist/unstyled.js.map +0 -1
- package/dist/unstyled.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
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"]}
|
|
@@ -1 +0,0 @@
|
|
|
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"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-WWT2ZSNU.mjs"}
|
|
@@ -1 +0,0 @@
|
|
|
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"]}
|
|
@@ -1 +0,0 @@
|
|
|
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"]}
|
|
@@ -1 +0,0 @@
|
|
|
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"]}
|
package/dist/consent.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"consent.js"}
|
package/dist/consent.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"consent.mjs"}
|
package/dist/core.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"core.js"}
|
package/dist/core.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"core.mjs"}
|
package/dist/cross-border.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"cross-border.js"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"cross-border.mjs"}
|
package/dist/dpia.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"dpia.js"}
|
package/dist/dpia.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"dpia.mjs"}
|
package/dist/dsr.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"dsr.js"}
|
package/dist/dsr.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"dsr.mjs"}
|
package/dist/hooks.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"hooks.js"}
|
package/dist/hooks.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"hooks.mjs"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
|
package/dist/lawful-basis.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"lawful-basis.js"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"lawful-basis.mjs"}
|
package/dist/policy.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"policy.js"}
|
package/dist/policy.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"policy.mjs"}
|
package/dist/ropa.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"ropa.js"}
|
package/dist/ropa.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"ropa.mjs"}
|
package/dist/unstyled.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contexts/ConsentContext.tsx","../src/components/consent/unstyled/UnstyledConsentBanner.tsx","../src/components/consent/unstyled/UnstyledConsentSettings.tsx","../src/components/consent/unstyled/UnstyledConsentToggle.tsx"],"names":["ConsentContext","createContext","useConsent","context","useContext","UnstyledConsentBanner","className","children","showBanner","acceptAll","rejectAll","openSettings","React","cookieCategories","UnstyledConsentSettings","showSettings","consentState","updateConsent","savePreferences","closeSettings","handleSave","category","e","UnstyledConsentToggle","label"],"mappings":"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","file":"unstyled.js","sourcesContent":["import React, { createContext, useContext, useState, useCallback, useEffect, ReactNode } from 'react';\n\nexport interface ConsentCategories {\n necessary: boolean;\n analytics: boolean;\n marketing: boolean;\n functional: boolean;\n [key: string]: boolean;\n}\n\nexport interface ConsentState {\n hasUserConsented: boolean;\n consentState: ConsentCategories;\n showBanner: boolean;\n showSettings: boolean;\n}\n\nexport interface ConsentActions {\n acceptAll: () => void;\n rejectAll: () => void;\n savePreferences: (preferences: Partial<ConsentCategories>) => void;\n openSettings: () => void;\n closeSettings: () => void;\n updateConsent: (category: keyof ConsentCategories, value: boolean) => void;\n}\n\nexport interface ConsentContextValue extends ConsentState, ConsentActions {}\n\nconst ConsentContext = createContext<ConsentContextValue | undefined>(undefined);\n\nexport interface ConsentProviderProps {\n children: ReactNode;\n initialConsent?: Partial<ConsentCategories>;\n onConsentChange?: (consent: ConsentCategories) => void;\n storageKey?: string;\n}\n\nconst defaultConsent: ConsentCategories = {\n necessary: true, // Always true\n analytics: false,\n marketing: false,\n functional: false,\n};\n\nexport function ConsentProvider({\n children,\n initialConsent = {},\n onConsentChange,\n storageKey = 'ndpr-consent',\n}: ConsentProviderProps) {\n const [consentState, setConsentState] = useState<ConsentCategories>(() => {\n // Try to load from localStorage\n if (typeof window !== 'undefined') {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n try {\n const parsed = JSON.parse(stored);\n return { ...defaultConsent, ...parsed };\n } catch (e) {\n console.error('Failed to parse consent from localStorage', e);\n }\n }\n }\n return { ...defaultConsent, ...initialConsent };\n });\n\n const [hasUserConsented, setHasUserConsented] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(`${storageKey}-set`) === 'true';\n }\n return false;\n });\n\n const [showBanner, setShowBanner] = useState(!hasUserConsented);\n const [showSettings, setShowSettings] = useState(false);\n\n // Persist consent to localStorage\n useEffect(() => {\n if (typeof window !== 'undefined' && hasUserConsented) {\n localStorage.setItem(storageKey, JSON.stringify(consentState));\n localStorage.setItem(`${storageKey}-set`, 'true');\n }\n }, [consentState, hasUserConsented, storageKey]);\n\n // Notify parent of consent changes\n useEffect(() => {\n if (hasUserConsented && onConsentChange) {\n onConsentChange(consentState);\n }\n }, [consentState, hasUserConsented, onConsentChange]);\n\n const acceptAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: true,\n marketing: true,\n functional: true,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const rejectAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: false,\n marketing: false,\n functional: false,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const savePreferences = useCallback((preferences: Partial<ConsentCategories>) => {\n setConsentState(prev => ({\n ...prev,\n ...preferences,\n necessary: true, // Always keep necessary as true\n }));\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const updateConsent = useCallback((category: keyof ConsentCategories, value: boolean) => {\n if (category === 'necessary') return; // Can't change necessary cookies\n \n setConsentState(prev => ({\n ...prev,\n [category]: value,\n }));\n }, []);\n\n const openSettings = useCallback(() => {\n setShowSettings(true);\n setShowBanner(false);\n }, []);\n\n const closeSettings = useCallback(() => {\n setShowSettings(false);\n }, []);\n\n const value: ConsentContextValue = {\n hasUserConsented,\n consentState,\n showBanner,\n showSettings,\n acceptAll,\n rejectAll,\n savePreferences,\n openSettings,\n closeSettings,\n updateConsent,\n };\n\n return (\n <ConsentContext.Provider value={value}>\n {children}\n </ConsentContext.Provider>\n );\n}\n\nexport function useConsent() {\n const context = useContext(ConsentContext);\n if (!context) {\n throw new Error('useConsent must be used within a ConsentProvider');\n }\n return context;\n}\n\n// Export for external use\nexport { ConsentContext };","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentBannerProps {\n className?: string;\n children?: ReactNode;\n}\n\nexport const UnstyledConsentBanner: React.FC<UnstyledConsentBannerProps> = ({\n className,\n children,\n}) => {\n const { showBanner, acceptAll, rejectAll, openSettings } = useConsent();\n\n if (!showBanner) return null;\n\n return (\n <div className={className} role=\"region\" aria-label=\"Cookie consent\">\n {children || (\n <>\n <div>\n <h3>Cookie Consent</h3>\n <p>We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.</p>\n </div>\n <div>\n <button onClick={acceptAll} aria-label=\"Accept all cookies\">\n Accept All\n </button>\n <button onClick={rejectAll} aria-label=\"Reject non-essential cookies\">\n Reject All\n </button>\n <button onClick={openSettings} aria-label=\"Manage cookie preferences\">\n Manage Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentSettingsProps {\n className?: string;\n children?: ReactNode;\n}\n\nconst cookieCategories = [\n {\n id: 'necessary',\n name: 'Necessary Cookies',\n description: 'These cookies are essential for the website to function properly.',\n disabled: true,\n },\n {\n id: 'analytics',\n name: 'Analytics Cookies',\n description: 'These cookies help us understand how visitors interact with our website.',\n disabled: false,\n },\n {\n id: 'marketing',\n name: 'Marketing Cookies',\n description: 'These cookies are used to track visitors across websites for marketing purposes.',\n disabled: false,\n },\n {\n id: 'functional',\n name: 'Functional Cookies',\n description: 'These cookies enable personalized features and functionality.',\n disabled: false,\n },\n];\n\nexport const UnstyledConsentSettings: React.FC<UnstyledConsentSettingsProps> = ({\n className,\n children,\n}) => {\n const { showSettings, consentState, updateConsent, savePreferences, closeSettings } = useConsent();\n\n if (!showSettings) return null;\n\n const handleSave = () => {\n savePreferences(consentState);\n };\n\n return (\n <div className={className} role=\"dialog\" aria-label=\"Cookie preferences\">\n {children || (\n <>\n <div>\n <h2>Cookie Preferences</h2>\n <p>Manage your cookie preferences. You can enable or disable different categories of cookies below.</p>\n </div>\n \n <div>\n {cookieCategories.map((category) => (\n <div key={category.id}>\n <div>\n <h4>{category.name}</h4>\n <p>{category.description}</p>\n </div>\n <input\n type=\"checkbox\"\n checked={consentState[category.id as keyof typeof consentState]}\n onChange={(e) => updateConsent(category.id as keyof typeof consentState, e.target.checked)}\n disabled={category.disabled}\n aria-label={`Toggle ${category.name}`}\n />\n </div>\n ))}\n </div>\n\n <div>\n <button onClick={closeSettings} aria-label=\"Cancel changes\">\n Cancel\n </button>\n <button onClick={handleSave} aria-label=\"Save cookie preferences\">\n Save Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentToggleProps {\n category: 'analytics' | 'marketing' | 'functional';\n className?: string;\n label?: string;\n}\n\nexport const UnstyledConsentToggle: React.FC<UnstyledConsentToggleProps> = ({\n category,\n className,\n label,\n}) => {\n const { consentState, updateConsent } = useConsent();\n\n return (\n <label className={className}>\n <input\n type=\"checkbox\"\n checked={consentState[category]}\n onChange={(e) => updateConsent(category, e.target.checked)}\n aria-label={label || `Toggle ${category} cookies`}\n />\n {label && <span>{label}</span>}\n </label>\n );\n};"]}
|
package/dist/unstyled.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contexts/ConsentContext.tsx","../src/components/consent/unstyled/UnstyledConsentBanner.tsx","../src/components/consent/unstyled/UnstyledConsentSettings.tsx","../src/components/consent/unstyled/UnstyledConsentToggle.tsx"],"names":["ConsentContext","createContext","useConsent","context","useContext","UnstyledConsentBanner","className","children","showBanner","acceptAll","rejectAll","openSettings","React","cookieCategories","UnstyledConsentSettings","showSettings","consentState","updateConsent","savePreferences","closeSettings","handleSave","category","e","UnstyledConsentToggle","label"],"mappings":"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","file":"unstyled.mjs","sourcesContent":["import React, { createContext, useContext, useState, useCallback, useEffect, ReactNode } from 'react';\n\nexport interface ConsentCategories {\n necessary: boolean;\n analytics: boolean;\n marketing: boolean;\n functional: boolean;\n [key: string]: boolean;\n}\n\nexport interface ConsentState {\n hasUserConsented: boolean;\n consentState: ConsentCategories;\n showBanner: boolean;\n showSettings: boolean;\n}\n\nexport interface ConsentActions {\n acceptAll: () => void;\n rejectAll: () => void;\n savePreferences: (preferences: Partial<ConsentCategories>) => void;\n openSettings: () => void;\n closeSettings: () => void;\n updateConsent: (category: keyof ConsentCategories, value: boolean) => void;\n}\n\nexport interface ConsentContextValue extends ConsentState, ConsentActions {}\n\nconst ConsentContext = createContext<ConsentContextValue | undefined>(undefined);\n\nexport interface ConsentProviderProps {\n children: ReactNode;\n initialConsent?: Partial<ConsentCategories>;\n onConsentChange?: (consent: ConsentCategories) => void;\n storageKey?: string;\n}\n\nconst defaultConsent: ConsentCategories = {\n necessary: true, // Always true\n analytics: false,\n marketing: false,\n functional: false,\n};\n\nexport function ConsentProvider({\n children,\n initialConsent = {},\n onConsentChange,\n storageKey = 'ndpr-consent',\n}: ConsentProviderProps) {\n const [consentState, setConsentState] = useState<ConsentCategories>(() => {\n // Try to load from localStorage\n if (typeof window !== 'undefined') {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n try {\n const parsed = JSON.parse(stored);\n return { ...defaultConsent, ...parsed };\n } catch (e) {\n console.error('Failed to parse consent from localStorage', e);\n }\n }\n }\n return { ...defaultConsent, ...initialConsent };\n });\n\n const [hasUserConsented, setHasUserConsented] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(`${storageKey}-set`) === 'true';\n }\n return false;\n });\n\n const [showBanner, setShowBanner] = useState(!hasUserConsented);\n const [showSettings, setShowSettings] = useState(false);\n\n // Persist consent to localStorage\n useEffect(() => {\n if (typeof window !== 'undefined' && hasUserConsented) {\n localStorage.setItem(storageKey, JSON.stringify(consentState));\n localStorage.setItem(`${storageKey}-set`, 'true');\n }\n }, [consentState, hasUserConsented, storageKey]);\n\n // Notify parent of consent changes\n useEffect(() => {\n if (hasUserConsented && onConsentChange) {\n onConsentChange(consentState);\n }\n }, [consentState, hasUserConsented, onConsentChange]);\n\n const acceptAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: true,\n marketing: true,\n functional: true,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const rejectAll = useCallback(() => {\n const newConsent: ConsentCategories = {\n necessary: true,\n analytics: false,\n marketing: false,\n functional: false,\n };\n setConsentState(newConsent);\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const savePreferences = useCallback((preferences: Partial<ConsentCategories>) => {\n setConsentState(prev => ({\n ...prev,\n ...preferences,\n necessary: true, // Always keep necessary as true\n }));\n setHasUserConsented(true);\n setShowBanner(false);\n setShowSettings(false);\n }, []);\n\n const updateConsent = useCallback((category: keyof ConsentCategories, value: boolean) => {\n if (category === 'necessary') return; // Can't change necessary cookies\n \n setConsentState(prev => ({\n ...prev,\n [category]: value,\n }));\n }, []);\n\n const openSettings = useCallback(() => {\n setShowSettings(true);\n setShowBanner(false);\n }, []);\n\n const closeSettings = useCallback(() => {\n setShowSettings(false);\n }, []);\n\n const value: ConsentContextValue = {\n hasUserConsented,\n consentState,\n showBanner,\n showSettings,\n acceptAll,\n rejectAll,\n savePreferences,\n openSettings,\n closeSettings,\n updateConsent,\n };\n\n return (\n <ConsentContext.Provider value={value}>\n {children}\n </ConsentContext.Provider>\n );\n}\n\nexport function useConsent() {\n const context = useContext(ConsentContext);\n if (!context) {\n throw new Error('useConsent must be used within a ConsentProvider');\n }\n return context;\n}\n\n// Export for external use\nexport { ConsentContext };","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentBannerProps {\n className?: string;\n children?: ReactNode;\n}\n\nexport const UnstyledConsentBanner: React.FC<UnstyledConsentBannerProps> = ({\n className,\n children,\n}) => {\n const { showBanner, acceptAll, rejectAll, openSettings } = useConsent();\n\n if (!showBanner) return null;\n\n return (\n <div className={className} role=\"region\" aria-label=\"Cookie consent\">\n {children || (\n <>\n <div>\n <h3>Cookie Consent</h3>\n <p>We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.</p>\n </div>\n <div>\n <button onClick={acceptAll} aria-label=\"Accept all cookies\">\n Accept All\n </button>\n <button onClick={rejectAll} aria-label=\"Reject non-essential cookies\">\n Reject All\n </button>\n <button onClick={openSettings} aria-label=\"Manage cookie preferences\">\n Manage Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React, { ReactNode } from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentSettingsProps {\n className?: string;\n children?: ReactNode;\n}\n\nconst cookieCategories = [\n {\n id: 'necessary',\n name: 'Necessary Cookies',\n description: 'These cookies are essential for the website to function properly.',\n disabled: true,\n },\n {\n id: 'analytics',\n name: 'Analytics Cookies',\n description: 'These cookies help us understand how visitors interact with our website.',\n disabled: false,\n },\n {\n id: 'marketing',\n name: 'Marketing Cookies',\n description: 'These cookies are used to track visitors across websites for marketing purposes.',\n disabled: false,\n },\n {\n id: 'functional',\n name: 'Functional Cookies',\n description: 'These cookies enable personalized features and functionality.',\n disabled: false,\n },\n];\n\nexport const UnstyledConsentSettings: React.FC<UnstyledConsentSettingsProps> = ({\n className,\n children,\n}) => {\n const { showSettings, consentState, updateConsent, savePreferences, closeSettings } = useConsent();\n\n if (!showSettings) return null;\n\n const handleSave = () => {\n savePreferences(consentState);\n };\n\n return (\n <div className={className} role=\"dialog\" aria-label=\"Cookie preferences\">\n {children || (\n <>\n <div>\n <h2>Cookie Preferences</h2>\n <p>Manage your cookie preferences. You can enable or disable different categories of cookies below.</p>\n </div>\n \n <div>\n {cookieCategories.map((category) => (\n <div key={category.id}>\n <div>\n <h4>{category.name}</h4>\n <p>{category.description}</p>\n </div>\n <input\n type=\"checkbox\"\n checked={consentState[category.id as keyof typeof consentState]}\n onChange={(e) => updateConsent(category.id as keyof typeof consentState, e.target.checked)}\n disabled={category.disabled}\n aria-label={`Toggle ${category.name}`}\n />\n </div>\n ))}\n </div>\n\n <div>\n <button onClick={closeSettings} aria-label=\"Cancel changes\">\n Cancel\n </button>\n <button onClick={handleSave} aria-label=\"Save cookie preferences\">\n Save Preferences\n </button>\n </div>\n </>\n )}\n </div>\n );\n};","import React from 'react';\nimport { useConsent } from '@/contexts/ConsentContext';\n\nexport interface UnstyledConsentToggleProps {\n category: 'analytics' | 'marketing' | 'functional';\n className?: string;\n label?: string;\n}\n\nexport const UnstyledConsentToggle: React.FC<UnstyledConsentToggleProps> = ({\n category,\n className,\n label,\n}) => {\n const { consentState, updateConsent } = useConsent();\n\n return (\n <label className={className}>\n <input\n type=\"checkbox\"\n checked={consentState[category]}\n onChange={(e) => updateConsent(category, e.target.checked)}\n aria-label={label || `Toggle ${category} cookies`}\n />\n {label && <span>{label}</span>}\n </label>\n );\n};"]}
|