lytx 0.3.0

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 (213) hide show
  1. package/.env.example +37 -0
  2. package/README.md +486 -0
  3. package/alchemy.run.ts +155 -0
  4. package/cli/bootstrap-admin.ts +284 -0
  5. package/cli/deploy-staging.ts +692 -0
  6. package/cli/import-events.ts +628 -0
  7. package/cli/import-sites.ts +518 -0
  8. package/cli/index.ts +609 -0
  9. package/cli/init-db.ts +269 -0
  10. package/cli/migrate-to-durable-objects.ts +564 -0
  11. package/cli/migration-worker.ts +300 -0
  12. package/cli/performance-test.ts +588 -0
  13. package/cli/pg/client.ts +4 -0
  14. package/cli/pg/new-site.ts +153 -0
  15. package/cli/rollback-durable-objects.ts +622 -0
  16. package/cli/seed-data.ts +459 -0
  17. package/cli/setup.js +18 -0
  18. package/cli/setup.ts +463 -0
  19. package/cli/validate-migration.ts +200 -0
  20. package/cli/wrangler-migration.jsonc +28 -0
  21. package/db/adapter.ts +166 -0
  22. package/db/analytics_engine/client.ts +0 -0
  23. package/db/analytics_engine/sites.ts +0 -0
  24. package/db/client.ts +16 -0
  25. package/db/d1/client.ts +8 -0
  26. package/db/d1/drizzle.config.ts +35 -0
  27. package/db/d1/migrations/0000_true_maelstrom.sql +165 -0
  28. package/db/d1/migrations/0001_wonderful_bloodaxe.sql +12 -0
  29. package/db/d1/migrations/0002_late_frightful_four.sql +1 -0
  30. package/db/d1/migrations/0003_cuddly_obadiah_stane.sql +16 -0
  31. package/db/d1/migrations/0004_mute_stardust.sql +1 -0
  32. package/db/d1/migrations/0005_awesome_silvermane.sql +3 -0
  33. package/db/d1/migrations/0006_volatile_shriek.sql +2 -0
  34. package/db/d1/migrations/0007_superb_lila_cheney.sql +1 -0
  35. package/db/d1/migrations/0008_bitter_longshot.sql +17 -0
  36. package/db/d1/migrations/0009_wonderful_madame_masque.sql +28 -0
  37. package/db/d1/migrations/meta/0000_snapshot.json +1112 -0
  38. package/db/d1/migrations/meta/0001_snapshot.json +1187 -0
  39. package/db/d1/migrations/meta/0002_snapshot.json +1194 -0
  40. package/db/d1/migrations/meta/0003_snapshot.json +1296 -0
  41. package/db/d1/migrations/meta/0004_snapshot.json +1303 -0
  42. package/db/d1/migrations/meta/0005_snapshot.json +1325 -0
  43. package/db/d1/migrations/meta/0006_snapshot.json +1339 -0
  44. package/db/d1/migrations/meta/0007_snapshot.json +1347 -0
  45. package/db/d1/migrations/meta/0008_snapshot.json +1464 -0
  46. package/db/d1/migrations/meta/0009_snapshot.json +1648 -0
  47. package/db/d1/migrations/meta/_journal.json +76 -0
  48. package/db/d1/schema.ts +407 -0
  49. package/db/d1/sites.ts +374 -0
  50. package/db/d1/teamAiUsage.ts +101 -0
  51. package/db/d1/teams.ts +127 -0
  52. package/db/durable/drizzle.config.ts +8 -0
  53. package/db/durable/durableObjectClient.ts +480 -0
  54. package/db/durable/events.ts +100 -0
  55. package/db/durable/migrations/0000_fair_bucky.sql +38 -0
  56. package/db/durable/migrations/meta/0000_snapshot.json +278 -0
  57. package/db/durable/migrations/meta/_journal.json +13 -0
  58. package/db/durable/migrations/migrations.js +10 -0
  59. package/db/durable/schema.ts +5 -0
  60. package/db/durable/siteDurableObject.ts +1352 -0
  61. package/db/durable/types.ts +53 -0
  62. package/db/postgres/client.ts +13 -0
  63. package/db/postgres/drizzle.config.ts +12 -0
  64. package/db/postgres/migrations/0000_brainy_sprite.sql +116 -0
  65. package/db/postgres/migrations/meta/0000_snapshot.json +681 -0
  66. package/db/postgres/migrations/meta/_journal.json +13 -0
  67. package/db/postgres/schema.ts +145 -0
  68. package/db/postgres/sites.ts +118 -0
  69. package/db/tranformReports.ts +595 -0
  70. package/db/types.ts +55 -0
  71. package/endpoints/api_worker.tsx +1854 -0
  72. package/endpoints/site_do_worker.ts +11 -0
  73. package/index.d.ts +63 -0
  74. package/index.ts +83 -0
  75. package/lib/auth.ts +279 -0
  76. package/lib/geojson/world_countries.json +45307 -0
  77. package/lib/random_name.ts +41 -0
  78. package/lib/sendMail.ts +252 -0
  79. package/package.json +142 -0
  80. package/public/favicon.ico +0 -0
  81. package/public/images/android-chrome-192x192.png +0 -0
  82. package/public/images/android-chrome-512x512.png +0 -0
  83. package/public/images/apple-touch-icon.png +0 -0
  84. package/public/images/favicon-16x16.png +0 -0
  85. package/public/images/favicon-32x32.png +0 -0
  86. package/public/images/lytx_dark_dashboard.png +0 -0
  87. package/public/images/lytx_light_dashboard.png +0 -0
  88. package/public/images/safari-pinned-tab.svg +4 -0
  89. package/public/logo.png +0 -0
  90. package/public/site.webmanifest +26 -0
  91. package/public/sw.js +107 -0
  92. package/src/Document.tsx +86 -0
  93. package/src/api/ai_api.ts +1156 -0
  94. package/src/api/authMiddleware.ts +45 -0
  95. package/src/api/auth_api.ts +465 -0
  96. package/src/api/event_labels_api.ts +193 -0
  97. package/src/api/events_api.ts +210 -0
  98. package/src/api/queueWorker.ts +303 -0
  99. package/src/api/reports_api.ts +278 -0
  100. package/src/api/seed_api.ts +288 -0
  101. package/src/api/sites_api.ts +904 -0
  102. package/src/api/tag_api.ts +458 -0
  103. package/src/api/tag_api_v2.ts +289 -0
  104. package/src/api/team_api.ts +456 -0
  105. package/src/app/Dashboard.tsx +1339 -0
  106. package/src/app/Events.tsx +974 -0
  107. package/src/app/Explore.tsx +312 -0
  108. package/src/app/Layout.tsx +58 -0
  109. package/src/app/Settings.tsx +1302 -0
  110. package/src/app/components/DashboardCard.tsx +118 -0
  111. package/src/app/components/EditableCell.tsx +123 -0
  112. package/src/app/components/EventForm.tsx +93 -0
  113. package/src/app/components/MarketingFooter.tsx +49 -0
  114. package/src/app/components/MarketingNav.tsx +150 -0
  115. package/src/app/components/Nav.tsx +755 -0
  116. package/src/app/components/NewSiteSetup.tsx +298 -0
  117. package/src/app/components/SQLEditor.tsx +740 -0
  118. package/src/app/components/SiteSelector.tsx +126 -0
  119. package/src/app/components/SiteTag.tsx +42 -0
  120. package/src/app/components/SiteTagInstallCard.tsx +241 -0
  121. package/src/app/components/WorldMapCard.tsx +337 -0
  122. package/src/app/components/charts/ChartComponents.tsx +1481 -0
  123. package/src/app/components/charts/EventFunnel.tsx +45 -0
  124. package/src/app/components/charts/EventSummary.tsx +194 -0
  125. package/src/app/components/charts/SankeyFlows.tsx +72 -0
  126. package/src/app/components/marketing/CheckIcon.tsx +16 -0
  127. package/src/app/components/marketing/MarketingLayout.tsx +23 -0
  128. package/src/app/components/marketing/SectionHeading.tsx +35 -0
  129. package/src/app/components/reports/AskAiWorkspace.tsx +371 -0
  130. package/src/app/components/reports/CreateReportStarter.tsx +74 -0
  131. package/src/app/components/reports/DashboardRouteFiltersContext.tsx +14 -0
  132. package/src/app/components/reports/DashboardToolbar.tsx +154 -0
  133. package/src/app/components/reports/DashboardWorkspaceLayout.tsx +63 -0
  134. package/src/app/components/reports/DashboardWorkspaceShell.tsx +118 -0
  135. package/src/app/components/reports/ReportBuilderWorkspace.tsx +76 -0
  136. package/src/app/components/reports/custom/CustomReportBuilderPage.tsx +1667 -0
  137. package/src/app/components/reports/custom/ReportWidgetChart.tsx +297 -0
  138. package/src/app/components/reports/custom/buildWidgetSql.ts +151 -0
  139. package/src/app/components/reports/custom/chartPalettes.ts +18 -0
  140. package/src/app/components/reports/custom/types.ts +50 -0
  141. package/src/app/components/reports/reportBuilderMenuItems.ts +17 -0
  142. package/src/app/components/reports/useDashboardToolbarControls.tsx +235 -0
  143. package/src/app/components/ui/AlertBanner.tsx +101 -0
  144. package/src/app/components/ui/Button.tsx +55 -0
  145. package/src/app/components/ui/Card.tsx +80 -0
  146. package/src/app/components/ui/Input.tsx +72 -0
  147. package/src/app/components/ui/Link.tsx +23 -0
  148. package/src/app/components/ui/ReportBuilderMenu.tsx +246 -0
  149. package/src/app/components/ui/ThemeToggle.tsx +54 -0
  150. package/src/app/constants.ts +6 -0
  151. package/src/app/headers.ts +33 -0
  152. package/src/app/providers/AuthProvider.tsx +189 -0
  153. package/src/app/providers/ClientProviders.tsx +18 -0
  154. package/src/app/providers/QueryProvider.tsx +23 -0
  155. package/src/app/providers/ThemeProvider.tsx +88 -0
  156. package/src/app/utils/chartThemes.ts +146 -0
  157. package/src/app/utils/keybinds.ts +96 -0
  158. package/src/app/utils/media.tsx +24 -0
  159. package/src/client.tsx +114 -0
  160. package/src/config/createLytxAppConfig.ts +252 -0
  161. package/src/config/resourceNames.ts +88 -0
  162. package/src/db/index.ts +67 -0
  163. package/src/index.css +285 -0
  164. package/src/lib/featureFlags.ts +69 -0
  165. package/src/pages/GetStarted.tsx +290 -0
  166. package/src/pages/Home.tsx +268 -0
  167. package/src/pages/Login.tsx +283 -0
  168. package/src/pages/PrivacyPolicy.tsx +120 -0
  169. package/src/pages/Signup.tsx +267 -0
  170. package/src/pages/TermsOfService.tsx +126 -0
  171. package/src/pages/VerifyEmail.tsx +56 -0
  172. package/src/session/durableObject.ts +7 -0
  173. package/src/session/siteSchema.ts +86 -0
  174. package/src/session/types.ts +36 -0
  175. package/src/templates/README.md +80 -0
  176. package/src/templates/cleanFunctions.js +44 -0
  177. package/src/templates/embedFunctions.js +52 -0
  178. package/src/templates/lytx-shared.ts +662 -0
  179. package/src/templates/lytxpixel-core.ts +144 -0
  180. package/src/templates/lytxpixel.ts +267 -0
  181. package/src/templates/lytxpixelBrowser.js +634 -0
  182. package/src/templates/lytxpixelBrowser.mjs +634 -0
  183. package/src/templates/parseData.js +12 -0
  184. package/src/templates/script.ts +31 -0
  185. package/src/templates/template.tsx +50 -0
  186. package/src/templates/test.js +3 -0
  187. package/src/templates/trackWebEvents.ts +177 -0
  188. package/src/templates/vendors/clickcease.ts +8 -0
  189. package/src/templates/vendors/google.ts +174 -0
  190. package/src/templates/vendors/linkedin.ts +23 -0
  191. package/src/templates/vendors/meta.ts +56 -0
  192. package/src/templates/vendors/quantcast.ts +22 -0
  193. package/src/templates/vendors/simplfi.ts +7 -0
  194. package/src/types/app-context.ts +16 -0
  195. package/src/utilities/dashboardParams.ts +188 -0
  196. package/src/utilities/dashboardQueries.ts +537 -0
  197. package/src/utilities/dashboardTransforms.ts +167 -0
  198. package/src/utilities/dataValidation.ts +414 -0
  199. package/src/utilities/detector.ts +73 -0
  200. package/src/utilities/encrypt.ts +103 -0
  201. package/src/utilities/index.ts +13 -0
  202. package/src/utilities/parser.ts +117 -0
  203. package/src/utilities/performanceMonitoring.ts +570 -0
  204. package/src/utilities/route_interuptors.ts +24 -0
  205. package/src/worker.tsx +675 -0
  206. package/tsconfig.json +78 -0
  207. package/types/env.d.ts +16 -0
  208. package/types/rw.d.ts +7 -0
  209. package/types/shims.d.ts +53 -0
  210. package/types/vite.d.ts +19 -0
  211. package/vite/vite-plugin-pixel-bundle.ts +126 -0
  212. package/vite.config.ts +53 -0
  213. package/worker-configuration.d.ts +8401 -0
