@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.
Files changed (110) hide show
  1. package/next-env.d.ts +5 -0
  2. package/package.json +1 -1
  3. package/packages/ndpr-toolkit/dist/components/breach/BreachNotificationManager.d.ts +62 -0
  4. package/packages/ndpr-toolkit/dist/components/breach/BreachReportForm.d.ts +66 -0
  5. package/packages/ndpr-toolkit/dist/components/breach/BreachRiskAssessment.d.ts +50 -0
  6. package/packages/ndpr-toolkit/dist/components/breach/RegulatoryReportGenerator.d.ts +94 -0
  7. package/packages/ndpr-toolkit/dist/components/consent/ConsentBanner.d.ts +79 -0
  8. package/packages/ndpr-toolkit/dist/components/consent/ConsentManager.d.ts +73 -0
  9. package/packages/ndpr-toolkit/dist/components/consent/ConsentStorage.d.ts +41 -0
  10. package/packages/ndpr-toolkit/dist/components/dpia/DPIAQuestionnaire.d.ts +70 -0
  11. package/packages/ndpr-toolkit/dist/components/dpia/DPIAReport.d.ts +40 -0
  12. package/packages/ndpr-toolkit/dist/components/dpia/StepIndicator.d.ts +64 -0
  13. package/packages/ndpr-toolkit/dist/components/dsr/DSRDashboard.d.ts +58 -0
  14. package/packages/ndpr-toolkit/dist/components/dsr/DSRRequestForm.d.ts +74 -0
  15. package/packages/ndpr-toolkit/dist/components/dsr/DSRTracker.d.ts +56 -0
  16. package/packages/ndpr-toolkit/dist/components/policy/PolicyExporter.d.ts +65 -0
  17. package/packages/ndpr-toolkit/dist/components/policy/PolicyGenerator.d.ts +54 -0
  18. package/packages/ndpr-toolkit/dist/components/policy/PolicyPreview.d.ts +71 -0
  19. package/packages/ndpr-toolkit/dist/hooks/useBreach.d.ts +97 -0
  20. package/packages/ndpr-toolkit/dist/hooks/useConsent.d.ts +63 -0
  21. package/packages/ndpr-toolkit/dist/hooks/useDPIA.d.ts +92 -0
  22. package/packages/ndpr-toolkit/dist/hooks/useDSR.d.ts +72 -0
  23. package/packages/ndpr-toolkit/dist/hooks/usePrivacyPolicy.d.ts +87 -0
  24. package/packages/ndpr-toolkit/dist/index.d.ts +31 -0
  25. package/packages/ndpr-toolkit/dist/index.esm.js +2 -0
  26. package/packages/ndpr-toolkit/dist/index.esm.js.map +1 -0
  27. package/packages/ndpr-toolkit/dist/index.js +2 -0
  28. package/packages/ndpr-toolkit/dist/index.js.map +1 -0
  29. package/packages/ndpr-toolkit/dist/setupTests.d.ts +2 -0
  30. package/packages/ndpr-toolkit/dist/types/breach.d.ts +239 -0
  31. package/packages/ndpr-toolkit/dist/types/consent.d.ts +95 -0
  32. package/packages/ndpr-toolkit/dist/types/dpia.d.ts +196 -0
  33. package/packages/ndpr-toolkit/dist/types/dsr.d.ts +162 -0
  34. package/packages/ndpr-toolkit/dist/types/privacy.d.ts +204 -0
  35. package/packages/ndpr-toolkit/dist/utils/breach.d.ts +14 -0
  36. package/packages/ndpr-toolkit/dist/utils/consent.d.ts +10 -0
  37. package/packages/ndpr-toolkit/dist/utils/dpia.d.ts +12 -0
  38. package/packages/ndpr-toolkit/dist/utils/dsr.d.ts +11 -0
  39. package/packages/ndpr-toolkit/dist/utils/privacy.d.ts +12 -0
  40. package/src/components/consent/ConsentBanner.tsx +82 -48
  41. package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +240 -129
  42. package/src/components/dpia/DPIAQuestionnaire.tsx +162 -122
  43. package/src/components/privacy-policy/PolicyGenerator.tsx +5 -5
  44. package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +103 -77
  45. package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +117 -63
  46. package/src/hooks/useConsent.ts +16 -10
  47. package/src/lib/consentService.ts +44 -37
  48. package/src/lib/dpiaQuestions.ts +139 -99
  49. package/src/lib/requestService.ts +21 -17
  50. package/src/types/index.ts +13 -8
  51. package/.claude/settings.local.json +0 -20
  52. package/.eslintrc.json +0 -10
  53. package/.github/workflows/ci.yml +0 -36
  54. package/.github/workflows/nextjs.yml +0 -104
  55. package/.husky/commit-msg +0 -4
  56. package/.husky/pre-commit +0 -4
  57. package/.lintstagedrc.js +0 -4
  58. package/.nvmrc +0 -1
  59. package/.versionrc +0 -17
  60. package/CLAUDE.md +0 -90
  61. package/commitlint.config.js +0 -36
  62. package/jest.config.js +0 -31
  63. package/jest.setup.js +0 -15
  64. package/packages/ndpr-toolkit/jest.config.js +0 -23
  65. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +0 -119
  66. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +0 -122
  67. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +0 -270
  68. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +0 -199
  69. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +0 -224
  70. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +0 -104
  71. package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +0 -161
  72. package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +0 -330
  73. package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +0 -149
  74. package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +0 -88
  75. package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +0 -160
  76. package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +0 -110
  77. package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +0 -97
  78. package/src/__tests__/example.test.ts +0 -13
  79. package/src/__tests__/requestService.test.ts +0 -57
  80. package/src/app/docs/components/DocLayout.tsx +0 -267
  81. package/src/app/docs/components/breach-notification/page.tsx +0 -797
  82. package/src/app/docs/components/consent-management/page.tsx +0 -576
  83. package/src/app/docs/components/data-subject-rights/page.tsx +0 -511
  84. package/src/app/docs/components/dpia-questionnaire/layout.tsx +0 -15
  85. package/src/app/docs/components/dpia-questionnaire/metadata.ts +0 -31
  86. package/src/app/docs/components/dpia-questionnaire/page.tsx +0 -666
  87. package/src/app/docs/components/hooks/page.tsx +0 -305
  88. package/src/app/docs/components/page.tsx +0 -84
  89. package/src/app/docs/components/privacy-policy-generator/page.tsx +0 -634
  90. package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +0 -123
  91. package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +0 -328
  92. package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +0 -28
  93. package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +0 -91
  94. package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +0 -118
  95. package/src/app/docs/guides/breach-notification-process/page.tsx +0 -39
  96. package/src/app/docs/guides/conducting-dpia/page.tsx +0 -593
  97. package/src/app/docs/guides/data-subject-requests/page.tsx +0 -666
  98. package/src/app/docs/guides/managing-consent/page.tsx +0 -738
  99. package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +0 -296
  100. package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +0 -145
  101. package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +0 -33
  102. package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +0 -99
  103. package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +0 -159
  104. package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +0 -38
  105. package/src/app/docs/guides/page.tsx +0 -67
  106. package/src/app/docs/layout.tsx +0 -15
  107. package/src/app/docs/metadata.ts +0 -31
  108. package/src/app/docs/page.tsx +0 -572
  109. package/src/components/docs/DocLayout.tsx +0 -289
  110. package/src/components/docs/index.ts +0 -2
