@tantainnovative/ndpr-toolkit 1.0.5 → 1.0.6

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 (159) hide show
  1. package/README.md +447 -84
  2. package/dist/index.esm.js +2 -0
  3. package/dist/index.esm.js.map +1 -0
  4. package/dist/index.js +2 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/types/index.d.ts +35 -0
  7. package/package.json +52 -70
  8. package/CHANGELOG.md +0 -16
  9. package/CNAME +0 -1
  10. package/CONTRIBUTING.md +0 -87
  11. package/RELEASE-NOTES-v1.0.0.md +0 -140
  12. package/RELEASE-NOTES-v1.0.1.md +0 -69
  13. package/SECURITY.md +0 -21
  14. package/components.json +0 -21
  15. package/eslint.config.mjs +0 -16
  16. package/next-env.d.ts +0 -5
  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/dist/index.esm.js +0 -2
  21. package/packages/ndpr-toolkit/dist/index.esm.js.map +0 -1
  22. package/packages/ndpr-toolkit/dist/index.js +0 -2
  23. package/packages/ndpr-toolkit/dist/index.js.map +0 -1
  24. package/packages/ndpr-toolkit/package-lock.json +0 -8197
  25. package/packages/ndpr-toolkit/package.json +0 -71
  26. package/packages/ndpr-toolkit/rollup.config.js +0 -34
  27. package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +0 -701
  28. package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +0 -631
  29. package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +0 -569
  30. package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +0 -496
  31. package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +0 -270
  32. package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +0 -217
  33. package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +0 -206
  34. package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +0 -342
  35. package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +0 -373
  36. package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +0 -174
  37. package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +0 -717
  38. package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +0 -476
  39. package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +0 -620
  40. package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +0 -541
  41. package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +0 -454
  42. package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +0 -333
  43. package/packages/ndpr-toolkit/src/hooks/useBreach.ts +0 -409
  44. package/packages/ndpr-toolkit/src/hooks/useConsent.ts +0 -263
  45. package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +0 -457
  46. package/packages/ndpr-toolkit/src/hooks/useDSR.ts +0 -236
  47. package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +0 -428
  48. package/packages/ndpr-toolkit/src/index.ts +0 -44
  49. package/packages/ndpr-toolkit/src/setupTests.ts +0 -5
  50. package/packages/ndpr-toolkit/src/types/breach.ts +0 -283
  51. package/packages/ndpr-toolkit/src/types/consent.ts +0 -111
  52. package/packages/ndpr-toolkit/src/types/dpia.ts +0 -236
  53. package/packages/ndpr-toolkit/src/types/dsr.ts +0 -192
  54. package/packages/ndpr-toolkit/src/types/index.ts +0 -42
  55. package/packages/ndpr-toolkit/src/types/privacy.ts +0 -246
  56. package/packages/ndpr-toolkit/src/utils/breach.ts +0 -122
  57. package/packages/ndpr-toolkit/src/utils/consent.ts +0 -51
  58. package/packages/ndpr-toolkit/src/utils/dpia.ts +0 -104
  59. package/packages/ndpr-toolkit/src/utils/dsr.ts +0 -77
  60. package/packages/ndpr-toolkit/src/utils/privacy.ts +0 -100
  61. package/packages/ndpr-toolkit/tsconfig.json +0 -23
  62. package/postcss.config.mjs +0 -5
  63. package/public/NDPR TOOLKIT.svg +0 -1
  64. package/public/favicon/android-chrome-192x192.png +0 -0
  65. package/public/favicon/android-chrome-512x512.png +0 -0
  66. package/public/favicon/apple-touch-icon.png +0 -0
  67. package/public/favicon/favicon-16x16.png +0 -0
  68. package/public/favicon/favicon-32x32.png +0 -0
  69. package/public/favicon/site.webmanifest +0 -1
  70. package/public/file.svg +0 -1
  71. package/public/globe.svg +0 -1
  72. package/public/ndpr-toolkit-logo.svg +0 -108
  73. package/public/next.svg +0 -1
  74. package/public/vercel.svg +0 -1
  75. package/public/window.svg +0 -1
  76. package/src/app/accessibility.css +0 -70
  77. package/src/app/favicon.ico +0 -0
  78. package/src/app/globals.css +0 -123
  79. package/src/app/layout.tsx +0 -37
  80. package/src/app/ndpr-demos/breach/page.tsx +0 -354
  81. package/src/app/ndpr-demos/consent/page.tsx +0 -366
  82. package/src/app/ndpr-demos/dpia/page.tsx +0 -495
  83. package/src/app/ndpr-demos/dsr/page.tsx +0 -280
  84. package/src/app/ndpr-demos/page.tsx +0 -73
  85. package/src/app/ndpr-demos/policy/page.tsx +0 -771
  86. package/src/app/page.tsx +0 -452
  87. package/src/components/ErrorBoundary.tsx +0 -90
  88. package/src/components/breach-notification/BreachNotificationForm.tsx +0 -479
  89. package/src/components/consent/ConsentBanner.tsx +0 -193
  90. package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +0 -530
  91. package/src/components/dpia/DPIAQuestionnaire.tsx +0 -523
  92. package/src/components/privacy-policy/PolicyGenerator.tsx +0 -1062
  93. package/src/components/privacy-policy/data.ts +0 -98
  94. package/src/components/privacy-policy/shared/CheckboxField.tsx +0 -38
  95. package/src/components/privacy-policy/shared/CheckboxGroup.tsx +0 -85
  96. package/src/components/privacy-policy/shared/FormField.tsx +0 -79
  97. package/src/components/privacy-policy/shared/StepIndicator.tsx +0 -86
  98. package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +0 -361
  99. package/src/components/privacy-policy/steps/DataCollectionStep.tsx +0 -231
  100. package/src/components/privacy-policy/steps/DataSharingStep.tsx +0 -418
  101. package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +0 -202
  102. package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +0 -226
  103. package/src/components/ui/Badge.tsx +0 -46
  104. package/src/components/ui/Button.tsx +0 -59
  105. package/src/components/ui/Card.tsx +0 -92
  106. package/src/components/ui/Checkbox.tsx +0 -57
  107. package/src/components/ui/FormField.tsx +0 -50
  108. package/src/components/ui/Input.tsx +0 -38
  109. package/src/components/ui/Loading.tsx +0 -201
  110. package/src/components/ui/Select.tsx +0 -42
  111. package/src/components/ui/TextArea.tsx +0 -38
  112. package/src/components/ui/label.tsx +0 -24
  113. package/src/components/ui/switch.tsx +0 -31
  114. package/src/components/ui/tabs.tsx +0 -66
  115. package/src/hooks/useConsent.ts +0 -70
  116. package/src/hooks/useLoadingState.ts +0 -85
  117. package/src/lib/consentService.ts +0 -144
  118. package/src/lib/dpiaQuestions.ts +0 -188
  119. package/src/lib/requestService.ts +0 -79
  120. package/src/lib/sanitize.ts +0 -108
  121. package/src/lib/storage.ts +0 -222
  122. package/src/lib/utils.ts +0 -6
  123. package/src/types/html-to-docx.d.ts +0 -30
  124. package/src/types/index.ts +0 -77
  125. package/tailwind.config.ts +0 -65
  126. package/tsconfig.json +0 -41
  127. /package/{packages/ndpr-toolkit/dist → dist}/components/breach/BreachNotificationManager.d.ts +0 -0
  128. /package/{packages/ndpr-toolkit/dist → dist}/components/breach/BreachReportForm.d.ts +0 -0
  129. /package/{packages/ndpr-toolkit/dist → dist}/components/breach/BreachRiskAssessment.d.ts +0 -0
  130. /package/{packages/ndpr-toolkit/dist → dist}/components/breach/RegulatoryReportGenerator.d.ts +0 -0
  131. /package/{packages/ndpr-toolkit/dist → dist}/components/consent/ConsentBanner.d.ts +0 -0
  132. /package/{packages/ndpr-toolkit/dist → dist}/components/consent/ConsentManager.d.ts +0 -0
  133. /package/{packages/ndpr-toolkit/dist → dist}/components/consent/ConsentStorage.d.ts +0 -0
  134. /package/{packages/ndpr-toolkit/dist → dist}/components/dpia/DPIAQuestionnaire.d.ts +0 -0
  135. /package/{packages/ndpr-toolkit/dist → dist}/components/dpia/DPIAReport.d.ts +0 -0
  136. /package/{packages/ndpr-toolkit/dist → dist}/components/dpia/StepIndicator.d.ts +0 -0
  137. /package/{packages/ndpr-toolkit/dist → dist}/components/dsr/DSRDashboard.d.ts +0 -0
  138. /package/{packages/ndpr-toolkit/dist → dist}/components/dsr/DSRRequestForm.d.ts +0 -0
  139. /package/{packages/ndpr-toolkit/dist → dist}/components/dsr/DSRTracker.d.ts +0 -0
  140. /package/{packages/ndpr-toolkit/dist → dist}/components/policy/PolicyExporter.d.ts +0 -0
  141. /package/{packages/ndpr-toolkit/dist → dist}/components/policy/PolicyGenerator.d.ts +0 -0
  142. /package/{packages/ndpr-toolkit/dist → dist}/components/policy/PolicyPreview.d.ts +0 -0
  143. /package/{packages/ndpr-toolkit/dist → dist}/hooks/useBreach.d.ts +0 -0
  144. /package/{packages/ndpr-toolkit/dist → dist}/hooks/useConsent.d.ts +0 -0
  145. /package/{packages/ndpr-toolkit/dist → dist}/hooks/useDPIA.d.ts +0 -0
  146. /package/{packages/ndpr-toolkit/dist → dist}/hooks/useDSR.d.ts +0 -0
  147. /package/{packages/ndpr-toolkit/dist → dist}/hooks/usePrivacyPolicy.d.ts +0 -0
  148. /package/{packages/ndpr-toolkit/dist → dist}/index.d.ts +0 -0
  149. /package/{packages/ndpr-toolkit/dist → dist}/setupTests.d.ts +0 -0
  150. /package/{packages/ndpr-toolkit/dist → dist}/types/breach.d.ts +0 -0
  151. /package/{packages/ndpr-toolkit/dist → dist}/types/consent.d.ts +0 -0
  152. /package/{packages/ndpr-toolkit/dist → dist}/types/dpia.d.ts +0 -0
  153. /package/{packages/ndpr-toolkit/dist → dist}/types/dsr.d.ts +0 -0
  154. /package/{packages/ndpr-toolkit/dist → dist}/types/privacy.d.ts +0 -0
  155. /package/{packages/ndpr-toolkit/dist → dist}/utils/breach.d.ts +0 -0
  156. /package/{packages/ndpr-toolkit/dist → dist}/utils/consent.d.ts +0 -0
  157. /package/{packages/ndpr-toolkit/dist → dist}/utils/dpia.d.ts +0 -0
  158. /package/{packages/ndpr-toolkit/dist → dist}/utils/dsr.d.ts +0 -0
  159. /package/{packages/ndpr-toolkit/dist → dist}/utils/privacy.d.ts +0 -0
