@tantainnovative/ndpr-toolkit 1.0.3 → 1.0.4

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 (156) hide show
  1. package/next-env.d.ts +5 -0
  2. package/package.json +1 -1
  3. package/.claude/settings.local.json +0 -20
  4. package/.eslintrc.json +0 -10
  5. package/.github/workflows/ci.yml +0 -36
  6. package/.github/workflows/nextjs.yml +0 -104
  7. package/.husky/commit-msg +0 -4
  8. package/.husky/pre-commit +0 -4
  9. package/.lintstagedrc.js +0 -4
  10. package/.nvmrc +0 -1
  11. package/.versionrc +0 -17
  12. package/CLAUDE.md +0 -90
  13. package/commitlint.config.js +0 -36
  14. package/eslint.config.mjs +0 -16
  15. package/jest.config.js +0 -31
  16. package/jest.setup.js +0 -15
  17. package/next.config.js +0 -15
  18. package/next.config.ts +0 -62
  19. package/packages/ndpr-toolkit/README.md +0 -467
  20. package/packages/ndpr-toolkit/jest.config.js +0 -23
  21. package/packages/ndpr-toolkit/package-lock.json +0 -8197
  22. package/packages/ndpr-toolkit/package.json +0 -71
  23. package/packages/ndpr-toolkit/rollup.config.js +0 -34
  24. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +0 -119
  25. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +0 -122
  26. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +0 -270
  27. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +0 -199
  28. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +0 -224
  29. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +0 -104
  30. package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +0 -161
  31. package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +0 -330
  32. package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +0 -149
  33. package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +0 -88
  34. package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +0 -160
  35. package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +0 -110
  36. package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +0 -97
  37. package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +0 -701
  38. package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +0 -631
  39. package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +0 -569
  40. package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +0 -496
  41. package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +0 -270
  42. package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +0 -217
  43. package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +0 -206
  44. package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +0 -342
  45. package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +0 -373
  46. package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +0 -174
  47. package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +0 -717
  48. package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +0 -476
  49. package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +0 -620
  50. package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +0 -541
  51. package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +0 -454
  52. package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +0 -333
  53. package/packages/ndpr-toolkit/src/hooks/useBreach.ts +0 -409
  54. package/packages/ndpr-toolkit/src/hooks/useConsent.ts +0 -263
  55. package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +0 -457
  56. package/packages/ndpr-toolkit/src/hooks/useDSR.ts +0 -236
  57. package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +0 -428
  58. package/packages/ndpr-toolkit/src/index.ts +0 -44
  59. package/packages/ndpr-toolkit/src/setupTests.ts +0 -5
  60. package/packages/ndpr-toolkit/src/types/breach.ts +0 -283
  61. package/packages/ndpr-toolkit/src/types/consent.ts +0 -111
  62. package/packages/ndpr-toolkit/src/types/dpia.ts +0 -236
  63. package/packages/ndpr-toolkit/src/types/dsr.ts +0 -192
  64. package/packages/ndpr-toolkit/src/types/index.ts +0 -42
  65. package/packages/ndpr-toolkit/src/types/privacy.ts +0 -246
  66. package/packages/ndpr-toolkit/src/utils/breach.ts +0 -122
  67. package/packages/ndpr-toolkit/src/utils/consent.ts +0 -51
  68. package/packages/ndpr-toolkit/src/utils/dpia.ts +0 -104
  69. package/packages/ndpr-toolkit/src/utils/dsr.ts +0 -77
  70. package/packages/ndpr-toolkit/src/utils/privacy.ts +0 -100
  71. package/packages/ndpr-toolkit/tsconfig.json +0 -23
  72. package/postcss.config.mjs +0 -5
  73. package/src/__tests__/example.test.ts +0 -13
  74. package/src/__tests__/requestService.test.ts +0 -57
  75. package/src/app/accessibility.css +0 -70
  76. package/src/app/docs/components/DocLayout.tsx +0 -267
  77. package/src/app/docs/components/breach-notification/page.tsx +0 -797
  78. package/src/app/docs/components/consent-management/page.tsx +0 -576
  79. package/src/app/docs/components/data-subject-rights/page.tsx +0 -511
  80. package/src/app/docs/components/dpia-questionnaire/layout.tsx +0 -15
  81. package/src/app/docs/components/dpia-questionnaire/metadata.ts +0 -31
  82. package/src/app/docs/components/dpia-questionnaire/page.tsx +0 -666
  83. package/src/app/docs/components/hooks/page.tsx +0 -305
  84. package/src/app/docs/components/page.tsx +0 -84
  85. package/src/app/docs/components/privacy-policy-generator/page.tsx +0 -634
  86. package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +0 -123
  87. package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +0 -328
  88. package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +0 -28
  89. package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +0 -91
  90. package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +0 -118
  91. package/src/app/docs/guides/breach-notification-process/page.tsx +0 -39
  92. package/src/app/docs/guides/conducting-dpia/page.tsx +0 -593
  93. package/src/app/docs/guides/data-subject-requests/page.tsx +0 -666
  94. package/src/app/docs/guides/managing-consent/page.tsx +0 -738
  95. package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +0 -296
  96. package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +0 -145
  97. package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +0 -33
  98. package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +0 -99
  99. package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +0 -159
  100. package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +0 -38
  101. package/src/app/docs/guides/page.tsx +0 -67
  102. package/src/app/docs/layout.tsx +0 -15
  103. package/src/app/docs/metadata.ts +0 -31
  104. package/src/app/docs/page.tsx +0 -572
  105. package/src/app/favicon.ico +0 -0
  106. package/src/app/globals.css +0 -123
  107. package/src/app/layout.tsx +0 -37
  108. package/src/app/ndpr-demos/breach/page.tsx +0 -354
  109. package/src/app/ndpr-demos/consent/page.tsx +0 -366
  110. package/src/app/ndpr-demos/dpia/page.tsx +0 -495
  111. package/src/app/ndpr-demos/dsr/page.tsx +0 -280
  112. package/src/app/ndpr-demos/page.tsx +0 -73
  113. package/src/app/ndpr-demos/policy/page.tsx +0 -771
  114. package/src/app/page.tsx +0 -452
  115. package/src/components/ErrorBoundary.tsx +0 -90
  116. package/src/components/breach-notification/BreachNotificationForm.tsx +0 -479
  117. package/src/components/consent/ConsentBanner.tsx +0 -159
  118. package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +0 -419
  119. package/src/components/docs/DocLayout.tsx +0 -289
  120. package/src/components/docs/index.ts +0 -2
  121. package/src/components/dpia/DPIAQuestionnaire.tsx +0 -483
  122. package/src/components/privacy-policy/PolicyGenerator.tsx +0 -1062
  123. package/src/components/privacy-policy/data.ts +0 -98
  124. package/src/components/privacy-policy/shared/CheckboxField.tsx +0 -38
  125. package/src/components/privacy-policy/shared/CheckboxGroup.tsx +0 -85
  126. package/src/components/privacy-policy/shared/FormField.tsx +0 -79
  127. package/src/components/privacy-policy/shared/StepIndicator.tsx +0 -86
  128. package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +0 -335
  129. package/src/components/privacy-policy/steps/DataCollectionStep.tsx +0 -231
  130. package/src/components/privacy-policy/steps/DataSharingStep.tsx +0 -418
  131. package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +0 -202
  132. package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +0 -172
  133. package/src/components/ui/Badge.tsx +0 -46
  134. package/src/components/ui/Button.tsx +0 -59
  135. package/src/components/ui/Card.tsx +0 -92
  136. package/src/components/ui/Checkbox.tsx +0 -57
  137. package/src/components/ui/FormField.tsx +0 -50
  138. package/src/components/ui/Input.tsx +0 -38
  139. package/src/components/ui/Loading.tsx +0 -201
  140. package/src/components/ui/Select.tsx +0 -42
  141. package/src/components/ui/TextArea.tsx +0 -38
  142. package/src/components/ui/label.tsx +0 -24
  143. package/src/components/ui/switch.tsx +0 -31
  144. package/src/components/ui/tabs.tsx +0 -66
  145. package/src/hooks/useConsent.ts +0 -64
  146. package/src/hooks/useLoadingState.ts +0 -85
  147. package/src/lib/consentService.ts +0 -137
  148. package/src/lib/dpiaQuestions.ts +0 -148
  149. package/src/lib/requestService.ts +0 -75
  150. package/src/lib/sanitize.ts +0 -108
  151. package/src/lib/storage.ts +0 -222
  152. package/src/lib/utils.ts +0 -6
  153. package/src/types/html-to-docx.d.ts +0 -30
  154. package/src/types/index.ts +0 -72
  155. package/tailwind.config.ts +0 -65
  156. package/tsconfig.json +0 -41
