@tantainnovative/ndpr-toolkit 1.0.3 → 1.0.4

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 (156) hide show
  1. package/next-env.d.ts +5 -0
  2. package/package.json +1 -1
  3. package/.claude/settings.local.json +0 -20
  4. package/.eslintrc.json +0 -10
  5. package/.github/workflows/ci.yml +0 -36
  6. package/.github/workflows/nextjs.yml +0 -104
  7. package/.husky/commit-msg +0 -4
  8. package/.husky/pre-commit +0 -4
  9. package/.lintstagedrc.js +0 -4
  10. package/.nvmrc +0 -1
  11. package/.versionrc +0 -17
  12. package/CLAUDE.md +0 -90
  13. package/commitlint.config.js +0 -36
  14. package/eslint.config.mjs +0 -16
  15. package/jest.config.js +0 -31
  16. package/jest.setup.js +0 -15
  17. package/next.config.js +0 -15
  18. package/next.config.ts +0 -62
  19. package/packages/ndpr-toolkit/README.md +0 -467
  20. package/packages/ndpr-toolkit/jest.config.js +0 -23
  21. package/packages/ndpr-toolkit/package-lock.json +0 -8197
  22. package/packages/ndpr-toolkit/package.json +0 -71
  23. package/packages/ndpr-toolkit/rollup.config.js +0 -34
  24. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentBanner.test.tsx +0 -119
  25. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentManager.test.tsx +0 -122
  26. package/packages/ndpr-toolkit/src/__tests__/components/consent/ConsentStorage.test.tsx +0 -270
  27. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRDashboard.test.tsx +0 -199
  28. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRRequestForm.test.tsx +0 -224
  29. package/packages/ndpr-toolkit/src/__tests__/components/dsr/DSRTracker.test.tsx +0 -104
  30. package/packages/ndpr-toolkit/src/__tests__/hooks/useConsent.test.tsx +0 -161
  31. package/packages/ndpr-toolkit/src/__tests__/hooks/useDSR.test.tsx +0 -330
  32. package/packages/ndpr-toolkit/src/__tests__/utils/breach.test.ts +0 -149
  33. package/packages/ndpr-toolkit/src/__tests__/utils/consent.test.ts +0 -88
  34. package/packages/ndpr-toolkit/src/__tests__/utils/dpia.test.ts +0 -160
  35. package/packages/ndpr-toolkit/src/__tests__/utils/dsr.test.ts +0 -110
  36. package/packages/ndpr-toolkit/src/__tests__/utils/privacy.test.ts +0 -97
  37. package/packages/ndpr-toolkit/src/components/breach/BreachNotificationManager.tsx +0 -701
  38. package/packages/ndpr-toolkit/src/components/breach/BreachReportForm.tsx +0 -631
  39. package/packages/ndpr-toolkit/src/components/breach/BreachRiskAssessment.tsx +0 -569
  40. package/packages/ndpr-toolkit/src/components/breach/RegulatoryReportGenerator.tsx +0 -496
  41. package/packages/ndpr-toolkit/src/components/consent/ConsentBanner.tsx +0 -270
  42. package/packages/ndpr-toolkit/src/components/consent/ConsentManager.tsx +0 -217
  43. package/packages/ndpr-toolkit/src/components/consent/ConsentStorage.tsx +0 -206
  44. package/packages/ndpr-toolkit/src/components/dpia/DPIAQuestionnaire.tsx +0 -342
  45. package/packages/ndpr-toolkit/src/components/dpia/DPIAReport.tsx +0 -373
  46. package/packages/ndpr-toolkit/src/components/dpia/StepIndicator.tsx +0 -174
  47. package/packages/ndpr-toolkit/src/components/dsr/DSRDashboard.tsx +0 -717
  48. package/packages/ndpr-toolkit/src/components/dsr/DSRRequestForm.tsx +0 -476
  49. package/packages/ndpr-toolkit/src/components/dsr/DSRTracker.tsx +0 -620
  50. package/packages/ndpr-toolkit/src/components/policy/PolicyExporter.tsx +0 -541
  51. package/packages/ndpr-toolkit/src/components/policy/PolicyGenerator.tsx +0 -454
  52. package/packages/ndpr-toolkit/src/components/policy/PolicyPreview.tsx +0 -333
  53. package/packages/ndpr-toolkit/src/hooks/useBreach.ts +0 -409
  54. package/packages/ndpr-toolkit/src/hooks/useConsent.ts +0 -263
  55. package/packages/ndpr-toolkit/src/hooks/useDPIA.ts +0 -457
  56. package/packages/ndpr-toolkit/src/hooks/useDSR.ts +0 -236
  57. package/packages/ndpr-toolkit/src/hooks/usePrivacyPolicy.ts +0 -428
  58. package/packages/ndpr-toolkit/src/index.ts +0 -44
  59. package/packages/ndpr-toolkit/src/setupTests.ts +0 -5
  60. package/packages/ndpr-toolkit/src/types/breach.ts +0 -283
  61. package/packages/ndpr-toolkit/src/types/consent.ts +0 -111
  62. package/packages/ndpr-toolkit/src/types/dpia.ts +0 -236
  63. package/packages/ndpr-toolkit/src/types/dsr.ts +0 -192
  64. package/packages/ndpr-toolkit/src/types/index.ts +0 -42
  65. package/packages/ndpr-toolkit/src/types/privacy.ts +0 -246
  66. package/packages/ndpr-toolkit/src/utils/breach.ts +0 -122
  67. package/packages/ndpr-toolkit/src/utils/consent.ts +0 -51
  68. package/packages/ndpr-toolkit/src/utils/dpia.ts +0 -104
  69. package/packages/ndpr-toolkit/src/utils/dsr.ts +0 -77
  70. package/packages/ndpr-toolkit/src/utils/privacy.ts +0 -100
  71. package/packages/ndpr-toolkit/tsconfig.json +0 -23
  72. package/postcss.config.mjs +0 -5
  73. package/src/__tests__/example.test.ts +0 -13
  74. package/src/__tests__/requestService.test.ts +0 -57
  75. package/src/app/accessibility.css +0 -70
  76. package/src/app/docs/components/DocLayout.tsx +0 -267
  77. package/src/app/docs/components/breach-notification/page.tsx +0 -797
  78. package/src/app/docs/components/consent-management/page.tsx +0 -576
  79. package/src/app/docs/components/data-subject-rights/page.tsx +0 -511
  80. package/src/app/docs/components/dpia-questionnaire/layout.tsx +0 -15
  81. package/src/app/docs/components/dpia-questionnaire/metadata.ts +0 -31
  82. package/src/app/docs/components/dpia-questionnaire/page.tsx +0 -666
  83. package/src/app/docs/components/hooks/page.tsx +0 -305
  84. package/src/app/docs/components/page.tsx +0 -84
  85. package/src/app/docs/components/privacy-policy-generator/page.tsx +0 -634
  86. package/src/app/docs/guides/breach-notification-process/components/BestPractices.tsx +0 -123
  87. package/src/app/docs/guides/breach-notification-process/components/ImplementationSteps.tsx +0 -328
  88. package/src/app/docs/guides/breach-notification-process/components/Introduction.tsx +0 -28
  89. package/src/app/docs/guides/breach-notification-process/components/NotificationTimeline.tsx +0 -91
  90. package/src/app/docs/guides/breach-notification-process/components/Resources.tsx +0 -118
  91. package/src/app/docs/guides/breach-notification-process/page.tsx +0 -39
  92. package/src/app/docs/guides/conducting-dpia/page.tsx +0 -593
  93. package/src/app/docs/guides/data-subject-requests/page.tsx +0 -666
  94. package/src/app/docs/guides/managing-consent/page.tsx +0 -738
  95. package/src/app/docs/guides/ndpr-compliance-checklist/components/ComplianceChecklist.tsx +0 -296
  96. package/src/app/docs/guides/ndpr-compliance-checklist/components/ImplementationTools.tsx +0 -145
  97. package/src/app/docs/guides/ndpr-compliance-checklist/components/Introduction.tsx +0 -33
  98. package/src/app/docs/guides/ndpr-compliance-checklist/components/KeyRequirements.tsx +0 -99
  99. package/src/app/docs/guides/ndpr-compliance-checklist/components/Resources.tsx +0 -159
  100. package/src/app/docs/guides/ndpr-compliance-checklist/page.tsx +0 -38
  101. package/src/app/docs/guides/page.tsx +0 -67
  102. package/src/app/docs/layout.tsx +0 -15
  103. package/src/app/docs/metadata.ts +0 -31
  104. package/src/app/docs/page.tsx +0 -572
  105. package/src/app/favicon.ico +0 -0
  106. package/src/app/globals.css +0 -123
  107. package/src/app/layout.tsx +0 -37
  108. package/src/app/ndpr-demos/breach/page.tsx +0 -354
  109. package/src/app/ndpr-demos/consent/page.tsx +0 -366
  110. package/src/app/ndpr-demos/dpia/page.tsx +0 -495
  111. package/src/app/ndpr-demos/dsr/page.tsx +0 -280
  112. package/src/app/ndpr-demos/page.tsx +0 -73
  113. package/src/app/ndpr-demos/policy/page.tsx +0 -771
  114. package/src/app/page.tsx +0 -452
  115. package/src/components/ErrorBoundary.tsx +0 -90
  116. package/src/components/breach-notification/BreachNotificationForm.tsx +0 -479
  117. package/src/components/consent/ConsentBanner.tsx +0 -159
  118. package/src/components/data-subject-rights/DataSubjectRequestForm.tsx +0 -419
  119. package/src/components/docs/DocLayout.tsx +0 -289
  120. package/src/components/docs/index.ts +0 -2
  121. package/src/components/dpia/DPIAQuestionnaire.tsx +0 -483
  122. package/src/components/privacy-policy/PolicyGenerator.tsx +0 -1062
  123. package/src/components/privacy-policy/data.ts +0 -98
  124. package/src/components/privacy-policy/shared/CheckboxField.tsx +0 -38
  125. package/src/components/privacy-policy/shared/CheckboxGroup.tsx +0 -85
  126. package/src/components/privacy-policy/shared/FormField.tsx +0 -79
  127. package/src/components/privacy-policy/shared/StepIndicator.tsx +0 -86
  128. package/src/components/privacy-policy/steps/CustomSectionsStep.tsx +0 -335
  129. package/src/components/privacy-policy/steps/DataCollectionStep.tsx +0 -231
  130. package/src/components/privacy-policy/steps/DataSharingStep.tsx +0 -418
  131. package/src/components/privacy-policy/steps/OrganizationInfoStep.tsx +0 -202
  132. package/src/components/privacy-policy/steps/PolicyPreviewStep.tsx +0 -172
  133. package/src/components/ui/Badge.tsx +0 -46
  134. package/src/components/ui/Button.tsx +0 -59
  135. package/src/components/ui/Card.tsx +0 -92
  136. package/src/components/ui/Checkbox.tsx +0 -57
  137. package/src/components/ui/FormField.tsx +0 -50
  138. package/src/components/ui/Input.tsx +0 -38
  139. package/src/components/ui/Loading.tsx +0 -201
  140. package/src/components/ui/Select.tsx +0 -42
  141. package/src/components/ui/TextArea.tsx +0 -38
  142. package/src/components/ui/label.tsx +0 -24
  143. package/src/components/ui/switch.tsx +0 -31
  144. package/src/components/ui/tabs.tsx +0 -66
  145. package/src/hooks/useConsent.ts +0 -64
  146. package/src/hooks/useLoadingState.ts +0 -85
  147. package/src/lib/consentService.ts +0 -137
  148. package/src/lib/dpiaQuestions.ts +0 -148
  149. package/src/lib/requestService.ts +0 -75
  150. package/src/lib/sanitize.ts +0 -108
  151. package/src/lib/storage.ts +0 -222
  152. package/src/lib/utils.ts +0 -6
  153. package/src/types/html-to-docx.d.ts +0 -30
  154. package/src/types/index.ts +0 -72
  155. package/tailwind.config.ts +0 -65
  156. package/tsconfig.json +0 -41
