@tantainnovative/ndpr-toolkit 1.0.2 → 1.0.3
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/.claude/settings.local.json +20 -0
- package/.eslintrc.json +10 -0
- package/.github/workflows/ci.yml +36 -0
- package/.github/workflows/nextjs.yml +104 -0
- package/.husky/commit-msg +4 -0
- package/.husky/pre-commit +4 -0
- package/.lintstagedrc.js +4 -0
- package/.nvmrc +1 -0
- package/.versionrc +17 -0
- package/CHANGELOG.md +16 -0
- package/CLAUDE.md +90 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +87 -0
- package/README.md +84 -447
- package/RELEASE-NOTES-v1.0.0.md +140 -0
- package/RELEASE-NOTES-v1.0.1.md +69 -0
- package/SECURITY.md +21 -0
- package/commitlint.config.js +36 -0
- package/components.json +21 -0
- package/eslint.config.mjs +16 -0
- package/jest.config.js +31 -0
- package/jest.setup.js +15 -0
- package/next.config.js +15 -0
- package/next.config.ts +62 -0
- package/package.json +70 -52
- package/packages/ndpr-toolkit/README.md +467 -0
- package/packages/ndpr-toolkit/jest.config.js +23 -0
- package/packages/ndpr-toolkit/package-lock.json +8197 -0
- package/packages/ndpr-toolkit/package.json +71 -0
- package/packages/ndpr-toolkit/rollup.config.js +34 -0
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +119 -0
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +122 -0
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +270 -0
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +199 -0
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +224 -0
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +104 -0
- package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +161 -0
- package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +330 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +149 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +88 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +160 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +110 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +97 -0
- package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +701 -0
- package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +631 -0
- package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +569 -0
- package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +496 -0
- package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +270 -0
- package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +217 -0
- package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +206 -0
- package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +342 -0
- package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +373 -0
- package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +174 -0
- package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +717 -0
- package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +476 -0
- package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +620 -0
- package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +541 -0
- package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +454 -0
- package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +333 -0
- package/packages/ndpr-toolkit/src/hooks/useBreach.ts +409 -0
- package/packages/ndpr-toolkit/src/hooks/useConsent.ts +263 -0
- package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +457 -0
- package/packages/ndpr-toolkit/src/hooks/useDSR.ts +236 -0
- package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +428 -0
- package/{dist/index.d.ts → packages/ndpr-toolkit/src/index.ts} +13 -0
- package/packages/ndpr-toolkit/src/setupTests.ts +5 -0
- package/packages/ndpr-toolkit/src/types/breach.ts +283 -0
- package/packages/ndpr-toolkit/src/types/consent.ts +111 -0
- package/packages/ndpr-toolkit/src/types/dpia.ts +236 -0
- package/packages/ndpr-toolkit/src/types/dsr.ts +192 -0
- package/packages/ndpr-toolkit/src/types/index.ts +42 -0
- package/packages/ndpr-toolkit/src/types/privacy.ts +246 -0
- package/packages/ndpr-toolkit/src/utils/breach.ts +122 -0
- package/packages/ndpr-toolkit/src/utils/consent.ts +51 -0
- package/packages/ndpr-toolkit/src/utils/dpia.ts +104 -0
- package/packages/ndpr-toolkit/src/utils/dsr.ts +77 -0
- package/packages/ndpr-toolkit/src/utils/privacy.ts +100 -0
- package/packages/ndpr-toolkit/tsconfig.json +23 -0
- package/postcss.config.mjs +5 -0
- package/public/NDPR TOOLKIT.svg +1 -0
- package/public/favicon/android-chrome-192x192.png +0 -0
- package/public/favicon/android-chrome-512x512.png +0 -0
- package/public/favicon/apple-touch-icon.png +0 -0
- package/public/favicon/favicon-16x16.png +0 -0
- package/public/favicon/favicon-32x32.png +0 -0
- package/public/favicon/site.webmanifest +1 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/ndpr-toolkit-logo.svg +108 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/src/__tests__/example.test.ts +13 -0
- package/src/__tests__/requestService.test.ts +57 -0
- package/src/app/accessibility.css +70 -0
- package/src/app/docs/components/DocLayout.tsx +267 -0
- package/src/app/docs/components/breach-notification/page.tsx +797 -0
- package/src/app/docs/components/consent-management/page.tsx +576 -0
- package/src/app/docs/components/data-subject-rights/page.tsx +511 -0
- package/src/app/docs/components/dpia-questionnaire/layout.tsx +15 -0
- package/src/app/docs/components/dpia-questionnaire/metadata.ts +31 -0
- package/src/app/docs/components/dpia-questionnaire/page.tsx +666 -0
- package/src/app/docs/components/hooks/page.tsx +305 -0
- package/src/app/docs/components/page.tsx +84 -0
- package/src/app/docs/components/privacy-policy-generator/page.tsx +634 -0
- package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +123 -0
- package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +328 -0
- package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +28 -0
- package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +91 -0
- package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +118 -0
- package/src/app/docs/guides/breach-notification-process/page.tsx +39 -0
- package/src/app/docs/guides/conducting-dpia/page.tsx +593 -0
- package/src/app/docs/guides/data-subject-requests/page.tsx +666 -0
- package/src/app/docs/guides/managing-consent/page.tsx +738 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +296 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +145 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +33 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +99 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +159 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +38 -0
- package/src/app/docs/guides/page.tsx +67 -0
- package/src/app/docs/layout.tsx +15 -0
- package/src/app/docs/metadata.ts +31 -0
- package/src/app/docs/page.tsx +572 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +123 -0
- package/src/app/layout.tsx +37 -0
- package/src/app/ndpr-demos/breach/page.tsx +354 -0
- package/src/app/ndpr-demos/consent/page.tsx +366 -0
- package/src/app/ndpr-demos/dpia/page.tsx +495 -0
- package/src/app/ndpr-demos/dsr/page.tsx +280 -0
- package/src/app/ndpr-demos/page.tsx +73 -0
- package/src/app/ndpr-demos/policy/page.tsx +771 -0
- package/src/app/page.tsx +452 -0
- package/src/components/ErrorBoundary.tsx +90 -0
- package/src/components/breach-notification/BreachNotificationForm.tsx +479 -0
- package/src/components/consent/ConsentBanner.tsx +159 -0
- package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +419 -0
- package/src/components/docs/DocLayout.tsx +289 -0
- package/src/components/docs/index.ts +2 -0
- package/src/components/dpia/DPIAQuestionnaire.tsx +483 -0
- package/src/components/privacy-policy/PolicyGenerator.tsx +1062 -0
- package/src/components/privacy-policy/data.ts +98 -0
- package/src/components/privacy-policy/shared/CheckboxField.tsx +38 -0
- package/src/components/privacy-policy/shared/CheckboxGroup.tsx +85 -0
- package/src/components/privacy-policy/shared/FormField.tsx +79 -0
- package/src/components/privacy-policy/shared/StepIndicator.tsx +86 -0
- package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +335 -0
- package/src/components/privacy-policy/steps/DataCollectionStep.tsx +231 -0
- package/src/components/privacy-policy/steps/DataSharingStep.tsx +418 -0
- package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +202 -0
- package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +172 -0
- package/src/components/ui/Badge.tsx +46 -0
- package/src/components/ui/Button.tsx +59 -0
- package/src/components/ui/Card.tsx +92 -0
- package/src/components/ui/Checkbox.tsx +57 -0
- package/src/components/ui/FormField.tsx +50 -0
- package/src/components/ui/Input.tsx +38 -0
- package/src/components/ui/Loading.tsx +201 -0
- package/src/components/ui/Select.tsx +42 -0
- package/src/components/ui/TextArea.tsx +38 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/hooks/useConsent.ts +64 -0
- package/src/hooks/useLoadingState.ts +85 -0
- package/src/lib/consentService.ts +137 -0
- package/src/lib/dpiaQuestions.ts +148 -0
- package/src/lib/requestService.ts +75 -0
- package/src/lib/sanitize.ts +108 -0
- package/src/lib/storage.ts +222 -0
- package/src/lib/utils.ts +6 -0
- package/src/types/html-to-docx.d.ts +30 -0
- package/src/types/index.ts +72 -0
- package/tailwind.config.ts +65 -0
- package/tsconfig.json +41 -0
- package/dist/components/breach/BreachNotificationManager.d.ts +0 -62
- package/dist/components/breach/BreachReportForm.d.ts +0 -66
- package/dist/components/breach/BreachRiskAssessment.d.ts +0 -50
- package/dist/components/breach/RegulatoryReportGenerator.d.ts +0 -94
- package/dist/components/consent/ConsentBanner.d.ts +0 -79
- package/dist/components/consent/ConsentManager.d.ts +0 -73
- package/dist/components/consent/ConsentStorage.d.ts +0 -41
- package/dist/components/dpia/DPIAQuestionnaire.d.ts +0 -70
- package/dist/components/dpia/DPIAReport.d.ts +0 -40
- package/dist/components/dpia/StepIndicator.d.ts +0 -64
- package/dist/components/dsr/DSRDashboard.d.ts +0 -58
- package/dist/components/dsr/DSRRequestForm.d.ts +0 -74
- package/dist/components/dsr/DSRTracker.d.ts +0 -56
- package/dist/components/policy/PolicyExporter.d.ts +0 -65
- package/dist/components/policy/PolicyGenerator.d.ts +0 -54
- package/dist/components/policy/PolicyPreview.d.ts +0 -71
- package/dist/hooks/useBreach.d.ts +0 -97
- package/dist/hooks/useConsent.d.ts +0 -63
- package/dist/hooks/useDPIA.d.ts +0 -92
- package/dist/hooks/useDSR.d.ts +0 -72
- package/dist/hooks/usePrivacyPolicy.d.ts +0 -87
- package/dist/index.esm.js +0 -2
- package/dist/index.esm.js.map +0 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -1
- package/dist/setupTests.d.ts +0 -2
- package/dist/types/breach.d.ts +0 -239
- package/dist/types/consent.d.ts +0 -95
- package/dist/types/dpia.d.ts +0 -196
- package/dist/types/dsr.d.ts +0 -162
- package/dist/types/privacy.d.ts +0 -204
- package/dist/utils/breach.d.ts +0 -14
- package/dist/utils/consent.d.ts +0 -10
- package/dist/utils/dpia.d.ts +0 -12
- package/dist/utils/dsr.d.ts +0 -11
- package/dist/utils/privacy.d.ts +0 -12
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
import { DocLayout } from '../DocLayout';
|
|
5
|
+
import { Button } from '@/components/ui/Button';
|
|
6
|
+
import { Card, CardContent } from '@/components/ui/Card';
|
|
7
|
+
|
|
8
|
+
export default function DataSubjectRightsDocs() {
|
|
9
|
+
return (
|
|
10
|
+
<DocLayout
|
|
11
|
+
title="Data Subject Rights Portal"
|
|
12
|
+
description="NDPR-compliant portal for managing data subject rights requests"
|
|
13
|
+
>
|
|
14
|
+
<div className="flex mb-6 space-x-2">
|
|
15
|
+
<Button asChild variant="outline" size="sm">
|
|
16
|
+
<Link href="/demo/data-subject-rights">
|
|
17
|
+
View Demo
|
|
18
|
+
</Link>
|
|
19
|
+
</Button>
|
|
20
|
+
<Button asChild variant="outline" size="sm">
|
|
21
|
+
<a href="https://github.com/tantainnovative/ndpr-toolkit/tree/main/src/components/data-subject-rights" target="_blank" rel="noopener noreferrer">
|
|
22
|
+
View Source
|
|
23
|
+
</a>
|
|
24
|
+
</Button>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<section id="overview" className="mb-8">
|
|
28
|
+
<h2 className="text-2xl font-bold mb-4">Overview</h2>
|
|
29
|
+
<p className="mb-4">
|
|
30
|
+
The Data Subject Rights Portal provides a complete solution for handling data subject access requests (DSARs)
|
|
31
|
+
and other rights requests in compliance with the Nigeria Data Protection Regulation (NDPR). It includes a request
|
|
32
|
+
submission form, admin dashboard for managing requests, and a tracking system for data subjects.
|
|
33
|
+
</p>
|
|
34
|
+
<div className="bg-blue-50 dark:bg-blue-900/20 p-4 rounded-md">
|
|
35
|
+
<h4 className="text-blue-800 dark:text-blue-200 font-medium mb-2">NDPR Data Subject Rights</h4>
|
|
36
|
+
<p className="text-blue-700 dark:text-blue-300 text-sm mb-0">
|
|
37
|
+
Under the NDPR, data subjects have several rights, including the right to access their personal data,
|
|
38
|
+
right to rectification, right to erasure, right to restrict processing, right to data portability, and
|
|
39
|
+
right to object to processing. Organizations must respond to these requests within 30 days.
|
|
40
|
+
</p>
|
|
41
|
+
</div>
|
|
42
|
+
</section>
|
|
43
|
+
|
|
44
|
+
<section id="installation" className="mb-8">
|
|
45
|
+
<h2 className="text-2xl font-bold mb-4">Installation</h2>
|
|
46
|
+
<p className="mb-4">
|
|
47
|
+
Install the NDPR Toolkit package which includes the Data Subject Rights components:
|
|
48
|
+
</p>
|
|
49
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto mb-4">
|
|
50
|
+
<pre><code>npm install @tantainnovative/ndpr-toolkit</code></pre>
|
|
51
|
+
</div>
|
|
52
|
+
<p>
|
|
53
|
+
Or if you're using yarn:
|
|
54
|
+
</p>
|
|
55
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
56
|
+
<pre><code>yarn add @tantainnovative/ndpr-toolkit</code></pre>
|
|
57
|
+
</div>
|
|
58
|
+
</section>
|
|
59
|
+
|
|
60
|
+
<section id="components" className="mb-8">
|
|
61
|
+
<h2 className="text-2xl font-bold mb-4">Components</h2>
|
|
62
|
+
<p className="mb-4">
|
|
63
|
+
The Data Subject Rights system includes several components that work together:
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<div className="space-y-6">
|
|
67
|
+
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
|
68
|
+
<h3 className="text-xl font-bold mb-2">DSRRequestForm</h3>
|
|
69
|
+
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
|
70
|
+
A form for data subjects to submit rights requests, with support for different request types.
|
|
71
|
+
</p>
|
|
72
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
73
|
+
<pre><code>{`import { DSRRequestForm, DSRType } from '@tantainnovative/ndpr-toolkit';
|
|
74
|
+
|
|
75
|
+
<DSRRequestForm
|
|
76
|
+
onSubmit={handleSubmitRequest}
|
|
77
|
+
requestTypes={[
|
|
78
|
+
{ id: 'access', label: 'Access my data' },
|
|
79
|
+
{ id: 'rectification', label: 'Correct my data' },
|
|
80
|
+
{ id: 'erasure', label: 'Delete my data' },
|
|
81
|
+
{ id: 'restriction', label: 'Restrict processing of my data' },
|
|
82
|
+
{ id: 'portability', label: 'Data portability' },
|
|
83
|
+
{ id: 'objection', label: 'Object to processing' }
|
|
84
|
+
]}
|
|
85
|
+
/>`}</code></pre>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
|
90
|
+
<h3 className="text-xl font-bold mb-2">DSRDashboard</h3>
|
|
91
|
+
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
|
92
|
+
An admin dashboard for managing and responding to data subject rights requests.
|
|
93
|
+
</p>
|
|
94
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
95
|
+
<pre><code>{`import { DSRDashboard } from '@tantainnovative/ndpr-toolkit';
|
|
96
|
+
|
|
97
|
+
<DSRDashboard
|
|
98
|
+
requests={dsrRequests}
|
|
99
|
+
onUpdateRequest={handleUpdateRequest}
|
|
100
|
+
onDeleteRequest={handleDeleteRequest}
|
|
101
|
+
onAssignRequest={handleAssignRequest}
|
|
102
|
+
/>`}</code></pre>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
|
107
|
+
<h3 className="text-xl font-bold mb-2">DSRTracker</h3>
|
|
108
|
+
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
|
109
|
+
A component for data subjects to track the status of their requests.
|
|
110
|
+
</p>
|
|
111
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
112
|
+
<pre><code>{`import { DSRTracker } from '@tantainnovative/ndpr-toolkit';
|
|
113
|
+
|
|
114
|
+
<DSRTracker
|
|
115
|
+
requestId="dsr-123456"
|
|
116
|
+
onLookup={handleLookupRequest}
|
|
117
|
+
/>`}</code></pre>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
|
122
|
+
<h3 className="text-xl font-bold mb-2">BreachReportForm</h3>
|
|
123
|
+
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
|
124
|
+
A form for reporting data breaches, which is a requirement under the NDPR.
|
|
125
|
+
</p>
|
|
126
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
127
|
+
<pre><code>{`import { BreachReportForm } from '@tantainnovative/ndpr-toolkit';
|
|
128
|
+
|
|
129
|
+
<BreachReportForm
|
|
130
|
+
onSubmit={handleSubmitBreachReport}
|
|
131
|
+
formDescription="Report a data breach that has occurred within your organization."
|
|
132
|
+
recipientEmail="dpo@example.com"
|
|
133
|
+
/>`}</code></pre>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</section>
|
|
138
|
+
|
|
139
|
+
<section id="usage" className="mb-8">
|
|
140
|
+
<h2 className="text-2xl font-bold mb-4">Usage</h2>
|
|
141
|
+
<p className="mb-4">
|
|
142
|
+
Here's a complete example of how to implement the Data Subject Rights system in your application:
|
|
143
|
+
</p>
|
|
144
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
145
|
+
<pre><code>{`import { useState, useEffect } from 'react';
|
|
146
|
+
import {
|
|
147
|
+
DSRRequestForm,
|
|
148
|
+
DSRDashboard,
|
|
149
|
+
DSRTracker,
|
|
150
|
+
useDSR,
|
|
151
|
+
DSRType,
|
|
152
|
+
DSRStatus
|
|
153
|
+
} from '@tantainnovative/ndpr-toolkit';
|
|
154
|
+
|
|
155
|
+
// Define your request types
|
|
156
|
+
const requestTypes = [
|
|
157
|
+
{ id: 'access', label: 'Access my data' },
|
|
158
|
+
{ id: 'rectification', label: 'Correct my data' },
|
|
159
|
+
{ id: 'erasure', label: 'Delete my data' },
|
|
160
|
+
{ id: 'restriction', label: 'Restrict processing of my data' },
|
|
161
|
+
{ id: 'portability', label: 'Data portability' },
|
|
162
|
+
{ id: 'objection', label: 'Object to processing' }
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
function DSRPortal() {
|
|
166
|
+
const [activeTab, setActiveTab] = useState('submit');
|
|
167
|
+
const [trackingId, setTrackingId] = useState('');
|
|
168
|
+
|
|
169
|
+
const {
|
|
170
|
+
requests,
|
|
171
|
+
submitRequest,
|
|
172
|
+
updateRequest,
|
|
173
|
+
deleteRequest,
|
|
174
|
+
getRequestById
|
|
175
|
+
} = useDSR();
|
|
176
|
+
|
|
177
|
+
const handleSubmitRequest = (request) => {
|
|
178
|
+
const newRequest = submitRequest({
|
|
179
|
+
type: request.type,
|
|
180
|
+
subject: {
|
|
181
|
+
name: request.name,
|
|
182
|
+
email: request.email,
|
|
183
|
+
phone: request.phone
|
|
184
|
+
},
|
|
185
|
+
details: request.details
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Show the tracking ID to the user
|
|
189
|
+
alert(\`Your request has been submitted. Your tracking ID is: \${newRequest.id}\`);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const handleLookupRequest = (id) => {
|
|
193
|
+
const request = getRequestById(id);
|
|
194
|
+
return request;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<div>
|
|
199
|
+
<nav>
|
|
200
|
+
<button onClick={() => setActiveTab('submit')}>Submit Request</button>
|
|
201
|
+
<button onClick={() => setActiveTab('track')}>Track Request</button>
|
|
202
|
+
<button onClick={() => setActiveTab('admin')}>Admin Dashboard</button>
|
|
203
|
+
</nav>
|
|
204
|
+
|
|
205
|
+
{activeTab === 'submit' && (
|
|
206
|
+
<DSRRequestForm
|
|
207
|
+
onSubmit={handleSubmitRequest}
|
|
208
|
+
requestTypes={requestTypes}
|
|
209
|
+
/>
|
|
210
|
+
)}
|
|
211
|
+
|
|
212
|
+
{activeTab === 'track' && (
|
|
213
|
+
<div>
|
|
214
|
+
<h2>Track Your Request</h2>
|
|
215
|
+
<input
|
|
216
|
+
type="text"
|
|
217
|
+
value={trackingId}
|
|
218
|
+
onChange={(e) => setTrackingId(e.target.value)}
|
|
219
|
+
placeholder="Enter your tracking ID"
|
|
220
|
+
/>
|
|
221
|
+
<button onClick={() => setActiveTab('tracking')}>Track</button>
|
|
222
|
+
|
|
223
|
+
{activeTab === 'tracking' && trackingId && (
|
|
224
|
+
<DSRTracker
|
|
225
|
+
requestId={trackingId}
|
|
226
|
+
onLookup={handleLookupRequest}
|
|
227
|
+
/>
|
|
228
|
+
)}
|
|
229
|
+
</div>
|
|
230
|
+
)}
|
|
231
|
+
|
|
232
|
+
{activeTab === 'admin' && (
|
|
233
|
+
<DSRDashboard
|
|
234
|
+
requests={requests}
|
|
235
|
+
onUpdateRequest={updateRequest}
|
|
236
|
+
onDeleteRequest={deleteRequest}
|
|
237
|
+
/>
|
|
238
|
+
)}
|
|
239
|
+
</div>
|
|
240
|
+
);
|
|
241
|
+
}`}</code></pre>
|
|
242
|
+
</div>
|
|
243
|
+
</section>
|
|
244
|
+
|
|
245
|
+
<section id="api" className="mb-8">
|
|
246
|
+
<h2 className="text-2xl font-bold mb-4">API Reference</h2>
|
|
247
|
+
|
|
248
|
+
<h3 className="text-xl font-bold mt-8 mb-4">DSRRequestForm Props</h3>
|
|
249
|
+
<div className="overflow-x-auto">
|
|
250
|
+
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
251
|
+
<thead className="bg-gray-50 dark:bg-gray-800">
|
|
252
|
+
<tr>
|
|
253
|
+
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Prop</th>
|
|
254
|
+
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Type</th>
|
|
255
|
+
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Default</th>
|
|
256
|
+
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Description</th>
|
|
257
|
+
</tr>
|
|
258
|
+
</thead>
|
|
259
|
+
<tbody className="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
|
|
260
|
+
<tr>
|
|
261
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">onSubmit</td>
|
|
262
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{`(request: DSRFormData) => void`}</td>
|
|
263
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">Required</td>
|
|
264
|
+
<td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Callback function when form is submitted</td>
|
|
265
|
+
</tr>
|
|
266
|
+
<tr>
|
|
267
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">requestTypes</td>
|
|
268
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{`Array<{id: string, label: string}>`}</td>
|
|
269
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">Required</td>
|
|
270
|
+
<td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Array of request types to display</td>
|
|
271
|
+
</tr>
|
|
272
|
+
<tr>
|
|
273
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">title</td>
|
|
274
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">string</td>
|
|
275
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">'Submit a Data Subject Rights Request'</td>
|
|
276
|
+
<td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Form title</td>
|
|
277
|
+
</tr>
|
|
278
|
+
<tr>
|
|
279
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">description</td>
|
|
280
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">string</td>
|
|
281
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">'Use this form to submit a request...'</td>
|
|
282
|
+
<td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Form description</td>
|
|
283
|
+
</tr>
|
|
284
|
+
<tr>
|
|
285
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">submitButtonText</td>
|
|
286
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">string</td>
|
|
287
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">'Submit Request'</td>
|
|
288
|
+
<td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Text for the submit button</td>
|
|
289
|
+
</tr>
|
|
290
|
+
</tbody>
|
|
291
|
+
</table>
|
|
292
|
+
</div>
|
|
293
|
+
|
|
294
|
+
<h3 className="text-xl font-bold mt-8 mb-4">useDSR Hook</h3>
|
|
295
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
296
|
+
<pre><code>{`// Import the hook
|
|
297
|
+
import { useDSR } from '@tantainnovative/ndpr-toolkit';
|
|
298
|
+
|
|
299
|
+
// Use the hook in your component
|
|
300
|
+
const {
|
|
301
|
+
requests, // Array of all DSR requests
|
|
302
|
+
submitRequest, // Function to submit a new request
|
|
303
|
+
updateRequest, // Function to update an existing request
|
|
304
|
+
deleteRequest, // Function to delete a request
|
|
305
|
+
getRequestById, // Function to get a request by ID
|
|
306
|
+
filterRequestsByStatus, // Function to filter requests by status
|
|
307
|
+
filterRequestsByType // Function to filter requests by type
|
|
308
|
+
} = useDSR();
|
|
309
|
+
|
|
310
|
+
// Submit a new request
|
|
311
|
+
const newRequest = submitRequest({
|
|
312
|
+
type: 'access',
|
|
313
|
+
subject: {
|
|
314
|
+
name: 'John Doe',
|
|
315
|
+
email: 'john@example.com',
|
|
316
|
+
phone: '1234567890'
|
|
317
|
+
},
|
|
318
|
+
details: 'I would like to access all my personal data.'
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Update a request
|
|
322
|
+
updateRequest('request-id', {
|
|
323
|
+
status: 'inProgress',
|
|
324
|
+
assignedTo: 'data-officer@example.com'
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// Get a request by ID
|
|
328
|
+
const request = getRequestById('request-id');
|
|
329
|
+
|
|
330
|
+
// Filter requests
|
|
331
|
+
const pendingRequests = filterRequestsByStatus('pending');
|
|
332
|
+
const accessRequests = filterRequestsByType('access');`}</code></pre>
|
|
333
|
+
</div>
|
|
334
|
+
|
|
335
|
+
<h3 className="text-xl font-bold mt-8 mb-4">DSRType Enum</h3>
|
|
336
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
337
|
+
<pre><code>{`export type DSRType = 'access' | 'rectification' | 'erasure' | 'restriction' | 'portability' | 'objection';`}</code></pre>
|
|
338
|
+
</div>
|
|
339
|
+
|
|
340
|
+
<h3 className="text-xl font-bold mt-8 mb-4">DSRStatus Enum</h3>
|
|
341
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
342
|
+
<pre><code>{`export type DSRStatus = 'pending' | 'awaitingVerification' | 'inProgress' | 'completed' | 'rejected';`}</code></pre>
|
|
343
|
+
</div>
|
|
344
|
+
|
|
345
|
+
<h3 className="text-xl font-bold mt-8 mb-4">DSRRequest Interface</h3>
|
|
346
|
+
<div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
|
|
347
|
+
<pre><code>{`export interface DSRRequest {
|
|
348
|
+
/**
|
|
349
|
+
* Unique identifier for the request
|
|
350
|
+
*/
|
|
351
|
+
id: string;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Type of request
|
|
355
|
+
*/
|
|
356
|
+
type: DSRType;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Current status of the request
|
|
360
|
+
*/
|
|
361
|
+
status: DSRStatus;
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Timestamp when the request was submitted
|
|
365
|
+
*/
|
|
366
|
+
createdAt: number;
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Timestamp when the request was last updated
|
|
370
|
+
*/
|
|
371
|
+
updatedAt: number;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Timestamp when the request was completed (if applicable)
|
|
375
|
+
*/
|
|
376
|
+
completedAt?: number;
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Timestamp when the identity was verified (if applicable)
|
|
380
|
+
*/
|
|
381
|
+
verifiedAt?: number;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Due date for responding to the request (timestamp)
|
|
385
|
+
*/
|
|
386
|
+
dueDate?: number;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Description or details of the request
|
|
390
|
+
*/
|
|
391
|
+
description?: string;
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Data subject information
|
|
395
|
+
*/
|
|
396
|
+
subject: {
|
|
397
|
+
/**
|
|
398
|
+
* Name of the data subject
|
|
399
|
+
*/
|
|
400
|
+
name: string;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Email address of the data subject
|
|
404
|
+
*/
|
|
405
|
+
email: string;
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Phone number of the data subject (optional)
|
|
409
|
+
*/
|
|
410
|
+
phone?: string;
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Identifier used to verify the data subject's identity (optional)
|
|
414
|
+
*/
|
|
415
|
+
identifierValue?: string;
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Type of identifier used (e.g., "email", "account", "customer_id") (optional)
|
|
419
|
+
*/
|
|
420
|
+
identifierType?: string;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Additional information provided by the data subject
|
|
425
|
+
*/
|
|
426
|
+
additionalInfo?: Record<string, any>;
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Notes added by staff processing the request
|
|
430
|
+
*/
|
|
431
|
+
internalNotes?: Array<{
|
|
432
|
+
timestamp: number;
|
|
433
|
+
author: string;
|
|
434
|
+
note: string;
|
|
435
|
+
}>;
|
|
436
|
+
}`}</code></pre>
|
|
437
|
+
</div>
|
|
438
|
+
</section>
|
|
439
|
+
|
|
440
|
+
<section id="best-practices" className="mb-8">
|
|
441
|
+
<h2 className="text-2xl font-bold mb-4">Best Practices</h2>
|
|
442
|
+
<ul className="list-disc pl-6 space-y-2">
|
|
443
|
+
<li>
|
|
444
|
+
<strong>Verification Process:</strong> Implement a verification process to confirm the identity of the data subject making the request.
|
|
445
|
+
</li>
|
|
446
|
+
<li>
|
|
447
|
+
<strong>Response Timeframe:</strong> The NDPR requires organizations to respond to DSARs within 30 days. Ensure your process allows for timely responses.
|
|
448
|
+
</li>
|
|
449
|
+
<li>
|
|
450
|
+
<strong>Complete Responses:</strong> Provide complete information in response to access requests, including what data you hold, howit's used, whoit's shared with, and its source.
|
|
451
|
+
</li>
|
|
452
|
+
<li>
|
|
453
|
+
<strong>Record Keeping:</strong> Maintain records of all DSARs and your responses to them. The DSRDashboard component helps with this.
|
|
454
|
+
</li>
|
|
455
|
+
<li>
|
|
456
|
+
<strong>Staff Training:</strong> Ensure staff handling DSARs are trained on the requirements of the NDPR and your internal processes.
|
|
457
|
+
</li>
|
|
458
|
+
</ul>
|
|
459
|
+
</section>
|
|
460
|
+
|
|
461
|
+
<section id="accessibility" className="mb-8">
|
|
462
|
+
<h2 className="text-2xl font-bold mb-4">Accessibility</h2>
|
|
463
|
+
<p className="mb-4">
|
|
464
|
+
The Data Subject Rights components are built with accessibility in mind:
|
|
465
|
+
</p>
|
|
466
|
+
<ul className="list-disc pl-6 space-y-2">
|
|
467
|
+
<li>All form elements have proper labels and ARIA attributes</li>
|
|
468
|
+
<li>Focus states are clearly visible</li>
|
|
469
|
+
<li>Color contrast meets WCAG 2.1 AA standards</li>
|
|
470
|
+
<li>Keyboard navigation is fully supported</li>
|
|
471
|
+
<li>Error messages are announced to screen readers</li>
|
|
472
|
+
</ul>
|
|
473
|
+
</section>
|
|
474
|
+
|
|
475
|
+
<section id="help-resources" className="mb-8">
|
|
476
|
+
<h2 className="text-2xl font-bold mb-4">Need Help?</h2>
|
|
477
|
+
<p className="mb-4">
|
|
478
|
+
If you have questions about implementing the Data Subject Rights system or need assistance with NDPR compliance, check out these resources:
|
|
479
|
+
</p>
|
|
480
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
481
|
+
<Card>
|
|
482
|
+
<CardContent className="p-4">
|
|
483
|
+
<h3 className="font-medium text-gray-900 dark:text-white mb-2">GitHub Issues</h3>
|
|
484
|
+
<p className="text-gray-600 dark:text-gray-300 text-sm mb-3">
|
|
485
|
+
Report bugs or request features on our GitHub repository.
|
|
486
|
+
</p>
|
|
487
|
+
<Button asChild variant="outline" size="sm">
|
|
488
|
+
<a href="https://github.com/tantainnovative/ndpr-toolkit/issues" target="_blank" rel="noopener noreferrer">
|
|
489
|
+
View Issues
|
|
490
|
+
</a>
|
|
491
|
+
</Button>
|
|
492
|
+
</CardContent>
|
|
493
|
+
</Card>
|
|
494
|
+
<Card>
|
|
495
|
+
<CardContent className="p-4">
|
|
496
|
+
<h3 className="font-medium text-gray-900 dark:text-white mb-2">NDPR Resources</h3>
|
|
497
|
+
<p className="text-gray-600 dark:text-gray-300 text-sm mb-3">
|
|
498
|
+
Learn more about NDPR compliance requirements.
|
|
499
|
+
</p>
|
|
500
|
+
<Button asChild variant="outline" size="sm">
|
|
501
|
+
<a href="https://nitda.gov.ng/wp-content/uploads/2020/01/NDPR-Implementation-Framework.pdf" target="_blank" rel="noopener noreferrer">
|
|
502
|
+
NDPR Framework
|
|
503
|
+
</a>
|
|
504
|
+
</Button>
|
|
505
|
+
</CardContent>
|
|
506
|
+
</Card>
|
|
507
|
+
</div>
|
|
508
|
+
</section>
|
|
509
|
+
</DocLayout>
|
|
510
|
+
);
|
|
511
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Metadata } from 'next';
|
|
2
|
+
|
|
3
|
+
export const metadata: Metadata = {
|
|
4
|
+
title: 'DPIA Questionnaire Component | NDPR Toolkit Documentation',
|
|
5
|
+
description: 'Learn how to implement an NDPR-compliant Data Protection Impact Assessment (DPIA) questionnaire in your applications using the NDPR Toolkit.',
|
|
6
|
+
keywords: 'DPIA, Data Protection Impact Assessment, NDPR Compliance, Risk Assessment, Privacy Impact',
|
|
7
|
+
openGraph: {
|
|
8
|
+
title: 'DPIA Questionnaire Component | NDPR Toolkit Documentation',
|
|
9
|
+
description: 'Learn how to implement an NDPR-compliant Data Protection Impact Assessment (DPIA) questionnaire in your applications using the NDPR Toolkit.',
|
|
10
|
+
url: 'https://tantainnovatives.com/ndpr-toolkit/docs/components/dpia-questionnaire',
|
|
11
|
+
siteName: 'Tanta Innovative NDPR Toolkit',
|
|
12
|
+
images: [
|
|
13
|
+
{
|
|
14
|
+
url: '/og-dpia-docs.png',
|
|
15
|
+
width: 1200,
|
|
16
|
+
height: 630,
|
|
17
|
+
alt: 'NDPR Toolkit DPIA Component Documentation',
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
locale: 'en_US',
|
|
21
|
+
type: 'website',
|
|
22
|
+
},
|
|
23
|
+
twitter: {
|
|
24
|
+
card: 'summary_large_image',
|
|
25
|
+
title: 'DPIA Questionnaire Component | NDPR Toolkit Documentation',
|
|
26
|
+
description: 'Learn how to implement an NDPR-compliant Data Protection Impact Assessment (DPIA) questionnaire in your applications using the NDPR Toolkit.',
|
|
27
|
+
images: ['/og-dpia-docs.png'],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default metadata;
|