@tantainnovative/ndpr-toolkit 1.0.1 → 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.
Files changed (212) hide show
  1. package/.claude/settings.local.json +20 -0
  2. package/.eslintrc.json +10 -0
  3. package/.github/workflows/ci.yml +36 -0
  4. package/.github/workflows/nextjs.yml +104 -0
  5. package/.husky/commit-msg +4 -0
  6. package/.husky/pre-commit +4 -0
  7. package/.lintstagedrc.js +4 -0
  8. package/.nvmrc +1 -0
  9. package/.versionrc +17 -0
  10. package/CHANGELOG.md +16 -0
  11. package/CLAUDE.md +90 -0
  12. package/CNAME +1 -0
  13. package/CONTRIBUTING.md +87 -0
  14. package/README.md +84 -431
  15. package/RELEASE-NOTES-v1.0.0.md +140 -0
  16. package/RELEASE-NOTES-v1.0.1.md +69 -0
  17. package/SECURITY.md +21 -0
  18. package/commitlint.config.js +36 -0
  19. package/components.json +21 -0
  20. package/eslint.config.mjs +16 -0
  21. package/jest.config.js +31 -0
  22. package/jest.setup.js +15 -0
  23. package/next.config.js +15 -0
  24. package/next.config.ts +62 -0
  25. package/package.json +70 -52
  26. package/packages/ndpr-toolkit/README.md +467 -0
  27. package/packages/ndpr-toolkit/jest.config.js +23 -0
  28. package/packages/ndpr-toolkit/package-lock.json +8197 -0
  29. package/packages/ndpr-toolkit/package.json +71 -0
  30. package/packages/ndpr-toolkit/rollup.config.js +34 -0
  31. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +119 -0
  32. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +122 -0
  33. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +270 -0
  34. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +199 -0
  35. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +224 -0
  36. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +104 -0
  37. package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +161 -0
  38. package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +330 -0
  39. package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +149 -0
  40. package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +88 -0
  41. package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +160 -0
  42. package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +110 -0
  43. package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +97 -0
  44. package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +701 -0
  45. package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +631 -0
  46. package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +569 -0
  47. package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +496 -0
  48. package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +270 -0
  49. package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +217 -0
  50. package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +206 -0
  51. package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +342 -0
  52. package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +373 -0
  53. package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +174 -0
  54. package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +717 -0
  55. package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +476 -0
  56. package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +620 -0
  57. package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +541 -0
  58. package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +454 -0
  59. package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +333 -0
  60. package/packages/ndpr-toolkit/src/hooks/useBreach.ts +409 -0
  61. package/packages/ndpr-toolkit/src/hooks/useConsent.ts +263 -0
  62. package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +457 -0
  63. package/packages/ndpr-toolkit/src/hooks/useDSR.ts +236 -0
  64. package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +428 -0
  65. package/{dist/index.d.ts → packages/ndpr-toolkit/src/index.ts} +14 -1
  66. package/packages/ndpr-toolkit/src/setupTests.ts +5 -0
  67. package/packages/ndpr-toolkit/src/types/breach.ts +283 -0
  68. package/packages/ndpr-toolkit/src/types/consent.ts +111 -0
  69. package/packages/ndpr-toolkit/src/types/dpia.ts +236 -0
  70. package/packages/ndpr-toolkit/src/types/dsr.ts +192 -0
  71. package/packages/ndpr-toolkit/src/types/index.ts +42 -0
  72. package/packages/ndpr-toolkit/src/types/privacy.ts +246 -0
  73. package/packages/ndpr-toolkit/src/utils/breach.ts +122 -0
  74. package/packages/ndpr-toolkit/src/utils/consent.ts +51 -0
  75. package/packages/ndpr-toolkit/src/utils/dpia.ts +104 -0
  76. package/packages/ndpr-toolkit/src/utils/dsr.ts +77 -0
  77. package/packages/ndpr-toolkit/src/utils/privacy.ts +100 -0
  78. package/packages/ndpr-toolkit/tsconfig.json +23 -0
  79. package/postcss.config.mjs +5 -0
  80. package/public/NDPR TOOLKIT.svg +1 -0
  81. package/public/favicon/android-chrome-192x192.png +0 -0
  82. package/public/favicon/android-chrome-512x512.png +0 -0
  83. package/public/favicon/apple-touch-icon.png +0 -0
  84. package/public/favicon/favicon-16x16.png +0 -0
  85. package/public/favicon/favicon-32x32.png +0 -0
  86. package/public/favicon/site.webmanifest +1 -0
  87. package/public/file.svg +1 -0
  88. package/public/globe.svg +1 -0
  89. package/public/ndpr-toolkit-logo.svg +108 -0
  90. package/public/next.svg +1 -0
  91. package/public/vercel.svg +1 -0
  92. package/public/window.svg +1 -0
  93. package/src/__tests__/example.test.ts +13 -0
  94. package/src/__tests__/requestService.test.ts +57 -0
  95. package/src/app/accessibility.css +70 -0
  96. package/src/app/docs/components/DocLayout.tsx +267 -0
  97. package/src/app/docs/components/breach-notification/page.tsx +797 -0
  98. package/src/app/docs/components/consent-management/page.tsx +576 -0
  99. package/src/app/docs/components/data-subject-rights/page.tsx +511 -0
  100. package/src/app/docs/components/dpia-questionnaire/layout.tsx +15 -0
  101. package/src/app/docs/components/dpia-questionnaire/metadata.ts +31 -0
  102. package/src/app/docs/components/dpia-questionnaire/page.tsx +666 -0
  103. package/src/app/docs/components/hooks/page.tsx +305 -0
  104. package/src/app/docs/components/page.tsx +84 -0
  105. package/src/app/docs/components/privacy-policy-generator/page.tsx +634 -0
  106. package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +123 -0
  107. package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +328 -0
  108. package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +28 -0
  109. package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +91 -0
  110. package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +118 -0
  111. package/src/app/docs/guides/breach-notification-process/page.tsx +39 -0
  112. package/src/app/docs/guides/conducting-dpia/page.tsx +593 -0
  113. package/src/app/docs/guides/data-subject-requests/page.tsx +666 -0
  114. package/src/app/docs/guides/managing-consent/page.tsx +738 -0
  115. package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +296 -0
  116. package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +145 -0
  117. package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +33 -0
  118. package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +99 -0
  119. package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +159 -0
  120. package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +38 -0
  121. package/src/app/docs/guides/page.tsx +67 -0
  122. package/src/app/docs/layout.tsx +15 -0
  123. package/src/app/docs/metadata.ts +31 -0
  124. package/src/app/docs/page.tsx +572 -0
  125. package/src/app/favicon.ico +0 -0
  126. package/src/app/globals.css +123 -0
  127. package/src/app/layout.tsx +37 -0
  128. package/src/app/ndpr-demos/breach/page.tsx +354 -0
  129. package/src/app/ndpr-demos/consent/page.tsx +366 -0
  130. package/src/app/ndpr-demos/dpia/page.tsx +495 -0
  131. package/src/app/ndpr-demos/dsr/page.tsx +280 -0
  132. package/src/app/ndpr-demos/page.tsx +73 -0
  133. package/src/app/ndpr-demos/policy/page.tsx +771 -0
  134. package/src/app/page.tsx +452 -0
  135. package/src/components/ErrorBoundary.tsx +90 -0
  136. package/src/components/breach-notification/BreachNotificationForm.tsx +479 -0
  137. package/src/components/consent/ConsentBanner.tsx +159 -0
  138. package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +419 -0
  139. package/src/components/docs/DocLayout.tsx +289 -0
  140. package/src/components/docs/index.ts +2 -0
  141. package/src/components/dpia/DPIAQuestionnaire.tsx +483 -0
  142. package/src/components/privacy-policy/PolicyGenerator.tsx +1062 -0
  143. package/src/components/privacy-policy/data.ts +98 -0
  144. package/src/components/privacy-policy/shared/CheckboxField.tsx +38 -0
  145. package/src/components/privacy-policy/shared/CheckboxGroup.tsx +85 -0
  146. package/src/components/privacy-policy/shared/FormField.tsx +79 -0
  147. package/src/components/privacy-policy/shared/StepIndicator.tsx +86 -0
  148. package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +335 -0
  149. package/src/components/privacy-policy/steps/DataCollectionStep.tsx +231 -0
  150. package/src/components/privacy-policy/steps/DataSharingStep.tsx +418 -0
  151. package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +202 -0
  152. package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +172 -0
  153. package/src/components/ui/Badge.tsx +46 -0
  154. package/src/components/ui/Button.tsx +59 -0
  155. package/src/components/ui/Card.tsx +92 -0
  156. package/src/components/ui/Checkbox.tsx +57 -0
  157. package/src/components/ui/FormField.tsx +50 -0
  158. package/src/components/ui/Input.tsx +38 -0
  159. package/src/components/ui/Loading.tsx +201 -0
  160. package/src/components/ui/Select.tsx +42 -0
  161. package/src/components/ui/TextArea.tsx +38 -0
  162. package/src/components/ui/label.tsx +24 -0
  163. package/src/components/ui/switch.tsx +31 -0
  164. package/src/components/ui/tabs.tsx +66 -0
  165. package/src/hooks/useConsent.ts +64 -0
  166. package/src/hooks/useLoadingState.ts +85 -0
  167. package/src/lib/consentService.ts +137 -0
  168. package/src/lib/dpiaQuestions.ts +148 -0
  169. package/src/lib/requestService.ts +75 -0
  170. package/src/lib/sanitize.ts +108 -0
  171. package/src/lib/storage.ts +222 -0
  172. package/src/lib/utils.ts +6 -0
  173. package/src/types/html-to-docx.d.ts +30 -0
  174. package/src/types/index.ts +72 -0
  175. package/tailwind.config.ts +65 -0
  176. package/tsconfig.json +41 -0
  177. package/dist/components/breach/BreachNotificationManager.d.ts +0 -62
  178. package/dist/components/breach/BreachReportForm.d.ts +0 -66
  179. package/dist/components/breach/BreachRiskAssessment.d.ts +0 -50
  180. package/dist/components/breach/RegulatoryReportGenerator.d.ts +0 -94
  181. package/dist/components/consent/ConsentBanner.d.ts +0 -79
  182. package/dist/components/consent/ConsentManager.d.ts +0 -73
  183. package/dist/components/consent/ConsentStorage.d.ts +0 -41
  184. package/dist/components/dpia/DPIAQuestionnaire.d.ts +0 -70
  185. package/dist/components/dpia/DPIAReport.d.ts +0 -40
  186. package/dist/components/dpia/StepIndicator.d.ts +0 -64
  187. package/dist/components/dsr/DSRDashboard.d.ts +0 -58
  188. package/dist/components/dsr/DSRRequestForm.d.ts +0 -74
  189. package/dist/components/dsr/DSRTracker.d.ts +0 -56
  190. package/dist/components/policy/PolicyExporter.d.ts +0 -65
  191. package/dist/components/policy/PolicyGenerator.d.ts +0 -54
  192. package/dist/components/policy/PolicyPreview.d.ts +0 -71
  193. package/dist/hooks/useBreach.d.ts +0 -97
  194. package/dist/hooks/useConsent.d.ts +0 -63
  195. package/dist/hooks/useDPIA.d.ts +0 -92
  196. package/dist/hooks/useDSR.d.ts +0 -72
  197. package/dist/hooks/usePrivacyPolicy.d.ts +0 -87
  198. package/dist/index.esm.js +0 -2
  199. package/dist/index.esm.js.map +0 -1
  200. package/dist/index.js +0 -2
  201. package/dist/index.js.map +0 -1
  202. package/dist/setupTests.d.ts +0 -2
  203. package/dist/types/breach.d.ts +0 -239
  204. package/dist/types/consent.d.ts +0 -95
  205. package/dist/types/dpia.d.ts +0 -196
  206. package/dist/types/dsr.d.ts +0 -162
  207. package/dist/types/privacy.d.ts +0 -204
  208. package/dist/utils/breach.d.ts +0 -14
  209. package/dist/utils/consent.d.ts +0 -10
  210. package/dist/utils/dpia.d.ts +0 -12
  211. package/dist/utils/dsr.d.ts +0 -11
  212. package/dist/utils/privacy.d.ts +0 -12