@@ -1,11 +1,13 @@
1
- 'use client';
1
+ "use client";
2
2
 
3
- import { useState, useEffect } from 'react';
4
- import { ConsentRecord } from '@/types';
5
- import consentService from '@/lib/consentService';
3
+ import { useState, useEffect } from "react";
4
+ import { ConsentRecord } from "@/types";
5
+ import consentService from "@/lib/consentService";
6
6
 
7
7
  export function useConsent() {
8
- const [consentRecord, setConsentRecord] = useState<ConsentRecord | null>(null);
8
+ const [consentRecord, setConsentRecord] = useState<ConsentRecord | null>(
9
+ null,
10
+ );
9
11
  const [isLoading, setIsLoading] = useState(true);
10
12
  const [showBanner, setShowBanner] = useState(false);
11
13
 
@@ -14,7 +16,7 @@ export function useConsent() {
14
16
  const storedConsent = consentService.getCurrentConsent();
15
17
  setConsentRecord(storedConsent);
16
18
  setIsLoading(false);
17
-
19
+
18
20
  // If no consent is stored, show the banner
19
21
  if (!storedConsent) {
20
22
  setShowBanner(true);
@@ -29,11 +31,15 @@ export function useConsent() {
29
31
  };
30
32
 
31
33
  const updateConsent = (
32
- consents: Record<string, boolean>,
34
+ consents: Record<string, boolean>,
33
35
  changeReason?: string,
34
- userId?: string
36
+ userId?: string,
35
37
  ) => {
36
- const updatedRecord = consentService.updateConsent(consents, changeReason, userId);
38
+ const updatedRecord = consentService.updateConsent(
39
+ consents,
40
+ changeReason,
41
+ userId,
42
+ );
37
43
  setConsentRecord(updatedRecord);
38
44
  return updatedRecord;
39
45
  };
@@ -59,6 +65,6 @@ export function useConsent() {
59
65
  updateConsent,
60
66
  hasConsent,
61
67
  openPreferences,
62
- closePreferences
68
+ closePreferences,
63
69
  };
64
70
  }
@@ -1,14 +1,14 @@
1
- 'use client';
1
+ "use client";
2
2
 
3
- import { ConsentRecord, ConsentHistoryEntry } from '@/types';
4
- import { v4 as uuidv4 } from 'uuid';
5
- import { storage } from './storage';
3
+ import { ConsentRecord, ConsentHistoryEntry } from "@/types";
4
+ import { v4 as uuidv4 } from "uuid";
5
+ import { storage } from "./storage";
6
6
 
7
7
  // In a real implementation, this would connect to a database
8
8
  // For demo purposes, we're using localStorage
9
9
 
10
- const CONSENT_STORAGE_KEY = 'ndpr_consent_records';
11
- const CONSENT_HISTORY_KEY = 'ndpr_consent_history';
10
+ const CONSENT_STORAGE_KEY = "ndpr_consent_records";
11
+ const CONSENT_HISTORY_KEY = "ndpr_consent_history";
12
12
 
13
13
  // Helper function to get consent history
14
14
  const getConsentHistoryHelper = (): ConsentHistoryEntry[] => {
@@ -17,37 +17,42 @@ const getConsentHistoryHelper = (): ConsentHistoryEntry[] => {
17
17
 
18
18
  export const consentService = {
19
19
  // Save a new consent record
20
- saveConsent: (consents: Record<string, boolean>, userId?: string): ConsentRecord => {
20
+ saveConsent: (
21
+ consents: Record<string, boolean>,
22
+ userId?: string,
23
+ ): ConsentRecord => {
21
24
  const consentRecord: ConsentRecord = {
22
25
  id: uuidv4(),
23
26
  userId,
24
27
  consents,
25
28
  timestamp: new Date(),
26
- ipAddress: 'Collected server-side in real implementation',
27
- userAgent: typeof window !== 'undefined' ? window.navigator.userAgent : 'Unknown',
28
- version: '1.0',
29
+ ipAddress: "Collected server-side in real implementation",
30
+ userAgent:
31
+ typeof window !== "undefined" ? window.navigator.userAgent : "Unknown",
32
+ version: "1.0",
29
33
  };
30
34
 
31
35
  // Store in localStorage for demo
32
36
  // Save as current consent
33
37
  if (!storage.setItem(CONSENT_STORAGE_KEY, consentRecord)) {
34
- throw new Error('Failed to save consent record');
38
+ throw new Error("Failed to save consent record");
35
39
  }
36
-
40
+
37
41
  // Add to history
38
42
  const historyEntry: ConsentHistoryEntry = {
39
43
  timestamp: new Date(),
40
44
  consents,
41
- action: 'granted',
42
- ipAddress: 'Collected server-side in real implementation',
43
- userAgent: typeof window !== 'undefined' ? window.navigator.userAgent : 'Unknown',
44
- version: '1.0',
45
+ action: "granted",
46
+ ipAddress: "Collected server-side in real implementation",
47
+ userAgent:
48
+ typeof window !== "undefined" ? window.navigator.userAgent : "Unknown",
49
+ version: "1.0",
45
50
  };
46
-
51
+
47
52
  const history = getConsentHistoryHelper();
48
53
  history.push(historyEntry);
49
54
  if (!storage.setItem(CONSENT_HISTORY_KEY, history)) {
50
- throw new Error('Failed to save consent history');
55
+ throw new Error("Failed to save consent history");
51
56
  }
52
57
 
53
58
  return consentRecord;
@@ -65,55 +70,57 @@ export const consentService = {
65
70
 
66
71
  // Update consent with change reason
67
72
  updateConsent: (
68
- consents: Record<string, boolean>,
73
+ consents: Record<string, boolean>,
69
74
  changeReason?: string,
70
- userId?: string
75
+ userId?: string,
71
76
  ): ConsentRecord => {
72
77
  // Get the previous consent to determine the action
73
78
  const previousConsent = consentService.getCurrentConsent();
74
-
79
+
75
80
  // Create the new consent record
76
81
  const consentRecord: ConsentRecord = {
77
82
  id: uuidv4(),
78
83
  userId,
79
84
  consents,
80
85
  timestamp: new Date(),
81
- ipAddress: 'Collected server-side in real implementation',
82
- userAgent: typeof window !== 'undefined' ? window.navigator.userAgent : 'Unknown',
83
- version: '1.0',
86
+ ipAddress: "Collected server-side in real implementation",
87
+ userAgent:
88
+ typeof window !== "undefined" ? window.navigator.userAgent : "Unknown",
89
+ version: "1.0",
84
90
  };
85
91
 
86
92
  // Store in localStorage for demo
87
93
  // Save as current consent
88
94
  if (!storage.setItem(CONSENT_STORAGE_KEY, consentRecord)) {
89
- throw new Error('Failed to save consent record');
95
+ throw new Error("Failed to save consent record");
90
96
  }
91
-
97
+
92
98
  // Determine the action type
93
- let action: 'granted' | 'revoked' | 'updated' = 'updated';
99
+ let action: "granted" | "revoked" | "updated" = "updated";
94
100
  if (!previousConsent) {
95
- action = 'granted';
101
+ action = "granted";
96
102
  } else {
97
- const allRevoked = Object.values(consents).every(v => !v);
103
+ const allRevoked = Object.values(consents).every((v) => !v);
98
104
  if (allRevoked) {
99
- action = 'revoked';
105
+ action = "revoked";
100
106
  }
101
107
  }
102
-
108
+
103
109
  // Add to history
104
110
  const historyEntry: ConsentHistoryEntry = {
105
111
  timestamp: new Date(),
106
112
  consents,
107
113
  action,
108
- ipAddress: 'Collected server-side in real implementation',
109
- userAgent: typeof window !== 'undefined' ? window.navigator.userAgent : 'Unknown',
110
- version: '1.0',
114
+ ipAddress: "Collected server-side in real implementation",
115
+ userAgent:
116
+ typeof window !== "undefined" ? window.navigator.userAgent : "Unknown",
117
+ version: "1.0",
111
118
  };
112
-
119
+
113
120
  const history = getConsentHistoryHelper();
114
121
  history.push(historyEntry);
115
122
  if (!storage.setItem(CONSENT_HISTORY_KEY, history)) {
116
- throw new Error('Failed to save consent history');
123
+ throw new Error("Failed to save consent history");
117
124
  }
118
125
 
119
126
  return consentRecord;
@@ -131,7 +138,7 @@ export const consentService = {
131
138
  const current = consentService.getCurrentConsent();
132
139
  if (!current) return false;
133
140
  return current.consents[type] === true;
134
- }
141
+ },
135
142
  };
136
143
 
137
144
  export default consentService;
@@ -1,148 +1,188 @@
1
- import { RiskAssessmentQuestion } from '@/types';
1
+ import { RiskAssessmentQuestion } from "@/types";
2
2
 
3
3
  export const dpiaQuestions: RiskAssessmentQuestion[] = [
4
4
  {
5
- id: 'data-collection-1',
6
- text: 'Does your project involve collecting personal data directly from individuals?',
7
- type: 'radio',
5
+ id: "data-collection-1",
6
+ text: "Does your project involve collecting personal data directly from individuals?",
7
+ type: "radio",
8
8
  required: true,
9
9
  options: [
10
- { value: "1", label: 'No personal data is collected' },
11
- { value: "2", label: 'Limited personal data is collected with clear consent' },
12
- { value: "3", label: 'Significant personal data is collected with consent' },
13
- { value: "4", label: 'Extensive personal data is collected' }
14
- ]
10
+ { value: "1", label: "No personal data is collected" },
11
+ {
12
+ value: "2",
13
+ label: "Limited personal data is collected with clear consent",
14
+ },
15
+ {
16
+ value: "3",
17
+ label: "Significant personal data is collected with consent",
18
+ },
19
+ { value: "4", label: "Extensive personal data is collected" },
20
+ ],
15
21
  },
16
22
  {
17
- id: 'data-collection-2',
18
- text: 'Does your project involve collecting sensitive personal data (e.g., health, biometric, religious beliefs)?',
19
- type: 'radio',
23
+ id: "data-collection-2",
24
+ text: "Does your project involve collecting sensitive personal data (e.g., health, biometric, religious beliefs)?",
25
+ type: "radio",
20
26
  required: true,
21
27
  options: [
22
- { value: "1", label: 'No sensitive data is collected' },
23
- { value: "2", label: 'Limited sensitive data with explicit consent' },
24
- { value: "3", label: 'Significant sensitive data with explicit consent' },
25
- { value: "4", label: 'Extensive sensitive data collection' }
26
- ]
28
+ { value: "1", label: "No sensitive data is collected" },
29
+ { value: "2", label: "Limited sensitive data with explicit consent" },
30
+ { value: "3", label: "Significant sensitive data with explicit consent" },
31
+ { value: "4", label: "Extensive sensitive data collection" },
32
+ ],
27
33
  },
28
34
  {
29
- id: 'data-collection-3',
30
- text: 'Does your project collect data from children or vulnerable individuals?',
31
- type: 'radio',
35
+ id: "data-collection-3",
36
+ text: "Does your project collect data from children or vulnerable individuals?",
37
+ type: "radio",
32
38
  required: true,
33
39
  options: [
34
- { value: "1", label: 'No data from children or vulnerable individuals' },
35
- { value: "2", label: 'Limited data with parental/guardian consent' },
36
- { value: "3", label: 'Significant data with enhanced safeguards' },
37
- { value: "4", label: 'Extensive data from vulnerable groups' }
38
- ]
40
+ { value: "1", label: "No data from children or vulnerable individuals" },
41
+ { value: "2", label: "Limited data with parental/guardian consent" },
42
+ { value: "3", label: "Significant data with enhanced safeguards" },
43
+ { value: "4", label: "Extensive data from vulnerable groups" },
44
+ ],
39
45
  },
40
46
  {
41
- id: 'data-processing-1',
42
- text: 'Does your project involve automated decision-making or profiling?',
43
- type: 'radio',
47
+ id: "data-processing-1",
48
+ text: "Does your project involve automated decision-making or profiling?",
49
+ type: "radio",
44
50
  required: true,
45
51
  options: [
46
- { value: "1", label: 'No automated decision-making' },
47
- { value: "2", label: 'Limited automation with human oversight' },
48
- { value: "3", label: 'Significant automation with opt-out options' },
49
- { value: "4", label: 'Extensive automated decisions affecting individuals' }
50
- ]
52
+ { value: "1", label: "No automated decision-making" },
53
+ { value: "2", label: "Limited automation with human oversight" },
54
+ { value: "3", label: "Significant automation with opt-out options" },
55
+ {
56
+ value: "4",
57
+ label: "Extensive automated decisions affecting individuals",
58
+ },
59
+ ],
51
60
  },
52
61
  {
53
- id: 'data-processing-2',
54
- text: 'Does your project involve processing data for purposes beyond what was initially collected for?',
55
- type: 'radio',
62
+ id: "data-processing-2",
63
+ text: "Does your project involve processing data for purposes beyond what was initially collected for?",
64
+ type: "radio",
56
65
  required: true,
57
66
  options: [
58
- { value: "1", label: 'Processing only for original purpose' },
59
- { value: "2", label: 'Limited secondary processing with notice' },
60
- { value: "3", label: 'Significant secondary processing with consent' },
61
- { value: "4", label: 'Extensive repurposing of data' }
62
- ]
67
+ { value: "1", label: "Processing only for original purpose" },
68
+ { value: "2", label: "Limited secondary processing with notice" },
69
+ { value: "3", label: "Significant secondary processing with consent" },
70
+ { value: "4", label: "Extensive repurposing of data" },
71
+ ],
63
72
  },
64
73
  {
65
- id: 'data-processing-3',
66
- text: 'Does your project combine data from multiple sources?',
67
- type: 'radio',
74
+ id: "data-processing-3",
75
+ text: "Does your project combine data from multiple sources?",
76
+ type: "radio",
68
77
  required: true,
69
78
  options: [
70
- { value: "1", label: 'No data combination' },
71
- { value: "2", label: 'Limited combination from controlled sources' },
72
- { value: "3", label: 'Significant combination with transparency' },
73
- { value: "4", label: 'Extensive data aggregation from various sources' }
74
- ]
79
+ { value: "1", label: "No data combination" },
80
+ { value: "2", label: "Limited combination from controlled sources" },
81
+ { value: "3", label: "Significant combination with transparency" },
82
+ { value: "4", label: "Extensive data aggregation from various sources" },
83
+ ],
75
84
  },
76
85
  {
77
- id: 'data-sharing-1',
78
- text: 'Does your project involve sharing personal data with third parties?',
79
- type: 'radio',
86
+ id: "data-sharing-1",
87
+ text: "Does your project involve sharing personal data with third parties?",
88
+ type: "radio",
80
89
  required: true,
81
90
  options: [
82
- { value: "1", label: 'No third-party sharing' },
83
- { value: "2", label: 'Limited sharing with contractual safeguards' },
84
- { value: "3", label: 'Significant sharing with data processing agreements' },
85
- { value: "4", label: 'Extensive sharing with multiple third parties' }
86
- ]
91
+ { value: "1", label: "No third-party sharing" },
92
+ { value: "2", label: "Limited sharing with contractual safeguards" },
93
+ {
94
+ value: "3",
95
+ label: "Significant sharing with data processing agreements",
96
+ },
97
+ { value: "4", label: "Extensive sharing with multiple third parties" },
98
+ ],
87
99
  },
88
100
  {
89
- id: 'data-sharing-2',
90
- text: 'Does your project involve transferring data outside Nigeria?',
91
- type: 'radio',
101
+ id: "data-sharing-2",
102
+ text: "Does your project involve transferring data outside Nigeria?",
103
+ type: "radio",
92
104
  required: true,
93
105
  options: [
94
- { value: "1", label: 'No international transfers' },
95
- { value: "2", label: 'Limited transfers to countries with adequate protection' },
96
- { value: "3", label: 'Significant transfers with standard contractual clauses' },
97
- { value: "4", label: 'Extensive transfers to countries without adequate protection' }
98
- ]
106
+ { value: "1", label: "No international transfers" },
107
+ {
108
+ value: "2",
109
+ label: "Limited transfers to countries with adequate protection",
110
+ },
111
+ {
112
+ value: "3",
113
+ label: "Significant transfers with standard contractual clauses",
114
+ },
115
+ {
116
+ value: "4",
117
+ label: "Extensive transfers to countries without adequate protection",
118
+ },
119
+ ],
99
120
  },