@@ -1,496 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { BreachReport, RiskAssessment, RegulatoryNotification } from '../../types/breach';
3
-
4
- export interface OrganizationInfo {
5
- /**
6
- * Name of the organization
7
- */
8
- name: string;
9
-
10
- /**
11
- * Registration number or business ID
12
- */
13
- registrationNumber?: string;
14
-
15
- /**
16
- * Physical address of the organization
17
- */
18
- address: string;
19
-
20
- /**
21
- * Website URL
22
- */
23
- website?: string;
24
-
25
- /**
26
- * Name of the Data Protection Officer
27
- */
28
- dpoName: string;
29
-
30
- /**
31
- * Email of the Data Protection Officer
32
- */
33
- dpoEmail: string;
34
-
35
- /**
36
- * Phone number of the Data Protection Officer
37
- */
38
- dpoPhone?: string;
39
- }
40
-
41
- export interface RegulatoryReportGeneratorProps {
42
- /**
43
- * The breach data to include in the report
44
- */
45
- breachData: BreachReport;
46
-
47
- /**
48
- * The risk assessment data
49
- */
50
- assessmentData?: RiskAssessment;
51
-
52
- /**
53
- * Organization information to include in the report
54
- */
55
- organizationInfo: OrganizationInfo;
56
-
57
- /**
58
- * Callback function called when the report is generated
59
- */
60
- onGenerate: (report: RegulatoryNotification) => void;
61
-
62
- /**
63
- * Title displayed on the generator form
64
- * @default "Generate NITDA Notification Report"
65
- */
66
- title?: string;
67
-
68
- /**
69
- * Description text displayed on the generator form
70
- * @default "Generate a report for submission to NITDA in compliance with the NDPR breach notification requirements."
71
- */
72
- description?: string;
73
-
74
- /**
75
- * Text for the generate button
76
- * @default "Generate Report"
77
- */
78
- generateButtonText?: string;
79
-
80
- /**
81
- * Custom CSS class for the form
82
- */
83
- className?: string;
84
-
85
- /**
86
- * Custom CSS class for the buttons
87
- */
88
- buttonClassName?: string;
89
-
90
- /**
91
- * Whether to show a preview of the generated report
92
- * @default true
93
- */
94
- showPreview?: boolean;
95
-
96
- /**
97
- * Whether to allow editing the report content
98
- * @default true
99
- */
100
- allowEditing?: boolean;
101
-
102
- /**
103
- * Whether to allow downloading the report
104
- * @default true
105
- */
106
- allowDownload?: boolean;
107
-
108
- /**
109
- * Format for downloading the report
110
- * @default "pdf"
111
- */
112
- downloadFormat?: 'pdf' | 'docx' | 'html';
113
- }
114
-
115
- export const RegulatoryReportGenerator: React.FC<RegulatoryReportGeneratorProps> = ({
116
- breachData,
117
- assessmentData,
118
- organizationInfo,
119
- onGenerate,
120
- title = "Generate NITDA Notification Report",
121
- description = "Generate a report for submission to NITDA in compliance with the NDPR breach notification requirements.",
122
- generateButtonText = "Generate Report",
123
- className = "",
124
- buttonClassName = "",
125
- showPreview = true,
126
- allowEditing = true,
127
- allowDownload = true,
128
- downloadFormat = "pdf"
129
- }) => {
130
- // Form state
131
- const [reportContent, setReportContent] = useState<string>("");
132
- const [contactName, setContactName] = useState<string>("");
133
- const [contactEmail, setContactEmail] = useState<string>("");
134
- const [contactPhone, setContactPhone] = useState<string>("");
135
- const [method, setMethod] = useState<'email' | 'portal' | 'letter' | 'other'>('email');
136
- const [referenceNumber, setReferenceNumber] = useState<string>("");
137
- const [additionalInfo, setAdditionalInfo] = useState<string>("");
138
- const [isGenerated, setIsGenerated] = useState<boolean>(false);
139
- const [isSubmitted, setIsSubmitted] = useState<boolean>(false);
140
-
141
- // Generate the initial report content
142
- useEffect(() => {
143
- if (!isGenerated) {
144
- const initialContent = generateInitialContent();
145
- setReportContent(initialContent);
146
- setIsGenerated(true);
147
- }
148
- }, [breachData, assessmentData, organizationInfo]);
149
-
150
- // Format a date from timestamp
151
- const formatDate = (timestamp: number): string => {
152
- return new Date(timestamp).toLocaleDateString('en-GB', {
153
- day: 'numeric',
154
- month: 'long',
155
- year: 'numeric'
156
- });
157
- };
158
-
159
- // Generate the initial report content
160
- const generateInitialContent = (): string => {
161
- const now = new Date();
162
- const formattedDate = now.toLocaleDateString('en-GB', {
163
- day: 'numeric',
164
- month: 'long',
165
- year: 'numeric'
166
- });
167
-
168
- return `
169
- NITDA DATA BREACH NOTIFICATION
170
-
171
- Date: ${formattedDate}
172
-
173
- ORGANIZATION DETAILS
174
- -------------------
175
- Organization Name: ${organizationInfo.name}
176
- ${organizationInfo.registrationNumber ? `Registration Number: ${organizationInfo.registrationNumber}` : ''}
177
- Address: ${organizationInfo.address}
178
- ${organizationInfo.website ? `Website: ${organizationInfo.website}` : ''}
179
-
180
- DATA PROTECTION OFFICER
181
- ----------------------
182
- Name: ${organizationInfo.dpoName}
183
- Email: ${organizationInfo.dpoEmail}
184
- ${organizationInfo.dpoPhone ? `Phone: ${organizationInfo.dpoPhone}` : ''}
185
-
186
- BREACH DETAILS
187
- -------------
188
- Breach Title: ${breachData.title}
189
- Date Discovered: ${formatDate(breachData.discoveredAt)}
190
- ${breachData.occurredAt ? `Date Occurred: ${formatDate(breachData.occurredAt)}` : 'Date Occurred: Unknown'}
191
- Status: ${breachData.status.charAt(0).toUpperCase() + breachData.status.slice(1)}
192
-
193
- Description of the Breach:
194
- ${breachData.description}
195
-
196
- Affected Systems/Applications:
197
- ${breachData.affectedSystems.join(', ')}
198
-
199
- Types of Personal Data Involved:
200
- ${breachData.dataTypes.join(', ')}
201
-
202
- Estimated Number of Data Subjects Affected:
203
- ${breachData.estimatedAffectedSubjects || 'Unknown'}
204
-
205
- RISK ASSESSMENT
206
- --------------
207
- ${assessmentData ? `
208
- Overall Risk Level: ${assessmentData.riskLevel.charAt(0).toUpperCase() + assessmentData.riskLevel.slice(1)}
209
- Risk to Rights and Freedoms of Data Subjects: ${assessmentData.risksToRightsAndFreedoms ? 'Yes' : 'No'}
210
- High Risk to Rights and Freedoms of Data Subjects: ${assessmentData.highRisksToRightsAndFreedoms ? 'Yes' : 'No'}
211
-
212
- Justification for Risk Assessment:
213
- ${assessmentData.justification}
214
- ` : 'Risk assessment has not been conducted yet.'}
215
-
216
- MEASURES TAKEN
217
- -------------
218
- Measures taken or proposed to address the breach:
219
- ${breachData.initialActions || 'To be determined'}
220
-
221
- Measures taken or proposed to mitigate possible adverse effects:
222
- [Please specify measures taken to mitigate adverse effects]
223
-
224
- NOTIFICATION TO DATA SUBJECTS
225
- ----------------------------
226
- Have data subjects been notified: [Yes/No]
227
- If yes, date of notification: [Date]
228
- If no, planned date of notification: [Date]
229
- Reason for delay (if applicable): [Reason]
230
-
231
- ADDITIONAL INFORMATION
232
- ---------------------
233
- [Any additional information relevant to the breach]
234
-
235
- This notification is made in compliance with the Nigeria Data Protection Regulation (NDPR).
236
- `;
237
- };
238
-
239
- // Handle form submission
240
- const handleSubmit = (e: React.FormEvent) => {
241
- e.preventDefault();
242
-
243
- const notification: RegulatoryNotification = {
244
- id: `notification_${Date.now()}`,
245
- breachId: breachData.id,
246
- sentAt: Date.now(),
247
- method,
248
- referenceNumber: referenceNumber || undefined,
249
- nitdaContact: contactName ? {
250
- name: contactName,
251
- email: contactEmail,
252
- phone: contactPhone || undefined
253
- } : undefined,
254
- content: reportContent,
255
- attachments: []
256
- };
257
-
258
- onGenerate(notification);
259
- setIsSubmitted(true);
260
- };
261
-
262
- // Handle download
263
- const handleDownload = () => {
264
- // In a real implementation, this would generate a PDF, DOCX, or HTML file
265
- // For this example, we'll just create a text file
266
-
267
- const element = document.createElement('a');
268
- const file = new Blob([reportContent], {type: 'text/plain'});
269
- element.href = URL.createObjectURL(file);
270
- element.download = `NITDA_Breach_Notification_${new Date().toISOString().split('T')[0]}.txt`;
271
- document.body.appendChild(element);
272
- element.click();
273
- document.body.removeChild(element);
274
- };
275
-
276
- // Render the notification method options
277
- const renderMethodOptions = () => {
278
- const options = [
279
- { value: 'email', label: 'Email' },
280
- { value: 'portal', label: 'NITDA Portal' },
281
- { value: 'letter', label: 'Formal Letter' },
282
- { value: 'other', label: 'Other' }
283
- ];
284
-
285
- return options.map(option => (
286
- <option key={option.value} value={option.value}>
287
- {option.label}
288
- </option>
289
- ));
290
- };
291
-
292
- return (
293
- <div className={`bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md ${className}`}>
294
- <h2 className="text-xl font-bold mb-2">{title}</h2>
295
- <p className="mb-6 text-gray-600 dark:text-gray-300">{description}</p>
296
-
297
- {isSubmitted ? (
298
- <div>
299
- <div className="mb-6 p-4 bg-green-50 dark:bg-green-900/20 rounded-md">
300
- <h3 className="text-lg font-bold text-green-800 dark:text-green-200 mb-2">Report Generated Successfully</h3>
301
- <p className="text-green-700 dark:text-green-300">
302
- Your NITDA notification report has been generated and is ready for submission.
303
- Please review the report carefully before submitting it to NITDA.
304
- </p>
305
- </div>
306
-
307
- <div className="mb-6">
308
- <h3 className="text-lg font-semibold mb-3">Submission Details</h3>
309
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
310
- <div>
311
- <p className="text-sm"><span className="font-medium">Method:</span> {method.charAt(0).toUpperCase() + method.slice(1)}</p>
312
- {contactName && <p className="text-sm"><span className="font-medium">Contact Name:</span> {contactName}</p>}
313
- {contactEmail && <p className="text-sm"><span className="font-medium">Contact Email:</span> {contactEmail}</p>}
314
- {contactPhone && <p className="text-sm"><span className="font-medium">Contact Phone:</span> {contactPhone}</p>}
315
- </div>
316
- <div>
317
- <p className="text-sm"><span className="font-medium">Date Generated:</span> {formatDate(Date.now())}</p>
318
- <p className="text-sm"><span className="font-medium">Breach ID:</span> {breachData.id}</p>
319
- {referenceNumber && <p className="text-sm"><span className="font-medium">Reference Number:</span> {referenceNumber}</p>}
320
- </div>
321
- </div>
322
- </div>
323
-
324
- {showPreview && (
325
- <div className="mb-6">
326
- <h3 className="text-lg font-semibold mb-3">Report Preview</h3>
327
- <div className="bg-gray-50 dark:bg-gray-700 p-4 rounded-md">
328
- <pre className="whitespace-pre-wrap text-sm font-mono text-gray-800 dark:text-gray-200">
329
- {reportContent}
330
- </pre>
331
- </div>
332
- </div>
333
- )}
334
-
335
- <div className="flex flex-wrap gap-3">
336
- {allowDownload && (
337
- <button
338
- onClick={handleDownload}
339
- className={`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 ${buttonClassName}`}
340
- >
341
- Download Report ({downloadFormat.toUpperCase()})
342
- </button>
343
- )}
344
- <button
345
- onClick={() => setIsSubmitted(false)}
346
- className={`px-4 py-2 bg-gray-200 text-gray-800 dark:bg-gray-700 dark:text-white rounded hover:bg-gray-300 dark:hover:bg-gray-600 ${buttonClassName}`}
347
- >
348
- Edit Report
349
- </button>
350
- </div>
351
- </div>
352
- ) : (
353
- <form onSubmit={handleSubmit}>
354
- <div className="space-y-6">
355
- {/* Notification Method */}
356
- <div>
357
- <h3 className="text-lg font-semibold mb-3">Notification Method</h3>
358
- <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
359
- <div>
360
- <label htmlFor="method" className="block text-sm font-medium mb-1">
361
- Method of Submission <span className="text-red-500">*</span>
362
- </label>
363
- <select
364
- id="method"
365
- value={method}
366
- onChange={e => setMethod(e.target.value as 'email' | 'portal' | 'letter' | 'other')}
367
- className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
368
- required
369
- >
370
- {renderMethodOptions()}
371
- </select>
372
- </div>
373
-
374
- <div>
375
- <label htmlFor="referenceNumber" className="block text-sm font-medium mb-1">
376
- Reference Number (if available)
377
- </label>
378
- <input
379
- type="text"
380
- id="referenceNumber"
381
- value={referenceNumber}
382
- onChange={e => setReferenceNumber(e.target.value)}
383
- placeholder="e.g. NITDA/BR/2023/001"
384
- className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
385
- />
386
- </div>
387
- </div>
388
- </div>
389
-
390
- {/* NITDA Contact */}
391
- <div>
392
- <h3 className="text-lg font-semibold mb-3">NITDA Contact (if known)</h3>
393
- <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
394
- <div>
395
- <label htmlFor="contactName" className="block text-sm font-medium mb-1">
396
- Contact Name
397
- </label>
398
- <input
399
- type="text"
400
- id="contactName"
401
- value={contactName}
402
- onChange={e => setContactName(e.target.value)}
403
- className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
404
- />
405
- </div>
406
-
407
- <div>
408
- <label htmlFor="contactEmail" className="block text-sm font-medium mb-1">
409
- Contact Email
410
- </label>
411
- <input
412
- type="email"
413
- id="contactEmail"
414
- value={contactEmail}
415
- onChange={e => setContactEmail(e.target.value)}
416
- className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
417
- />
418
- </div>
419
-
420
- <div>
421
- <label htmlFor="contactPhone" className="block text-sm font-medium mb-1">
422
- Contact Phone
423
- </label>
424
- <input
425
- type="tel"
426
- id="contactPhone"
427
- value={contactPhone}
428
- onChange={e => setContactPhone(e.target.value)}
429
- className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
430
- />
431
- </div>
432
- </div>
433
- </div>
434
-
435
- {/* Additional Information */}
436
- <div>
437
- <h3 className="text-lg font-semibold mb-3">Additional Information</h3>
438
- <div>
439
- <label htmlFor="additionalInfo" className="block text-sm font-medium mb-1">
440
- Additional Information to Include
441
- </label>
442
- <textarea
443
- id="additionalInfo"
444
- value={additionalInfo}
445
- onChange={e => setAdditionalInfo(e.target.value)}
446
- rows={3}
447
- placeholder="Any additional information you want to include in the report"
448
- className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
449
- />
450
- </div>
451
- </div>
452
-
453
- {/* Report Content */}
454
- {allowEditing && (
455
- <div>
456
- <h3 className="text-lg font-semibold mb-3">Report Content</h3>
457
- <div>
458
- <label htmlFor="reportContent" className="block text-sm font-medium mb-1">
459
- Edit Report Content <span className="text-red-500">*</span>
460
- </label>
461
- <textarea
462
- id="reportContent"
463
- value={reportContent}
464
- onChange={e => setReportContent(e.target.value)}
465
- rows={20}
466
- className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm"
467
- required
468
- />
469
- </div>
470
- </div>
471
- )}
472
-
473
- {/* NDPR Notice */}
474
- <div className="mt-6 p-4 bg-blue-50 dark:bg-blue-900/20 rounded-md">
475
- <h3 className="text-sm font-bold text-blue-800 dark:text-blue-200 mb-2">NDPR Breach Notification Requirements</h3>
476
- <p className="text-blue-700 dark:text-blue-300 text-sm">
477
- Under the Nigeria Data Protection Regulation (NDPR), data breaches that pose a risk to the rights and freedoms of data subjects must be reported to NITDA within 72 hours of discovery.
478
- This report will help you comply with this requirement.
479
- </p>
480
- </div>
481
-
482
- {/* Submit Button */}
483
- <div className="mt-6">
484
- <button
485
- type="submit"
486
- className={`px-6 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${buttonClassName}`}
487
- >
488
- {generateButtonText}
489
- </button>
490
- </div>
491
- </div>
492
- </form>
493
- )}
494
- </div>
495
- );
496
- };