@@ -0,0 +1,797 @@
1
+ 'use client';
2
+
3
+ import Link from 'next/link';
4
+ import { DocLayout } from '@/components/docs/DocLayout';
5
+ import { Button } from '@/components/ui/Button';
6
+ import { Card, CardContent } from '@/components/ui/Card';
7
+
8
+ export default function BreachNotificationDocs() {
9
+ return (
10
+ <DocLayout
11
+ title="Breach Notification System"
12
+ description="NDPR-compliant system for managing and reporting data breaches"
13
+ >
14
+ <div className="flex mb-6 space-x-2">
15
+ <Button asChild variant="outline" size="sm">
16
+ <Link href="/ndpr-demos/breach-notification">
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/breach-notification" 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 Breach Notification System provides a complete solution for detecting, managing, and reporting data breaches
31
+ in compliance with the Nigeria Data Protection Regulation (NDPR). It includes components for breach reporting,
32
+ risk assessment, notification management, and regulatory reporting.
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 Breach Notification Requirements</h4>
36
+ <p className="text-blue-700 dark:text-blue-300 text-sm mb-0">
37
+ Under the NDPR, organizations must report data breaches to the National Information Technology Development Agency (NITDA)
38
+ within 72 hours of becoming aware of the breach. Organizations must also notify affected data subjects without undue delay.
39
+ </p>
40
+ </div>
41
+ </section>
42
+
43
+ <section id="installation" className="mb-8">
44
+ <h2 className="text-2xl font-bold mb-4">Installation</h2>
45
+ <p className="mb-4">
46
+ Install the NDPR Toolkit package which includes the Breach Notification components:
47
+ </p>
48
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto mb-4">
49
+ <pre><code>npm install @tantainnovative/ndpr-toolkit</code></pre>
50
+ </div>
51
+ <p>
52
+ Or if you&apos;re using yarn:
53
+ </p>
54
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
55
+ <pre><code>yarn add @tantainnovative/ndpr-toolkit</code></pre>
56
+ </div>
57
+ </section>
58
+
59
+ <section id="components" className="mb-8">
60
+ <h2 className="text-2xl font-bold mb-4">Components</h2>
61
+ <p className="mb-4">
62
+ The Breach Notification system includes several components that work together:
63
+ </p>
64
+
65
+ <div className="space-y-6">
66
+ <div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
67
+ <h3 className="text-xl font-bold mb-2">BreachReportForm</h3>
68
+ <p className="text-gray-600 dark:text-gray-300 mb-4">
69
+ A form for internal staff to report suspected data breaches, capturing essential details.
70
+ </p>
71
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
72
+ <pre><code>{`import { BreachReportForm } from '@tantainnovative/ndpr-toolkit';
73
+
74
+ <BreachReportForm
75
+ onSubmit={handleSubmitBreachReport}
76
+ categories={[
77
+ { id: 'unauthorized-access', label: 'Unauthorized Access' },
78
+ { id: 'data-loss', label: 'Data Loss' },
79
+ { id: 'system-compromise', label: 'System Compromise' },
80
+ { id: 'phishing', label: 'Phishing Attack' },
81
+ { id: 'other', label: 'Other' }
82
+ ]}
83
+ />`}</code></pre>
84
+ </div>
85
+ </div>
86
+
87
+ <div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
88
+ <h3 className="text-xl font-bold mb-2">BreachRiskAssessment</h3>
89
+ <p className="text-gray-600 dark:text-gray-300 mb-4">
90
+ A tool for assessing the risk level of a data breach and determining notification requirements.
91
+ </p>
92
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
93
+ <pre><code>{`import { BreachRiskAssessment } from '@tantainnovative/ndpr-toolkit';
94
+
95
+ <BreachRiskAssessment
96
+ breachData={breachData}
97
+ onComplete={handleRiskAssessmentComplete}
98
+ />`}</code></pre>
99
+ </div>
100
+ </div>
101
+
102
+ <div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
103
+ <h3 className="text-xl font-bold mb-2">BreachNotificationManager</h3>
104
+ <p className="text-gray-600 dark:text-gray-300 mb-4">
105
+ A dashboard for managing breach notifications, including tracking notification status and deadlines.
106
+ </p>
107
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
108
+ <pre><code>{`import { BreachNotificationManager } from '@tantainnovative/ndpr-toolkit';
109
+
110
+ <BreachNotificationManager
111
+ breaches={breaches}
112
+ onUpdateStatus={handleUpdateStatus}
113
+ onSendNotification={handleSendNotification}
114
+ />`}</code></pre>
115
+ </div>
116
+ </div>
117
+
118
+ <div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
119
+ <h3 className="text-xl font-bold mb-2">RegulatoryReportGenerator</h3>
120
+ <p className="text-gray-600 dark:text-gray-300 mb-4">
121
+ A tool for generating NDPR-compliant breach notification reports for submission to NITDA.
122
+ </p>
123
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
124
+ <pre><code>{`import { RegulatoryReportGenerator } from '@tantainnovative/ndpr-toolkit';
125
+
126
+ <RegulatoryReportGenerator
127
+ breachData={breachData}
128
+ organizationInfo={organizationInfo}
129
+ onGenerate={handleGenerateReport}
130
+ />`}</code></pre>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </section>
135
+
136
+ <section id="usage" className="mb-8">
137
+ <h2 className="text-2xl font-bold mb-4">Usage</h2>
138
+ <p className="mb-4">
139
+ Here&apos;s a complete example of how to implement the Breach Notification system in your application:
140
+ </p>
141
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
142
+ <pre><code>{`import { useState, useEffect } from 'react';
143
+ import {
144
+ BreachReportForm,
145
+ BreachRiskAssessment,
146
+ BreachNotificationManager,
147
+ RegulatoryReportGenerator
148
+ } from '@tantainnovative/ndpr-toolkit';
149
+
150
+ // Define breach categories
151
+ const breachCategories = [
152
+ { id: 'unauthorized-access', label: 'Unauthorized Access' },
153
+ { id: 'data-loss', label: 'Data Loss' },
154
+ { id: 'system-compromise', label: 'System Compromise' },
155
+ { id: 'phishing', label: 'Phishing Attack' },
156
+ { id: 'other', label: 'Other' }
157
+ ];
158
+
159
+ // Organization information
160
+ const organizationInfo = {
161
+ name: 'Example Company Ltd.',
162
+ address: '123 Main Street, Lagos, Nigeria',
163
+ dpoName: 'John Doe',
164
+ dpoEmail: 'dpo@example.com',
165
+ dpoPhone: '+234 123 456 7890'
166
+ };
167
+
168
+ // Sample breach service (replace with your actual data service)
169
+ const breachService = {
170
+ breaches: [],
171
+
172
+ reportBreach: (breachData) => {
173
+ const newBreach = {
174
+ ...breachData,
175
+ id: \`breach-\${Date.now()}\`,
176
+ status: 'reported',
177
+ reportedAt: new Date(),
178
+ riskAssessment: null,
179
+ notifications: [],
180
+ regulatoryReport: null
181
+ };
182
+ breachService.breaches.push(newBreach);
183
+ return newBreach;
184
+ },
185
+
186
+ getBreaches: () => {
187
+ return breachService.breaches;
188
+ },
189
+
190
+ getBreachById: (id) => {
191
+ return breachService.breaches.find(breach => breach.id === id);
192
+ },
193
+
194
+ updateBreachStatus: (id, status) => {
195
+ const breach = breachService.breaches.find(breach => breach.id === id);
196
+ if (breach) {
197
+ breach.status = status;
198
+ breach.updatedAt = new Date();
199
+ }
200
+ return breach;
201
+ },
202
+
203
+ saveRiskAssessment: (id, assessment) => {
204
+ const breach = breachService.breaches.find(breach => breach.id === id);
205
+ if (breach) {
206
+ breach.riskAssessment = assessment;
207
+ breach.updatedAt = new Date();
208
+
209
+ // Update status based on risk level
210
+ if (assessment.riskLevel === 'high') {
211
+ breach.status = 'high-risk';
212
+ } else if (assessment.riskLevel === 'medium') {
213
+ breach.status = 'medium-risk';
214
+ } else {
215
+ breach.status = 'low-risk';
216
+ }
217
+ }
218
+ return breach;
219
+ },
220
+
221
+ recordNotification: (id, notification) => {
222
+ const breach = breachService.breaches.find(breach => breach.id === id);
223
+ if (breach) {
224
+ breach.notifications.push({
225
+ ...notification,
226
+ id: \`notification-\${Date.now()}\`,
227
+ sentAt: new Date()
228
+ });
229
+ breach.updatedAt = new Date();
230
+
231
+ // Update status if all required notifications are sent
232
+ if (breach.notifications.length >= breach.riskAssessment.requiredNotifications.length) {
233
+ breach.status = 'notifications-complete';
234
+ }
235
+ }
236
+ return breach;
237
+ },
238
+
239
+ saveRegulatoryReport: (id, report) => {
240
+ const breach = breachService.breaches.find(breach => breach.id === id);
241
+ if (breach) {
242
+ breach.regulatoryReport = {
243
+ ...report,
244
+ generatedAt: new Date()
245
+ };
246
+ breach.status = 'report-generated';
247
+ breach.updatedAt = new Date();
248
+ }
249
+ return breach;
250
+ }
251
+ };
252
+
253
+ // Breach reporting form component
254
+ function BreachReportingPage() {
255
+ const [submitted, setSubmitted] = useState(false);
256
+ const [currentBreach, setCurrentBreach] = useState(null);
257
+
258
+ const handleSubmitBreachReport = (breachData) => {
259
+ const newBreach = breachService.reportBreach(breachData);
260
+ setCurrentBreach(newBreach);
261
+ setSubmitted(true);
262
+ };
263
+
264
+ const handleRiskAssessmentComplete = (assessment) => {
265
+ const updatedBreach = breachService.saveRiskAssessment(currentBreach.id, assessment);
266
+ setCurrentBreach(updatedBreach);
267
+ };
268
+
269
+ return (
270
+ <div>
271
+ <h1>Data Breach Reporting</h1>
272
+
273
+ {!submitted ? (
274
+ <>
275
+ <p>
276
+ Use this form to report a suspected data breach. All breaches must be
277
+ reported internally within 24 hours of discovery.
278
+ </p>
279
+
280
+ <BreachReportForm
281
+ onSubmit={handleSubmitBreachReport}
282
+ categories={breachCategories}
283
+ />
284
+ </>
285
+ ) : (
286
+ <div>
287
+ <h2>Breach Reported</h2>
288
+ <p>
289
+ The breach has been reported successfully. Reference number: <strong>{currentBreach.id}</strong>
290
+ </p>
291
+
292
+ <h3>Risk Assessment</h3>
293
+ <p>
294
+ Please complete the risk assessment to determine notification requirements.
295
+ </p>
296
+
297
+ <BreachRiskAssessment
298
+ breachData={currentBreach}
299
+ onComplete={handleRiskAssessmentComplete}
300
+ />
301
+
302
+ {currentBreach.riskAssessment && (
303
+ <div>
304
+ <h3>Risk Assessment Complete</h3>
305
+ <p>
306
+ Risk Level: <strong>{currentBreach.riskAssessment.riskLevel}</strong>
307
+ </p>
308
+ <p>
309
+ {currentBreach.riskAssessment.requiresNitdaNotification
310
+ ? 'NITDA notification is required within 72 hours.'
311
+ : 'NITDA notification is not required.'}
312
+ </p>
313
+ <p>
314
+ {currentBreach.riskAssessment.requiresDataSubjectNotification
315
+ ? 'Data subject notification is required without undue delay.'
316
+ : 'Data subject notification is not required.'}
317
+ </p>
318
+ </div>
319
+ )}
320
+ </div>
321
+ )}
322
+ </div>
323
+ );
324
+ }
325
+
326
+ // Breach management dashboard component
327
+ function BreachManagementDashboard() {
328
+ const [breaches, setBreaches] = useState([]);
329
+ const [selectedBreach, setSelectedBreach] = useState(null);
330
+
331
+ useEffect(() => {
332
+ // Load breaches from service
333
+ setBreaches(breachService.getBreaches());
334
+ }, []);
335
+
336
+ const handleUpdateStatus = (id, status) => {
337
+ const updatedBreach = breachService.updateBreachStatus(id, status);
338
+ setBreaches(breachService.getBreaches());
339
+ };
340
+
341
+ const handleSendNotification = (id, notification) => {
342
+ const updatedBreach = breachService.recordNotification(id, notification);
343
+ setBreaches(breachService.getBreaches());
344
+ };
345
+
346
+ const handleGenerateReport = (id, report) => {
347
+ const updatedBreach = breachService.saveRegulatoryReport(id, report);
348
+ setBreaches(breachService.getBreaches());
349
+ setSelectedBreach(updatedBreach);
350
+ };
351
+
352
+ return (
353
+ <div>
354
+ <h1>Breach Management Dashboard</h1>
355
+
356
+ <BreachNotificationManager
357
+ breaches={breaches}
358
+ onUpdateStatus={handleUpdateStatus}
359
+ onSendNotification={handleSendNotification}
360
+ onSelectBreach={setSelectedBreach}
361
+ />
362
+
363
+ {selectedBreach && selectedBreach.riskAssessment &&
364
+ selectedBreach.riskAssessment.requiresNitdaNotification && (
365
+ <div>
366
+ <h2>Regulatory Report Generator</h2>
367
+ <p>
368
+ Generate a NITDA breach notification report for submission.
369
+ </p>
370
+
371
+ <RegulatoryReportGenerator
372
+ breachData={selectedBreach}
373
+ organizationInfo={organizationInfo}
374
+ onGenerate={(report) => handleGenerateReport(selectedBreach.id, report)}
375
+ />
376
+ </div>
377
+ )}
378
+ </div>
379
+ );
380
+ }`}</code></pre>
381
+ </div>
382
+ </section>
383
+
384
+ <section id="props" className="mb-8">
385
+ <h2 className="text-2xl font-bold mb-4">Props</h2>
386
+
387
+ <h3 className="text-xl font-bold mb-4">BreachReportForm Props</h3>
388
+ <div className="overflow-x-auto">
389
+ <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
390
+ <thead className="bg-gray-50 dark:bg-gray-800">
391
+ <tr>
392
+ <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Name</th>
393
+ <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>
394
+ <th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Required</th>
395
+ <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>
396
+ </tr>
397
+ </thead>
398
+ <tbody className="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-800">
399
+ <tr>
400
+ <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white"><code>onSubmit</code></td>
401
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"><code>(data: BreachReport) =&gt; void</code></td>
402
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">Yes</td>
403
+ <td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Callback function when user submits a breach report</td>
404
+ </tr>
405
+ <tr>
406
+ <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white"><code>categories</code></td>
407
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"><code>{'{ id: string, label: string }[]'}</code></td>
408
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">Yes</td>
409
+ <td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Array of breach categories to display</td>
410
+ </tr>
411
+ <tr>
412
+ <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white"><code>initialValues</code></td>
413
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400"><code>Partial&lt;BreachReport&gt;</code></td>
414
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">No</td>
415
+ <td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">Initial values for the form fields</td>
416
+ </tr>
417
+ </tbody>
418
+ </table>
419
+ </div>
420
+
421
+ <h3 className="text-xl font-bold mt-8 mb-4">BreachReport Type</h3>
422
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
423
+ <pre><code>{`type BreachReport = {
424
+ id?: string;
425
+ title: string;
426
+ category: string;
427
+ description: string;
428
+ discoveredAt: Date;
429
+ reportedBy: {
430
+ name: string;
431
+ email: string;
432
+ department: string;
433
+ };
434
+ affectedSystems: string[];
435
+ affectedDataTypes: string[];
436
+ estimatedImpact: string;
437
+ initialActions: string;
438
+ status?: string;
439
+ reportedAt?: Date;
440
+ updatedAt?: Date;
441
+ };`}</code></pre>
442
+ </div>
443
+ </section>
444
+
445
+ <section id="72-hour-timeline" className="mb-8">
446
+ <h2 className="text-2xl font-bold mb-4">72-Hour Notification Timeline</h2>
447
+ <p className="mb-4">
448
+ The NDPR requires organizations to notify NITDA of data breaches within 72 hours of becoming aware of the breach.
449
+ Here&apos;s a recommended timeline for handling breaches:
450
+ </p>
451
+
452
+ <div className="relative border-l-2 border-blue-500 pl-8 pb-8 space-y-10">
453
+ <div className="relative">
454
+ <div className="absolute -left-10 mt-1.5 h-6 w-6 rounded-full bg-blue-500 flex items-center justify-center">
455
+ <span className="text-white font-bold text-sm">1</span>
456
+ </div>
457
+ <h3 className="text-xl font-bold">Hour 0-4: Initial Response</h3>
458
+ <p className="text-gray-600 dark:text-gray-300 mt-2">
459
+ - Report the breach internally using the BreachReportForm<br />
460
+ - Assemble the response team<br />
461
+ - Begin containment measures<br />
462
+ - Preserve evidence
463
+ </p>
464
+ </div>
465
+
466
+ <div className="relative">
467
+ <div className="absolute -left-10 mt-1.5 h-6 w-6 rounded-full bg-blue-500 flex items-center justify-center">
468
+ <span className="text-white font-bold text-sm">2</span>
469
+ </div>
470
+ <h3 className="text-xl font-bold">Hour 4-24: Risk Assessment</h3>
471
+ <p className="text-gray-600 dark:text-gray-300 mt-2">
472
+ - Complete the BreachRiskAssessment<br />
473
+ - Determine notification requirements<br />
474
+ - Continue containment and investigation<br />
475
+ - Begin preparing notification drafts
476
+ </p>
477
+ </div>
478
+
479
+ <div className="relative">
480
+ <div className="absolute -left-10 mt-1.5 h-6 w-6 rounded-full bg-blue-500 flex items-center justify-center">
481
+ <span className="text-white font-bold text-sm">3</span>
482
+ </div>
483
+ <h3 className="text-xl font-bold">Hour 24-48: Notification Preparation</h3>
484
+ <p className="text-gray-600 dark:text-gray-300 mt-2">
485
+ - Use the RegulatoryReportGenerator to prepare NITDA notification<br />
486
+ - Draft data subject notifications if required<br />
487
+ - Review and approve notifications<br />
488
+ - Continue investigation and remediation
489
+ </p>
490
+ </div>
491
+
492
+ <div className="relative">
493
+ <div className="absolute -left-10 mt-1.5 h-6 w-6 rounded-full bg-blue-500 flex items-center justify-center">
494
+ <span className="text-white font-bold text-sm">4</span>
495
+ </div>
496
+ <h3 className="text-xl font-bold">Hour 48-72: Notification Submission</h3>
497
+ <p className="text-gray-600 dark:text-gray-300 mt-2">
498
+ - Submit notification to NITDA<br />
499
+ - Begin notifying affected data subjects if required<br />
500
+ - Document all notification activities<br />
501
+ - Continue remediation efforts
502
+ </p>
503
+ </div>
504
+ </div>
505
+ </section>
506
+
507
+ <section id="api" className="mb-8">
508
+ <h2 className="text-2xl font-bold mb-4">API Reference</h2>
509
+
510
+ <h3 className="text-xl font-bold mt-8 mb-4">BreachReport Interface</h3>
511
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
512
+ <pre><code>{`export interface BreachReport {
513
+ /**
514
+ * Unique identifier for the breach report
515
+ */
516
+ id: string;
517
+
518
+ /**
519
+ * Title/summary of the breach
520
+ */
521
+ title: string;
522
+
523
+ /**
524
+ * Detailed description of the breach
525
+ */
526
+ description: string;
527
+
528
+ /**
529
+ * Category of the breach
530
+ */
531
+ category: string;
532
+
533
+ /**
534
+ * Timestamp when the breach was discovered
535
+ */
536
+ discoveredAt: number;
537
+
538
+ /**
539
+ * Timestamp when the breach occurred (if known)
540
+ */
541
+ occurredAt?: number;
542
+
543
+ /**
544
+ * Timestamp when the breach was reported internally
545
+ */
546
+ reportedAt: number;
547
+
548
+ /**
549
+ * Person who reported the breach
550
+ */
551
+ reporter: {
552
+ name: string;
553
+ email: string;
554
+ department: string;
555
+ phone?: string;
556
+ };
557
+
558
+ /**
559
+ * Systems or data affected by the breach
560
+ */
561
+ affectedSystems: string[];
562
+
563
+ /**
564
+ * Types of data involved in the breach
565
+ */
566
+ dataTypes: string[];
567
+
568
+ /**
569
+ * Estimated number of data subjects affected
570
+ */
571
+ estimatedAffectedSubjects?: number;
572
+
573
+ /**
574
+ * Whether the breach is ongoing or contained
575
+ */
576
+ status: 'ongoing' | 'contained' | 'resolved';
577
+ }`}</code></pre>
578
+ </div>
579
+
580
+ <h3 className="text-xl font-bold mt-8 mb-4">RiskAssessment Interface</h3>
581
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
582
+ <pre><code>{`export interface RiskAssessment {
583
+ /**
584
+ * Unique identifier for the risk assessment
585
+ */
586
+ id: string;
587
+
588
+ /**
589
+ * ID of the breach this assessment is for
590
+ */
591
+ breachId: string;
592
+
593
+ /**
594
+ * Timestamp when the assessment was conducted
595
+ */
596
+ assessedAt: number;
597
+
598
+ /**
599
+ * Person who conducted the assessment
600
+ */
601
+ assessor: {
602
+ name: string;
603
+ role: string;
604
+ email: string;
605
+ };
606
+
607
+ /**
608
+ * Confidentiality impact (1-5)
609
+ */
610
+ confidentialityImpact: number;
611
+
612
+ /**
613
+ * Integrity impact (1-5)
614
+ */
615
+ integrityImpact: number;
616
+
617
+ /**
618
+ * Availability impact (1-5)
619
+ */
620
+ availabilityImpact: number;
621
+
622
+ /**
623
+ * Likelihood of harm to data subjects (1-5)
624
+ */
625
+ harmLikelihood: number;
626
+
627
+ /**
628
+ * Severity of potential harm to data subjects (1-5)
629
+ */
630
+ harmSeverity: number;
631
+
632
+ /**
633
+ * Overall risk score
634
+ */
635
+ overallRiskScore: number;
636
+
637
+ /**
638
+ * Risk level based on the overall score
639
+ */
640
+ riskLevel: 'low' | 'medium' | 'high' | 'critical';
641
+
642
+ /**
643
+ * Whether the breach is likely to result in a risk to the rights and freedoms of data subjects
644
+ */
645
+ risksToRightsAndFreedoms: boolean;
646
+ }`}</code></pre>
647
+ </div>
648
+
649
+ <h3 className="text-xl font-bold mt-8 mb-4">NotificationRequirement Interface</h3>
650
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
651
+ <pre><code>{`export interface NotificationRequirement {
652
+ /**
653
+ * Whether NITDA notification is required
654
+ */
655
+ nitdaNotificationRequired: boolean;
656
+
657
+ /**
658
+ * Deadline for NITDA notification (72 hours from discovery)
659
+ */
660
+ nitdaNotificationDeadline: number;
661
+
662
+ /**
663
+ * Whether data subject notification is required
664
+ */
665
+ dataSubjectNotificationRequired: boolean;
666
+
667
+ /**
668
+ * Justification for the notification decision
669
+ */
670
+ justification: string;
671
+ }`}</code></pre>
672
+ </div>
673
+
674
+ <h3 className="text-xl font-bold mt-8 mb-4">useBreach Hook</h3>
675
+ <div className="bg-gray-800 text-gray-200 p-4 rounded-md overflow-x-auto">
676
+ <pre><code>{`// Import the hook
677
+ import { useBreach } from '@tantainnovative/ndpr-toolkit';
678
+
679
+ // Use the hook in your component
680
+ const {
681
+ breaches, // Array of all breach reports
682
+ submitBreachReport, // Function to submit a new breach report
683
+ updateBreachReport, // Function to update an existing breach report
684
+ performRiskAssessment, // Function to perform a risk assessment
685
+ determineNotificationRequirements, // Function to determine notification requirements
686
+ generateRegulatoryReport, // Function to generate a report for NITDA
687
+ getBreachById, // Function to get a breach by ID
688
+ } = useBreach();
689
+
690
+ // Submit a new breach report
691
+ const newBreachReport = submitBreachReport({
692
+ title: 'Unauthorized Database Access',
693
+ description: 'An unauthorized IP address accessed our customer database.',
694
+ category: 'unauthorized-access',
695
+ discoveredAt: Date.now(),
696
+ occurredAt: Date.now() - 3600000, // 1 hour ago
697
+ reporter: {
698
+ name: 'John Doe',
699
+ email: 'john@example.com',
700
+ department: 'IT Security',
701
+ phone: '1234567890'
702
+ },
703
+ affectedSystems: ['customer-database'],
704
+ dataTypes: ['personal-information', 'contact-details'],
705
+ estimatedAffectedSubjects: 500,
706
+ status: 'contained'
707
+ });
708
+
709
+ // Perform a risk assessment
710
+ const riskAssessment = performRiskAssessment({
711
+ breachId: newBreachReport.id,
712
+ assessor: {
713
+ name: 'Jane Smith',
714
+ role: 'Data Protection Officer',
715
+ email: 'jane@example.com'
716
+ },
717
+ confidentialityImpact: 4,
718
+ integrityImpact: 3,
719
+ availabilityImpact: 2,
720
+ harmLikelihood: 3,
721
+ harmSeverity: 4
722
+ });
723
+
724
+ // Determine notification requirements
725
+ const requirements = determineNotificationRequirements({
726
+ breachId: newBreachReport.id,
727
+ riskAssessmentId: riskAssessment.id
728
+ });
729
+
730
+ // Generate a regulatory report for NITDA
731
+ if (requirements.nitdaNotificationRequired) {
732
+ const report = generateRegulatoryReport({
733
+ breachId: newBreachReport.id,
734
+ riskAssessmentId: riskAssessment.id
735
+ });
736
+ }`}</code></pre>
737
+ </div>
738
+ </section>
739
+
740
+ <section id="best-practices" className="mb-8">
741
+ <h2 className="text-2xl font-bold mb-4">Best Practices</h2>
742
+ <ul className="list-disc pl-6 space-y-2">
743
+ <li>
744
+ <strong>Breach Response Plan:</strong> Develop a comprehensive breach response plan that includes roles, responsibilities, and procedures.
745
+ </li>
746
+ <li>
747
+ <strong>Regular Training:</strong> Conduct regular training for staff on breach identification, reporting, and response procedures.
748
+ </li>
749
+ <li>
750
+ <strong>Documentation:</strong> Maintain detailed documentation of all breach-related activities, including containment, investigation, and notification.
751
+ </li>
752
+ <li>
753
+ <strong>Testing:</strong> Regularly test your breach response procedures through tabletop exercises or simulations.
754
+ </li>
755
+ <li>
756
+ <strong>Post-Breach Review:</strong> Conduct a thorough review after each breach to identify lessons learned and improve your response procedures.
757
+ </li>
758
+ </ul>
759
+ </section>
760
+
761
+ <section id="help-resources" className="mb-8">
762
+ <h2 className="text-2xl font-bold mb-4">Need Help?</h2>
763
+ <p className="mb-4">
764
+ If you have questions about implementing the Breach Notification system or need assistance with NDPR compliance, check out these resources:
765
+ </p>
766
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
767
+ <Card>
768
+ <CardContent className="p-4">
769
+ <h3 className="font-medium text-gray-900 dark:text-white mb-2">GitHub Issues</h3>
770
+ <p className="text-gray-600 dark:text-gray-300 text-sm mb-3">
771
+ Report bugs or request features on our GitHub repository.
772
+ </p>
773
+ <Button asChild variant="outline" size="sm">
774
+ <a href="https://github.com/tantainnovative/ndpr-toolkit/issues" target="_blank" rel="noopener noreferrer">
775
+ View Issues
776
+ </a>
777
+ </Button>
778
+ </CardContent>
779
+ </Card>
780
+ <Card>
781
+ <CardContent className="p-4">
782
+ <h3 className="font-medium text-gray-900 dark:text-white mb-2">NDPR Resources</h3>
783
+ <p className="text-gray-600 dark:text-gray-300 text-sm mb-3">
784
+ Learn more about NDPR compliance requirements.
785
+ </p>
786
+ <Button asChild variant="outline" size="sm">
787
+ <a href="https://nitda.gov.ng/wp-content/uploads/2020/01/NDPR-Implementation-Framework.pdf" target="_blank" rel="noopener noreferrer">
788
+ NDPR Framework
789
+ </a>
790
+ </Button>
791
+ </CardContent>
792
+ </Card>
793
+ </div>
794
+ </section>
795
+ </DocLayout>
796
+ );
797
+ }