100
121
  {
101
- id: 'security-1',
102
- text: 'What level of security measures does your project implement?',
103
- type: 'radio',
122
+ id: "security-1",
123
+ text: "What level of security measures does your project implement?",
124
+ type: "radio",
104
125
  required: true,
105
126
  options: [
106
- { value: "1", label: 'Comprehensive security with encryption, access controls, and regular audits' },
107
- { value: "2", label: 'Strong security measures with some monitoring' },
108
- { value: "3", label: 'Basic security measures meeting minimum requirements' },
109
- { value: "4", label: 'Limited security measures' }
110
- ]
127
+ {
128
+ value: "1",
129
+ label:
130
+ "Comprehensive security with encryption, access controls, and regular audits",
131
+ },
132
+ { value: "2", label: "Strong security measures with some monitoring" },
133
+ {
134
+ value: "3",
135
+ label: "Basic security measures meeting minimum requirements",
136
+ },
137
+ { value: "4", label: "Limited security measures" },
138
+ ],
111
139
  },
112
140
  {
113
- id: 'security-2',
114
- text: 'Does your project have a data breach response plan?',
115
- type: 'radio',
141
+ id: "security-2",
142
+ text: "Does your project have a data breach response plan?",
143
+ type: "radio",
116
144
  required: true,
117
145
  options: [
118
- { value: "1", label: 'Comprehensive breach plan with regular testing' },
119
- { value: "2", label: 'Documented breach plan with assigned responsibilities' },
120
- { value: "3", label: 'Basic breach notification procedure' },
121
- { value: "4", label: 'No formal breach response plan' }
122
- ]
146
+ { value: "1", label: "Comprehensive breach plan with regular testing" },
147
+ {
148
+ value: "2",
149
+ label: "Documented breach plan with assigned responsibilities",
150
+ },
151
+ { value: "3", label: "Basic breach notification procedure" },
152
+ { value: "4", label: "No formal breach response plan" },
153
+ ],
123
154
  },