@@ -1,201 +0,0 @@
1
- 'use client';
2
-
3
- import React from 'react';
4
- import { cn } from '@/lib/utils';
5
-
6
- interface LoadingSpinnerProps {
7
- size?: 'sm' | 'md' | 'lg';
8
- className?: string;
9
- }
10
-
11
- export function LoadingSpinner({ size = 'md', className }: LoadingSpinnerProps) {
12
- const sizeClasses = {
13
- sm: 'h-4 w-4',
14
- md: 'h-8 w-8',
15
- lg: 'h-12 w-12',
16
- };
17
-
18
- return (
19
- <div
20
- className={cn('inline-block animate-spin rounded-full border-2 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]', sizeClasses[size], className)}
21
- role="status"
22
- aria-label="Loading"
23
- >
24
- <span className="sr-only">Loading...</span>
25
- </div>
26
- );
27
- }
28
-
29
- interface LoadingOverlayProps {
30
- children?: React.ReactNode;
31
- message?: string;
32
- }
33
-
34
- export function LoadingOverlay({ children, message = 'Loading...' }: LoadingOverlayProps) {
35
- return (
36
- <div className="relative">
37
- <div className="absolute inset-0 bg-white/75 dark:bg-gray-900/75 backdrop-blur-sm z-10 flex items-center justify-center">
38
- <div className="text-center">
39
- <LoadingSpinner size="lg" className="mx-auto mb-4 text-blue-600 dark:text-blue-400" />
40
- <p className="text-sm font-medium text-gray-700 dark:text-gray-300">{message}</p>
41
- </div>
42
- </div>
43
- {children}
44
- </div>
45
- );
46
- }
47
-
48
- interface LoadingSkeletonProps {
49
- className?: string;
50
- lines?: number;
51
- }
52
-
53
- export function LoadingSkeleton({ className, lines = 1 }: LoadingSkeletonProps) {
54
- return (
55
- <div className={cn('animate-pulse', className)}>
56
- {Array.from({ length: lines }).map((_, i) => (
57
- <div
58
- key={i}
59
- className={cn(
60
- 'h-4 bg-gray-200 dark:bg-gray-700 rounded',
61
- i !== lines - 1 && 'mb-2',
62
- i === lines - 1 && 'w-3/4'
63
- )}
64
- />
65
- ))}
66
- </div>
67
- );
68
- }
69
-
70
- interface LoadingButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
71
- loading?: boolean;
72
- loadingText?: string;
73
- children: React.ReactNode;
74
- }
75
-
76
- export function LoadingButton({
77
- loading = false,
78
- loadingText = 'Loading...',
79
- children,
80
- disabled,
81
- className,
82
- ...props
83
- }: LoadingButtonProps) {
84
- return (
85
- <button
86
- disabled={loading || disabled}
87
- className={cn(
88
- 'relative inline-flex items-center justify-center',
89
- loading && 'cursor-not-allowed opacity-70',
90
- className
91
- )}
92
- {...props}
93
- >
94
- {loading ? (
95
- <>
96
- <LoadingSpinner size="sm" className="mr-2" />
97
- <span>{loadingText}</span>
98
- </>
99
- ) : (
100
- children
101
- )}
102
- </button>
103
- );
104
- }
105
-
106
- interface LoadingStateProps {
107
- loading: boolean;
108
- error?: Error | null;
109
- empty?: boolean;
110
- children: React.ReactNode;
111
- loadingComponent?: React.ReactNode;
112
- errorComponent?: React.ReactNode;
113
- emptyComponent?: React.ReactNode;
114
- emptyMessage?: string;
115
- }
116
-
117
- export function LoadingState({
118
- loading,
119
- error,
120
- empty,
121
- children,
122
- loadingComponent,
123
- errorComponent,
124
- emptyComponent,
125
- emptyMessage = 'No data found',
126
- }: LoadingStateProps) {
127
- if (loading) {
128
- return (
129
- <>
130
- {loadingComponent || (
131
- <div className="flex items-center justify-center py-8">
132
- <LoadingSpinner size="lg" />
133
- </div>
134
- )}
135
- </>
136
- );
137
- }
138
-
139
- if (error) {
140
- return (
141
- <>
142
- {errorComponent || (
143
- <div className="rounded-md bg-red-50 dark:bg-red-900/20 p-4" role="alert">
144
- <div className="flex">
145
- <div className="flex-shrink-0">
146
- <svg
147
- className="h-5 w-5 text-red-400"
148
- viewBox="0 0 20 20"
149
- fill="currentColor"
150
- aria-hidden="true"
151
- >
152
- <path
153
- fillRule="evenodd"
154
- d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z"
155
- clipRule="evenodd"
156
- />
157
- </svg>
158
- </div>
159
- <div className="ml-3">
160
- <h3 className="text-sm font-medium text-red-800 dark:text-red-200">
161
- Error loading data
162
- </h3>
163
- <p className="mt-1 text-sm text-red-700 dark:text-red-300">
164
- {error.message}
165
- </p>
166
- </div>
167
- </div>
168
- </div>
169
- )}
170
- </>
171
- );
172
- }
173
-
174
- if (empty) {
175
- return (
176
- <>
177
- {emptyComponent || (
178
- <div className="text-center py-8">
179
- <svg
180
- className="mx-auto h-12 w-12 text-gray-400"
181
- fill="none"
182
- viewBox="0 0 24 24"
183
- stroke="currentColor"
184
- aria-hidden="true"
185
- >
186
- <path
187
- strokeLinecap="round"
188
- strokeLinejoin="round"
189
- strokeWidth={2}
190
- d="M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"
191
- />
192
- </svg>
193
- <p className="mt-2 text-sm text-gray-500 dark:text-gray-400">{emptyMessage}</p>
194
- </div>
195
- )}
196
- </>
197
- );
198
- }
199
-
200
- return <>{children}</>;
201
- }
@@ -1,42 +0,0 @@
1
- 'use client';
2
-
3
- import React from 'react';
4
- import { cn } from '@/lib/utils';
5
-
6
- // This interface extends the standard HTML select attributes
7
- // and allows for additional props to be added in the future
8
- /* eslint-disable-next-line @typescript-eslint/no-empty-object-type */
9
- export interface SelectProps
10
- extends React.SelectHTMLAttributes<HTMLSelectElement> {
11
- // Custom props can be added here
12
- }
13
-
14
- const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
15
- ({ className, children, ...props }, ref) => {
16
- return (
17
- <select
18
- className={cn(
19
- "block w-full px-3 py-2 text-base",
20
- "border border-gray-300 dark:border-gray-600 rounded-md shadow-sm",
21
- "bg-white dark:bg-gray-800 text-gray-900 dark:text-white",
22
- "placeholder:text-gray-400 dark:placeholder:text-gray-500",
23
- "focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-400 dark:focus:border-blue-400",
24
- "disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-gray-50 dark:disabled:bg-gray-900",
25
- "appearance-none bg-no-repeat bg-right",
26
- "bg-[url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20stroke%3D%22%236b7280%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20stroke-width%3D%221.5%22%20d%3D%22m6%208%204%204%204-4%22%2F%3E%3C%2Fsvg%3E')]",
27
- "bg-[length:1.25em_1.25em] pr-10",
28
- "hover:border-blue-400 dark:hover:border-blue-500 transition-colors duration-200",
29
- className
30
- )}
31
- ref={ref}
32
- {...props}
33
- >
34
- {children}
35
- </select>
36
- );
37
- }
38
- );
39
-
40
- Select.displayName = "Select";
41
-
42
- export { Select };
@@ -1,38 +0,0 @@
1
- 'use client';
2
-
3
- import React from 'react';
4
- import { cn } from '@/lib/utils';
5
-
6
- // This interface extends the standard HTML textarea attributes
7
- // and allows for additional props to be added in the future
8
- /* eslint-disable-next-line @typescript-eslint/no-empty-object-type */
9
- export interface TextAreaProps
10
- extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
11
- // Custom props can be added here
12
- }
13
-
14
- const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
15
- ({ className, ...props }, ref) => {
16
- return (
17
- <textarea
18
- className={cn(
19
- "block w-full px-3 py-2 text-base",
20
- "border border-gray-300 dark:border-gray-600 rounded-md shadow-sm",
21
- "bg-white dark:bg-gray-800 text-gray-900 dark:text-white",
22
- "placeholder:text-gray-400 dark:placeholder:text-gray-500",
23
- "focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-400 dark:focus:border-blue-400",
24
- "disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-gray-50 dark:disabled:bg-gray-900",
25
- "min-h-[80px] resize-y",
26
- "hover:border-blue-400 dark:hover:border-blue-500 transition-colors duration-200",
27
- className
28
- )}
29
- ref={ref}
30
- {...props}
31
- />
32
- );
33
- }
34
- );
35
-
36
- TextArea.displayName = "TextArea";
37
-
38
- export { TextArea };
@@ -1,24 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as LabelPrimitive from "@radix-ui/react-label"
5
-
6
- import { cn } from "@/lib/utils"
7
-
8
- function Label({
9
- className,
10
- ...props
11
- }: React.ComponentProps<typeof LabelPrimitive.Root>) {
12
- return (
13
- <LabelPrimitive.Root
14
- data-slot="label"
15
- className={cn(
16
- "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
17
- className
18
- )}
19
- {...props}
20
- />
21
- )
22
- }
23
-
24
- export { Label }
@@ -1,31 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as SwitchPrimitive from "@radix-ui/react-switch"
5
-
6
- import { cn } from "@/lib/utils"
7
-
8
- function Switch({
9
- className,
10
- ...props
11
- }: React.ComponentProps<typeof SwitchPrimitive.Root>) {
12
- return (
13
- <SwitchPrimitive.Root
14
- data-slot="switch"
15
- className={cn(
16
- "peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
17
- className
18
- )}
19
- {...props}
20
- >
21
- <SwitchPrimitive.Thumb
22
- data-slot="switch-thumb"
23
- className={cn(
24
- "bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
25
- )}
26
- />
27
- </SwitchPrimitive.Root>
28
- )
29
- }
30
-
31
- export { Switch }
@@ -1,66 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as TabsPrimitive from "@radix-ui/react-tabs"
5
-
6
- import { cn } from "@/lib/utils"
7
-
8
- function Tabs({
9
- className,
10
- ...props
11
- }: React.ComponentProps<typeof TabsPrimitive.Root>) {
12
- return (
13
- <TabsPrimitive.Root
14
- data-slot="tabs"
15
- className={cn("flex flex-col gap-2", className)}
16
- {...props}
17
- />
18
- )
19
- }
20
-
21
- function TabsList({
22
- className,
23
- ...props
24
- }: React.ComponentProps<typeof TabsPrimitive.List>) {
25
- return (
26
- <TabsPrimitive.List
27
- data-slot="tabs-list"
28
- className={cn(
29
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
30
- className
31
- )}
32
- {...props}
33
- />
34
- )
35
- }
36
-
37
- function TabsTrigger({
38
- className,
39
- ...props
40
- }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
41
- return (
42
- <TabsPrimitive.Trigger
43
- data-slot="tabs-trigger"
44
- className={cn(
45
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
46
- className
47
- )}
48
- {...props}
49
- />
50
- )
51
- }
52
-
53
- function TabsContent({
54
- className,
55
- ...props
56
- }: React.ComponentProps<typeof TabsPrimitive.Content>) {
57
- return (
58
- <TabsPrimitive.Content
59
- data-slot="tabs-content"
60
- className={cn("flex-1 outline-none", className)}
61
- {...props}
62
- />
63
- )
64
- }
65
-
66
- export { Tabs, TabsList, TabsTrigger, TabsContent }
@@ -1,70 +0,0 @@
1
- "use client";
2
-
3
- import { useState, useEffect } from "react";
4
- import { ConsentRecord } from "@/types";
5
- import consentService from "@/lib/consentService";
6
-
7
- export function useConsent() {
8
- const [consentRecord, setConsentRecord] = useState<ConsentRecord | null>(
9
- null,
10
- );
11
- const [isLoading, setIsLoading] = useState(true);
12
- const [showBanner, setShowBanner] = useState(false);
13
-
14
- useEffect(() => {
15
- // Load consent from storage on component mount
16
- const storedConsent = consentService.getCurrentConsent();
17
- setConsentRecord(storedConsent);
18
- setIsLoading(false);
19
-
20
- // If no consent is stored, show the banner
21
- if (!storedConsent) {
22
- setShowBanner(true);
23
- }
24
- }, []);
25
-
26
- const saveConsent = (consents: Record<string, boolean>, userId?: string) => {
27
- const newRecord = consentService.saveConsent(consents, userId);
28
- setConsentRecord(newRecord);
29
- setShowBanner(false);
30
- return newRecord;
31
- };
32
-
33
- const updateConsent = (
34
- consents: Record<string, boolean>,
35
- changeReason?: string,
36
- userId?: string,
37
- ) => {
38
- const updatedRecord = consentService.updateConsent(
39
- consents,
40
- changeReason,
41
- userId,
42
- );
43
- setConsentRecord(updatedRecord);
44
- return updatedRecord;
45
- };
46
-
47
- const hasConsent = (type: string): boolean => {
48
- if (!consentRecord) return false;
49
- return consentRecord.consents[type] === true;
50
- };
51
-
52
- const openPreferences = () => {
53
- setShowBanner(true);
54
- };
55
-
56
- const closePreferences = () => {
57
- setShowBanner(false);
58
- };
59
-
60
- return {
61
- consentRecord,
62
- isLoading,
63
- showBanner,
64
- saveConsent,
65
- updateConsent,
66
- hasConsent,
67
- openPreferences,
68
- closePreferences,
69
- };
70
- }
@@ -1,85 +0,0 @@
1
- "use client";
2
-
3
- import { useState, useCallback } from "react";
4
-
5
- interface LoadingState<T = unknown> {
6
- loading: boolean;
7
- error: Error | null;
8
- data: T | null;
9
- }
10
-
11
- interface UseLoadingStateReturn<T = unknown> extends LoadingState<T> {
12
- setLoading: (loading: boolean) => void;
13
- setError: (error: Error | null) => void;
14
- setData: (data: T | null) => void;
15
- reset: () => void;
16
- execute: <R = T>(asyncFunction: () => Promise<R>) => Promise<R | null>;
17
- }
18
-
19
- export function useLoadingState<T = unknown>(
20
- initialData: T | null = null,
21
- ): UseLoadingStateReturn<T> {
22
- const [state, setState] = useState<LoadingState<T>>({
23
- loading: false,
24
- error: null,
25
- data: initialData,
26
- });
27
-
28
- const setLoading = useCallback((loading: boolean) => {
29
- setState((prev) => ({ ...prev, loading }));
30
- }, []);
31
-
32
- const setError = useCallback((error: Error | null) => {
33
- setState((prev) => ({ ...prev, error, loading: false }));
34
- }, []);
35
-
36
- const setData = useCallback((data: T | null) => {
37
- setState((prev) => ({ ...prev, data, loading: false, error: null }));
38
- }, []);
39
-
40
- const reset = useCallback(() => {
41
- setState({
42
- loading: false,
43
- error: null,
44
- data: initialData,
45
- });
46
- }, [initialData]);
47
-
48
- const execute = useCallback(
49
- async <R = T>(asyncFunction: () => Promise<R>): Promise<R | null> => {
50
- try {
51
- setLoading(true);
52
- const result = await asyncFunction();
53
- setData(result as unknown as T);
54
- return result;
55
- } catch (error) {
56
- setError(error as Error);
57
- return null;
58
- }
59
- },
60
- [setLoading, setData, setError],
61
- );
62
-
63
- return {
64
- ...state,
65
- setLoading,
66
- setError,
67
- setData,
68
- reset,
69
- execute,
70
- };
71
- }
72
-
73
- // Hook for managing multiple loading states
74
- export function useMultipleLoadingStates<T extends Record<string, unknown>>(
75
- keys: (keyof T)[],
76
- ): Record<keyof T, UseLoadingStateReturn> {
77
- const states: Partial<Record<keyof T, UseLoadingStateReturn>> = {};
78
-
79
- keys.forEach((key) => {
80
- // eslint-disable-next-line react-hooks/rules-of-hooks
81
- states[key] = useLoadingState();
82
- });
83
-
84
- return states as Record<keyof T, UseLoadingStateReturn>;
85
- }