@tantainnovative/ndpr-toolkit 1.0.2 → 1.0.3

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 (212) hide show
  1. package/.claude/settings.local.json +20 -0
  2. package/.eslintrc.json +10 -0
  3. package/.github/workflows/ci.yml +36 -0
  4. package/.github/workflows/nextjs.yml +104 -0
  5. package/.husky/commit-msg +4 -0
  6. package/.husky/pre-commit +4 -0
  7. package/.lintstagedrc.js +4 -0
  8. package/.nvmrc +1 -0
  9. package/.versionrc +17 -0
  10. package/CHANGELOG.md +16 -0
  11. package/CLAUDE.md +90 -0
  12. package/CNAME +1 -0
  13. package/CONTRIBUTING.md +87 -0
  14. package/README.md +84 -447
  15. package/RELEASE-NOTES-v1.0.0.md +140 -0
  16. package/RELEASE-NOTES-v1.0.1.md +69 -0
  17. package/SECURITY.md +21 -0
  18. package/commitlint.config.js +36 -0
  19. package/components.json +21 -0
  20. package/eslint.config.mjs +16 -0
  21. package/jest.config.js +31 -0
  22. package/jest.setup.js +15 -0
  23. package/next.config.js +15 -0
  24. package/next.config.ts +62 -0
  25. package/package.json +70 -52
  26. package/packages/ndpr-toolkit/README.md +467 -0
  27. package/packages/ndpr-toolkit/jest.config.js +23 -0
  28. package/packages/ndpr-toolkit/package-lock.json +8197 -0
  29. package/packages/ndpr-toolkit/package.json +71 -0
  30. package/packages/ndpr-toolkit/rollup.config.js +34 -0
  31. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +119 -0
  32. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +122 -0
  33. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +270 -0
  34. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +199 -0
  35. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +224 -0
  36. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +104 -0
  37. package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +161 -0
  38. package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +330 -0
  39. package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +149 -0
  40. package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +88 -0
  41. package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +160 -0
  42. package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +110 -0
  43. package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +97 -0
  44. package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +701 -0
  45. package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +631 -0
  46. package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +569 -0
  47. package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +496 -0
  48. package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +270 -0
  49. package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +217 -0
  50. package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +206 -0
  51. package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +342 -0
  52. package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +373 -0
  53. package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +174 -0
  54. package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +717 -0
  55. package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +476 -0
  56. package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +620 -0
  57. package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +541 -0
  58. package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +454 -0
  59. package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +333 -0
  60. package/packages/ndpr-toolkit/src/hooks/useBreach.ts +409 -0
  61. package/packages/ndpr-toolkit/src/hooks/useConsent.ts +263 -0
  62. package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +457 -0
  63. package/packages/ndpr-toolkit/src/hooks/useDSR.ts +236 -0
  64. package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +428 -0
  65. package/{dist/index.d.ts → packages/ndpr-toolkit/src/index.ts} +13 -0
  66. package/packages/ndpr-toolkit/src/setupTests.ts +5 -0
  67. package/packages/ndpr-toolkit/src/types/breach.ts +283 -0
  68. package/packages/ndpr-toolkit/src/types/consent.ts +111 -0
  69. package/packages/ndpr-toolkit/src/types/dpia.ts +236 -0
  70. package/packages/ndpr-toolkit/src/types/dsr.ts +192 -0
  71. package/packages/ndpr-toolkit/src/types/index.ts +42 -0
  72. package/packages/ndpr-toolkit/src/types/privacy.ts +246 -0
  73. package/packages/ndpr-toolkit/src/utils/breach.ts +122 -0
  74. package/packages/ndpr-toolkit/src/utils/consent.ts +51 -0
  75. package/packages/ndpr-toolkit/src/utils/dpia.ts +104 -0
  76. package/packages/ndpr-toolkit/src/utils/dsr.ts +77 -0
  77. package/packages/ndpr-toolkit/src/utils/privacy.ts +100 -0
  78. package/packages/ndpr-toolkit/tsconfig.json +23 -0
  79. package/postcss.config.mjs +5 -0
  80. package/public/NDPR TOOLKIT.svg +1 -0
  81. package/public/favicon/android-chrome-192x192.png +0 -0
  82. package/public/favicon/android-chrome-512x512.png +0 -0
  83. package/public/favicon/apple-touch-icon.png +0 -0
  84. package/public/favicon/favicon-16x16.png +0 -0
  85. package/public/favicon/favicon-32x32.png +0 -0
  86. package/public/favicon/site.webmanifest +1 -0
  87. package/public/file.svg +1 -0
  88. package/public/globe.svg +1 -0
  89. package/public/ndpr-toolkit-logo.svg +108 -0
  90. package/public/next.svg +1 -0
  91. package/public/vercel.svg +1 -0
  92. package/public/window.svg +1 -0
  93. package/src/__tests__/example.test.ts +13 -0
  94. package/src/__tests__/requestService.test.ts +57 -0
  95. package/src/app/accessibility.css +70 -0
  96. package/src/app/docs/components/DocLayout.tsx +267 -0
  97. package/src/app/docs/components/breach-notification/page.tsx +797 -0
  98. package/src/app/docs/components/consent-management/page.tsx +576 -0
  99. package/src/app/docs/components/data-subject-rights/page.tsx +511 -0
  100. package/src/app/docs/components/dpia-questionnaire/layout.tsx +15 -0
  101. package/src/app/docs/components/dpia-questionnaire/metadata.ts +31 -0
  102. package/src/app/docs/components/dpia-questionnaire/page.tsx +666 -0
  103. package/src/app/docs/components/hooks/page.tsx +305 -0
  104. package/src/app/docs/components/page.tsx +84 -0
  105. package/src/app/docs/components/privacy-policy-generator/page.tsx +634 -0
  106. package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +123 -0
  107. package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +328 -0
  108. package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +28 -0
  109. package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +91 -0
  110. package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +118 -0
  111. package/src/app/docs/guides/breach-notification-process/page.tsx +39 -0
  112. package/src/app/docs/guides/conducting-dpia/page.tsx +593 -0
  113. package/src/app/docs/guides/data-subject-requests/page.tsx +666 -0
  114. package/src/app/docs/guides/managing-consent/page.tsx +738 -0
  115. package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +296 -0
  116. package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +145 -0
  117. package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +33 -0
  118. package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +99 -0
  119. package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +159 -0
  120. package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +38 -0
  121. package/src/app/docs/guides/page.tsx +67 -0
  122. package/src/app/docs/layout.tsx +15 -0
  123. package/src/app/docs/metadata.ts +31 -0
  124. package/src/app/docs/page.tsx +572 -0
  125. package/src/app/favicon.ico +0 -0
  126. package/src/app/globals.css +123 -0
  127. package/src/app/layout.tsx +37 -0
  128. package/src/app/ndpr-demos/breach/page.tsx +354 -0
  129. package/src/app/ndpr-demos/consent/page.tsx +366 -0
  130. package/src/app/ndpr-demos/dpia/page.tsx +495 -0
  131. package/src/app/ndpr-demos/dsr/page.tsx +280 -0
  132. package/src/app/ndpr-demos/page.tsx +73 -0
  133. package/src/app/ndpr-demos/policy/page.tsx +771 -0
  134. package/src/app/page.tsx +452 -0
  135. package/src/components/ErrorBoundary.tsx +90 -0
  136. package/src/components/breach-notification/BreachNotificationForm.tsx +479 -0
  137. package/src/components/consent/ConsentBanner.tsx +159 -0
  138. package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +419 -0
  139. package/src/components/docs/DocLayout.tsx +289 -0
  140. package/src/components/docs/index.ts +2 -0
  141. package/src/components/dpia/DPIAQuestionnaire.tsx +483 -0
  142. package/src/components/privacy-policy/PolicyGenerator.tsx +1062 -0
  143. package/src/components/privacy-policy/data.ts +98 -0
  144. package/src/components/privacy-policy/shared/CheckboxField.tsx +38 -0
  145. package/src/components/privacy-policy/shared/CheckboxGroup.tsx +85 -0
  146. package/src/components/privacy-policy/shared/FormField.tsx +79 -0
  147. package/src/components/privacy-policy/shared/StepIndicator.tsx +86 -0
  148. package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +335 -0
  149. package/src/components/privacy-policy/steps/DataCollectionStep.tsx +231 -0
  150. package/src/components/privacy-policy/steps/DataSharingStep.tsx +418 -0
  151. package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +202 -0
  152. package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +172 -0
  153. package/src/components/ui/Badge.tsx +46 -0
  154. package/src/components/ui/Button.tsx +59 -0
  155. package/src/components/ui/Card.tsx +92 -0
  156. package/src/components/ui/Checkbox.tsx +57 -0
  157. package/src/components/ui/FormField.tsx +50 -0
  158. package/src/components/ui/Input.tsx +38 -0
  159. package/src/components/ui/Loading.tsx +201 -0
  160. package/src/components/ui/Select.tsx +42 -0
  161. package/src/components/ui/TextArea.tsx +38 -0
  162. package/src/components/ui/label.tsx +24 -0
  163. package/src/components/ui/switch.tsx +31 -0
  164. package/src/components/ui/tabs.tsx +66 -0
  165. package/src/hooks/useConsent.ts +64 -0
  166. package/src/hooks/useLoadingState.ts +85 -0
  167. package/src/lib/consentService.ts +137 -0
  168. package/src/lib/dpiaQuestions.ts +148 -0
  169. package/src/lib/requestService.ts +75 -0
  170. package/src/lib/sanitize.ts +108 -0
  171. package/src/lib/storage.ts +222 -0
  172. package/src/lib/utils.ts +6 -0
  173. package/src/types/html-to-docx.d.ts +30 -0
  174. package/src/types/index.ts +72 -0
  175. package/tailwind.config.ts +65 -0
  176. package/tsconfig.json +41 -0
  177. package/dist/components/breach/BreachNotificationManager.d.ts +0 -62
  178. package/dist/components/breach/BreachReportForm.d.ts +0 -66
  179. package/dist/components/breach/BreachRiskAssessment.d.ts +0 -50
  180. package/dist/components/breach/RegulatoryReportGenerator.d.ts +0 -94
  181. package/dist/components/consent/ConsentBanner.d.ts +0 -79
  182. package/dist/components/consent/ConsentManager.d.ts +0 -73
  183. package/dist/components/consent/ConsentStorage.d.ts +0 -41
  184. package/dist/components/dpia/DPIAQuestionnaire.d.ts +0 -70
  185. package/dist/components/dpia/DPIAReport.d.ts +0 -40
  186. package/dist/components/dpia/StepIndicator.d.ts +0 -64
  187. package/dist/components/dsr/DSRDashboard.d.ts +0 -58
  188. package/dist/components/dsr/DSRRequestForm.d.ts +0 -74
  189. package/dist/components/dsr/DSRTracker.d.ts +0 -56
  190. package/dist/components/policy/PolicyExporter.d.ts +0 -65
  191. package/dist/components/policy/PolicyGenerator.d.ts +0 -54
  192. package/dist/components/policy/PolicyPreview.d.ts +0 -71
  193. package/dist/hooks/useBreach.d.ts +0 -97
  194. package/dist/hooks/useConsent.d.ts +0 -63
  195. package/dist/hooks/useDPIA.d.ts +0 -92
  196. package/dist/hooks/useDSR.d.ts +0 -72
  197. package/dist/hooks/usePrivacyPolicy.d.ts +0 -87
  198. package/dist/index.esm.js +0 -2
  199. package/dist/index.esm.js.map +0 -1
  200. package/dist/index.js +0 -2
  201. package/dist/index.js.map +0 -1
  202. package/dist/setupTests.d.ts +0 -2
  203. package/dist/types/breach.d.ts +0 -239
  204. package/dist/types/consent.d.ts +0 -95
  205. package/dist/types/dpia.d.ts +0 -196
  206. package/dist/types/dsr.d.ts +0 -162
  207. package/dist/types/privacy.d.ts +0 -204
  208. package/dist/utils/breach.d.ts +0 -14
  209. package/dist/utils/consent.d.ts +0 -10
  210. package/dist/utils/dpia.d.ts +0 -12
  211. package/dist/utils/dsr.d.ts +0 -11
  212. package/dist/utils/privacy.d.ts +0 -12