124
155
  {
125
- id: 'data-subject-rights-1',
126
- text: 'How does your project facilitate data subject rights (access, rectification, erasure, etc.)?',
127
- type: 'radio',
156
+ id: "data-subject-rights-1",
157
+ text: "How does your project facilitate data subject rights (access, rectification, erasure, etc.)?",
158
+ type: "radio",
128
159
  required: true,
129
160
  options: [
130
- { value: "1", label: 'Automated self-service portal for all rights' },
131
- { value: "2", label: 'Documented procedures with reasonable response times' },
132
- { value: "3", label: 'Basic manual process for handling requests' },
133
- { value: "4", label: 'Limited or no formal process for rights requests' }
134
- ]
161
+ { value: "1", label: "Automated self-service portal for all rights" },
162
+ {
163
+ value: "2",
164
+ label: "Documented procedures with reasonable response times",
165
+ },
166
+ { value: "3", label: "Basic manual process for handling requests" },
167
+ { value: "4", label: "Limited or no formal process for rights requests" },
168
+ ],
135
169
  },
136
170
  {
137
- id: 'data-subject-rights-2',
138
- text: 'Does your project provide clear privacy information to data subjects?',
139
- type: 'radio',
171
+ id: "data-subject-rights-2",
172
+ text: "Does your project provide clear privacy information to data subjects?",
173
+ type: "radio",
140
174
  required: true,
141
175
  options: [
142
- { value: "1", label: 'Comprehensive, layered privacy notices in plain language' },
143
- { value: "2", label: 'Clear privacy policy with all required information' },
144
- { value: "3", label: 'Basic privacy notice covering essential elements' },
145
- { value: "4", label: 'Minimal or complex privacy information' }
146
- ]
147
- }
148
- ];
176
+ {
177
+ value: "1",
178
+ label: "Comprehensive, layered privacy notices in plain language",
179
+ },
180
+ {
181
+ value: "2",
182
+ label: "Clear privacy policy with all required information",
183
+ },
184
+ { value: "3", label: "Basic privacy notice covering essential elements" },
185
+ { value: "4", label: "Minimal or complex privacy information" },
186
+ ],
187
+ },
188
+ ];
@@ -1,10 +1,10 @@
1
- 'use client';
1
+ "use client";
2
2
 