@@ -1,267 +0,0 @@
1
- 'use client';
2
-
3
- import React, { useState } from 'react';
4
- import Link from 'next/link';
5
- import { usePathname } from 'next/navigation';
6
- import { Button } from '@/components/ui/Button';
7
-
8
- type NavItem = {
9
- title: string;
10
- href: string;
11
- icon?: React.ReactNode;
12
- children?: NavItem[];
13
- };
14
-
15
- type DocLayoutProps = {
16
- children: React.ReactNode;
17
- title: string;
18
- description?: string;
19
- };
20
-
21
- const navigation: NavItem[] = [
22
- {
23
- title: 'Getting Started',
24
- href: '/docs',
25
- icon: (
26
- <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
27
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
28
- </svg>
29
- ),
30
- },
31
- {
32
- title: 'Components',
33
- href: '/docs/components',
34
- icon: (
35
- <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
36
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
37
- </svg>
38
- ),
39
- children: [
40
- { title: 'DPIA Questionnaire', href: '/docs/components/dpia-questionnaire' },
41
- { title: 'Consent Management', href: '/docs/components/consent-management' },
42
- { title: 'Data Subject Rights', href: '/docs/components/data-subject-rights' },
43
- { title: 'Breach Notification', href: '/docs/components/breach-notification' },
44
- { title: 'Privacy Policy Generator', href: '/docs/components/privacy-policy-generator' },
45
- ],
46
- },
47
- {
48
- title: 'Implementation Guides',
49
- href: '/docs/guides',
50
- icon: (
51
- <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
52
- <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" />
53
- </svg>
54
- ),
55
- children: [
56
- { title: 'NDPR Compliance Checklist', href: '/docs/guides/ndpr-compliance-checklist' },
57
- { title: 'Conducting a DPIA', href: '/docs/guides/conducting-dpia' },
58
- { title: 'Managing Consent', href: '/docs/guides/managing-consent' },
59
- { title: 'Handling Data Subject Requests', href: '/docs/guides/data-subject-requests' },
60
- { title: 'Breach Notification Process', href: '/docs/guides/breach-notification-process' },
61
- ],
62
- },
63
- ];
64
-
65
- export function DocLayout({ children, title, description }: DocLayoutProps) {
66
- const pathname = usePathname();
67
- const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
68
-
69
- // Function to check if a nav item is active
70
- const isActive = (href: string) => {
71
- if (href === '/docs' && pathname === '/docs') {
72
- return true;
73
- }
74
- return pathname !== '/docs' && pathname.startsWith(href);
75
- };
76
-
77
- // Function to check if a nav item should be expanded
78
- const shouldExpand = (item: NavItem) => {
79
- if (!item.children) return false;
80
- return item.children.some(child => pathname === child.href || pathname.startsWith(child.href));
81
- };
82
-
83
- return (
84
- <div className="min-h-screen bg-gray-50 dark:bg-gray-900">
85
- {/* Mobile menu button */}
86
- <div className="lg:hidden fixed top-4 left-4 z-50">
87
- <button
88
- type="button"
89
- className="p-2 rounded-md text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500"
90
- onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
91
- >
92
- <span className="sr-only">Open sidebar</span>
93
- <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
94
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
95
- </svg>
96
- </button>
97
- </div>
98
-
99
- {/* Sidebar for desktop */}
100
- <div className="hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col">
101
- <div className="flex flex-col flex-grow border-r border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 overflow-y-auto">
102
- <div className="flex items-center flex-shrink-0 px-4 py-5">
103
- <Link href="/" className="flex items-center">
104
- <span className="text-xl font-bold text-gray-900 dark:text-white">NDPR Toolkit</span>
105
- </Link>
106
- </div>
107
- <div className="flex-grow flex flex-col">
108
- <nav className="flex-1 px-2 pb-4 space-y-1">
109
- {navigation.map((item) => (
110
- <div key={item.title} className="space-y-1">
111
- <Link
112
- href={item.href}
113
- className={`group flex items-center px-3 py-2 text-sm font-medium rounded-md ${
114
- isActive(item.href)
115
- ? 'bg-blue-50 text-blue-700 dark:bg-blue-900/30 dark:text-blue-200'
116
- : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700'
117
- }`}
118
- >
119
- {item.icon && (
120
- <span className={`mr-3 ${isActive(item.href) ? 'text-blue-500 dark:text-blue-400' : 'text-gray-500 dark:text-gray-400'}`}>
121
- {item.icon}
122
- </span>
123
- )}
124
- {item.title}
125
- </Link>
126
- {item.children && shouldExpand(item) && (
127
- <div className="mt-1 ml-8 space-y-1">
128
- {item.children.map((child) => (
129
- <Link
130
- key={child.title}
131
- href={child.href}
132
- className={`group flex items-center px-3 py-2 text-sm font-medium rounded-md ${
133
- pathname === child.href
134
- ? 'bg-blue-50 text-blue-700 dark:bg-blue-900/30 dark:text-blue-200'
135
- : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700'
136
- }`}
137
- >
138
- {child.title}
139
- </Link>
140
- ))}
141
- </div>
142
- )}
143
- </div>
144
- ))}
145
- </nav>
146
- </div>
147
- <div className="p-4 border-t border-gray-200 dark:border-gray-700">
148
- <Button asChild variant="outline" size="sm" className="w-full">
149
- <a href="https://github.com/tantainnovative/ndpr-toolkit" target="_blank" rel="noopener noreferrer" className="flex items-center">
150
- <svg className="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 24 24">
151
- <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" />
152
- </svg>
153
- GitHub
154
- </a>
155
- </Button>
156
- </div>
157
- </div>
158
- </div>
159
-
160
- {/* Mobile menu, show/hide based on mobile menu state */}
161
- <div className={`lg:hidden fixed inset-0 z-40 ${mobileMenuOpen ? 'block' : 'hidden'}`}>
162
- {/* Background overlay */}
163
- <div className="fixed inset-0 bg-gray-600 bg-opacity-75" onClick={() => setMobileMenuOpen(false)} />
164
-
165
- {/* Mobile menu panel */}
166
- <div className="fixed inset-y-0 left-0 max-w-xs w-full bg-white dark:bg-gray-800 overflow-y-auto">
167
- <div className="flex items-center justify-between px-4 py-5">
168
- <Link href="/" className="flex items-center" onClick={() => setMobileMenuOpen(false)}>
169
- <span className="text-xl font-bold text-gray-900 dark:text-white">NDPR Toolkit</span>
170
- </Link>
171
- <button
172
- type="button"
173
- className="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500"
174
- onClick={() => setMobileMenuOpen(false)}
175
- >
176
- <span className="sr-only">Close sidebar</span>
177
- <svg className="h-6 w-6 text-gray-500 dark:text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
178
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
179
- </svg>
180
- </button>
181
- </div>
182
- <div className="mt-5 px-2 space-y-1">
183
- <nav className="space-y-1">
184
- {navigation.map((item) => (
185
- <div key={item.title} className="space-y-1">
186
- <Link
187
- href={item.href}
188
- className={`group flex items-center px-3 py-2 text-sm font-medium rounded-md ${
189
- isActive(item.href)
190
- ? 'bg-blue-50 text-blue-700 dark:bg-blue-900/30 dark:text-blue-200'
191
- : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700'
192
- }`}
193
- onClick={() => setMobileMenuOpen(false)}
194
- >
195
- {item.icon && (
196
- <span className={`mr-3 ${isActive(item.href) ? 'text-blue-500 dark:text-blue-400' : 'text-gray-500 dark:text-gray-400'}`}>
197
- {item.icon}
198
- </span>
199
- )}
200
- {item.title}
201
- </Link>
202
- {item.children && shouldExpand(item) && (
203
- <div className="mt-1 ml-8 space-y-1">
204
- {item.children.map((child) => (
205
- <Link
206
- key={child.title}
207
- href={child.href}
208
- className={`group flex items-center px-3 py-2 text-sm font-medium rounded-md ${
209
- pathname === child.href
210
- ? 'bg-blue-50 text-blue-700 dark:bg-blue-900/30 dark:text-blue-200'
211
- : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700'
212
- }`}
213
- onClick={() => setMobileMenuOpen(false)}
214
- >
215
- {child.title}
216
- </Link>
217
- ))}
218
- </div>
219
- )}
220
- </div>
221
- ))}
222
- </nav>
223
- </div>
224
- <div className="p-4 border-t border-gray-200 dark:border-gray-700">
225
- <Button asChild variant="outline" size="sm" className="w-full">
226
- <a href="https://github.com/tantainnovative/ndpr-toolkit" target="_blank" rel="noopener noreferrer" className="flex items-center">
227
- <svg className="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 24 24">
228
- <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" />
229
- </svg>
230
- GitHub
231
- </a>
232
- </Button>
233
- </div>
234
- </div>
235
- </div>
236
-
237
- {/* Main content */}
238
- <div className="lg:pl-64">
239
- <main className="py-10">
240
- <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
241
- <div className="pb-5 border-b border-gray-200 dark:border-gray-700 mb-6">
242
- <div className="flex flex-col md:flex-row md:items-center md:justify-between">
243
- <div>
244
- <h1 className="text-3xl font-bold text-gray-900 dark:text-white">{title}</h1>
245
- {description && <p className="mt-2 text-lg text-gray-500 dark:text-gray-400">{description}</p>}
246
- </div>
247
- <div className="mt-4 md:mt-0 flex space-x-3">
248
- <Button asChild variant="outline" size="sm">
249
- <Link href="/ndpr-demos">View Demos</Link>
250
- </Button>
251
- <Button asChild variant="default" size="sm">
252
- <Link href="/">Back to Home</Link>
253
- </Button>
254
- </div>
255
- </div>
256
- </div>
257
-
258
- {/* Page content */}
259
- <div className="prose prose-blue max-w-none dark:prose-invert">
260
- {children}
261
- </div>
262
- </div>
263
- </main>
264
- </div>
265
- </div>
266
- );
267
- }