@@ -0,0 +1,452 @@
1
+ import Link from "next/link";
2
+ import { Button } from "@/components/ui/Button";
3
+ import { Badge } from "@/components/ui/Badge";
4
+ import { Card } from "@/components/ui/Card";
5
+
6
+ export const metadata = {
7
+ title: 'NDPR Toolkit | Nigerian Data Protection Compliance Made Easy',
8
+ description: 'Open-source toolkit for Nigerian developers to implement NDPR and DPA compliant features in web applications with minimal effort.',
9
+ keywords: 'NDPR, DPA, Nigerian Data Protection, Compliance, Toolkit, React, Next.js, Open Source',
10
+ openGraph: {
11
+ title: 'NDPR Toolkit | Nigerian Data Protection Compliance Made Easy',
12
+ description: 'Open-source toolkit for Nigerian developers to implement NDPR and DPA compliant features in web applications with minimal effort.',
13
+ url: 'https://ndprtoolkit.com.ng',
14
+ siteName: 'NDPR Toolkit',
15
+ images: [
16
+ {
17
+ url: '/og-image.png',
18
+ width: 1200,
19
+ height: 630,
20
+ alt: 'NDPR Toolkit by Tanta Innovative',
21
+ },
22
+ ],
23
+ locale: 'en_US',
24
+ type: 'website',
25
+ },
26
+ twitter: {
27
+ card: 'summary_large_image',
28
+ title: 'NDPR Toolkit | Nigerian Data Protection Compliance Made Easy',
29
+ description: 'Open-source toolkit for Nigerian developers to implement NDPR and DPA compliant features in web applications with minimal effort.',
30
+ images: ['/og-image.png'],
31
+ },
32
+ };
33
+
34
+ export default function Home() {
35
+ // Features of the NDPR-Toolkit
36
+ const features = [
37
+ {
38
+ title: "Consent Management System",
39
+ description: "User-friendly consent banners and modals with customizable styling, granular consent options, and audit trails.",
40
+ icon: "/icons/consent.svg",
41
+ href: "/ndpr-demos/consent",
42
+ color: "blue",
43
+ iconPath: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
44
+ },
45
+ {
46
+ title: "Data Subject Rights Portal",
47
+ description: "Pre-built UI components for handling access, rectification, erasure, and other data subject rights requests.",
48
+ icon: "/icons/rights.svg",
49
+ href: "/ndpr-demos/dsr",
50
+ color: "purple",
51
+ iconPath: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
52
+ },
53
+ {
54
+ title: "Privacy Policy Generator",
55
+ description: "Interactive wizard to create NDPR-compliant privacy policies with customizable sections and templates.",
56
+ icon: "/icons/policy.svg",
57
+ href: "/ndpr-demos/policy",
58
+ color: "green",
59
+ iconPath: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
60
+ },
61
+ {
62
+ title: "Data Protection Impact Assessment",
63
+ description: "Questionnaire-based tool to help organizations assess data processing risks with mitigation recommendations.",
64
+ icon: "/icons/dpia.svg",
65
+ href: "/ndpr-demos/dpia",
66
+ color: "amber",
67
+ iconPath: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"
68
+ },
69
+ {
70
+ title: "Breach Notification Module",
71
+ description: "Templates for mandatory breach notifications with timeline tracking to ensure 72-hour notification compliance.",
72
+ icon: "/icons/breach.svg",
73
+ href: "/ndpr-demos/breach",
74
+ color: "red",
75
+ iconPath: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
76
+ }
77
+ ];
78
+
79
+ // Benefits of using the toolkit
80
+ const benefits = [
81
+ {
82
+ title: "Rapid Implementation",
83
+ description: "Deploy compliance features in days, not months, with our pre-built components."
84
+ },
85
+ {
86
+ title: "NDPR & DPA Compliant",
87
+ description: "All components are designed to meet the requirements of the Nigerian Data Protection Regulation and Data Protection Act."
88
+ },
89
+ {
90
+ title: "Customizable UI",
91
+ description: "Fully customizable components that can be styled to match your brand's look and feel."
92
+ },
93
+ {
94
+ title: "Developer-Friendly",
95
+ description: "Well-documented API with TypeScript support and examples to help you get started quickly."
96
+ }
97
+ ];
98
+
99
+ return (
100
+ <div className="min-h-screen bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
101
+ {/* Hero Section */}
102
+ <div className="relative overflow-hidden bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
103
+ <div className="absolute inset-0 bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 opacity-50"></div>
104
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 sm:py-24 lg:py-32 relative">
105
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
106
+ <div className="text-center lg:text-left">
107
+ <Badge variant="primary" className="mb-4 px-3 py-1 text-sm">
108
+ NDPR & DPA Compliant
109
+ </Badge>
110
+ <h1 className="text-4xl tracking-tight font-extrabold text-gray-900 dark:text-white sm:text-5xl md:text-6xl">
111
+ <span className="block">Nigerian Data Protection</span>
112
+ <span className="block mt-2 bg-gradient-to-r from-blue-600 to-indigo-600 bg-clip-text text-transparent">Compliance Toolkit</span>
113
+ </h1>
114
+ <p className="mt-6 text-xl text-gray-500 dark:text-gray-300 leading-relaxed">
115
+ An open-source toolkit that helps Nigerian developers implement NDPR and DPA compliant features in their web applications with minimal effort.
116
+ </p>
117
+
118
+ <div className="mt-8 flex flex-col sm:flex-row justify-center lg:justify-start gap-4">
119
+ <Button
120
+ variant="default"
121
+ size="lg"
122
+ asChild
123
+ className="rounded-lg shadow-lg shadow-blue-500/20 hover:shadow-blue-500/30 transition-all duration-200"
124
+ >
125
+ <Link href="/ndpr-demos" className="flex items-center">
126
+ <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
127
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
128
+ </svg>
129
+ Live Demos
130
+ </Link>
131
+ </Button>
132
+
133
+ <Button
134
+ variant="outline"
135
+ size="lg"
136
+ asChild
137
+ className="rounded-lg border-2 hover:bg-gray-50 dark:hover:bg-gray-800 transition-all duration-200"
138
+ >
139
+ <Link
140
+ href="/docs"
141
+ className="flex items-center"
142
+ >
143
+ <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
144
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
145
+ </svg>
146
+ Documentation
147
+ </Link>
148
+ </Button>
149
+
150
+ <Button
151
+ variant="outline"
152
+ size="lg"
153
+ asChild
154
+ className="rounded-lg border-2 hover:bg-gray-50 dark:hover:bg-gray-800 transition-all duration-200"
155
+ >
156
+ <Link
157
+ href="https://github.com/tantainnovative/ndpr-toolkit"
158
+ target="_blank"
159
+ rel="noopener noreferrer"
160
+ className="flex items-center"
161
+ >
162
+ <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
163
+ <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" fill="currentColor" />
164
+ </svg>
165
+ GitHub
166
+ </Link>
167
+ </Button>
168
+
169
+ </div>
170
+
171
+ <div className="mt-8 flex items-center justify-center lg:justify-start text-sm text-gray-500 dark:text-gray-400">
172
+ <div className="flex -space-x-2 mr-3">
173
+ <div className="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white text-xs font-bold">NG</div>
174
+ <div className="w-8 h-8 rounded-full bg-green-500 flex items-center justify-center text-white text-xs font-bold">DPA</div>
175
+ <div className="w-8 h-8 rounded-full bg-purple-500 flex items-center justify-center text-white text-xs font-bold">UI</div>
176
+ </div>
177
+ <span>Built for Nigerian businesses with enterprise-ready components</span>
178
+ </div>
179
+
180
+ <div className="mt-4 text-sm text-gray-500 dark:text-gray-400">
181
+ <div className="inline-flex items-center bg-blue-50 dark:bg-blue-900/30 px-3 py-1 rounded-full">
182
+ <span className="mr-1 text-blue-600 dark:text-blue-400">v1.0.1</span>
183
+ <span className="px-1.5 py-0.5 text-xs bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300 rounded-full ml-2">React 19 Compatible</span>
184
+ </div>
185
+ </div>
186
+ </div>
187
+
188
+ <div className="relative hidden lg:block">
189
+ <div className="absolute -top-16 -right-16 w-72 h-72 bg-blue-400 rounded-full mix-blend-multiply filter blur-2xl opacity-20 animate-blob"></div>
190
+ <div className="absolute -bottom-16 -left-16 w-72 h-72 bg-purple-400 rounded-full mix-blend-multiply filter blur-2xl opacity-20 animate-blob animation-delay-2000"></div>
191
+ <div className="absolute top-32 right-32 w-72 h-72 bg-green-400 rounded-full mix-blend-multiply filter blur-2xl opacity-20 animate-blob animation-delay-4000"></div>
192
+
193
+ <div className="relative">
194
+ <div className="absolute inset-0 rounded-2xl bg-gradient-to-tr from-blue-600 to-indigo-600 shadow-lg transform -rotate-6 scale-105 opacity-10"></div>
195
+ <div className="relative bg-white dark:bg-gray-800 rounded-2xl shadow-lg overflow-hidden border border-gray-200 dark:border-gray-700">
196
+ <div className="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex items-center">
197
+ <div className="flex space-x-2">
198
+ <div className="w-3 h-3 rounded-full bg-red-500"></div>
199
+ <div className="w-3 h-3 rounded-full bg-yellow-500"></div>
200
+ <div className="w-3 h-3 rounded-full bg-green-500"></div>
201
+ </div>
202
+ <div className="mx-auto text-sm font-medium text-gray-500 dark:text-gray-400">NDPR Toolkit Demo</div>
203
+ </div>
204
+ <div className="p-6 space-y-6">
205
+ {features.map((feature, index) => (
206
+ <div key={index} className="flex items-start">
207
+ <div className={`flex-shrink-0 w-10 h-10 rounded-lg bg-${feature.color}-100 dark:bg-${feature.color}-900/30 flex items-center justify-center text-${feature.color}-600 dark:text-${feature.color}-400`}>
208
+ <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
209
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={feature.iconPath} />
210
+ </svg>
211
+ </div>
212
+ <div className="ml-4">
213
+ <h3 className="text-sm font-medium text-gray-900 dark:text-white">{feature.title}</h3>
214
+ <p className="mt-1 text-xs text-gray-500 dark:text-gray-400 line-clamp-2">{feature.description}</p>
215
+ </div>
216
+ </div>
217
+ ))}
218
+ </div>
219
+ </div>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+
226
+ {/* Features Section */}
227
+ <div className="py-16 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700" id="demos">
228
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
229
+ <div className="text-center">
230
+ <Badge variant="secondary" className="mb-4 px-3 py-1 text-sm">
231
+ Enterprise-Ready Components
232
+ </Badge>
233
+ <h2 className="text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-white">
234
+ Comprehensive NDPR Compliance
235
+ </h2>
236
+ <p className="mt-4 max-w-2xl mx-auto text-xl text-gray-500 dark:text-gray-300">
237
+ Our toolkit provides professional, customizable components to help Nigerian businesses implement NDPR compliance features with minimal development effort.
238
+ </p>
239
+ </div>
240
+
241
+ <div className="mt-16 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
242
+ {features.map((feature) => (
243
+ <Card key={feature.title} className="overflow-hidden transition-all duration-300 hover:shadow-lg">
244
+ <Link href={feature.href} className="block h-full">
245
+ <div className="p-1 bg-gradient-to-r from-blue-500 to-indigo-600">
246
+ <div className="bg-white dark:bg-gray-800 p-5">
247
+ <div className={`w-12 h-12 rounded-lg bg-${feature.color}-100 dark:bg-${feature.color}-900/30 flex items-center justify-center text-${feature.color}-600 dark:text-${feature.color}-400 mb-4`}>
248
+ <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
249
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={feature.iconPath} />
250
+ </svg>
251
+ </div>
252
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
253
+ {feature.title}
254
+ </h3>
255
+ <p className="text-gray-500 dark:text-gray-300">
256
+ {feature.description}
257
+ </p>
258
+ <div className="mt-4 flex items-center text-blue-600 dark:text-blue-400 font-medium">
259
+ <span>View Demo</span>
260
+ <svg className="w-4 h-4 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
261
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14 5l7 7m0 0l-7 7m7-7H3" />
262
+ </svg>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ </Link>
267
+ </Card>
268
+ ))}
269
+ </div>
270
+ </div>
271
+ </div>
272
+
273
+ {/* Benefits Section */}
274
+ <div className="py-16 bg-gray-50 dark:bg-gray-900">
275
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
276
+ <div className="text-center mb-12">
277
+ <Badge variant="primary" className="mb-4 px-3 py-1 text-sm">
278
+ Why Choose Us
279
+ </Badge>
280
+ <h2 className="text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-white">
281
+ Benefits of Our Toolkit
282
+ </h2>
283
+ <p className="mt-4 max-w-2xl mx-auto text-xl text-gray-500 dark:text-gray-300">
284
+ Designed to make compliance easy, efficient, and developer-friendly.
285
+ </p>
286
+ </div>
287
+
288
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
289
+ {benefits.map((benefit, index) => (
290
+ <div key={index} className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 flex items-start border border-gray-200 dark:border-gray-700">
291
+ <div className="flex-shrink-0 w-12 h-12 rounded-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center text-blue-600 dark:text-blue-400 mr-4">
292
+ <span className="text-xl font-bold">{index + 1}</span>
293
+ </div>
294
+ <div>
295
+ <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">{benefit.title}</h3>
296
+ <p className="text-gray-500 dark:text-gray-300">{benefit.description}</p>
297
+ </div>
298
+ </div>
299
+ ))}
300
+ </div>
301
+ </div>
302
+ </div>
303
+
304
+ {/* CTA Section */}
305
+ <div className="relative bg-gradient-to-r from-blue-600 to-indigo-700 overflow-hidden">
306
+ <div className="absolute inset-0 opacity-10">
307
+ <svg className="w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
308
+ <path d="M0,0 L100,0 L100,100 L0,100 Z" fill="url(#grid)" />
309
+ <defs>
310
+ <pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse">
311
+ <path d="M 10 0 L 0 0 0 10" fill="none" stroke="white" strokeWidth="0.5" />
312
+ </pattern>
313
+ </defs>
314
+ </svg>
315
+ </div>
316
+ <div className="max-w-7xl mx-auto py-16 px-4 sm:py-24 sm:px-6 lg:px-8 relative">
317
+ <div className="lg:grid lg:grid-cols-2 lg:gap-8 items-center">
318
+ <div>
319
+ <h2 className="text-3xl font-extrabold text-white sm:text-4xl">
320
+ <span className="block">Ready to implement NDPR compliance?</span>
321
+ <span className="block text-blue-200">Start using the toolkit today.</span>
322
+ </h2>
323
+ <p className="mt-4 text-lg text-blue-100 max-w-md">
324
+ Join the growing community of Nigerian businesses using our enterprise-ready toolkit to implement NDPR compliance features in their applications.
325
+ </p>
326
+ <div className="mt-8 flex flex-col sm:flex-row gap-4">
327
+
328
+
329
+ <Button
330
+ variant="secondary"
331
+ size="lg"
332
+ asChild
333
+ className="bg-white text-blue-600 hover:bg-blue-50"
334
+ >
335
+ <Link
336
+ href="https://github.com/tantainnovative/ndpr-toolkit"
337
+ target="_blank"
338
+ rel="noopener noreferrer"
339
+ >
340
+
341
+ <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
342
+ <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" fill="currentColor" />
343
+ </svg>
344
+ Get Started on GitHub
345
+ </Link>
346
+
347
+ </Button>
348
+
349
+ <Button
350
+ variant="default"
351
+ size="lg"
352
+ asChild
353
+ className="text-white border-white hover:bg-blue-700"
354
+ >
355
+ <Link href="/docs">
356
+
357
+
358
+ <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
359
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
360
+ </svg>
361
+ Documentation
362
+ </Link>
363
+ </Button>
364
+
365
+
366
+ </div>
367
+ </div>
368
+ <div className="mt-12 lg:mt-0 hidden lg:block">
369
+ <div className="pl-4 -mr-48 sm:pl-6 md:-mr-16 lg:px-0 lg:m-0 lg:relative lg:h-full">
370
+ <div className="w-full rounded-xl shadow-xl ring-1 ring-black ring-opacity-5 overflow-hidden transform rotate-3 translate-x-6 bg-white dark:bg-gray-800">
371
+ <div className="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex items-center">
372
+ <div className="flex space-x-2">
373
+ <div className="w-3 h-3 rounded-full bg-red-500"></div>
374
+ <div className="w-3 h-3 rounded-full bg-yellow-500"></div>
375
+ <div className="w-3 h-3 rounded-full bg-green-500"></div>
376
+ </div>
377
+ <div className="mx-auto text-sm font-medium text-gray-500 dark:text-gray-400">NDPR Toolkit</div>
378
+ </div>
379
+ <div className="relative bg-white dark:bg-gray-800 p-6">
380
+ <div className="h-64 bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 rounded-lg flex items-center justify-center">
381
+ <div className="text-center">
382
+ <div className="w-16 h-16 mx-auto rounded-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center text-blue-600 dark:text-blue-400 mb-4">
383
+ <svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
384
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
385
+ </svg>
386
+ </div>
387
+ <p className="text-sm text-gray-500 dark:text-gray-400">NDPR Compliant</p>
388
+ <h3 className="mt-2 text-lg font-medium text-gray-900 dark:text-white">Ready for Production</h3>
389
+ </div>
390
+ </div>
391
+ </div>
392
+ </div>
393
+ </div>
394
+ </div>
395
+ </div>
396
+ </div>
397
+ </div>
398
+
399
+ {/* Footer */}
400
+ <footer className="bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700">
401
+ <div className="max-w-7xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
402
+ <div className="flex flex-col md:flex-row justify-between items-center">
403
+ <div className="mb-6 md:mb-0">
404
+ <div className="flex items-center">
405
+ <div className="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center text-white font-bold mr-3">NT</div>
406
+ <div>
407
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-white">NDPR Toolkit</h3>
408
+ <p className="text-sm text-gray-500 dark:text-gray-400">
409
+ <a href="https://ndprtoolkit.com.ng" target="_blank" rel="noopener noreferrer" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">Tanta Innovative</a>
410
+ </p>
411
+ </div>
412
+ </div>
413
+ </div>
414
+ <div className="flex space-x-6">
415
+ <a href="https://github.com/tantainnovative/ndpr-toolkit" target="_blank" rel="noopener noreferrer" className="text-gray-400 hover:text-gray-500">
416
+ <span className="sr-only">GitHub</span>
417
+ <svg className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
418
+ <path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
419
+ </svg>
420
+ </a>
421
+ <a href="/docs" className="text-gray-400 hover:text-gray-500">
422
+ <span className="sr-only">Documentation</span>
423
+ <svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
424
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
425
+ </svg>
426
+ </a>
427
+ <a href="https://tantainnovatives.com" target="_blank" rel="noopener noreferrer" className="text-gray-400 hover:text-gray-500">
428
+ <span className="sr-only">Tanta Innovative Website</span>
429
+ <svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
430
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9" />
431
+ </svg>
432
+ </a>
433
+ </div>
434
+ </div>
435
+ <div className="mt-8 border-t border-gray-200 dark:border-gray-700 pt-8 text-center">
436
+ <p className="text-base text-gray-500 dark:text-gray-400">
437
+ &copy; {new Date().getFullYear()} <a href="https://tantainnovatives.com" target="_blank" rel="noopener noreferrer" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">Tanta Innovative</a>. All rights reserved.
438
+ </p>
439
+ <p className="text-sm text-gray-500 dark:text-gray-400 mt-2">
440
+ Developed as an open-source solution for Nigerian tech businesses.
441
+ </p>
442
+ <div className="flex justify-center mt-4 space-x-4">
443
+ <a href="https://tantainnovatives.com/contact-us" target="_blank" rel="noopener noreferrer" className="text-sm text-gray-500 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors">Contact Us</a>
444
+ <a href="https://tantainnovatives.com/services" target="_blank" rel="noopener noreferrer" className="text-sm text-gray-500 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors">Services</a>
445
+ <a href="https://tantainnovatives.com/about-us" target="_blank" rel="noopener noreferrer" className="text-sm text-gray-500 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors">About Us</a>
446
+ </div>
447
+ </div>
448
+ </div>
449
+ </footer>
450
+ </div>
451
+ );
452
+ }
@@ -0,0 +1,90 @@
1
+ 'use client';
2
+
3
+ import React, { Component, ReactNode } from 'react';
4
+
5
+ interface Props {
6
+ children: ReactNode;
7
+ fallback?: ReactNode;
8
+ }
9
+
10
+ interface State {
11
+ hasError: boolean;
12
+ error: Error | null;
13
+ }
14
+
15
+ export class ErrorBoundary extends Component<Props, State> {
16
+ constructor(props: Props) {
17
+ super(props);
18
+ this.state = { hasError: false, error: null };
19
+ }
20
+
21
+ static getDerivedStateFromError(error: Error): State {
22
+ return { hasError: true, error };
23
+ }
24
+
25
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
26
+ // In production, this would be sent to an error reporting service
27
+ console.error('Error caught by boundary:', error, errorInfo);
28
+ }
29
+
30
+ render() {
31
+ if (this.state.hasError) {
32
+ if (this.props.fallback) {
33
+ return this.props.fallback;
34
+ }
35
+
36
+ return (
37
+ <div className="min-h-[400px] flex items-center justify-center">
38
+ <div className="text-center max-w-md mx-auto p-6">
39
+ <div className="mb-4">
40
+ <svg
41
+ className="mx-auto h-12 w-12 text-red-500"
42
+ fill="none"
43
+ stroke="currentColor"
44
+ viewBox="0 0 24 24"
45
+ xmlns="http://www.w3.org/2000/svg"
46
+ >
47
+ <path
48
+ strokeLinecap="round"
49
+ strokeLinejoin="round"
50
+ strokeWidth={2}
51
+ d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
52
+ />
53
+ </svg>
54
+ </div>
55
+ <h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">
56
+ Something went wrong
57
+ </h2>
58
+ <p className="text-gray-600 dark:text-gray-400 mb-4">
59
+ We encountered an unexpected error. Please try refreshing the page.
60
+ </p>
61
+ <button
62
+ onClick={() => window.location.reload()}
63
+ className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
64
+ >
65
+ Refresh Page
66
+ </button>
67
+ </div>
68
+ </div>
69
+ );
70
+ }
71
+
72
+ return this.props.children;
73
+ }
74
+ }
75
+
76
+ // Hook for functional components to handle errors
77
+ export function useErrorHandler() {
78
+ const [error, setError] = React.useState<Error | null>(null);
79
+
80
+ React.useEffect(() => {
81
+ if (error) {
82
+ throw error;
83
+ }
84
+ }, [error]);
85
+
86
+ return {
87
+ throwError: setError,
88
+ resetError: () => setError(null),
89
+ };
90
+ }