@tantainnovative/ndpr-toolkit 1.0.5 → 1.0.7
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/README.md +88 -14
- package/dist/components/breach-notification/BreachNotificationForm.d.ts +18 -0
- package/dist/components/breach-notification/BreachNotificationForm.d.ts.map +1 -0
- package/dist/components/consent/ConsentBanner.d.ts +30 -0
- package/dist/components/consent/ConsentBanner.d.ts.map +1 -0
- package/dist/components/consent/ConsentManager.d.ts +51 -0
- package/dist/components/consent/ConsentManager.d.ts.map +1 -0
- package/dist/components/consent/ConsentSettings.d.ts +15 -0
- package/dist/components/consent/ConsentSettings.d.ts.map +1 -0
- package/dist/components/consent/unstyled/UnstyledConsentBanner.d.ts +7 -0
- package/dist/components/consent/unstyled/UnstyledConsentBanner.d.ts.map +1 -0
- package/dist/components/consent/unstyled/UnstyledConsentSettings.d.ts +7 -0
- package/dist/components/consent/unstyled/UnstyledConsentSettings.d.ts.map +1 -0
- package/dist/components/consent/unstyled/UnstyledConsentToggle.d.ts +8 -0
- package/dist/components/consent/unstyled/UnstyledConsentToggle.d.ts.map +1 -0
- package/dist/components/consent/unstyled/index.d.ts +4 -0
- package/dist/components/consent/unstyled/index.d.ts.map +1 -0
- package/dist/components/data-subject-rights/DataSubjectRequestForm.d.ts +14 -0
- package/dist/components/data-subject-rights/DataSubjectRequestForm.d.ts.map +1 -0
- package/dist/components/docs/DocLayout.d.ts +9 -0
- package/dist/components/docs/DocLayout.d.ts.map +1 -0
- package/dist/components/docs/index.d.ts +2 -0
- package/dist/components/docs/index.d.ts.map +1 -0
- package/dist/components/dpia/DPIAQuestionnaire.d.ts +9 -0
- package/dist/components/dpia/DPIAQuestionnaire.d.ts.map +1 -0
- package/dist/components/privacy-policy/PolicyGenerator.d.ts +12 -0
- package/dist/components/privacy-policy/PolicyGenerator.d.ts.map +1 -0
- package/dist/components/privacy-policy/data.d.ts +8 -0
- package/dist/components/privacy-policy/data.d.ts.map +1 -0
- package/dist/components/privacy-policy/shared/CheckboxField.d.ts +13 -0
- package/dist/components/privacy-policy/shared/CheckboxField.d.ts.map +1 -0
- package/dist/components/privacy-policy/shared/CheckboxGroup.d.ts +13 -0
- package/dist/components/privacy-policy/shared/CheckboxGroup.d.ts.map +1 -0
- package/dist/components/privacy-policy/shared/FormField.d.ts +13 -0
- package/dist/components/privacy-policy/shared/FormField.d.ts.map +1 -0
- package/dist/components/privacy-policy/shared/StepIndicator.d.ts +8 -0
- package/dist/components/privacy-policy/shared/StepIndicator.d.ts.map +1 -0
- package/dist/components/privacy-policy/steps/CustomSectionsStep.d.ts +15 -0
- package/dist/components/privacy-policy/steps/CustomSectionsStep.d.ts.map +1 -0
- package/dist/components/privacy-policy/steps/DataCollectionStep.d.ts +20 -0
- package/dist/components/privacy-policy/steps/DataCollectionStep.d.ts.map +1 -0
- package/dist/components/privacy-policy/steps/DataSharingStep.d.ts +34 -0
- package/dist/components/privacy-policy/steps/DataSharingStep.d.ts.map +1 -0
- package/dist/components/privacy-policy/steps/OrganizationInfoStep.d.ts +17 -0
- package/dist/components/privacy-policy/steps/OrganizationInfoStep.d.ts.map +1 -0
- package/dist/components/privacy-policy/steps/PolicyPreviewStep.d.ts +30 -0
- package/dist/components/privacy-policy/steps/PolicyPreviewStep.d.ts.map +1 -0
- package/dist/components/ui/Badge.d.ts +10 -0
- package/dist/components/ui/Badge.d.ts.map +1 -0
- package/dist/components/ui/Button.d.ts +11 -0
- package/dist/components/ui/Button.d.ts.map +1 -0
- package/dist/components/ui/Card.d.ts +10 -0
- package/dist/components/ui/Card.d.ts.map +1 -0
- package/dist/components/ui/Checkbox.d.ts +8 -0
- package/dist/components/ui/Checkbox.d.ts.map +1 -0
- package/dist/components/ui/FormField.d.ts +11 -0
- package/dist/components/ui/FormField.d.ts.map +1 -0
- package/dist/components/ui/Input.d.ts +6 -0
- package/dist/components/ui/Input.d.ts.map +1 -0
- package/dist/components/ui/Select.d.ts +6 -0
- package/dist/components/ui/Select.d.ts.map +1 -0
- package/dist/components/ui/TextArea.d.ts +6 -0
- package/dist/components/ui/TextArea.d.ts.map +1 -0
- package/dist/components/ui/dialog.d.ts +18 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/tabs.d.ts +8 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/contexts/ConsentContext.d.ts +35 -0
- package/dist/contexts/ConsentContext.d.ts.map +1 -0
- package/dist/contexts/GenericConsentContext.d.ts +11 -0
- package/dist/contexts/GenericConsentContext.d.ts.map +1 -0
- package/dist/hooks/useConsent.d.ts +12 -0
- package/dist/hooks/useConsent.d.ts.map +1 -0
- package/dist/hooks/useConsentActions.d.ts +12 -0
- package/dist/hooks/useConsentActions.d.ts.map +1 -0
- package/dist/hooks/useConsentManager.d.ts +14 -0
- package/dist/hooks/useConsentManager.d.ts.map +1 -0
- package/dist/hooks/useConsentState.d.ts +10 -0
- package/dist/hooks/useConsentState.d.ts.map +1 -0
- package/dist/index.d.mts +256 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/consentService.d.ts +11 -0
- package/dist/lib/consentService.d.ts.map +1 -0
- package/dist/lib/dpiaQuestions.d.ts +3 -0
- package/dist/lib/dpiaQuestions.d.ts.map +1 -0
- package/dist/lib/requestService.d.ts +10 -0
- package/dist/lib/requestService.d.ts.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/styles.css +38 -0
- package/dist/types/consent.d.ts +57 -0
- package/dist/types/consent.d.ts.map +1 -0
- package/dist/types/index.d.ts +91 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/unstyled.d.mts +22 -0
- package/dist/unstyled.d.ts +2 -0
- package/dist/unstyled.d.ts.map +1 -0
- package/dist/unstyled.js +2 -0
- package/dist/unstyled.js.map +1 -0
- package/dist/unstyled.mjs +2 -0
- package/dist/unstyled.mjs.map +1 -0
- package/package.json +33 -5
- package/CHANGELOG.md +0 -16
- package/CNAME +0 -1
- package/CONTRIBUTING.md +0 -87
- package/RELEASE-NOTES-v1.0.0.md +0 -140
- package/RELEASE-NOTES-v1.0.1.md +0 -69
- package/SECURITY.md +0 -21
- package/components.json +0 -21
- package/eslint.config.mjs +0 -16
- package/next-env.d.ts +0 -5
- package/next.config.js +0 -15
- package/next.config.ts +0 -62
- package/packages/ndpr-toolkit/README.md +0 -467
- package/packages/ndpr-toolkit/dist/components/breach/BreachNotificationManager.d.ts +0 -62
- package/packages/ndpr-toolkit/dist/components/breach/BreachReportForm.d.ts +0 -66
- package/packages/ndpr-toolkit/dist/components/breach/BreachRiskAssessment.d.ts +0 -50
- package/packages/ndpr-toolkit/dist/components/breach/RegulatoryReportGenerator.d.ts +0 -94
- package/packages/ndpr-toolkit/dist/components/consent/ConsentBanner.d.ts +0 -79
- package/packages/ndpr-toolkit/dist/components/consent/ConsentManager.d.ts +0 -73
- package/packages/ndpr-toolkit/dist/components/consent/ConsentStorage.d.ts +0 -41
- package/packages/ndpr-toolkit/dist/components/dpia/DPIAQuestionnaire.d.ts +0 -70
- package/packages/ndpr-toolkit/dist/components/dpia/DPIAReport.d.ts +0 -40
- package/packages/ndpr-toolkit/dist/components/dpia/StepIndicator.d.ts +0 -64
- package/packages/ndpr-toolkit/dist/components/dsr/DSRDashboard.d.ts +0 -58
- package/packages/ndpr-toolkit/dist/components/dsr/DSRRequestForm.d.ts +0 -74
- package/packages/ndpr-toolkit/dist/components/dsr/DSRTracker.d.ts +0 -56
- package/packages/ndpr-toolkit/dist/components/policy/PolicyExporter.d.ts +0 -65
- package/packages/ndpr-toolkit/dist/components/policy/PolicyGenerator.d.ts +0 -54
- package/packages/ndpr-toolkit/dist/components/policy/PolicyPreview.d.ts +0 -71
- package/packages/ndpr-toolkit/dist/hooks/useBreach.d.ts +0 -97
- package/packages/ndpr-toolkit/dist/hooks/useConsent.d.ts +0 -63
- package/packages/ndpr-toolkit/dist/hooks/useDPIA.d.ts +0 -92
- package/packages/ndpr-toolkit/dist/hooks/useDSR.d.ts +0 -72
- package/packages/ndpr-toolkit/dist/hooks/usePrivacyPolicy.d.ts +0 -87
- package/packages/ndpr-toolkit/dist/index.d.ts +0 -31
- package/packages/ndpr-toolkit/dist/index.esm.js +0 -2
- package/packages/ndpr-toolkit/dist/index.esm.js.map +0 -1
- package/packages/ndpr-toolkit/dist/index.js +0 -2
- package/packages/ndpr-toolkit/dist/index.js.map +0 -1
- package/packages/ndpr-toolkit/dist/setupTests.d.ts +0 -2
- package/packages/ndpr-toolkit/dist/types/breach.d.ts +0 -239
- package/packages/ndpr-toolkit/dist/types/consent.d.ts +0 -95
- package/packages/ndpr-toolkit/dist/types/dpia.d.ts +0 -196
- package/packages/ndpr-toolkit/dist/types/dsr.d.ts +0 -162
- package/packages/ndpr-toolkit/dist/types/privacy.d.ts +0 -204
- package/packages/ndpr-toolkit/dist/utils/breach.d.ts +0 -14
- package/packages/ndpr-toolkit/dist/utils/consent.d.ts +0 -10
- package/packages/ndpr-toolkit/dist/utils/dpia.d.ts +0 -12
- package/packages/ndpr-toolkit/dist/utils/dsr.d.ts +0 -11
- package/packages/ndpr-toolkit/dist/utils/privacy.d.ts +0 -12
- package/packages/ndpr-toolkit/package-lock.json +0 -8197
- package/packages/ndpr-toolkit/package.json +0 -71
- package/packages/ndpr-toolkit/rollup.config.js +0 -34
- package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +0 -701
- package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +0 -631
- package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +0 -569
- package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +0 -496
- package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +0 -270
- package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +0 -217
- package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +0 -206
- package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +0 -342
- package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +0 -373
- package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +0 -174
- package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +0 -717
- package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +0 -476
- package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +0 -620
- package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +0 -541
- package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +0 -454
- package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +0 -333
- package/packages/ndpr-toolkit/src/hooks/useBreach.ts +0 -409
- package/packages/ndpr-toolkit/src/hooks/useConsent.ts +0 -263
- package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +0 -457
- package/packages/ndpr-toolkit/src/hooks/useDSR.ts +0 -236
- package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +0 -428
- package/packages/ndpr-toolkit/src/index.ts +0 -44
- package/packages/ndpr-toolkit/src/setupTests.ts +0 -5
- package/packages/ndpr-toolkit/src/types/breach.ts +0 -283
- package/packages/ndpr-toolkit/src/types/consent.ts +0 -111
- package/packages/ndpr-toolkit/src/types/dpia.ts +0 -236
- package/packages/ndpr-toolkit/src/types/dsr.ts +0 -192
- package/packages/ndpr-toolkit/src/types/index.ts +0 -42
- package/packages/ndpr-toolkit/src/types/privacy.ts +0 -246
- package/packages/ndpr-toolkit/src/utils/breach.ts +0 -122
- package/packages/ndpr-toolkit/src/utils/consent.ts +0 -51
- package/packages/ndpr-toolkit/src/utils/dpia.ts +0 -104
- package/packages/ndpr-toolkit/src/utils/dsr.ts +0 -77
- package/packages/ndpr-toolkit/src/utils/privacy.ts +0 -100
- package/packages/ndpr-toolkit/tsconfig.json +0 -23
- package/postcss.config.mjs +0 -5
- package/public/NDPR TOOLKIT.svg +0 -1
- package/public/favicon/android-chrome-192x192.png +0 -0
- package/public/favicon/android-chrome-512x512.png +0 -0
- package/public/favicon/apple-touch-icon.png +0 -0
- package/public/favicon/favicon-16x16.png +0 -0
- package/public/favicon/favicon-32x32.png +0 -0
- package/public/favicon/site.webmanifest +0 -1
- package/public/file.svg +0 -1
- package/public/globe.svg +0 -1
- package/public/ndpr-toolkit-logo.svg +0 -108
- package/public/next.svg +0 -1
- package/public/vercel.svg +0 -1
- package/public/window.svg +0 -1
- package/src/app/accessibility.css +0 -70
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +0 -123
- package/src/app/layout.tsx +0 -37
- package/src/app/ndpr-demos/breach/page.tsx +0 -354
- package/src/app/ndpr-demos/consent/page.tsx +0 -366
- package/src/app/ndpr-demos/dpia/page.tsx +0 -495
- package/src/app/ndpr-demos/dsr/page.tsx +0 -280
- package/src/app/ndpr-demos/page.tsx +0 -73
- package/src/app/ndpr-demos/policy/page.tsx +0 -771
- package/src/app/page.tsx +0 -452
- package/src/components/ErrorBoundary.tsx +0 -90
- package/src/components/breach-notification/BreachNotificationForm.tsx +0 -479
- package/src/components/consent/ConsentBanner.tsx +0 -193
- package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +0 -530
- package/src/components/dpia/DPIAQuestionnaire.tsx +0 -523
- package/src/components/privacy-policy/PolicyGenerator.tsx +0 -1062
- package/src/components/privacy-policy/data.ts +0 -98
- package/src/components/privacy-policy/shared/CheckboxField.tsx +0 -38
- package/src/components/privacy-policy/shared/CheckboxGroup.tsx +0 -85
- package/src/components/privacy-policy/shared/FormField.tsx +0 -79
- package/src/components/privacy-policy/shared/StepIndicator.tsx +0 -86
- package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +0 -361
- package/src/components/privacy-policy/steps/DataCollectionStep.tsx +0 -231
- package/src/components/privacy-policy/steps/DataSharingStep.tsx +0 -418
- package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +0 -202
- package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +0 -226
- package/src/components/ui/Badge.tsx +0 -46
- package/src/components/ui/Button.tsx +0 -59
- package/src/components/ui/Card.tsx +0 -92
- package/src/components/ui/Checkbox.tsx +0 -57
- package/src/components/ui/FormField.tsx +0 -50
- package/src/components/ui/Input.tsx +0 -38
- package/src/components/ui/Loading.tsx +0 -201
- package/src/components/ui/Select.tsx +0 -42
- package/src/components/ui/TextArea.tsx +0 -38
- package/src/components/ui/label.tsx +0 -24
- package/src/components/ui/switch.tsx +0 -31
- package/src/components/ui/tabs.tsx +0 -66
- package/src/hooks/useConsent.ts +0 -70
- package/src/hooks/useLoadingState.ts +0 -85
- package/src/lib/consentService.ts +0 -144
- package/src/lib/dpiaQuestions.ts +0 -188
- package/src/lib/requestService.ts +0 -79
- package/src/lib/sanitize.ts +0 -108
- package/src/lib/storage.ts +0 -222
- package/src/lib/utils.ts +0 -6
- package/src/types/html-to-docx.d.ts +0 -30
- package/src/types/index.ts +0 -77
- package/tailwind.config.ts +0 -65
- package/tsconfig.json +0 -41
|
@@ -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 }
|
package/src/hooks/useConsent.ts
DELETED
|
@@ -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
|
-
}
|