@codaijs/keel 0.2.3 → 0.2.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 (80) hide show
  1. package/dist/__tests__/sail-installer.test.js +25 -25
  2. package/dist/sail-installer.js +174 -174
  3. package/dist/scaffold.js +68 -68
  4. package/package.json +58 -58
  5. package/sails/_template/addon.json +20 -20
  6. package/sails/_template/install.ts +402 -402
  7. package/sails/admin-dashboard/README.md +117 -117
  8. package/sails/admin-dashboard/addon.json +28 -28
  9. package/sails/admin-dashboard/files/backend/middleware/admin.ts +34 -34
  10. package/sails/admin-dashboard/files/backend/routes/admin.ts +243 -243
  11. package/sails/admin-dashboard/files/frontend/components/admin/StatsCard.tsx +40 -40
  12. package/sails/admin-dashboard/files/frontend/components/admin/UsersTable.tsx +240 -240
  13. package/sails/admin-dashboard/files/frontend/hooks/useAdmin.ts +149 -149
  14. package/sails/admin-dashboard/files/frontend/pages/admin/Dashboard.tsx +173 -173
  15. package/sails/admin-dashboard/files/frontend/pages/admin/UserDetail.tsx +203 -203
  16. package/sails/admin-dashboard/install.ts +305 -305
  17. package/sails/analytics/README.md +178 -178
  18. package/sails/analytics/addon.json +27 -27
  19. package/sails/analytics/files/frontend/components/AnalyticsProvider.tsx +58 -58
  20. package/sails/analytics/files/frontend/hooks/useAnalytics.ts +64 -64
  21. package/sails/analytics/files/frontend/lib/analytics.ts +103 -103
  22. package/sails/analytics/install.ts +297 -297
  23. package/sails/file-uploads/addon.json +30 -30
  24. package/sails/file-uploads/files/backend/routes/files.ts +198 -198
  25. package/sails/file-uploads/files/backend/schema/files.ts +36 -36
  26. package/sails/file-uploads/files/backend/services/file-storage.ts +128 -128
  27. package/sails/file-uploads/files/frontend/components/FileList.tsx +248 -248
  28. package/sails/file-uploads/files/frontend/components/FileUploadButton.tsx +147 -147
  29. package/sails/file-uploads/files/frontend/hooks/useFileUpload.ts +106 -106
  30. package/sails/file-uploads/files/frontend/hooks/useFiles.ts +118 -118
  31. package/sails/file-uploads/files/frontend/pages/Files.tsx +37 -37
  32. package/sails/file-uploads/install.ts +466 -466
  33. package/sails/gdpr/README.md +174 -174
  34. package/sails/gdpr/addon.json +27 -27
  35. package/sails/gdpr/files/backend/routes/gdpr.ts +140 -140
  36. package/sails/gdpr/files/backend/services/gdpr.ts +293 -293
  37. package/sails/gdpr/files/frontend/components/auth/ConsentCheckboxes.tsx +97 -97
  38. package/sails/gdpr/files/frontend/components/gdpr/AccountDeletionRequest.tsx +192 -192
  39. package/sails/gdpr/files/frontend/components/gdpr/DataExportButton.tsx +75 -75
  40. package/sails/gdpr/files/frontend/pages/PrivacyPolicy.tsx +186 -186
  41. package/sails/gdpr/install.ts +756 -756
  42. package/sails/google-oauth/README.md +121 -121
  43. package/sails/google-oauth/addon.json +22 -22
  44. package/sails/google-oauth/files/GoogleButton.tsx +50 -50
  45. package/sails/google-oauth/install.ts +252 -252
  46. package/sails/i18n/README.md +193 -193
  47. package/sails/i18n/addon.json +30 -30
  48. package/sails/i18n/files/frontend/components/LanguageSwitcher.tsx +108 -108
  49. package/sails/i18n/files/frontend/hooks/useLanguage.ts +31 -31
  50. package/sails/i18n/files/frontend/lib/i18n.ts +32 -32
  51. package/sails/i18n/files/frontend/locales/de/common.json +44 -44
  52. package/sails/i18n/files/frontend/locales/en/common.json +44 -44
  53. package/sails/i18n/install.ts +407 -407
  54. package/sails/push-notifications/README.md +163 -163
  55. package/sails/push-notifications/addon.json +31 -31
  56. package/sails/push-notifications/files/backend/routes/notifications.ts +153 -153
  57. package/sails/push-notifications/files/backend/schema/notifications.ts +31 -31
  58. package/sails/push-notifications/files/backend/services/notifications.ts +117 -117
  59. package/sails/push-notifications/files/frontend/components/PushNotificationInit.tsx +12 -12
  60. package/sails/push-notifications/files/frontend/hooks/usePushNotifications.ts +154 -154
  61. package/sails/push-notifications/install.ts +384 -384
  62. package/sails/r2-storage/addon.json +29 -29
  63. package/sails/r2-storage/files/backend/services/storage.ts +71 -71
  64. package/sails/r2-storage/files/frontend/components/ProfilePictureUpload.tsx +167 -167
  65. package/sails/r2-storage/install.ts +412 -412
  66. package/sails/rate-limiting/addon.json +20 -20
  67. package/sails/rate-limiting/files/backend/middleware/rate-limit-store.ts +104 -104
  68. package/sails/rate-limiting/files/backend/middleware/rate-limit.ts +137 -137
  69. package/sails/rate-limiting/install.ts +300 -300
  70. package/sails/registry.json +107 -107
  71. package/sails/stripe/README.md +214 -214
  72. package/sails/stripe/addon.json +24 -24
  73. package/sails/stripe/files/backend/routes/stripe.ts +154 -154
  74. package/sails/stripe/files/backend/schema/stripe.ts +74 -74
  75. package/sails/stripe/files/backend/services/stripe.ts +224 -224
  76. package/sails/stripe/files/frontend/components/SubscriptionStatus.tsx +135 -135
  77. package/sails/stripe/files/frontend/hooks/useSubscription.ts +86 -86
  78. package/sails/stripe/files/frontend/pages/Checkout.tsx +116 -116
  79. package/sails/stripe/files/frontend/pages/Pricing.tsx +226 -226
  80. package/sails/stripe/install.ts +378 -378
