@tantainnovative/ndpr-toolkit 1.0.3 → 1.0.5
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/next-env.d.ts +5 -0
- package/package.json +1 -1
- package/packages/ndpr-toolkit/dist/components/breach/BreachNotificationManager.d.ts +62 -0
- package/packages/ndpr-toolkit/dist/components/breach/BreachReportForm.d.ts +66 -0
- package/packages/ndpr-toolkit/dist/components/breach/BreachRiskAssessment.d.ts +50 -0
- package/packages/ndpr-toolkit/dist/components/breach/RegulatoryReportGenerator.d.ts +94 -0
- package/packages/ndpr-toolkit/dist/components/consent/ConsentBanner.d.ts +79 -0
- package/packages/ndpr-toolkit/dist/components/consent/ConsentManager.d.ts +73 -0
- package/packages/ndpr-toolkit/dist/components/consent/ConsentStorage.d.ts +41 -0
- package/packages/ndpr-toolkit/dist/components/dpia/DPIAQuestionnaire.d.ts +70 -0
- package/packages/ndpr-toolkit/dist/components/dpia/DPIAReport.d.ts +40 -0
- package/packages/ndpr-toolkit/dist/components/dpia/StepIndicator.d.ts +64 -0
- package/packages/ndpr-toolkit/dist/components/dsr/DSRDashboard.d.ts +58 -0
- package/packages/ndpr-toolkit/dist/components/dsr/DSRRequestForm.d.ts +74 -0
- package/packages/ndpr-toolkit/dist/components/dsr/DSRTracker.d.ts +56 -0
- package/packages/ndpr-toolkit/dist/components/policy/PolicyExporter.d.ts +65 -0
- package/packages/ndpr-toolkit/dist/components/policy/PolicyGenerator.d.ts +54 -0
- package/packages/ndpr-toolkit/dist/components/policy/PolicyPreview.d.ts +71 -0
- package/packages/ndpr-toolkit/dist/hooks/useBreach.d.ts +97 -0
- package/packages/ndpr-toolkit/dist/hooks/useConsent.d.ts +63 -0
- package/packages/ndpr-toolkit/dist/hooks/useDPIA.d.ts +92 -0
- package/packages/ndpr-toolkit/dist/hooks/useDSR.d.ts +72 -0
- package/packages/ndpr-toolkit/dist/hooks/usePrivacyPolicy.d.ts +87 -0
- package/packages/ndpr-toolkit/dist/index.d.ts +31 -0
- package/packages/ndpr-toolkit/dist/index.esm.js +2 -0
- package/packages/ndpr-toolkit/dist/index.esm.js.map +1 -0
- package/packages/ndpr-toolkit/dist/index.js +2 -0
- package/packages/ndpr-toolkit/dist/index.js.map +1 -0
- package/packages/ndpr-toolkit/dist/setupTests.d.ts +2 -0
- package/packages/ndpr-toolkit/dist/types/breach.d.ts +239 -0
- package/packages/ndpr-toolkit/dist/types/consent.d.ts +95 -0
- package/packages/ndpr-toolkit/dist/types/dpia.d.ts +196 -0
- package/packages/ndpr-toolkit/dist/types/dsr.d.ts +162 -0
- package/packages/ndpr-toolkit/dist/types/privacy.d.ts +204 -0
- package/packages/ndpr-toolkit/dist/utils/breach.d.ts +14 -0
- package/packages/ndpr-toolkit/dist/utils/consent.d.ts +10 -0
- package/packages/ndpr-toolkit/dist/utils/dpia.d.ts +12 -0
- package/packages/ndpr-toolkit/dist/utils/dsr.d.ts +11 -0
- package/packages/ndpr-toolkit/dist/utils/privacy.d.ts +12 -0
- package/src/components/consent/ConsentBanner.tsx +82 -48
- package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +240 -129
- package/src/components/dpia/DPIAQuestionnaire.tsx +162 -122
- package/src/components/privacy-policy/PolicyGenerator.tsx +5 -5
- package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +103 -77
- package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +117 -63
- package/src/hooks/useConsent.ts +16 -10
- package/src/lib/consentService.ts +44 -37
- package/src/lib/dpiaQuestions.ts +139 -99
- package/src/lib/requestService.ts +21 -17
- package/src/types/index.ts +13 -8
- package/.claude/settings.local.json +0 -20
- package/.eslintrc.json +0 -10
- package/.github/workflows/ci.yml +0 -36
- package/.github/workflows/nextjs.yml +0 -104
- package/.husky/commit-msg +0 -4
- package/.husky/pre-commit +0 -4
- package/.lintstagedrc.js +0 -4
- package/.nvmrc +0 -1
- package/.versionrc +0 -17
- package/CLAUDE.md +0 -90
- package/commitlint.config.js +0 -36
- package/jest.config.js +0 -31
- package/jest.setup.js +0 -15
- package/packages/ndpr-toolkit/jest.config.js +0 -23
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +0 -119
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +0 -122
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +0 -270
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +0 -199
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +0 -224
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +0 -104
- package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +0 -161
- package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +0 -330
- package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +0 -149
- package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +0 -88
- package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +0 -160
- package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +0 -110
- package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +0 -97
- package/src/__tests__/example.test.ts +0 -13
- package/src/__tests__/requestService.test.ts +0 -57
- package/src/app/docs/components/DocLayout.tsx +0 -267
- package/src/app/docs/components/breach-notification/page.tsx +0 -797
- package/src/app/docs/components/consent-management/page.tsx +0 -576
- package/src/app/docs/components/data-subject-rights/page.tsx +0 -511
- package/src/app/docs/components/dpia-questionnaire/layout.tsx +0 -15
- package/src/app/docs/components/dpia-questionnaire/metadata.ts +0 -31
- package/src/app/docs/components/dpia-questionnaire/page.tsx +0 -666
- package/src/app/docs/components/hooks/page.tsx +0 -305
- package/src/app/docs/components/page.tsx +0 -84
- package/src/app/docs/components/privacy-policy-generator/page.tsx +0 -634
- package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +0 -123
- package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +0 -328
- package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +0 -28
- package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +0 -91
- package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +0 -118
- package/src/app/docs/guides/breach-notification-process/page.tsx +0 -39
- package/src/app/docs/guides/conducting-dpia/page.tsx +0 -593
- package/src/app/docs/guides/data-subject-requests/page.tsx +0 -666
- package/src/app/docs/guides/managing-consent/page.tsx +0 -738
- package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +0 -296
- package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +0 -145
- package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +0 -33
- package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +0 -99
- package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +0 -159
- package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +0 -38
- package/src/app/docs/guides/page.tsx +0 -67
- package/src/app/docs/layout.tsx +0 -15
- package/src/app/docs/metadata.ts +0 -31
- package/src/app/docs/page.tsx +0 -572
- package/src/components/docs/DocLayout.tsx +0 -289
- package/src/components/docs/index.ts +0 -2
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import React, { useRef, useState } from
|
|
4
|
-
import { FormField } from
|
|
5
|
-
import { Button } from
|
|
6
|
-
import { Input } from
|
|
7
|
-
import { TextArea } from
|
|
8
|
-
import {
|
|
9
|
-
|
|
3
|
+
import React, { useRef, useState } from "react";
|
|
4
|
+
import { FormField } from "@/components/ui/FormField";
|
|
5
|
+
import { Button } from "@/components/ui/Button";
|
|
6
|
+
import { Input } from "@/components/ui/Input";
|
|
7
|
+
import { TextArea } from "@/components/ui/TextArea";
|
|
8
|
+
import {
|
|
9
|
+
Card,
|
|
10
|
+
CardContent,
|
|
11
|
+
CardHeader,
|
|
12
|
+
CardTitle,
|
|
13
|
+
CardDescription,
|
|
14
|
+
} from "@/components/ui/Card";
|
|
15
|
+
import { Select } from "@/components/ui/Select";
|
|
10
16
|
|
|
11
17
|
interface CustomSectionsStepProps {
|
|
12
18
|
formData: {
|
|
@@ -33,15 +39,17 @@ export default function CustomSectionsStep({
|
|
|
33
39
|
}: CustomSectionsStepProps) {
|
|
34
40
|
const titleInputRef = useRef<HTMLInputElement>(null);
|
|
35
41
|
const contentInputRef = useRef<HTMLTextAreaElement>(null);
|
|
36
|
-
const [selectedTemplate, setSelectedTemplate] = useState<string>(
|
|
37
|
-
const [showTemplateContent, setShowTemplateContent] =
|
|
42
|
+
const [selectedTemplate, setSelectedTemplate] = useState<string>("");
|
|
43
|
+
const [showTemplateContent, setShowTemplateContent] =
|
|
44
|
+
useState<boolean>(false);
|
|
38
45
|
|
|
39
46
|
// Template sections that can be added to the policy
|
|
40
47
|
const templateSections: TemplateSectionType[] = [
|
|
41
48
|
{
|
|
42
|
-
id:
|
|
43
|
-
title:
|
|
44
|
-
description:
|
|
49
|
+
id: "gdpr-compliance",
|
|
50
|
+
title: "GDPR Compliance",
|
|
51
|
+
description:
|
|
52
|
+
"Information about compliance with the EU General Data Protection Regulation",
|
|
45
53
|
content: `In addition to complying with the Nigeria Data Protection Regulation (NDPR) and Data Protection Act (DPA), we also adhere to the European Union's General Data Protection Regulation (GDPR) for users from the European Economic Area (EEA).
|
|
46
54
|
|
|
47
55
|
When processing personal data of individuals in the EEA, we ensure that:
|
|
@@ -52,12 +60,13 @@ When processing personal data of individuals in the EEA, we ensure that:
|
|
|
52
60
|
- We maintain records of processing activities
|
|
53
61
|
|
|
54
62
|
For more information about our GDPR compliance measures, please contact us at the details provided in the 'Contact Us' section.`,
|
|
55
|
-
categories: [
|
|
63
|
+
categories: ["All"],
|
|
56
64
|
},
|
|
57
65
|
{
|
|
58
|
-
id:
|
|
59
|
-
title:
|
|
60
|
-
description:
|
|
66
|
+
id: "california-privacy-rights",
|
|
67
|
+
title: "California Privacy Rights",
|
|
68
|
+
description:
|
|
69
|
+
"Information about compliance with California privacy laws (CCPA/CPRA)",
|
|
61
70
|
content: `If you are a California resident, you have specific rights under California privacy laws, including the California Consumer Privacy Act (CCPA) and the California Privacy Rights Act (CPRA).
|
|
62
71
|
|
|
63
72
|
As a California resident, you have the right to:
|
|
@@ -68,12 +77,12 @@ As a California resident, you have the right to:
|
|
|
68
77
|
- Non-discrimination for exercising your rights
|
|
69
78
|
|
|
70
79
|
To exercise your California privacy rights, please contact us using the information in the 'Contact Us' section. We will respond to verifiable consumer requests within 45 days.`,
|
|
71
|
-
categories: [
|
|
80
|
+
categories: ["All"],
|
|
72
81
|
},
|
|
73
82
|
{
|
|
74
|
-
id:
|
|
75
|
-
title:
|
|
76
|
-
description:
|
|
83
|
+
id: "mobile-app-privacy",
|
|
84
|
+
title: "Mobile Application Privacy",
|
|
85
|
+
description: "Privacy information specific to mobile applications",
|
|
77
86
|
content: `Our mobile application collects and processes personal data as described in this Privacy Policy. In addition to the information outlined elsewhere in this policy, our mobile application may:
|
|
78
87
|
|
|
79
88
|
- Access your device's camera, microphone, or other sensors with your permission
|
|
@@ -82,45 +91,47 @@ To exercise your California privacy rights, please contact us using the informat
|
|
|
82
91
|
- Collect information about your mobile network and internet connection
|
|
83
92
|
|
|
84
93
|
You can control these permissions through your device settings. If you choose to deny certain permissions, some features of the application may not be available or may have limited functionality.`,
|
|
85
|
-
categories: [
|
|
94
|
+
categories: ["All"],
|
|
86
95
|
},
|
|
87
96
|
{
|
|
88
|
-
id:
|
|
89
|
-
title:
|
|
90
|
-
description:
|
|
97
|
+
id: "social-media-integration",
|
|
98
|
+
title: "Social Media Integration",
|
|
99
|
+
description: "Information about social media features and widgets",
|
|
91
100
|
content: `Our services may include social media features, such as the Facebook Like button, and widgets, such as the Share button. These features may collect your IP address, which page you are visiting, and may set a cookie to enable the feature to function properly.
|
|
92
101
|
|
|
93
102
|
Social media features and widgets are either hosted by a third party or hosted directly on our site. Your interactions with these features are governed by the privacy policy of the company providing it.
|
|
94
103
|
|
|
95
104
|
If you choose to connect your account with us to a social media account, we may receive personal information about you from the social media provider, including your profile information, friends or connections list, and other information you have permitted the social media provider to share with third parties.`,
|
|
96
|
-
categories: [
|
|
105
|
+
categories: ["All"],
|
|
97
106
|
},
|
|
98
107
|
{
|
|
99
|
-
id:
|
|
100
|
-
title:
|
|
101
|
-
description:
|
|
108
|
+
id: "ecommerce-payments",
|
|
109
|
+
title: "Payment Processing",
|
|
110
|
+
description: "Information about payment processing and financial data",
|
|
102
111
|
content: `When you make a purchase through our services, your payment information is processed by our payment service providers. We do not store complete credit card or debit card details on our servers.
|
|
103
112
|
|
|
104
113
|
Our payment processors collect and store your payment information in accordance with industry standards and applicable regulations, including the Payment Card Industry Data Security Standard (PCI DSS).
|
|
105
114
|
|
|
106
115
|
We may retain certain information about your transactions, such as the date and amount of the purchase, the items purchased, and your billing and shipping information, for record-keeping, accounting, and legal compliance purposes.`,
|
|
107
|
-
categories: [
|
|
116
|
+
categories: ["E-commerce and retail", "Financial services and fintech"],
|
|
108
117
|
},
|
|
109
118
|
{
|
|
110
|
-
id:
|
|
111
|
-
title:
|
|
112
|
-
description:
|
|
119
|
+
id: "healthcare-privacy",
|
|
120
|
+
title: "Healthcare Information Privacy",
|
|
121
|
+
description:
|
|
122
|
+
"Information about healthcare data protection (relevant for healthcare organizations)",
|
|
113
123
|
content: `We understand the sensitive nature of health information and are committed to protecting the privacy and security of your health data. We implement specific measures to safeguard health information in accordance with applicable healthcare privacy laws.
|
|
114
124
|
|
|
115
125
|
We only collect health information with your explicit consent or when necessary to provide our healthcare services. We limit access to health information to authorized personnel who need it to perform their duties.
|
|
116
126
|
|
|
117
127
|
We do not use or disclose your health information for marketing purposes without your explicit consent. We maintain audit trails of access to health information and regularly review our security practices to ensure the ongoing protection of your health data.`,
|
|
118
|
-
categories: [
|
|
128
|
+
categories: ["Healthcare and medical"],
|
|
119
129
|
},
|
|
120
130
|
{
|
|
121
|
-
id:
|
|
122
|
-
title:
|
|
123
|
-
description:
|
|
131
|
+
id: "educational-privacy",
|
|
132
|
+
title: "Educational Records Privacy",
|
|
133
|
+
description:
|
|
134
|
+
"Information about educational data protection (relevant for educational institutions)",
|
|
124
135
|
content: `We are committed to protecting the privacy of educational records and student information. We collect and process educational data only for legitimate educational purposes and in accordance with applicable education privacy laws.
|
|
125
136
|
|
|
126
137
|
We implement specific measures to safeguard educational records, including:
|
|
@@ -130,12 +141,13 @@ We implement specific measures to safeguard educational records, including:
|
|
|
130
141
|
- Implementing security measures specific to the protection of educational data
|
|
131
142
|
|
|
132
143
|
We do not use student information for targeted advertising purposes or sell student information to third parties.`,
|
|
133
|
-
categories: [
|
|
144
|
+
categories: ["Education and e-learning"],
|
|
134
145
|
},
|
|
135
146
|
{
|
|
136
|
-
id:
|
|
137
|
-
title:
|
|
138
|
-
description:
|
|
147
|
+
id: "ndpr-dpa-details",
|
|
148
|
+
title: "NDPR and DPA Compliance Details",
|
|
149
|
+
description:
|
|
150
|
+
"Detailed information about compliance with Nigerian data protection laws",
|
|
139
151
|
content: `We are committed to full compliance with the Nigeria Data Protection Regulation (NDPR) of 2019 and the Data Protection Act (DPA) of 2023. Our compliance measures include:
|
|
140
152
|
|
|
141
153
|
1. **Data Protection Officer**: We have appointed a Data Protection Officer responsible for overseeing our data protection strategy and implementation.
|
|
@@ -153,22 +165,24 @@ We do not use student information for targeted advertising purposes or sell stud
|
|
|
153
165
|
7. **Data Processing Agreements**: We enter into written agreements with all data processors as required by Section 2.7 of the NDPR and Section 37 of the DPA.
|
|
154
166
|
|
|
155
167
|
For more information about our NDPR and DPA compliance program, please contact our Data Protection Officer.`,
|
|
156
|
-
categories: [
|
|
168
|
+
categories: ["All"],
|
|
157
169
|
},
|
|
158
170
|
];
|
|
159
171
|
|
|
160
172
|
// Filter template sections based on industry category
|
|
161
|
-
const filteredTemplateSections = templateSections.filter(
|
|
162
|
-
template
|
|
173
|
+
const filteredTemplateSections = templateSections.filter(
|
|
174
|
+
(template) =>
|
|
175
|
+
template.categories.includes("All") ||
|
|
176
|
+
template.categories.includes(formData.industryCategory),
|
|
163
177
|
);
|
|
164
178
|
|
|
165
179
|
// Handle adding a template section
|
|
166
180
|
const handleAddTemplateSection = () => {
|
|
167
181
|
if (selectedTemplate) {
|
|
168
|
-
const template = templateSections.find(t => t.id === selectedTemplate);
|
|
182
|
+
const template = templateSections.find((t) => t.id === selectedTemplate);
|
|
169
183
|
if (template) {
|
|
170
184
|
onAddCustomSection(template.title, template.content);
|
|
171
|
-
setSelectedTemplate(
|
|
185
|
+
setSelectedTemplate("");
|
|
172
186
|
setShowTemplateContent(false);
|
|
173
187
|
}
|
|
174
188
|
}
|
|
@@ -176,11 +190,18 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
176
190
|
|
|
177
191
|
// Handle adding a custom section
|
|
178
192
|
const handleAddCustomSection = () => {
|
|
179
|
-
if (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
titleInputRef.current.value
|
|
183
|
-
contentInputRef.current.value
|
|
193
|
+
if (
|
|
194
|
+
titleInputRef.current &&
|
|
195
|
+
contentInputRef.current &&
|
|
196
|
+
titleInputRef.current.value.trim() &&
|
|
197
|
+
contentInputRef.current.value.trim()
|
|
198
|
+
) {
|
|
199
|
+
onAddCustomSection(
|
|
200
|
+
titleInputRef.current.value.trim(),
|
|
201
|
+
contentInputRef.current.value.trim(),
|
|
202
|
+
);
|
|
203
|
+
titleInputRef.current.value = "";
|
|
204
|
+
contentInputRef.current.value = "";
|
|
184
205
|
}
|
|
185
206
|
};
|
|
186
207
|
|
|
@@ -188,17 +209,16 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
188
209
|
<div className="space-y-8">
|
|
189
210
|
<Card className="overflow-hidden shadow-md border border-gray-200 dark:border-gray-700">
|
|
190
211
|
<CardHeader className="bg-gradient-to-r from-slate-100 to-gray-100 dark:from-slate-800 dark:to-gray-800 pb-3">
|
|
191
|
-
<CardTitle className="text-lg font-semibold text-gray-800 dark:text-white">
|
|
212
|
+
<CardTitle className="text-lg font-semibold text-gray-800 dark:text-white">
|
|
213
|
+
Template Sections
|
|
214
|
+
</CardTitle>
|
|
192
215
|
<CardDescription className="text-sm text-gray-600 dark:text-gray-300">
|
|
193
216
|
Add pre-written sections to your privacy policy
|
|
194
217
|
</CardDescription>
|
|
195
218
|
</CardHeader>
|
|
196
219
|
<CardContent className="pt-5">
|
|
197
220
|
<div className="space-y-3">
|
|
198
|
-
<FormField
|
|
199
|
-
id="templateSection"
|
|
200
|
-
label="Select a Template Section"
|
|
201
|
-
>
|
|
221
|
+
<FormField id="templateSection" label="Select a Template Section">
|
|
202
222
|
<Select
|
|
203
223
|
id="templateSection"
|
|
204
224
|
value={selectedTemplate}
|
|
@@ -215,18 +235,24 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
215
235
|
))}
|
|
216
236
|
</Select>
|
|
217
237
|
</FormField>
|
|
218
|
-
|
|
238
|
+
|
|
219
239
|
{showTemplateContent && selectedTemplate && (
|
|
220
240
|
<div className="mt-3 bg-white dark:bg-gray-800 p-3 rounded border border-gray-200 dark:border-gray-600">
|
|
221
241
|
<h5 className="font-medium text-gray-900 dark:text-white mb-2">
|
|
222
|
-
{
|
|
242
|
+
{
|
|
243
|
+
templateSections.find((t) => t.id === selectedTemplate)
|
|
244
|
+
?.title
|
|
245
|
+
}
|
|
223
246
|
</h5>
|
|
224
247
|
<div className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-line max-h-40 overflow-y-auto">
|
|
225
|
-
{
|
|
248
|
+
{
|
|
249
|
+
templateSections.find((t) => t.id === selectedTemplate)
|
|
250
|
+
?.content
|
|
251
|
+
}
|
|
226
252
|
</div>
|
|
227
253
|
</div>
|
|
228
254
|
)}
|
|
229
|
-
|
|
255
|
+
|
|
230
256
|
<Button
|
|
231
257
|
variant="default"
|
|
232
258
|
size="sm"
|
|
@@ -238,32 +264,28 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
238
264
|
</div>
|
|
239
265
|
</CardContent>
|
|
240
266
|
</Card>
|
|
241
|
-
|
|
267
|
+
|
|
242
268
|
{/* Custom Sections */}
|
|
243
269
|
<Card className="overflow-hidden shadow-md border border-gray-200 dark:border-gray-700">
|
|
244
270
|
<CardHeader className="bg-gradient-to-r from-slate-100 to-gray-100 dark:from-slate-800 dark:to-gray-800 pb-3">
|
|
245
|
-
<CardTitle className="text-lg font-semibold text-gray-800 dark:text-white">
|
|
271
|
+
<CardTitle className="text-lg font-semibold text-gray-800 dark:text-white">
|
|
272
|
+
Create Custom Section
|
|
273
|
+
</CardTitle>
|
|
246
274
|
<CardDescription className="text-sm text-gray-600 dark:text-gray-300">
|
|
247
275
|
Add your own custom section to the privacy policy
|
|
248
276
|
</CardDescription>
|
|
249
277
|
</CardHeader>
|
|
250
278
|
<CardContent className="pt-5">
|
|
251
279
|
<div className="space-y-3">
|
|
252
|
-
<FormField
|
|
253
|
-
id="customSectionTitle"
|
|
254
|
-
label="Section Title"
|
|
255
|
-
>
|
|
280
|
+
<FormField id="customSectionTitle" label="Section Title">
|
|
256
281
|
<Input
|
|
257
282
|
id="customSectionTitle"
|
|
258
283
|
ref={titleInputRef}
|
|
259
284
|
placeholder="e.g., Cookies Policy, International Transfers"
|
|
260
285
|
/>
|
|
261
286
|
</FormField>
|
|
262
|
-
|
|
263
|
-
<FormField
|
|
264
|
-
id="customSectionContent"
|
|
265
|
-
label="Section Content"
|
|
266
|
-
>
|
|
287
|
+
|
|
288
|
+
<FormField id="customSectionContent" label="Section Content">
|
|
267
289
|
<TextArea
|
|
268
290
|
id="customSectionContent"
|
|
269
291
|
ref={contentInputRef}
|
|
@@ -271,7 +293,7 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
271
293
|
placeholder="Enter the content for this section..."
|
|
272
294
|
/>
|
|
273
295
|
</FormField>
|
|
274
|
-
|
|
296
|
+
|
|
275
297
|
<Button
|
|
276
298
|
variant="default"
|
|
277
299
|
size="sm"
|
|
@@ -282,12 +304,14 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
282
304
|
</div>
|
|
283
305
|
</CardContent>
|
|
284
306
|
</Card>
|
|
285
|
-
|
|
307
|
+
|
|
286
308
|
{/* Added Sections List */}
|
|
287
309
|
{formData.customSections.length > 0 && (
|
|
288
310
|
<Card className="overflow-hidden shadow-md border border-gray-200 dark:border-gray-700">
|
|
289
311
|
<CardHeader className="bg-gradient-to-r from-slate-100 to-gray-100 dark:from-slate-800 dark:to-gray-800 pb-3">
|
|
290
|
-
<CardTitle className="text-lg font-semibold text-gray-800 dark:text-white">
|
|
312
|
+
<CardTitle className="text-lg font-semibold text-gray-800 dark:text-white">
|
|
313
|
+
Added Custom Sections
|
|
314
|
+
</CardTitle>
|
|
291
315
|
<CardDescription className="text-sm text-gray-600 dark:text-gray-300">
|
|
292
316
|
Custom sections that will be included in your privacy policy
|
|
293
317
|
</CardDescription>
|
|
@@ -298,7 +322,9 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
298
322
|
<Card key={index} className="overflow-visible">
|
|
299
323
|
<CardContent className="pt-4">
|
|
300
324
|
<div className="flex items-center justify-between mb-2">
|
|
301
|
-
<h5 className="font-medium text-gray-900 dark:text-white">
|
|
325
|
+
<h5 className="font-medium text-gray-900 dark:text-white">
|
|
326
|
+
{section.title}
|
|
327
|
+
</h5>
|
|
302
328
|
<Button
|
|
303
329
|
variant="destructive"
|
|
304
330
|
size="sm"
|
|
@@ -309,8 +335,8 @@ For more information about our NDPR and DPA compliance program, please contact o
|
|
|
309
335
|
</Button>
|
|
310
336
|
</div>
|
|
311
337
|
<div className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-line max-h-32 overflow-y-auto">
|
|
312
|
-
{section.template.length > 200
|
|
313
|
-
? `${section.template.substring(0, 200)}...`
|
|
338
|
+
{section.template.length > 200
|
|
339
|
+
? `${section.template.substring(0, 200)}...`
|
|
314
340
|
: section.template}
|
|
315
341
|
</div>
|
|
316
342
|
{section.template.length > 200 && (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import React from
|
|
4
|
-
import { Card, CardContent } from
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Card, CardContent } from "@/components/ui/Card";
|
|
5
5
|
|
|
6
6
|
interface PolicyPreviewStepProps {
|
|
7
7
|
formData: {
|
|
@@ -37,8 +37,18 @@ export default function PolicyPreviewStep({
|
|
|
37
37
|
<CardContent className="p-6">
|
|
38
38
|
<div className="flex items-center justify-between mb-4 pb-3 border-b border-gray-200 dark:border-gray-700">
|
|
39
39
|
<h3 className="text-lg font-medium text-gray-900 dark:text-white flex items-center">
|
|
40
|
-
<svg
|
|
41
|
-
|
|
40
|
+
<svg
|
|
41
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
42
|
+
className="h-5 w-5 mr-2 text-indigo-500"
|
|
43
|
+
viewBox="0 0 20 20"
|
|
44
|
+
fill="currentColor"
|
|
45
|
+
aria-hidden="true"
|
|
46
|
+
>
|
|
47
|
+
<path
|
|
48
|
+
fillRule="evenodd"
|
|
49
|
+
d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z"
|
|
50
|
+
clipRule="evenodd"
|
|
51
|
+
/>
|
|
42
52
|
</svg>
|
|
43
53
|
Privacy Policy Preview
|
|
44
54
|
</h3>
|
|
@@ -47,24 +57,35 @@ export default function PolicyPreviewStep({
|
|
|
47
57
|
</span>
|
|
48
58
|
</div>
|
|
49
59
|
|
|
50
|
-
<div
|
|
60
|
+
<div
|
|
61
|
+
ref={previewRef}
|
|
62
|
+
className="prose dark:prose-invert prose-indigo max-w-none text-base prose-headings:text-gray-800 dark:prose-headings:text-gray-100 prose-p:text-gray-600 dark:prose-p:text-gray-300 prose-li:text-gray-600 dark:prose-li:text-gray-300 prose-h1:text-2xl prose-h1:font-bold prose-h2:text-xl prose-h2:font-semibold prose-h2:border-b prose-h2:border-gray-200 dark:prose-h2:border-gray-700 prose-h2:pb-2 prose-h2:mt-8 overflow-auto"
|
|
63
|
+
>
|
|
51
64
|
<h1>{formData.organizationName} Privacy Policy</h1>
|
|
52
65
|
|
|
53
66
|
<h2>Introduction</h2>
|
|
54
67
|
<p>
|
|
55
|
-
This Privacy Policy describes how {formData.organizationName}
|
|
56
|
-
|
|
68
|
+
This Privacy Policy describes how {formData.organizationName}{" "}
|
|
69
|
+
collects, uses, and discloses your personal information.
|
|
70
|
+
{formData.includeNDPRCompliance &&
|
|
71
|
+
" This policy is compliant with the Nigeria Data Protection Regulation (NDPR) and the Data Protection Act (DPA)."}
|
|
57
72
|
</p>
|
|
58
73
|
|
|
59
74
|
<h2>About Us</h2>
|
|
60
75
|
<p>
|
|
61
76
|
{formData.organizationName}
|
|
62
|
-
{formData.organizationAddress &&
|
|
63
|
-
|
|
77
|
+
{formData.organizationAddress &&
|
|
78
|
+
` is located at ${formData.organizationAddress}`}
|
|
79
|
+
.
|
|
80
|
+
{formData.organizationWebsite &&
|
|
81
|
+
` Our website is ${formData.organizationWebsite}.`}
|
|
64
82
|
</p>
|
|
65
83
|
|
|
66
84
|
<h2>Information We Collect</h2>
|
|
67
|
-
<p>
|
|
85
|
+
<p>
|
|
86
|
+
We collect and process your personal data for the following
|
|
87
|
+
purposes:
|
|
88
|
+
</p>
|
|
68
89
|
<ul>
|
|
69
90
|
{(formData.dataCollectionPurposes || []).map((purpose, index) => (
|
|
70
91
|
<li key={`purpose-${index}`}>{purpose}</li>
|
|
@@ -73,51 +94,74 @@ export default function PolicyPreviewStep({
|
|
|
73
94
|
|
|
74
95
|
<h2>Data Retention</h2>
|
|
75
96
|
<p>
|
|
76
|
-
We will retain your personal data for
|
|
77
|
-
|
|
97
|
+
We will retain your personal data for{" "}
|
|
98
|
+
{formData.dataRetentionPeriod ||
|
|
99
|
+
"a period appropriate to the purpose"}
|
|
100
|
+
, or for as long as necessary to fulfill the purposes for which it
|
|
101
|
+
was collected.
|
|
78
102
|
</p>
|
|
79
103
|
|
|
80
|
-
{formData.thirdPartySharing &&
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
{formData.thirdPartySharing &&
|
|
105
|
+
(formData.thirdParties || []).length > 0 && (
|
|
106
|
+
<>
|
|
107
|
+
<h2>Third-Party Sharing</h2>
|
|
108
|
+
<p>
|
|
109
|
+
We may share your personal information with the following
|
|
110
|
+
third parties:
|
|
111
|
+
</p>
|
|
112
|
+
<ul>
|
|
113
|
+
{(formData.thirdParties || []).map((party, index) => (
|
|
114
|
+
<li key={`party-${index}`}>{party}</li>
|
|
115
|
+
))}
|
|
116
|
+
</ul>
|
|
117
|
+
</>
|
|
118
|
+
)}
|
|
119
|
+
|
|
120
|
+
{formData.cookiesUsed &&
|
|
121
|
+
(formData.cookieTypes || []).length > 0 && (
|
|
122
|
+
<>
|
|
123
|
+
<h2>Cookies and Tracking Technologies</h2>
|
|
124
|
+
<p>
|
|
125
|
+
Our website uses cookies and similar tracking technologies.
|
|
126
|
+
We use the following types of cookies:
|
|
127
|
+
</p>
|
|
128
|
+
<ul>
|
|
129
|
+
{(formData.cookieTypes || []).map((type, index) => (
|
|
130
|
+
<li key={`type-${index}`}>{type}</li>
|
|
131
|
+
))}
|
|
132
|
+
</ul>
|
|
133
|
+
</>
|
|
134
|
+
)}
|
|
135
|
+
|
|
136
|
+
{formData.internationalTransfers &&
|
|
137
|
+
(formData.transferCountries || []).length > 0 && (
|
|
138
|
+
<>
|
|
139
|
+
<h2>International Data Transfers</h2>
|
|
140
|
+
<p>
|
|
141
|
+
We may transfer your personal data to the following
|
|
142
|
+
countries outside Nigeria:
|
|
143
|
+
</p>
|
|
144
|
+
<ul>
|
|
145
|
+
{(formData.transferCountries || []).map(
|
|
146
|
+
(country, index) => (
|
|
147
|
+
<li key={`country-${index}`}>{country}</li>
|
|
148
|
+
),
|
|
149
|
+
)}
|
|
150
|
+
</ul>
|
|
151
|
+
<p>
|
|
152
|
+
We ensure appropriate safeguards are in place to protect
|
|
153
|
+
your data when transferred internationally.
|
|
154
|
+
</p>
|
|
155
|
+
</>
|
|
156
|
+
)}
|
|
116
157
|
|
|
117
158
|
{(formData.securityMeasures || []).length > 0 && (
|
|
118
159
|
<>
|
|
119
160
|
<h2>Security Measures</h2>
|
|
120
|
-
<p>
|
|
161
|
+
<p>
|
|
162
|
+
We implement the following security measures to protect your
|
|
163
|
+
personal data:
|
|
164
|
+
</p>
|
|
121
165
|
<ul>
|
|
122
166
|
{(formData.securityMeasures || []).map((measure, index) => (
|
|
123
167
|
<li key={`measure-${index}`}>{measure}</li>
|
|
@@ -128,9 +172,9 @@ export default function PolicyPreviewStep({
|
|
|
128
172
|
|
|
129
173
|
<h2>Your Rights</h2>
|
|
130
174
|
<p>
|
|
131
|
-
{formData.includeNDPRCompliance
|
|
132
|
-
?
|
|
133
|
-
:
|
|
175
|
+
{formData.includeNDPRCompliance
|
|
176
|
+
? "Under the NDPR and DPA, you have the following rights:"
|
|
177
|
+
: "You have the following rights regarding your personal data:"}
|
|
134
178
|
</p>
|
|
135
179
|
<ul>
|
|
136
180
|
<li>Right to access your personal data</li>
|
|
@@ -140,29 +184,39 @@ export default function PolicyPreviewStep({
|
|
|
140
184
|
<li>Right to object to processing</li>
|
|
141
185
|
<li>Right to data portability</li>
|
|
142
186
|
</ul>
|
|
143
|
-
<p>
|
|
187
|
+
<p>
|
|
188
|
+
To exercise these rights, please contact us at{" "}
|
|
189
|
+
{formData.organizationContact}.
|
|
190
|
+
</p>
|
|
144
191
|
|
|
145
|
-
{(formData.customSections || []).length > 0 &&
|
|
146
|
-
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
192
|
+
{(formData.customSections || []).length > 0 &&
|
|
193
|
+
(formData.customSections || []).map((section, index) => (
|
|
194
|
+
<div key={`section-${index}`}>
|
|
195
|
+
<h2>{section.title}</h2>
|
|
196
|
+
<p>{section.template}</p>
|
|
197
|
+
</div>
|
|
198
|
+
))}
|
|
151
199
|
|
|
152
200
|
{formData.hasDPO && formData.dpoContact && (
|
|
153
201
|
<>
|
|
154
202
|
<h2>Data Protection Officer</h2>
|
|
155
|
-
<p>
|
|
203
|
+
<p>
|
|
204
|
+
You can contact our Data Protection Officer at{" "}
|
|
205
|
+
{formData.dpoContact}.
|
|
206
|
+
</p>
|
|
156
207
|
</>
|
|
157
208
|
)}
|
|
158
209
|
|
|
159
210
|
<h2>Contact Us</h2>
|
|
160
211
|
<p>
|
|
161
|
-
If you have any questions about this Privacy Policy, please
|
|
212
|
+
If you have any questions about this Privacy Policy, please
|
|
213
|
+
contact us at {formData.organizationContact}.
|
|
162
214
|
</p>
|
|
163
215
|
|
|
164
216
|
<p className="text-gray-500 dark:text-gray-400 mt-4">
|
|
165
|
-
Last Updated:
|
|
217
|
+
Last Updated:{" "}
|
|
218
|
+
{formData.policyEffectiveDate ||
|
|
219
|
+
new Date().toISOString().split("T")[0]}
|
|
166
220
|
</p>
|
|
167
221
|
</div>
|
|
168
222
|
</CardContent>
|