@@ -0,0 +1,298 @@
1
+ "use client";
2
+ import React, { useContext, useState } from "react";
3
+ import { AuthContext } from "@/app/providers/AuthProvider";
4
+ // import { SiteTag } from "@/app/components/SiteTag";
5
+ interface NewSiteSetupProps {
6
+ onSiteCreated?: (siteData: any) => void;
7
+ }
8
+
9
+ export const NewSiteSetup: React.FC<NewSiteSetupProps> = ({
10
+ onSiteCreated,
11
+ }) => {
12
+ const { data: session } = useContext(AuthContext);
13
+ const teamName = session?.team?.name || "";
14
+ const [formData, setFormData] = useState({
15
+ name: "",
16
+ domain: "",
17
+ track_web_events: true,
18
+ gdpr: false,
19
+ event_load_strategy: "sdk" as "sdk" | "kv",
20
+ });
21
+ const [isSubmitting, setIsSubmitting] = useState(false);
22
+ const [error, setError] = useState<string | null>(null);
23
+
24
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
25
+ const { name, value, type, checked } = e.target;
26
+ setFormData((prev) => ({
27
+ ...prev,
28
+ [name]: type === "checkbox" ? checked : value,
29
+ }));
30
+ };
31
+
32
+ const handleSubmit = async (e: React.FormEvent) => {
33
+ e.preventDefault();
34
+ setIsSubmitting(true);
35
+ setError(null);
36
+
37
+ try {
38
+ const response = await fetch("/api/sites", {
39
+ method: "POST",
40
+ headers: {
41
+ "Content-Type": "application/json",
42
+ },
43
+ body: JSON.stringify(formData),
44
+ });
45
+
46
+ if (!response.ok) {
47
+ throw new Error("Failed to create site");
48
+ }
49
+
50
+ const siteData = await response.json();
51
+ onSiteCreated?.(siteData);
52
+ window.location.href = "/dashboard/settings";
53
+ } catch (err) {
54
+ setError(err instanceof Error ? err.message : "An error occurred");
55
+ } finally {
56
+ setIsSubmitting(false);
57
+ }
58
+ };
59
+
60
+ return (
61
+ <div className="flex flex-col min-h-screen bg-[var(--theme-bg-primary)]">
62
+ {/* Header */}
63
+ <div className="flex items-center justify-between w-full p-6 border-b border-[var(--theme-border-primary)]">
64
+ <div className="flex items-center space-x-3">
65
+ <span className="text-[var(--theme-text-primary)] font-semibold">
66
+ Welcome to Lytx Analytics
67
+ </span>
68
+ </div>
69
+ </div>
70
+
71
+ {/* Main Content */}
72
+ <main className="flex-1 p-8 overflow-y-auto">
73
+ <div className="mx-auto">
74
+ {/* Welcome Section */}
75
+ <section className="mb-8 text-center">
76
+ <h1 className="text-3xl font-bold text-[var(--theme-text-primary)] mb-4">
77
+ Set up your first site{teamName ? ` for ${teamName}` : ""}
78
+ </h1>
79
+ <p className="text-[var(--theme-text-secondary)] text-lg">
80
+ Get started by adding your website to begin tracking analytics and
81
+ events.
82
+ </p>
83
+ </section>
84
+
85
+ {/* Setup Form Card */}
86
+ <div className="bg-[var(--theme-card-bg)] border border-[var(--theme-card-border)] rounded-lg p-8">
87
+ <h2 className="text-xl font-semibold text-[var(--theme-text-primary)] mb-6">
88
+ Site Configuration
89
+ </h2>
90
+
91
+ {error && (
92
+ <div className="bg-[var(--color-danger)] bg-opacity-20 border border-[var(--color-danger)] text-[var(--color-danger)] px-4 py-3 rounded mb-6">
93
+ {error}
94
+ </div>
95
+ )}
96
+
97
+ <form onSubmit={handleSubmit} className="space-y-6">
98
+ {/* Site Name */}
99
+ <div>
100
+ <label
101
+ htmlFor="name"
102
+ className="block text-sm font-medium text-[var(--theme-text-primary)] mb-2"
103
+ >
104
+ Site Name
105
+ </label>
106
+ <input
107
+ type="text"
108
+ id="name"
109
+ name="name"
110
+ value={formData.name}
111
+ onChange={handleInputChange}
112
+ required
113
+ className="w-full px-3 py-2 bg-[var(--theme-input-bg)] border border-[var(--theme-input-border)] rounded-md text-[var(--theme-text-primary)] placeholder-[var(--theme-text-secondary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:border-transparent transition-colors"
114
+ placeholder="My Awesome Website"
115
+ />
116
+ <p className="text-xs text-[var(--theme-text-secondary)] mt-1">
117
+ A friendly name to identify your site in the dashboard
118
+ </p>
119
+ </div>
120
+
121
+ {/* Domain */}
122
+ <div>
123
+ <label
124
+ htmlFor="domain"
125
+ className="block text-sm font-medium text-[var(--theme-text-primary)] mb-2"
126
+ >
127
+ Domain
128
+ </label>
129
+ <input
130
+ type="url"
131
+ id="domain"
132
+ name="domain"
133
+ value={formData.domain}
134
+ onChange={handleInputChange}
135
+ required
136
+ className="w-full px-3 py-2 bg-[var(--theme-input-bg)] border border-[var(--theme-input-border)] rounded-md text-[var(--theme-text-primary)] placeholder-[var(--theme-text-secondary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:border-transparent transition-colors"
137
+ placeholder="https://example.com"
138
+ />
139
+ <p className="text-xs text-[var(--theme-text-secondary)] mt-1">
140
+ The full URL of your website (including https://)
141
+ </p>
142
+ </div>
143
+
144
+ {/* Tracking Options */}
145
+ <div className="space-y-4">
146
+ <h3 className="text-lg font-medium text-[var(--theme-text-primary)]">
147
+ Tracking Options
148
+ </h3>
149
+
150
+ <div className="flex items-start space-x-3">
151
+ <input
152
+ type="checkbox"
153
+ id="track_web_events"
154
+ name="track_web_events"
155
+ checked={formData.track_web_events}
156
+ onChange={handleInputChange}
157
+ className="mt-1 h-4 w-4 text-[var(--color-primary)] bg-[var(--theme-input-bg)] border-[var(--theme-input-border)] rounded focus:ring-[var(--color-primary)] focus:ring-2"
158
+ />
159
+ <div>
160
+ <label
161
+ htmlFor="track_web_events"
162
+ className="text-sm font-medium text-[var(--theme-text-primary)]"
163
+ >
164
+ Enable Web Event Tracking
165
+ </label>
166
+ <p className="text-xs text-[var(--theme-text-secondary)]">
167
+ Track page views, clicks, and custom events on your
168
+ website
169
+ </p>
170
+ </div>
171
+ </div>
172
+
173
+ <div className="flex items-start space-x-3">
174
+ <input
175
+ type="checkbox"
176
+ id="event_load_strategy"
177
+ name="event_load_strategy"
178
+ checked={formData.event_load_strategy === "kv"}
179
+ onChange={(e) =>
180
+ setFormData((prev) => ({
181
+ ...prev,
182
+ event_load_strategy: e.target.checked ? "kv" : "sdk",
183
+ }))
184
+ }
185
+ className="mt-1 h-4 w-4 text-[var(--color-primary)] bg-[var(--theme-input-bg)] border-[var(--theme-input-border)] rounded focus:ring-[var(--color-primary)] focus:ring-2"
186
+ />
187
+ <div>
188
+ <label
189
+ htmlFor="event_load_strategy"
190
+ className="text-sm font-medium text-[var(--theme-text-primary)]"
191
+ >
192
+ Load Events From KV
193
+ </label>
194
+ <p className="text-xs text-[var(--theme-text-secondary)]">
195
+ Include stored event rules in the site tag payload
196
+ </p>
197
+ </div>
198
+ </div>
199
+
200
+ <div className="flex items-start space-x-3">
201
+ <input
202
+ type="checkbox"
203
+ id="gdpr"
204
+ name="gdpr"
205
+ checked={formData.gdpr}
206
+ onChange={handleInputChange}
207
+ className="mt-1 h-4 w-4 text-[var(--color-primary)] bg-[var(--theme-input-bg)] border-[var(--theme-input-border)] rounded focus:ring-[var(--color-primary)] focus:ring-2"
208
+ />
209
+ <div>
210
+ <label
211
+ htmlFor="gdpr"
212
+ className="text-sm font-medium text-[var(--theme-text-primary)]"
213
+ >
214
+ GDPR Compliance Mode
215
+ </label>
216
+ <p className="text-xs text-[var(--theme-text-secondary)]">
217
+ Enable additional privacy controls for EU visitors
218
+ </p>
219
+ </div>
220
+ </div>
221
+ </div>
222
+
223
+ {/* Submit Button */}
224
+ <div className="pt-4">
225
+ <button
226
+ type="submit"
227
+ disabled={isSubmitting}
228
+ className="w-full bg-[var(--theme-button-bg)] hover:bg-[var(--theme-button-hover)] disabled:bg-[var(--theme-text-secondary)] disabled:cursor-not-allowed text-white font-medium py-3 px-4 rounded-md transition-colors duration-200"
229
+ >
230
+ {isSubmitting ? (
231
+ <div className="flex items-center justify-center">
232
+ <svg
233
+ className="animate-spin -ml-1 mr-3 h-5 w-5 text-white"
234
+ xmlns="http://www.w3.org/2000/svg"
235
+ fill="none"
236
+ viewBox="0 0 24 24"
237
+ >
238
+ <circle
239
+ className="opacity-25"
240
+ cx="12"
241
+ cy="12"
242
+ r="10"
243
+ stroke="currentColor"
244
+ strokeWidth="4"
245
+ ></circle>
246
+ <path
247
+ className="opacity-75"
248
+ fill="currentColor"
249
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
250
+ ></path>
251
+ </svg>
252
+ Creating Site...
253
+ </div>
254
+ ) : (
255
+ "Create Site & Get Tracking Code"
256
+ )}
257
+ </button>
258
+ </div>
259
+ </form>
260
+ </div>
261
+
262
+ {/* Next Steps Preview */}
263
+ <div className="mt-8 bg-[var(--theme-card-bg)] border border-[var(--theme-card-border)] rounded-lg p-6">
264
+ <h3 className="text-lg font-semibold text-[var(--theme-text-primary)] mb-4">
265
+ What happens next?
266
+ </h3>
267
+ <div className="space-y-3">
268
+ <div className="flex items-center space-x-3">
269
+ <div className="w-6 h-6 bg-[var(--color-primary)] rounded-full flex items-center justify-center text-white text-sm font-bold">
270
+ 1
271
+ </div>
272
+ <span className="text-[var(--theme-text-secondary)]">
273
+ We'll generate a unique tracking code for your site
274
+ </span>
275
+ </div>
276
+ <div className="flex items-center space-x-3">
277
+ <div className="w-6 h-6 bg-[var(--color-primary)] rounded-full flex items-center justify-center text-white text-sm font-bold">
278
+ 2
279
+ </div>
280
+ <span className="text-[var(--theme-text-secondary)]">
281
+ Add the tracking code to your website
282
+ </span>
283
+ </div>
284
+ <div className="flex items-center space-x-3">
285
+ <div className="w-6 h-6 bg-[var(--color-primary)] rounded-full flex items-center justify-center text-white text-sm font-bold">
286
+ 3
287
+ </div>
288
+ <span className="text-[var(--theme-text-secondary)]">
289
+ Open the dashboard to confirm ingestion and continue setup
290
+ </span>
291
+ </div>
292
+ </div>
293
+ </div>
294
+ </div>
295
+ </main>
296
+ </div>
297
+ );
298
+ };