@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.
- package/.claude/settings.local.json +20 -0
- package/.eslintrc.json +10 -0
- package/.github/workflows/ci.yml +36 -0
- package/.github/workflows/nextjs.yml +104 -0
- package/.husky/commit-msg +4 -0
- package/.husky/pre-commit +4 -0
- package/.lintstagedrc.js +4 -0
- package/.nvmrc +1 -0
- package/.versionrc +17 -0
- package/CHANGELOG.md +16 -0
- package/CLAUDE.md +90 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +87 -0
- package/README.md +84 -447
- package/RELEASE-NOTES-v1.0.0.md +140 -0
- package/RELEASE-NOTES-v1.0.1.md +69 -0
- package/SECURITY.md +21 -0
- package/commitlint.config.js +36 -0
- package/components.json +21 -0
- package/eslint.config.mjs +16 -0
- package/jest.config.js +31 -0
- package/jest.setup.js +15 -0
- package/next.config.js +15 -0
- package/next.config.ts +62 -0
- package/package.json +70 -52
- package/packages/ndpr-toolkit/README.md +467 -0
- package/packages/ndpr-toolkit/jest.config.js +23 -0
- package/packages/ndpr-toolkit/package-lock.json +8197 -0
- package/packages/ndpr-toolkit/package.json +71 -0
- package/packages/ndpr-toolkit/rollup.config.js +34 -0
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +119 -0
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +122 -0
- package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +270 -0
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +199 -0
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +224 -0
- package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +104 -0
- package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +161 -0
- package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +330 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +149 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +88 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +160 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +110 -0
- package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +97 -0
- package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +701 -0
- package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +631 -0
- package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +569 -0
- package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +496 -0
- package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +270 -0
- package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +217 -0
- package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +206 -0
- package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +342 -0
- package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +373 -0
- package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +174 -0
- package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +717 -0
- package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +476 -0
- package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +620 -0
- package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +541 -0
- package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +454 -0
- package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +333 -0
- package/packages/ndpr-toolkit/src/hooks/useBreach.ts +409 -0
- package/packages/ndpr-toolkit/src/hooks/useConsent.ts +263 -0
- package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +457 -0
- package/packages/ndpr-toolkit/src/hooks/useDSR.ts +236 -0
- package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +428 -0
- package/{dist/index.d.ts → packages/ndpr-toolkit/src/index.ts} +13 -0
- package/packages/ndpr-toolkit/src/setupTests.ts +5 -0
- package/packages/ndpr-toolkit/src/types/breach.ts +283 -0
- package/packages/ndpr-toolkit/src/types/consent.ts +111 -0
- package/packages/ndpr-toolkit/src/types/dpia.ts +236 -0
- package/packages/ndpr-toolkit/src/types/dsr.ts +192 -0
- package/packages/ndpr-toolkit/src/types/index.ts +42 -0
- package/packages/ndpr-toolkit/src/types/privacy.ts +246 -0
- package/packages/ndpr-toolkit/src/utils/breach.ts +122 -0
- package/packages/ndpr-toolkit/src/utils/consent.ts +51 -0
- package/packages/ndpr-toolkit/src/utils/dpia.ts +104 -0
- package/packages/ndpr-toolkit/src/utils/dsr.ts +77 -0
- package/packages/ndpr-toolkit/src/utils/privacy.ts +100 -0
- package/packages/ndpr-toolkit/tsconfig.json +23 -0
- package/postcss.config.mjs +5 -0
- package/public/NDPR TOOLKIT.svg +1 -0
- 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 +1 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/ndpr-toolkit-logo.svg +108 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/src/__tests__/example.test.ts +13 -0
- package/src/__tests__/requestService.test.ts +57 -0
- package/src/app/accessibility.css +70 -0
- package/src/app/docs/components/DocLayout.tsx +267 -0
- package/src/app/docs/components/breach-notification/page.tsx +797 -0
- package/src/app/docs/components/consent-management/page.tsx +576 -0
- package/src/app/docs/components/data-subject-rights/page.tsx +511 -0
- package/src/app/docs/components/dpia-questionnaire/layout.tsx +15 -0
- package/src/app/docs/components/dpia-questionnaire/metadata.ts +31 -0
- package/src/app/docs/components/dpia-questionnaire/page.tsx +666 -0
- package/src/app/docs/components/hooks/page.tsx +305 -0
- package/src/app/docs/components/page.tsx +84 -0
- package/src/app/docs/components/privacy-policy-generator/page.tsx +634 -0
- package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +123 -0
- package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +328 -0
- package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +28 -0
- package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +91 -0
- package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +118 -0
- package/src/app/docs/guides/breach-notification-process/page.tsx +39 -0
- package/src/app/docs/guides/conducting-dpia/page.tsx +593 -0
- package/src/app/docs/guides/data-subject-requests/page.tsx +666 -0
- package/src/app/docs/guides/managing-consent/page.tsx +738 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +296 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +145 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +33 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +99 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +159 -0
- package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +38 -0
- package/src/app/docs/guides/page.tsx +67 -0
- package/src/app/docs/layout.tsx +15 -0
- package/src/app/docs/metadata.ts +31 -0
- package/src/app/docs/page.tsx +572 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +123 -0
- package/src/app/layout.tsx +37 -0
- package/src/app/ndpr-demos/breach/page.tsx +354 -0
- package/src/app/ndpr-demos/consent/page.tsx +366 -0
- package/src/app/ndpr-demos/dpia/page.tsx +495 -0
- package/src/app/ndpr-demos/dsr/page.tsx +280 -0
- package/src/app/ndpr-demos/page.tsx +73 -0
- package/src/app/ndpr-demos/policy/page.tsx +771 -0
- package/src/app/page.tsx +452 -0
- package/src/components/ErrorBoundary.tsx +90 -0
- package/src/components/breach-notification/BreachNotificationForm.tsx +479 -0
- package/src/components/consent/ConsentBanner.tsx +159 -0
- package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +419 -0
- package/src/components/docs/DocLayout.tsx +289 -0
- package/src/components/docs/index.ts +2 -0
- package/src/components/dpia/DPIAQuestionnaire.tsx +483 -0
- package/src/components/privacy-policy/PolicyGenerator.tsx +1062 -0
- package/src/components/privacy-policy/data.ts +98 -0
- package/src/components/privacy-policy/shared/CheckboxField.tsx +38 -0
- package/src/components/privacy-policy/shared/CheckboxGroup.tsx +85 -0
- package/src/components/privacy-policy/shared/FormField.tsx +79 -0
- package/src/components/privacy-policy/shared/StepIndicator.tsx +86 -0
- package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +335 -0
- package/src/components/privacy-policy/steps/DataCollectionStep.tsx +231 -0
- package/src/components/privacy-policy/steps/DataSharingStep.tsx +418 -0
- package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +202 -0
- package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +172 -0
- package/src/components/ui/Badge.tsx +46 -0
- package/src/components/ui/Button.tsx +59 -0
- package/src/components/ui/Card.tsx +92 -0
- package/src/components/ui/Checkbox.tsx +57 -0
- package/src/components/ui/FormField.tsx +50 -0
- package/src/components/ui/Input.tsx +38 -0
- package/src/components/ui/Loading.tsx +201 -0
- package/src/components/ui/Select.tsx +42 -0
- package/src/components/ui/TextArea.tsx +38 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/hooks/useConsent.ts +64 -0
- package/src/hooks/useLoadingState.ts +85 -0
- package/src/lib/consentService.ts +137 -0
- package/src/lib/dpiaQuestions.ts +148 -0
- package/src/lib/requestService.ts +75 -0
- package/src/lib/sanitize.ts +108 -0
- package/src/lib/storage.ts +222 -0
- package/src/lib/utils.ts +6 -0
- package/src/types/html-to-docx.d.ts +30 -0
- package/src/types/index.ts +72 -0
- package/tailwind.config.ts +65 -0
- package/tsconfig.json +41 -0
- package/dist/components/breach/BreachNotificationManager.d.ts +0 -62
- package/dist/components/breach/BreachReportForm.d.ts +0 -66
- package/dist/components/breach/BreachRiskAssessment.d.ts +0 -50
- package/dist/components/breach/RegulatoryReportGenerator.d.ts +0 -94
- package/dist/components/consent/ConsentBanner.d.ts +0 -79
- package/dist/components/consent/ConsentManager.d.ts +0 -73
- package/dist/components/consent/ConsentStorage.d.ts +0 -41
- package/dist/components/dpia/DPIAQuestionnaire.d.ts +0 -70
- package/dist/components/dpia/DPIAReport.d.ts +0 -40
- package/dist/components/dpia/StepIndicator.d.ts +0 -64
- package/dist/components/dsr/DSRDashboard.d.ts +0 -58
- package/dist/components/dsr/DSRRequestForm.d.ts +0 -74
- package/dist/components/dsr/DSRTracker.d.ts +0 -56
- package/dist/components/policy/PolicyExporter.d.ts +0 -65
- package/dist/components/policy/PolicyGenerator.d.ts +0 -54
- package/dist/components/policy/PolicyPreview.d.ts +0 -71
- package/dist/hooks/useBreach.d.ts +0 -97
- package/dist/hooks/useConsent.d.ts +0 -63
- package/dist/hooks/useDPIA.d.ts +0 -92
- package/dist/hooks/useDSR.d.ts +0 -72
- package/dist/hooks/usePrivacyPolicy.d.ts +0 -87
- package/dist/index.esm.js +0 -2
- package/dist/index.esm.js.map +0 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -1
- package/dist/setupTests.d.ts +0 -2
- package/dist/types/breach.d.ts +0 -239
- package/dist/types/consent.d.ts +0 -95
- package/dist/types/dpia.d.ts +0 -196
- package/dist/types/dsr.d.ts +0 -162
- package/dist/types/privacy.d.ts +0 -204
- package/dist/utils/breach.d.ts +0 -14
- package/dist/utils/consent.d.ts +0 -10
- package/dist/utils/dpia.d.ts +0 -12
- package/dist/utils/dsr.d.ts +0 -11
- package/dist/utils/privacy.d.ts +0 -12
package/src/app/page.tsx
ADDED
|
@@ -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
|
+
© {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
|
+
}
|