@@ -1,75 +1,75 @@
1
- import { useState } from "react";
2
-
3
- export default function DataExportButton() {
4
- const [isLoading, setIsLoading] = useState(false);
5
- const [error, setError] = useState("");
6
-
7
- const handleExport = async () => {
8
- setIsLoading(true);
9
- setError("");
10
-
11
- try {
12
- const response = await fetch("/api/gdpr/export", {
13
- credentials: "include",
14
- });
15
-
16
- if (!response.ok) {
17
- throw new Error("Failed to export data.");
18
- }
19
-
20
- const data = await response.json();
21
- const blob = new Blob([JSON.stringify(data, null, 2)], {
22
- type: "application/json",
23
- });
24
- const url = URL.createObjectURL(blob);
25
- const link = document.createElement("a");
26
- link.href = url;
27
- link.download = `keel-data-export-${new Date().toISOString().slice(0, 10)}.json`;
28
- document.body.appendChild(link);
29
- link.click();
30
- document.body.removeChild(link);
31
- URL.revokeObjectURL(url);
32
- } catch (err) {
33
- setError(
34
- err instanceof Error ? err.message : "Failed to export data.",
35
- );
36
- } finally {
37
- setIsLoading(false);
38
- }
39
- };
40
-
41
- return (
42
- <div>
43
- <button
44
- onClick={handleExport}
45
- disabled={isLoading}
46
- className="inline-flex items-center rounded-lg border border-keel-gray-800 px-4 py-2 text-sm font-medium text-keel-gray-100 transition-colors hover:border-keel-gray-400 disabled:opacity-50"
47
- >
48
- {isLoading ? (
49
- <>
50
- <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-keel-gray-800 border-t-keel-blue" />
51
- Exporting...
52
- </>
53
- ) : (
54
- <>
55
- <svg
56
- className="mr-2 h-4 w-4"
57
- fill="none"
58
- viewBox="0 0 24 24"
59
- stroke="currentColor"
60
- >
61
- <path
62
- strokeLinecap="round"
63
- strokeLinejoin="round"
64
- strokeWidth={2}
65
- d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 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"
66
- />
67
- </svg>
68
- Export my data
69
- </>
70
- )}
71
- </button>
72
- {error && <p className="mt-2 text-xs text-red-400">{error}</p>}
73
- </div>
74
- );
75
- }
1
+ import { useState } from "react";
2
+
3
+ export default function DataExportButton() {
4
+ const [isLoading, setIsLoading] = useState(false);
5
+ const [error, setError] = useState("");
6
+
7
+ const handleExport = async () => {
8
+ setIsLoading(true);
9
+ setError("");
10
+
11
+ try {
12
+ const response = await fetch("/api/gdpr/export", {
13
+ credentials: "include",
14
+ });
15
+
16
+ if (!response.ok) {
17
+ throw new Error("Failed to export data.");
18
+ }
19
+
20
+ const data = await response.json();
21
+ const blob = new Blob([JSON.stringify(data, null, 2)], {
22
+ type: "application/json",
23
+ });
24
+ const url = URL.createObjectURL(blob);
25
+ const link = document.createElement("a");
26
+ link.href = url;
27
+ link.download = `keel-data-export-${new Date().toISOString().slice(0, 10)}.json`;
28
+ document.body.appendChild(link);
29
+ link.click();
30
+ document.body.removeChild(link);
31
+ URL.revokeObjectURL(url);
32
+ } catch (err) {
33
+ setError(
34
+ err instanceof Error ? err.message : "Failed to export data.",
35
+ );
36
+ } finally {
37
+ setIsLoading(false);
38
+ }
39
+ };
40
+
41
+ return (
42
+ <div>
43
+ <button
44
+ onClick={handleExport}
45
+ disabled={isLoading}
46
+ className="inline-flex items-center rounded-lg border border-keel-gray-800 px-4 py-2 text-sm font-medium text-keel-gray-100 transition-colors hover:border-keel-gray-400 disabled:opacity-50"
47
+ >
48
+ {isLoading ? (
49
+ <>
50
+ <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-keel-gray-800 border-t-keel-blue" />
51
+ Exporting...
52
+ </>
53
+ ) : (
54
+ <>
55
+ <svg
56
+ className="mr-2 h-4 w-4"
57
+ fill="none"
58
+ viewBox="0 0 24 24"
59
+ stroke="currentColor"
60
+ >
61
+ <path
62
+ strokeLinecap="round"
63
+ strokeLinejoin="round"
64
+ strokeWidth={2}
65
+ d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 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"
66
+ />
67
+ </svg>
68
+ Export my data
69
+ </>
70
+ )}
71
+ </button>
72
+ {error && <p className="mt-2 text-xs text-red-400">{error}</p>}
73
+ </div>
74
+ );
75
+ }
@@ -1,186 +1,186 @@
1
- export default function PrivacyPolicy() {
2
- return (
3
- <div className="mx-auto w-full max-w-3xl px-4 py-8 sm:px-6 lg:px-8">
4
- <article className="max-w-none">
5
- <h1 className="text-3xl font-bold text-white">Privacy Policy</h1>
6
- <p className="text-sm text-keel-gray-400">Last updated: March 18, 2026</p>
7
-
8
- <section className="mt-8 space-y-6">
9
- <div>
10
- <h2 className="text-xl font-semibold text-white">
11
- 1. What Data We Collect
12
- </h2>
13
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
14
- We collect the following personal data when you use our service:
15
- </p>
16
- <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
17
- <li>
18
- <strong className="text-keel-gray-100">Account information:</strong> your name, email address,
19
- and encrypted password when you create an account.
20
- </li>
21
- <li>
22
- <strong className="text-keel-gray-100">Profile data:</strong> profile picture and any
23
- additional information you choose to provide.
24
- </li>
25
- <li>
26
- <strong className="text-keel-gray-100">Usage data:</strong> information about how you interact
27
- with our service, including pages visited, features used, and
28
- session duration (only with your explicit consent).
29
- </li>
30
- <li>
31
- <strong className="text-keel-gray-100">Technical data:</strong> IP address, browser type,
32
- device information, and operating system for security and
33
- service operation purposes.
34
- </li>
35
- </ul>
36
- </div>
37
-
38
- <div>
39
- <h2 className="text-xl font-semibold text-white">
40
- 2. Why We Collect It
41
- </h2>
42
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
43
- We process your personal data for the following purposes:
44
- </p>
45
- <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
46
- <li>
47
- <strong className="text-keel-gray-100">Service provision:</strong> to create and manage your
48
- account, authenticate your identity, and provide the core
49
- functionality of the service.
50
- </li>
51
- <li>
52
- <strong className="text-keel-gray-100">Communication:</strong> to send you important service
53
- notifications, such as email verification and password resets.
54
- </li>
55
- <li>
56
- <strong className="text-keel-gray-100">Marketing:</strong> to send you product updates and
57
- promotional content (only with your explicit consent).
58
- </li>
59
- <li>
60
- <strong className="text-keel-gray-100">Analytics:</strong> to understand how the service is
61
- used and improve it (only with your explicit consent).
62
- </li>
63
- <li>
64
- <strong className="text-keel-gray-100">Security:</strong> to protect your account and detect
65
- unauthorized access or abuse.
66
- </li>
67
- <li>
68
- <strong className="text-keel-gray-100">Legal compliance:</strong> to comply with applicable
69
- laws and regulations.
70
- </li>
71
- </ul>
72
- </div>
73
-
74
- <div>
75
- <h2 className="text-xl font-semibold text-white">
76
- 3. How Long We Keep It
77
- </h2>
78
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
79
- We retain your personal data for as long as your account is
80
- active. If you request account deletion, your data will be
81
- permanently removed within 30 days of the scheduled deletion date.
82
- Some data may be retained for a longer period if required by law
83
- (e.g., financial records for tax compliance).
84
- </p>
85
- </div>
86
-
87
- <div>
88
- <h2 className="text-xl font-semibold text-white">
89
- 4. Your Rights
90
- </h2>
91
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
92
- Under the General Data Protection Regulation (GDPR), you have the
93
- following rights:
94
- </p>
95
- <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
96
- <li>
97
- <strong className="text-keel-gray-100">Right of access:</strong> you can request a copy of your
98
- personal data at any time.
99
- </li>
100
- <li>
101
- <strong className="text-keel-gray-100">Right to data portability:</strong> you can export your
102
- data in a machine-readable format (JSON).
103
- </li>
104
- <li>
105
- <strong className="text-keel-gray-100">Right to erasure:</strong> you can request the deletion
106
- of your account and all associated data.
107
- </li>
108
- <li>
109
- <strong className="text-keel-gray-100">Right to withdraw consent:</strong> you can withdraw any
110
- optional consent (marketing, analytics) at any time through your
111
- account settings.
112
- </li>
113
- <li>
114
- <strong className="text-keel-gray-100">Right to rectification:</strong> you can update or
115
- correct your personal data through your profile settings.
116
- </li>
117
- <li>
118
- <strong className="text-keel-gray-100">Right to object:</strong> you can object to the
119
- processing of your personal data for specific purposes.
120
- </li>
121
- </ul>
122
- </div>
123
-
124
- <div>
125
- <h2 className="text-xl font-semibold text-white">
126
- 5. How to Exercise Your Rights
127
- </h2>
128
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
129
- You can exercise most of your rights directly through the
130
- application:
131
- </p>
132
- <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
133
- <li>
134
- <strong className="text-keel-gray-100">Data export:</strong> go to Settings &gt; Data &amp;
135
- Privacy &gt; Export my data.
136
- </li>
137
- <li>
138
- <strong className="text-keel-gray-100">Account deletion:</strong> go to Settings &gt; Data
139
- &amp; Privacy &gt; Delete my account.
140
- </li>
141
- <li>
142
- <strong className="text-keel-gray-100">Consent management:</strong> go to Settings &gt; Consent
143
- Preferences to manage your marketing and analytics opt-ins.
144
- </li>
145
- <li>
146
- <strong className="text-keel-gray-100">Profile updates:</strong> go to Profile to update your
147
- personal information.
148
- </li>
149
- </ul>
150
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
151
- For any other requests, please contact us using the information
152
- below.
153
- </p>
154
- </div>
155
-
156
- <div>
157
- <h2 className="text-xl font-semibold text-white">
158
- 6. Data Security
159
- </h2>
160
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
161
- We implement appropriate technical and organizational measures to
162
- protect your personal data against unauthorized access, alteration,
163
- disclosure, or destruction. This includes encryption of passwords,
164
- secure HTTPS connections, and regular security audits.
165
- </p>
166
- </div>
167
-
168
- <div>
169
- <h2 className="text-xl font-semibold text-white">
170
- 7. Contact Information
171
- </h2>
172
- <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
173
- If you have any questions about this Privacy Policy or wish to
174
- exercise your rights, please contact us at:
175
- </p>
176
- <p className="mt-2 text-sm text-keel-gray-400">
177
- <strong className="text-keel-gray-100">Email:</strong> privacy@yourdomain.com
178
- <br />
179
- <strong className="text-keel-gray-100">Data Protection Officer:</strong> dpo@yourdomain.com
180
- </p>
181
- </div>
182
- </section>
183
- </article>
184
- </div>
185
- );
186
- }
1
+ export default function PrivacyPolicy() {
2
+ return (
3
+ <div className="mx-auto w-full max-w-3xl px-4 py-8 sm:px-6 lg:px-8">
4
+ <article className="max-w-none">
5
+ <h1 className="text-3xl font-bold text-white">Privacy Policy</h1>
6
+ <p className="text-sm text-keel-gray-400">Last updated: March 18, 2026</p>
7
+
8
+ <section className="mt-8 space-y-6">
9
+ <div>
10
+ <h2 className="text-xl font-semibold text-white">
11
+ 1. What Data We Collect
12
+ </h2>
13
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
14
+ We collect the following personal data when you use our service:
15
+ </p>
16
+ <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
17
+ <li>
18
+ <strong className="text-keel-gray-100">Account information:</strong> your name, email address,
19
+ and encrypted password when you create an account.
20
+ </li>
21
+ <li>
22
+ <strong className="text-keel-gray-100">Profile data:</strong> profile picture and any
23
+ additional information you choose to provide.
24
+ </li>
25
+ <li>
26
+ <strong className="text-keel-gray-100">Usage data:</strong> information about how you interact
27
+ with our service, including pages visited, features used, and
28
+ session duration (only with your explicit consent).
29
+ </li>
30
+ <li>
31
+ <strong className="text-keel-gray-100">Technical data:</strong> IP address, browser type,
32
+ device information, and operating system for security and
33
+ service operation purposes.
34
+ </li>
35
+ </ul>
36
+ </div>
37
+
38
+ <div>
39
+ <h2 className="text-xl font-semibold text-white">
40
+ 2. Why We Collect It
41
+ </h2>
42
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
43
+ We process your personal data for the following purposes:
44
+ </p>
45
+ <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
46
+ <li>
47
+ <strong className="text-keel-gray-100">Service provision:</strong> to create and manage your
48
+ account, authenticate your identity, and provide the core
49
+ functionality of the service.
50
+ </li>
51
+ <li>
52
+ <strong className="text-keel-gray-100">Communication:</strong> to send you important service
53
+ notifications, such as email verification and password resets.
54
+ </li>
55
+ <li>
56
+ <strong className="text-keel-gray-100">Marketing:</strong> to send you product updates and
57
+ promotional content (only with your explicit consent).
58
+ </li>
59
+ <li>
60
+ <strong className="text-keel-gray-100">Analytics:</strong> to understand how the service is
61
+ used and improve it (only with your explicit consent).
62
+ </li>
63
+ <li>
64
+ <strong className="text-keel-gray-100">Security:</strong> to protect your account and detect
65
+ unauthorized access or abuse.
66
+ </li>
67
+ <li>
68
+ <strong className="text-keel-gray-100">Legal compliance:</strong> to comply with applicable
69
+ laws and regulations.
70
+ </li>
71
+ </ul>
72
+ </div>
73
+
74
+ <div>
75
+ <h2 className="text-xl font-semibold text-white">
76
+ 3. How Long We Keep It
77
+ </h2>
78
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
79
+ We retain your personal data for as long as your account is
80
+ active. If you request account deletion, your data will be
81
+ permanently removed within 30 days of the scheduled deletion date.
82
+ Some data may be retained for a longer period if required by law
83
+ (e.g., financial records for tax compliance).
84
+ </p>
85
+ </div>
86
+
87
+ <div>
88
+ <h2 className="text-xl font-semibold text-white">
89
+ 4. Your Rights
90
+ </h2>
91
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
92
+ Under the General Data Protection Regulation (GDPR), you have the
93
+ following rights:
94
+ </p>
95
+ <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
96
+ <li>
97
+ <strong className="text-keel-gray-100">Right of access:</strong> you can request a copy of your
98
+ personal data at any time.
99
+ </li>
100
+ <li>
101
+ <strong className="text-keel-gray-100">Right to data portability:</strong> you can export your
102
+ data in a machine-readable format (JSON).
103
+ </li>
104
+ <li>
105
+ <strong className="text-keel-gray-100">Right to erasure:</strong> you can request the deletion
106
+ of your account and all associated data.
107
+ </li>
108
+ <li>
109
+ <strong className="text-keel-gray-100">Right to withdraw consent:</strong> you can withdraw any
110
+ optional consent (marketing, analytics) at any time through your
111
+ account settings.
112
+ </li>
113
+ <li>
114
+ <strong className="text-keel-gray-100">Right to rectification:</strong> you can update or
115
+ correct your personal data through your profile settings.
116
+ </li>
117
+ <li>
118
+ <strong className="text-keel-gray-100">Right to object:</strong> you can object to the
119
+ processing of your personal data for specific purposes.
120
+ </li>
121
+ </ul>
122
+ </div>
123
+
124
+ <div>
125
+ <h2 className="text-xl font-semibold text-white">
126
+ 5. How to Exercise Your Rights
127
+ </h2>
128
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
129
+ You can exercise most of your rights directly through the
130
+ application:
131
+ </p>
132
+ <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-keel-gray-400">
133
+ <li>
134
+ <strong className="text-keel-gray-100">Data export:</strong> go to Settings &gt; Data &amp;
135
+ Privacy &gt; Export my data.
136
+ </li>
137
+ <li>
138
+ <strong className="text-keel-gray-100">Account deletion:</strong> go to Settings &gt; Data
139
+ &amp; Privacy &gt; Delete my account.
140
+ </li>
141
+ <li>
142
+ <strong className="text-keel-gray-100">Consent management:</strong> go to Settings &gt; Consent
143
+ Preferences to manage your marketing and analytics opt-ins.
144
+ </li>
145
+ <li>
146
+ <strong className="text-keel-gray-100">Profile updates:</strong> go to Profile to update your
147
+ personal information.
148
+ </li>
149
+ </ul>
150
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
151
+ For any other requests, please contact us using the information
152
+ below.
153
+ </p>
154
+ </div>
155
+
156
+ <div>
157
+ <h2 className="text-xl font-semibold text-white">
158
+ 6. Data Security
159
+ </h2>
160
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
161
+ We implement appropriate technical and organizational measures to
162
+ protect your personal data against unauthorized access, alteration,
163
+ disclosure, or destruction. This includes encryption of passwords,
164
+ secure HTTPS connections, and regular security audits.
165
+ </p>
166
+ </div>
167
+
168
+ <div>
169
+ <h2 className="text-xl font-semibold text-white">
170
+ 7. Contact Information
171
+ </h2>
172
+ <p className="mt-2 text-sm leading-relaxed text-keel-gray-400">
173
+ If you have any questions about this Privacy Policy or wish to
174
+ exercise your rights, please contact us at:
175
+ </p>
176
+ <p className="mt-2 text-sm text-keel-gray-400">
177
+ <strong className="text-keel-gray-100">Email:</strong> privacy@yourdomain.com
178
+ <br />
179
+ <strong className="text-keel-gray-100">Data Protection Officer:</strong> dpo@yourdomain.com
180
+ </p>
181
+ </div>
182
+ </section>
183
+ </article>
184
+ </div>
185
+ );
186
+ }