3
- import { DataSubjectRequest, RequestStatus } from '@/types';
4
- import { v4 as uuidv4 } from 'uuid';
5
- import { storage } from './storage';
3
+ import { DataSubjectRequest, RequestStatus } from "@/types";
4
+ import { v4 as uuidv4 } from "uuid";
5
+ import { storage } from "./storage";
6
6
 
7
- const REQUEST_STORAGE_KEY = 'ndpr_requests';
7
+ const REQUEST_STORAGE_KEY = "ndpr_requests";
8
8
 
9
9
  const getStoredRequests = (): DataSubjectRequest[] => {
10
10
  return storage.getItem<DataSubjectRequest[]>(REQUEST_STORAGE_KEY, []) || [];
@@ -12,16 +12,15 @@ const getStoredRequests = (): DataSubjectRequest[] => {
12
12
 
13
13
  export const requestService = {
14
14
  createRequest: (
15
- requestType: DataSubjectRequest['type'],
15
+ requestType: DataSubjectRequest["type"],
16
16
  requesterName: string,
17
17
  requesterEmail: string,
18
18
  details: string,
19
- consent: boolean
20
19
  ): DataSubjectRequest => {
21
20
  const request: DataSubjectRequest = {
22
21
  id: uuidv4(),
23
22
  type: requestType,
24
- status: 'pending',
23
+ status: "pending",
25
24
  createdAt: Date.now(),
26
25
  updatedAt: Date.now(),
27
26
  subject: {
@@ -34,33 +33,38 @@ export const requestService = {
34
33
  const requests = getStoredRequests();
35
34
  requests.push(request);
36
35
  const saved = storage.setItem(REQUEST_STORAGE_KEY, requests);
37
-
36
+
38
37
  if (!saved) {
39
- throw new Error('Failed to save request. Storage may be full or unavailable.');
38
+ throw new Error(
39
+ "Failed to save request. Storage may be full or unavailable.",
40
+ );
40
41
  }
41
42
 
42
43
  return request;
43
44
  },
44
45
 
45
- updateStatus: (id: string, status: RequestStatus): DataSubjectRequest | null => {
46
+ updateStatus: (
47
+ id: string,
48
+ status: RequestStatus,
49
+ ): DataSubjectRequest | null => {
46
50
  const requests = getStoredRequests();
47
- const idx = requests.findIndex(r => r.id === id);
51
+ const idx = requests.findIndex((r) => r.id === id);
48
52
  if (idx === -1) return null;
49
-
53
+
50
54
  requests[idx].status = status;
51
55
  requests[idx].updatedAt = Date.now();
52
-
56
+
53
57
  const saved = storage.setItem(REQUEST_STORAGE_KEY, requests);
54
58
  if (!saved) {
55
- throw new Error('Failed to update request status.');
59
+ throw new Error("Failed to update request status.");
56
60
  }
57
-
61
+
58
62
  return requests[idx];
59
63
  },
60
64
 
61
65
  getRequest: (id: string): DataSubjectRequest | null => {
62
66
  const requests = getStoredRequests();
63
- return requests.find(r => r.id === id) || null;
67
+ return requests.find((r) => r.id === id) || null;
64
68
  },
65
69
 
66
70
  getAllRequests: (): DataSubjectRequest[] => {
@@ -1,12 +1,12 @@
1
1
  // Re-export all types from the package
2
2
  // This ensures consistency between the main app and the package
3
- export * from '@tantainnovative/ndpr-toolkit';
4
- import type { DSRStatus, DSRType } from '@tantainnovative/ndpr-toolkit';
3
+ export * from "@tantainnovative/ndpr-toolkit";
4
+ import type { DSRStatus, DSRType } from "@tantainnovative/ndpr-toolkit";
5
5
 
6
6
  // Additional app-specific types that extend the package types
7
7
  export interface AppConfig {
8
8
  apiUrl?: string;
9
- environment: 'development' | 'staging' | 'production';
9
+ environment: "development" | "staging" | "production";
10
10
  features: {
11
11
  consent: boolean;
12
12
  dsr: boolean;
@@ -38,14 +38,19 @@ export type {
38
38
  OrganizationInfo,
39
39
  DPIAQuestion as RiskAssessmentQuestion,
40
40
  DPIASection,
41
- DPIAResult
42
- } from '@tantainnovative/ndpr-toolkit';
41
+ DPIAResult,
42
+ } from "@tantainnovative/ndpr-toolkit";
43
43
 
44
44
  // Define ConsentType locally since it's not exported from the package
45
- export type ConsentType = 'necessary' | 'functional' | 'analytics' | 'marketing' | 'preferences';
45
+ export type ConsentType =
46
+ | "necessary"
47
+ | "functional"
48
+ | "analytics"
49
+ | "marketing"
50
+ | "preferences";
46
51
 
47
52
  // Define BreachSeverity type
48
- export type BreachSeverity = 'low' | 'medium' | 'high' | 'critical';
53
+ export type BreachSeverity = "low" | "medium" | "high" | "critical";
49
54
 
50
55
  // Define missing types that are not exported from the package
51
56
  export interface ConsentRecord {
@@ -61,7 +66,7 @@ export interface ConsentRecord {
61
66
  export interface ConsentHistoryEntry {
62
67
  timestamp: Date;
63
68
  consents: Record<string, boolean>;
64
- action: 'granted' | 'revoked' | 'updated';
69
+ action: "granted" | "revoked" | "updated";
65
70
  ipAddress?: string;
66
71
  userAgent?: string;
67
72
  version: string;
@@ -1,20 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(find:*)",
5
- "Bash(grep:*)",
6
- "Bash(git push:*)",
7
- "Bash(npm run lint)",
8
- "Bash(pnpm lint:*)",
9
- "Bash(pnpm install:*)",
10
- "Bash(git add:*)",
11
- "Bash(git commit:*)",
12
- "Bash(pnpm add:*)",
13
- "Bash(pnpm build:*)",
14
- "Bash(sed:*)",
15
- "Bash(cat:*)",
16
- "Bash(npm:*)"
17
- ],
18
- "deny": []
19
- }
20
- }