@sonordev/site-kit 1.2.7

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 (300) hide show
  1. package/README.md +376 -0
  2. package/dist/SetupWizard-Cki06kB0.d.mts +12 -0
  3. package/dist/SetupWizard-Cki06kB0.d.ts +12 -0
  4. package/dist/analytics/index.d.mts +93 -0
  5. package/dist/analytics/index.d.ts +93 -0
  6. package/dist/analytics/index.js +89 -0
  7. package/dist/analytics/index.js.map +1 -0
  8. package/dist/analytics/index.mjs +71 -0
  9. package/dist/analytics/index.mjs.map +1 -0
  10. package/dist/api-CWtoFJCO.d.mts +137 -0
  11. package/dist/api-CWtoFJCO.d.ts +137 -0
  12. package/dist/blog/index.d.mts +305 -0
  13. package/dist/blog/index.d.ts +305 -0
  14. package/dist/blog/index.js +1578 -0
  15. package/dist/blog/index.js.map +1 -0
  16. package/dist/blog/index.mjs +1562 -0
  17. package/dist/blog/index.mjs.map +1 -0
  18. package/dist/blog/server.d.mts +229 -0
  19. package/dist/blog/server.d.ts +229 -0
  20. package/dist/blog/server.js +692 -0
  21. package/dist/blog/server.js.map +1 -0
  22. package/dist/blog/server.mjs +666 -0
  23. package/dist/blog/server.mjs.map +1 -0
  24. package/dist/chunk-24277A3Q.mjs +968 -0
  25. package/dist/chunk-24277A3Q.mjs.map +1 -0
  26. package/dist/chunk-373TK6TZ.js +321 -0
  27. package/dist/chunk-373TK6TZ.js.map +1 -0
  28. package/dist/chunk-3MYZS6PD.js +30 -0
  29. package/dist/chunk-3MYZS6PD.js.map +1 -0
  30. package/dist/chunk-43GBM4SX.js +283 -0
  31. package/dist/chunk-43GBM4SX.js.map +1 -0
  32. package/dist/chunk-4XPGGLVP.mjs +53 -0
  33. package/dist/chunk-4XPGGLVP.mjs.map +1 -0
  34. package/dist/chunk-622GAQP5.js +2008 -0
  35. package/dist/chunk-622GAQP5.js.map +1 -0
  36. package/dist/chunk-6BIPAKL4.mjs +28 -0
  37. package/dist/chunk-6BIPAKL4.mjs.map +1 -0
  38. package/dist/chunk-6ZCISNAB.mjs +343 -0
  39. package/dist/chunk-6ZCISNAB.mjs.map +1 -0
  40. package/dist/chunk-72MQFHYJ.js +1429 -0
  41. package/dist/chunk-72MQFHYJ.js.map +1 -0
  42. package/dist/chunk-7557OTHW.js +62 -0
  43. package/dist/chunk-7557OTHW.js.map +1 -0
  44. package/dist/chunk-7FUV73JZ.js +981 -0
  45. package/dist/chunk-7FUV73JZ.js.map +1 -0
  46. package/dist/chunk-7RF6PVHA.mjs +324 -0
  47. package/dist/chunk-7RF6PVHA.mjs.map +1 -0
  48. package/dist/chunk-7RYCHO6D.mjs +134 -0
  49. package/dist/chunk-7RYCHO6D.mjs.map +1 -0
  50. package/dist/chunk-7UKPRW25.mjs +1999 -0
  51. package/dist/chunk-7UKPRW25.mjs.map +1 -0
  52. package/dist/chunk-7URAOG2M.js +14864 -0
  53. package/dist/chunk-7URAOG2M.js.map +1 -0
  54. package/dist/chunk-AFAO3TGS.mjs +810 -0
  55. package/dist/chunk-AFAO3TGS.mjs.map +1 -0
  56. package/dist/chunk-BYLIU6XG.js +343 -0
  57. package/dist/chunk-BYLIU6XG.js.map +1 -0
  58. package/dist/chunk-D63MUKZ6.mjs +4423 -0
  59. package/dist/chunk-D63MUKZ6.mjs.map +1 -0
  60. package/dist/chunk-DDKW2FNA.js +390 -0
  61. package/dist/chunk-DDKW2FNA.js.map +1 -0
  62. package/dist/chunk-DQYMKR27.mjs +341 -0
  63. package/dist/chunk-DQYMKR27.mjs.map +1 -0
  64. package/dist/chunk-DW5UJKHH.js +221 -0
  65. package/dist/chunk-DW5UJKHH.js.map +1 -0
  66. package/dist/chunk-EEZCR6E6.js +50 -0
  67. package/dist/chunk-EEZCR6E6.js.map +1 -0
  68. package/dist/chunk-GCJXQ4AG.mjs +59 -0
  69. package/dist/chunk-GCJXQ4AG.mjs.map +1 -0
  70. package/dist/chunk-JGNQK2G6.mjs +14845 -0
  71. package/dist/chunk-JGNQK2G6.mjs.map +1 -0
  72. package/dist/chunk-JTLOJLWQ.mjs +563 -0
  73. package/dist/chunk-JTLOJLWQ.mjs.map +1 -0
  74. package/dist/chunk-K23A4G76.mjs +202 -0
  75. package/dist/chunk-K23A4G76.mjs.map +1 -0
  76. package/dist/chunk-KKU3K7RG.js +336 -0
  77. package/dist/chunk-KKU3K7RG.js.map +1 -0
  78. package/dist/chunk-KUGMH4ZF.js +571 -0
  79. package/dist/chunk-KUGMH4ZF.js.map +1 -0
  80. package/dist/chunk-LBVWVP72.js +110 -0
  81. package/dist/chunk-LBVWVP72.js.map +1 -0
  82. package/dist/chunk-LIVWLY2P.js +138 -0
  83. package/dist/chunk-LIVWLY2P.js.map +1 -0
  84. package/dist/chunk-M2T6R7BA.mjs +1003 -0
  85. package/dist/chunk-M2T6R7BA.mjs.map +1 -0
  86. package/dist/chunk-MV3QN7PW.mjs +47 -0
  87. package/dist/chunk-MV3QN7PW.mjs.map +1 -0
  88. package/dist/chunk-OB7E654K.js +72 -0
  89. package/dist/chunk-OB7E654K.js.map +1 -0
  90. package/dist/chunk-OIIKTGRL.mjs +380 -0
  91. package/dist/chunk-OIIKTGRL.mjs.map +1 -0
  92. package/dist/chunk-P3UWIUJS.mjs +1427 -0
  93. package/dist/chunk-P3UWIUJS.mjs.map +1 -0
  94. package/dist/chunk-PKN27UMH.mjs +136 -0
  95. package/dist/chunk-PKN27UMH.mjs.map +1 -0
  96. package/dist/chunk-QXV4667R.mjs +105 -0
  97. package/dist/chunk-QXV4667R.mjs.map +1 -0
  98. package/dist/chunk-S7FRYNSU.mjs +315 -0
  99. package/dist/chunk-S7FRYNSU.mjs.map +1 -0
  100. package/dist/chunk-TFLQX7K7.mjs +68 -0
  101. package/dist/chunk-TFLQX7K7.mjs.map +1 -0
  102. package/dist/chunk-UWE5PCYJ.mjs +279 -0
  103. package/dist/chunk-UWE5PCYJ.mjs.map +1 -0
  104. package/dist/chunk-UYFDNX2F.js +4469 -0
  105. package/dist/chunk-UYFDNX2F.js.map +1 -0
  106. package/dist/chunk-W4PALSGM.js +350 -0
  107. package/dist/chunk-W4PALSGM.js.map +1 -0
  108. package/dist/chunk-WECQ6KOB.js +1008 -0
  109. package/dist/chunk-WECQ6KOB.js.map +1 -0
  110. package/dist/chunk-XQQWI6WB.js +814 -0
  111. package/dist/chunk-XQQWI6WB.js.map +1 -0
  112. package/dist/chunk-XZJOZJB6.js +140 -0
  113. package/dist/chunk-XZJOZJB6.js.map +1 -0
  114. package/dist/chunk-ZSMWDLMK.js +63 -0
  115. package/dist/chunk-ZSMWDLMK.js.map +1 -0
  116. package/dist/cli/index.js +37243 -0
  117. package/dist/cli/index.js.map +1 -0
  118. package/dist/cli/index.mjs +37209 -0
  119. package/dist/cli/index.mjs.map +1 -0
  120. package/dist/commerce/index.d.mts +170 -0
  121. package/dist/commerce/index.d.ts +170 -0
  122. package/dist/commerce/index.js +174 -0
  123. package/dist/commerce/index.js.map +1 -0
  124. package/dist/commerce/index.mjs +5 -0
  125. package/dist/commerce/index.mjs.map +1 -0
  126. package/dist/commerce/server.d.mts +107 -0
  127. package/dist/commerce/server.d.ts +107 -0
  128. package/dist/commerce/server.js +187 -0
  129. package/dist/commerce/server.js.map +1 -0
  130. package/dist/commerce/server.mjs +177 -0
  131. package/dist/commerce/server.mjs.map +1 -0
  132. package/dist/config/index.d.mts +43 -0
  133. package/dist/config/index.d.ts +43 -0
  134. package/dist/config/index.js +66 -0
  135. package/dist/config/index.js.map +1 -0
  136. package/dist/config/index.mjs +64 -0
  137. package/dist/config/index.mjs.map +1 -0
  138. package/dist/engage/index.d.mts +33 -0
  139. package/dist/engage/index.d.ts +33 -0
  140. package/dist/engage/index.js +22 -0
  141. package/dist/engage/index.js.map +1 -0
  142. package/dist/engage/index.mjs +5 -0
  143. package/dist/engage/index.mjs.map +1 -0
  144. package/dist/forms/index.d.mts +437 -0
  145. package/dist/forms/index.d.ts +437 -0
  146. package/dist/forms/index.js +1168 -0
  147. package/dist/forms/index.js.map +1 -0
  148. package/dist/forms/index.mjs +1142 -0
  149. package/dist/forms/index.mjs.map +1 -0
  150. package/dist/generators-2XKQMPKH.mjs +4 -0
  151. package/dist/generators-2XKQMPKH.mjs.map +1 -0
  152. package/dist/generators-DTMO36DV.js +33 -0
  153. package/dist/generators-DTMO36DV.js.map +1 -0
  154. package/dist/images/index.d.mts +4 -0
  155. package/dist/images/index.d.ts +4 -0
  156. package/dist/images/index.js +46 -0
  157. package/dist/images/index.js.map +1 -0
  158. package/dist/images/index.mjs +5 -0
  159. package/dist/images/index.mjs.map +1 -0
  160. package/dist/images/server.d.mts +69 -0
  161. package/dist/images/server.d.ts +69 -0
  162. package/dist/images/server.js +21 -0
  163. package/dist/images/server.js.map +1 -0
  164. package/dist/images/server.mjs +4 -0
  165. package/dist/images/server.mjs.map +1 -0
  166. package/dist/index.d.mts +846 -0
  167. package/dist/index.d.ts +846 -0
  168. package/dist/index.js +2623 -0
  169. package/dist/index.js.map +1 -0
  170. package/dist/index.mjs +2416 -0
  171. package/dist/index.mjs.map +1 -0
  172. package/dist/layout/index.d.mts +53 -0
  173. package/dist/layout/index.d.ts +53 -0
  174. package/dist/layout/index.js +187 -0
  175. package/dist/layout/index.js.map +1 -0
  176. package/dist/layout/index.mjs +185 -0
  177. package/dist/layout/index.mjs.map +1 -0
  178. package/dist/llms/index.d.mts +448 -0
  179. package/dist/llms/index.d.ts +448 -0
  180. package/dist/llms/index.js +581 -0
  181. package/dist/llms/index.js.map +1 -0
  182. package/dist/llms/index.mjs +529 -0
  183. package/dist/llms/index.mjs.map +1 -0
  184. package/dist/manifest/index.d.mts +62 -0
  185. package/dist/manifest/index.d.ts +62 -0
  186. package/dist/manifest/index.js +85 -0
  187. package/dist/manifest/index.js.map +1 -0
  188. package/dist/manifest/index.mjs +83 -0
  189. package/dist/manifest/index.mjs.map +1 -0
  190. package/dist/middleware/index.d.mts +63 -0
  191. package/dist/middleware/index.d.ts +63 -0
  192. package/dist/middleware/index.js +54 -0
  193. package/dist/middleware/index.js.map +1 -0
  194. package/dist/middleware/index.mjs +51 -0
  195. package/dist/middleware/index.mjs.map +1 -0
  196. package/dist/migrator-2MQHOFDQ.mjs +4 -0
  197. package/dist/migrator-2MQHOFDQ.mjs.map +1 -0
  198. package/dist/migrator-THJCF6MZ.js +37 -0
  199. package/dist/migrator-THJCF6MZ.js.map +1 -0
  200. package/dist/redirects/index.d.mts +78 -0
  201. package/dist/redirects/index.d.ts +78 -0
  202. package/dist/redirects/index.js +26 -0
  203. package/dist/redirects/index.js.map +1 -0
  204. package/dist/redirects/index.mjs +5 -0
  205. package/dist/redirects/index.mjs.map +1 -0
  206. package/dist/reputation/index.d.mts +57 -0
  207. package/dist/reputation/index.d.ts +57 -0
  208. package/dist/reputation/index.js +21 -0
  209. package/dist/reputation/index.js.map +1 -0
  210. package/dist/reputation/index.mjs +4 -0
  211. package/dist/reputation/index.mjs.map +1 -0
  212. package/dist/robots/index.d.mts +38 -0
  213. package/dist/robots/index.d.ts +38 -0
  214. package/dist/robots/index.js +52 -0
  215. package/dist/robots/index.js.map +1 -0
  216. package/dist/robots/index.mjs +50 -0
  217. package/dist/robots/index.mjs.map +1 -0
  218. package/dist/routing-B5XS-6_W.d.mts +118 -0
  219. package/dist/routing-DZYzyDHw.d.ts +118 -0
  220. package/dist/scanner-GAF5PO5F.js +53 -0
  221. package/dist/scanner-GAF5PO5F.js.map +1 -0
  222. package/dist/scanner-LKJKW7IT.mjs +4 -0
  223. package/dist/scanner-LKJKW7IT.mjs.map +1 -0
  224. package/dist/securityHeaders-nwZ6nP4g.d.mts +24 -0
  225. package/dist/securityHeaders-nwZ6nP4g.d.ts +24 -0
  226. package/dist/seo/index.d.mts +600 -0
  227. package/dist/seo/index.d.ts +600 -0
  228. package/dist/seo/index.js +883 -0
  229. package/dist/seo/index.js.map +1 -0
  230. package/dist/seo/index.mjs +773 -0
  231. package/dist/seo/index.mjs.map +1 -0
  232. package/dist/seo/register-sitemap-cli.js +151 -0
  233. package/dist/seo/register-sitemap-cli.js.map +1 -0
  234. package/dist/seo/register-sitemap-cli.mjs +144 -0
  235. package/dist/seo/register-sitemap-cli.mjs.map +1 -0
  236. package/dist/seo/server.d.mts +107 -0
  237. package/dist/seo/server.d.ts +107 -0
  238. package/dist/seo/server.js +207 -0
  239. package/dist/seo/server.js.map +1 -0
  240. package/dist/seo/server.mjs +186 -0
  241. package/dist/seo/server.mjs.map +1 -0
  242. package/dist/server-api-EWXKOQZA.mjs +4 -0
  243. package/dist/server-api-EWXKOQZA.mjs.map +1 -0
  244. package/dist/server-api-GJPNRYUP.js +81 -0
  245. package/dist/server-api-GJPNRYUP.js.map +1 -0
  246. package/dist/setup/client.d.mts +60 -0
  247. package/dist/setup/client.d.ts +60 -0
  248. package/dist/setup/client.js +31 -0
  249. package/dist/setup/client.js.map +1 -0
  250. package/dist/setup/client.mjs +6 -0
  251. package/dist/setup/client.mjs.map +1 -0
  252. package/dist/setup/index.d.mts +5 -0
  253. package/dist/setup/index.d.ts +5 -0
  254. package/dist/setup/index.js +35 -0
  255. package/dist/setup/index.js.map +1 -0
  256. package/dist/setup/index.mjs +6 -0
  257. package/dist/setup/index.mjs.map +1 -0
  258. package/dist/setup/server.d.mts +14 -0
  259. package/dist/setup/server.d.ts +14 -0
  260. package/dist/setup/server.js +13 -0
  261. package/dist/setup/server.js.map +1 -0
  262. package/dist/setup/server.mjs +4 -0
  263. package/dist/setup/server.mjs.map +1 -0
  264. package/dist/site-config/index.d.mts +24 -0
  265. package/dist/site-config/index.d.ts +24 -0
  266. package/dist/site-config/index.js +17 -0
  267. package/dist/site-config/index.js.map +1 -0
  268. package/dist/site-config/index.mjs +4 -0
  269. package/dist/site-config/index.mjs.map +1 -0
  270. package/dist/sitemap/index.d.mts +96 -0
  271. package/dist/sitemap/index.d.ts +96 -0
  272. package/dist/sitemap/index.js +288 -0
  273. package/dist/sitemap/index.js.map +1 -0
  274. package/dist/sitemap/index.mjs +285 -0
  275. package/dist/sitemap/index.mjs.map +1 -0
  276. package/dist/socket-loader-J26QHHOB.js +16 -0
  277. package/dist/socket-loader-J26QHHOB.js.map +1 -0
  278. package/dist/socket-loader-R7S2YJ2J.mjs +14 -0
  279. package/dist/socket-loader-R7S2YJ2J.mjs.map +1 -0
  280. package/dist/types-0dmq3k20.d.mts +168 -0
  281. package/dist/types-0dmq3k20.d.ts +168 -0
  282. package/dist/types-Blb2QNkV.d.mts +263 -0
  283. package/dist/types-Blb2QNkV.d.ts +263 -0
  284. package/dist/types-BnCwwUX3.d.mts +250 -0
  285. package/dist/types-BnCwwUX3.d.ts +250 -0
  286. package/dist/types-CGlnp43R.d.mts +312 -0
  287. package/dist/types-CGlnp43R.d.ts +312 -0
  288. package/dist/types-D08004rU.d.mts +179 -0
  289. package/dist/types-D08004rU.d.ts +179 -0
  290. package/dist/types-DNSYU7qI.d.mts +127 -0
  291. package/dist/types-DNSYU7qI.d.ts +127 -0
  292. package/dist/types-KZP_VWZp.d.mts +266 -0
  293. package/dist/types-KZP_VWZp.d.ts +266 -0
  294. package/dist/useEventModal-BVTx69XE.d.mts +274 -0
  295. package/dist/useEventModal-Dx1dItTJ.d.ts +274 -0
  296. package/dist/web-vitals-444RLW3B.js +252 -0
  297. package/dist/web-vitals-444RLW3B.js.map +1 -0
  298. package/dist/web-vitals-KPICZIEF.mjs +241 -0
  299. package/dist/web-vitals-KPICZIEF.mjs.map +1 -0
  300. package/package.json +192 -0
@@ -0,0 +1,810 @@
1
+ 'use client';
2
+ import { useState, useMemo } from 'react';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ // src/setup/integration-generator.ts
6
+ function generateIntegrationCode(context) {
7
+ const snippets = [];
8
+ const apiUrl = context.apiUrl || "https://api.uptrademedia.com";
9
+ let order = 0;
10
+ snippets.push(...generateProviderSnippets(context, apiUrl, order));
11
+ order += 10;
12
+ for (const module of context.enabledModules) {
13
+ switch (module) {
14
+ case "analytics":
15
+ snippets.push(...generateAnalyticsSnippets(context, order));
16
+ order += 10;
17
+ break;
18
+ case "engage":
19
+ snippets.push(...generateEngageSnippets(context, order));
20
+ order += 10;
21
+ break;
22
+ case "forms":
23
+ snippets.push(...generateFormsSnippets(context, order));
24
+ order += 10;
25
+ break;
26
+ case "commerce":
27
+ snippets.push(...generateCommerceSnippets(context, order));
28
+ order += 10;
29
+ break;
30
+ case "seo":
31
+ snippets.push(...generateSEOSnippets(context, order));
32
+ order += 10;
33
+ break;
34
+ case "blog":
35
+ snippets.push(...generateBlogSnippets(context, order));
36
+ order += 10;
37
+ break;
38
+ }
39
+ }
40
+ return snippets;
41
+ }
42
+ function getSnippetsByModule(snippets) {
43
+ return snippets.reduce((acc, snippet) => {
44
+ if (!acc[snippet.module]) {
45
+ acc[snippet.module] = [];
46
+ }
47
+ acc[snippet.module].push(snippet);
48
+ return acc;
49
+ }, {});
50
+ }
51
+ function generateProviderSnippets(ctx, apiUrl, startOrder) {
52
+ const enabledModulesConfig = ctx.enabledModules.map((m) => {
53
+ if (m === "analytics") return " analytics={{ enabled: true }}";
54
+ if (m === "engage") return " engage={{ enabled: true }}";
55
+ return null;
56
+ }).filter(Boolean).join("\n");
57
+ return [
58
+ {
59
+ module: "provider",
60
+ snippetType: "install",
61
+ title: "Install @sonordev/site-kit",
62
+ description: "Install the Uptrade Site Kit package",
63
+ code: `pnpm add @sonordev/site-kit`,
64
+ language: "bash",
65
+ order: startOrder,
66
+ required: true
67
+ },
68
+ {
69
+ module: "provider",
70
+ snippetType: "env",
71
+ title: "Environment Variables",
72
+ description: "Add these to your .env.local file",
73
+ filePath: ".env.local",
74
+ code: `# Uptrade Integration
75
+ NEXT_PUBLIC_UPTRADE_API_URL=${apiUrl}
76
+ NEXT_PUBLIC_UPTRADE_PROJECT_ID=${ctx.projectId}
77
+ UPTRADE_API_KEY=your-api-key-here`,
78
+ language: "env",
79
+ order: startOrder + 1,
80
+ required: true
81
+ },
82
+ {
83
+ module: "provider",
84
+ snippetType: "layout",
85
+ title: "Root Layout Provider",
86
+ description: "Wrap your app with SiteKitProvider in app/layout.tsx",
87
+ filePath: "app/layout.tsx",
88
+ code: `import { SiteKitProvider } from '@sonordev/site-kit'
89
+ import { ManagedFavicon } from '@sonordev/site-kit/images'
90
+
91
+ export default function RootLayout({
92
+ children,
93
+ }: {
94
+ children: React.ReactNode
95
+ }) {
96
+ return (
97
+ <html lang="en">
98
+ <head>
99
+ <ManagedFavicon />
100
+ </head>
101
+ <body>
102
+ <SiteKitProvider
103
+ apiUrl={process.env.NEXT_PUBLIC_UPTRADE_API_URL!}
104
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
105
+ ${enabledModulesConfig}
106
+ >
107
+ {children}
108
+ </SiteKitProvider>
109
+ </body>
110
+ </html>
111
+ )
112
+ }`,
113
+ language: "tsx",
114
+ order: startOrder + 2,
115
+ required: true
116
+ }
117
+ ];
118
+ }
119
+ function generateAnalyticsSnippets(ctx, startOrder) {
120
+ return [
121
+ {
122
+ module: "analytics",
123
+ snippetType: "component",
124
+ title: "Custom Event Tracking",
125
+ description: "Track custom events throughout your app",
126
+ filePath: "components/TrackableButton.tsx",
127
+ code: `'use client'
128
+
129
+ import { useSiteKit } from '@sonordev/site-kit'
130
+
131
+ interface TrackableButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
132
+ eventName: string
133
+ eventData?: Record<string, unknown>
134
+ children: React.ReactNode
135
+ }
136
+
137
+ export function TrackableButton({
138
+ children,
139
+ eventName,
140
+ eventData,
141
+ ...props
142
+ }: TrackableButtonProps) {
143
+ const { analytics } = useSiteKit()
144
+
145
+ const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
146
+ analytics?.trackEvent(eventName, eventData)
147
+ props.onClick?.(e)
148
+ }
149
+
150
+ return (
151
+ <button {...props} onClick={handleClick}>
152
+ {children}
153
+ </button>
154
+ )
155
+ }`,
156
+ language: "tsx",
157
+ order: startOrder,
158
+ required: false
159
+ }
160
+ ];
161
+ }
162
+ function generateEngageSnippets(ctx, startOrder) {
163
+ const primaryColor = ctx.brand?.primaryColor || "#0066cc";
164
+ return [
165
+ {
166
+ module: "engage",
167
+ snippetType: "component",
168
+ title: "Chat Widget",
169
+ description: "Add the AI chat widget to your site. This is unstyled - customize to match your brand.",
170
+ filePath: "components/ChatWidget.tsx",
171
+ code: `'use client'
172
+
173
+ import { ChatWidget } from '@sonordev/site-kit/engage'
174
+
175
+ export function SiteChat() {
176
+ return (
177
+ <ChatWidget
178
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
179
+ config={{
180
+ position: 'bottom-right',
181
+ buttonColor: '${primaryColor}',
182
+ greeting: 'Hi! How can I help you today?',
183
+ placeholder: 'Type your message...',
184
+ }}
185
+ />
186
+ )
187
+ }`,
188
+ language: "tsx",
189
+ order: startOrder,
190
+ required: true
191
+ },
192
+ {
193
+ module: "engage",
194
+ snippetType: "layout",
195
+ title: "Add Chat to Layout",
196
+ description: "Add the ChatWidget component to your root layout",
197
+ filePath: "app/layout.tsx",
198
+ code: `// Add import at top:
199
+ import { SiteChat } from '@/components/ChatWidget'
200
+
201
+ // Add inside your layout body, after SiteKitProvider children:
202
+ <SiteChat />`,
203
+ language: "tsx",
204
+ order: startOrder + 1,
205
+ required: true
206
+ }
207
+ ];
208
+ }
209
+ function generateFormsSnippets(ctx, startOrder) {
210
+ return [
211
+ {
212
+ module: "forms",
213
+ snippetType: "component",
214
+ title: "Managed Form Component",
215
+ description: "Embed a managed form from the Portal. Form slug must match one created in Forms module.",
216
+ filePath: "components/ContactForm.tsx",
217
+ code: `import { ManagedForm } from '@sonordev/site-kit/forms'
218
+
219
+ interface ContactFormProps {
220
+ formSlug?: string
221
+ className?: string
222
+ }
223
+
224
+ export async function ContactForm({
225
+ formSlug = 'contact',
226
+ className
227
+ }: ContactFormProps) {
228
+ return (
229
+ <ManagedForm
230
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
231
+ formSlug={formSlug}
232
+ className={className}
233
+ />
234
+ )
235
+ }`,
236
+ language: "tsx",
237
+ order: startOrder,
238
+ required: false
239
+ },
240
+ {
241
+ module: "forms",
242
+ snippetType: "api-route",
243
+ title: "Form Submission Handler",
244
+ description: "API route to proxy form submissions to Portal API",
245
+ filePath: "app/api/forms/[formId]/submit/route.ts",
246
+ code: `import { NextRequest, NextResponse } from 'next/server'
247
+
248
+ export async function POST(
249
+ request: NextRequest,
250
+ { params }: { params: { formId: string } }
251
+ ) {
252
+ const body = await request.json()
253
+
254
+ const response = await fetch(
255
+ \`\${process.env.NEXT_PUBLIC_UPTRADE_API_URL}/forms/\${params.formId}/submit\`,
256
+ {
257
+ method: 'POST',
258
+ headers: {
259
+ 'Content-Type': 'application/json',
260
+ 'X-API-Key': process.env.UPTRADE_API_KEY!,
261
+ },
262
+ body: JSON.stringify(body),
263
+ }
264
+ )
265
+
266
+ const data = await response.json()
267
+ return NextResponse.json(data, { status: response.status })
268
+ }`,
269
+ language: "typescript",
270
+ order: startOrder + 1,
271
+ required: true
272
+ }
273
+ ];
274
+ }
275
+ function generateCommerceSnippets(ctx, startOrder) {
276
+ return [
277
+ {
278
+ module: "commerce",
279
+ snippetType: "component",
280
+ title: "Product Grid",
281
+ description: "Display products from your commerce catalog",
282
+ filePath: "components/Products.tsx",
283
+ code: `import { ProductGrid } from '@sonordev/site-kit/commerce'
284
+
285
+ interface ProductsSectionProps {
286
+ category?: string
287
+ limit?: number
288
+ }
289
+
290
+ export async function ProductsSection({
291
+ category = 'featured',
292
+ limit = 8
293
+ }: ProductsSectionProps) {
294
+ return (
295
+ <section className="py-12">
296
+ <h2 className="text-2xl font-bold mb-6">Our Products</h2>
297
+ <ProductGrid
298
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
299
+ category={category}
300
+ limit={limit}
301
+ />
302
+ </section>
303
+ )
304
+ }`,
305
+ language: "tsx",
306
+ order: startOrder,
307
+ required: false
308
+ },
309
+ {
310
+ module: "commerce",
311
+ snippetType: "component",
312
+ title: "Upcoming Events",
313
+ description: "Display upcoming events and classes",
314
+ filePath: "components/Events.tsx",
315
+ code: `import { UpcomingEvents, EventCalendar } from '@sonordev/site-kit/commerce'
316
+
317
+ export async function EventsSection({ limit = 6 }: { limit?: number }) {
318
+ return (
319
+ <section className="py-12">
320
+ <h2 className="text-2xl font-bold mb-6">Upcoming Events</h2>
321
+ <UpcomingEvents
322
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
323
+ limit={limit}
324
+ />
325
+ </section>
326
+ )
327
+ }
328
+
329
+ export async function FullCalendar() {
330
+ return (
331
+ <EventCalendar
332
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
333
+ />
334
+ )
335
+ }`,
336
+ language: "tsx",
337
+ order: startOrder + 1,
338
+ required: false
339
+ }
340
+ ];
341
+ }
342
+ function generateSEOSnippets(ctx, startOrder) {
343
+ return [
344
+ {
345
+ module: "seo",
346
+ snippetType: "component",
347
+ title: "Managed FAQ Section",
348
+ description: "Render FAQs with automatic JSON-LD schema markup. FAQs are managed in Portal SEO module.",
349
+ filePath: "components/FAQSection.tsx",
350
+ code: `import { ManagedFAQ } from '@sonordev/site-kit/seo'
351
+
352
+ interface FAQSectionProps {
353
+ path: string // Page path to fetch FAQs for (e.g., '/services/plumbing')
354
+ className?: string
355
+ }
356
+
357
+ export async function FAQSection({ path, className }: FAQSectionProps) {
358
+ return (
359
+ <section className={className}>
360
+ <ManagedFAQ
361
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
362
+ path={path}
363
+ showTitle
364
+ includeSchema
365
+ />
366
+ </section>
367
+ )
368
+ }`,
369
+ language: "tsx",
370
+ order: startOrder,
371
+ required: true
372
+ },
373
+ {
374
+ module: "seo",
375
+ snippetType: "page",
376
+ title: "Page with Managed Metadata + FAQs",
377
+ description: "Example dynamic page using managed metadata and FAQ sections",
378
+ filePath: "app/services/[slug]/page.tsx",
379
+ code: `import { getManagedMetadata, ManagedFAQ } from '@sonordev/site-kit/seo'
380
+ import type { Metadata } from 'next'
381
+
382
+ interface Props {
383
+ params: { slug: string }
384
+ }
385
+
386
+ export async function generateMetadata({ params }: Props): Promise<Metadata> {
387
+ const path = \`/services/\${params.slug}\`
388
+ return getManagedMetadata({
389
+ projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,
390
+ path,
391
+ })
392
+ }
393
+
394
+ export default async function ServicePage({ params }: Props) {
395
+ const path = \`/services/\${params.slug}\`
396
+
397
+ return (
398
+ <main>
399
+ <h1 className="text-3xl font-bold">Service: {params.slug}</h1>
400
+
401
+ {/* Your page content here */}
402
+
403
+ {/* FAQs section with JSON-LD schema */}
404
+ <section className="mt-12">
405
+ <ManagedFAQ
406
+ projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}
407
+ path={path}
408
+ showTitle
409
+ includeSchema
410
+ />
411
+ </section>
412
+ </main>
413
+ )
414
+ }`,
415
+ language: "tsx",
416
+ order: startOrder + 1,
417
+ required: false
418
+ }
419
+ ];
420
+ }
421
+ function generateBlogSnippets(ctx, startOrder) {
422
+ return [
423
+ {
424
+ module: "blog",
425
+ snippetType: "page",
426
+ title: "Blog List Page",
427
+ description: "Display all blog posts from Portal",
428
+ filePath: "app/blog/page.tsx",
429
+ code: `import { getBlogPosts } from '@sonordev/site-kit/blog'
430
+ import Link from 'next/link'
431
+
432
+ export default async function BlogPage() {
433
+ const posts = await getBlogPosts({
434
+ projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,
435
+ limit: 10,
436
+ })
437
+
438
+ return (
439
+ <main className="py-12">
440
+ <h1 className="text-3xl font-bold mb-8">Blog</h1>
441
+ <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
442
+ {posts.map((post) => (
443
+ <article key={post.id} className="border rounded-lg p-4">
444
+ {post.featured_image && (
445
+ <img
446
+ src={post.featured_image}
447
+ alt={post.title}
448
+ className="w-full h-48 object-cover rounded mb-4"
449
+ />
450
+ )}
451
+ <h2 className="text-xl font-semibold mb-2">
452
+ <Link href={\`/blog/\${post.slug}\`}>{post.title}</Link>
453
+ </h2>
454
+ <p className="text-gray-600">{post.excerpt}</p>
455
+ </article>
456
+ ))}
457
+ </div>
458
+ </main>
459
+ )
460
+ }`,
461
+ language: "tsx",
462
+ order: startOrder,
463
+ required: false
464
+ },
465
+ {
466
+ module: "blog",
467
+ snippetType: "page",
468
+ title: "Blog Post Page",
469
+ description: "Individual blog post page with SEO metadata",
470
+ filePath: "app/blog/[slug]/page.tsx",
471
+ code: `import { getBlogPost, getBlogPosts } from '@sonordev/site-kit/blog'
472
+ import type { Metadata } from 'next'
473
+ import { notFound } from 'next/navigation'
474
+
475
+ interface Props {
476
+ params: { slug: string }
477
+ }
478
+
479
+ export async function generateStaticParams() {
480
+ const posts = await getBlogPosts({
481
+ projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,
482
+ })
483
+ return posts.map((post) => ({ slug: post.slug }))
484
+ }
485
+
486
+ export async function generateMetadata({ params }: Props): Promise<Metadata> {
487
+ const post = await getBlogPost({
488
+ projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,
489
+ slug: params.slug,
490
+ })
491
+
492
+ if (!post) return {}
493
+
494
+ return {
495
+ title: post.title,
496
+ description: post.excerpt,
497
+ openGraph: {
498
+ title: post.title,
499
+ description: post.excerpt,
500
+ images: post.featured_image ? [post.featured_image] : [],
501
+ },
502
+ }
503
+ }
504
+
505
+ export default async function BlogPostPage({ params }: Props) {
506
+ const post = await getBlogPost({
507
+ projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,
508
+ slug: params.slug,
509
+ })
510
+
511
+ if (!post) notFound()
512
+
513
+ return (
514
+ <article className="py-12 max-w-3xl mx-auto">
515
+ <h1 className="text-4xl font-bold mb-4">{post.title}</h1>
516
+ {post.featured_image && (
517
+ <img
518
+ src={post.featured_image}
519
+ alt={post.title}
520
+ className="w-full rounded-lg mb-8"
521
+ />
522
+ )}
523
+ <div
524
+ className="prose prose-lg"
525
+ dangerouslySetInnerHTML={{ __html: post.content }}
526
+ />
527
+ </article>
528
+ )
529
+ }`,
530
+ language: "tsx",
531
+ order: startOrder + 1,
532
+ required: false
533
+ }
534
+ ];
535
+ }
536
+ function CopyIcon({ className }) {
537
+ return /* @__PURE__ */ jsxs("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
538
+ /* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
539
+ /* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
540
+ ] });
541
+ }
542
+ function CheckIcon({ className }) {
543
+ return /* @__PURE__ */ jsx("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) });
544
+ }
545
+ function ChevronDownIcon({ className }) {
546
+ return /* @__PURE__ */ jsx("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) });
547
+ }
548
+ function ChevronRightIcon({ className }) {
549
+ return /* @__PURE__ */ jsx("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" }) });
550
+ }
551
+ var moduleLabels = {
552
+ provider: "Setup",
553
+ analytics: "Analytics",
554
+ engage: "Engage (Chat)",
555
+ forms: "Forms",
556
+ commerce: "Commerce",
557
+ seo: "SEO",
558
+ blog: "Blog"
559
+ };
560
+ var moduleColors = {
561
+ provider: "#6366f1",
562
+ // indigo
563
+ analytics: "#8b5cf6",
564
+ // violet
565
+ engage: "#ec4899",
566
+ // pink
567
+ forms: "#14b8a6",
568
+ // teal
569
+ commerce: "#f59e0b",
570
+ // amber
571
+ seo: "#10b981",
572
+ // emerald
573
+ blog: "#3b82f6"
574
+ // blue
575
+ };
576
+ function IntegrationCodeView({
577
+ projectId,
578
+ enabledModules,
579
+ apiUrl,
580
+ brand,
581
+ className,
582
+ onCopy
583
+ }) {
584
+ const [expandedModules, setExpandedModules] = useState(/* @__PURE__ */ new Set(["provider"]));
585
+ const [copiedId, setCopiedId] = useState(null);
586
+ const snippets = useMemo(() => {
587
+ return generateIntegrationCode({
588
+ projectId,
589
+ enabledModules,
590
+ apiUrl,
591
+ brand
592
+ });
593
+ }, [projectId, enabledModules, apiUrl, brand]);
594
+ const snippetsByModule = useMemo(() => {
595
+ return getSnippetsByModule(snippets);
596
+ }, [snippets]);
597
+ const toggleModule = (module) => {
598
+ setExpandedModules((prev) => {
599
+ const next = new Set(prev);
600
+ if (next.has(module)) {
601
+ next.delete(module);
602
+ } else {
603
+ next.add(module);
604
+ }
605
+ return next;
606
+ });
607
+ };
608
+ const copyCode = async (code, id, title) => {
609
+ try {
610
+ await navigator.clipboard.writeText(code);
611
+ setCopiedId(id);
612
+ onCopy?.(code, title);
613
+ setTimeout(() => setCopiedId(null), 2e3);
614
+ } catch (err) {
615
+ console.error("Failed to copy:", err);
616
+ }
617
+ };
618
+ const copyAll = async () => {
619
+ const allCode = snippets.map((s) => `// ${s.title}
620
+ ${s.filePath ? `// File: ${s.filePath}
621
+ ` : ""}${s.code}`).join("\n\n// ---\n\n");
622
+ try {
623
+ await navigator.clipboard.writeText(allCode);
624
+ onCopy?.(allCode, "All snippets");
625
+ } catch (err) {
626
+ console.error("Failed to copy:", err);
627
+ }
628
+ };
629
+ if (enabledModules.length === 0) {
630
+ return /* @__PURE__ */ jsxs("div", { className, style: { textAlign: "center", padding: "2rem", color: "#666" }, children: [
631
+ /* @__PURE__ */ jsx("p", { children: "No modules enabled for this project." }),
632
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", marginTop: "0.5rem" }, children: "Enable modules in Project Settings to generate integration code." })
633
+ ] });
634
+ }
635
+ return /* @__PURE__ */ jsxs("div", { className, style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
636
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
637
+ /* @__PURE__ */ jsxs("div", { children: [
638
+ /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontWeight: 600 }, children: "Integration Code" }),
639
+ /* @__PURE__ */ jsxs("p", { style: { margin: "0.25rem 0 0", fontSize: "0.875rem", color: "#666" }, children: [
640
+ snippets.length,
641
+ " snippets for ",
642
+ enabledModules.length,
643
+ " modules"
644
+ ] })
645
+ ] }),
646
+ /* @__PURE__ */ jsxs(
647
+ "button",
648
+ {
649
+ onClick: copyAll,
650
+ style: {
651
+ display: "flex",
652
+ alignItems: "center",
653
+ gap: "0.5rem",
654
+ padding: "0.5rem 1rem",
655
+ border: "1px solid #e5e7eb",
656
+ borderRadius: "0.375rem",
657
+ background: "white",
658
+ cursor: "pointer",
659
+ fontSize: "0.875rem"
660
+ },
661
+ children: [
662
+ /* @__PURE__ */ jsx(CopyIcon, {}),
663
+ "Copy All"
664
+ ]
665
+ }
666
+ )
667
+ ] }),
668
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: Object.entries(snippetsByModule).map(([module, moduleSnippets]) => {
669
+ const isExpanded = expandedModules.has(module);
670
+ const color = moduleColors[module] || "#6366f1";
671
+ return /* @__PURE__ */ jsxs(
672
+ "div",
673
+ {
674
+ style: {
675
+ border: "1px solid #e5e7eb",
676
+ borderRadius: "0.5rem",
677
+ overflow: "hidden"
678
+ },
679
+ children: [
680
+ /* @__PURE__ */ jsxs(
681
+ "button",
682
+ {
683
+ onClick: () => toggleModule(module),
684
+ style: {
685
+ width: "100%",
686
+ display: "flex",
687
+ alignItems: "center",
688
+ justifyContent: "space-between",
689
+ padding: "0.75rem 1rem",
690
+ background: "#f9fafb",
691
+ border: "none",
692
+ cursor: "pointer",
693
+ textAlign: "left"
694
+ },
695
+ children: [
696
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem" }, children: [
697
+ /* @__PURE__ */ jsx(
698
+ "div",
699
+ {
700
+ style: {
701
+ width: "0.5rem",
702
+ height: "0.5rem",
703
+ borderRadius: "50%",
704
+ background: color
705
+ }
706
+ }
707
+ ),
708
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: moduleLabels[module] || module }),
709
+ /* @__PURE__ */ jsx(
710
+ "span",
711
+ {
712
+ style: {
713
+ fontSize: "0.75rem",
714
+ padding: "0.125rem 0.5rem",
715
+ background: "#e5e7eb",
716
+ borderRadius: "9999px"
717
+ },
718
+ children: moduleSnippets.length
719
+ }
720
+ )
721
+ ] }),
722
+ isExpanded ? /* @__PURE__ */ jsx(ChevronDownIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, {})
723
+ ]
724
+ }
725
+ ),
726
+ isExpanded && /* @__PURE__ */ jsx("div", { children: moduleSnippets.map((snippet, idx) => {
727
+ const snippetId = `${module}-${idx}`;
728
+ const isCopied = copiedId === snippetId;
729
+ return /* @__PURE__ */ jsxs(
730
+ "div",
731
+ {
732
+ style: {
733
+ padding: "1rem",
734
+ borderTop: "1px solid #e5e7eb"
735
+ },
736
+ children: [
737
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: "0.75rem" }, children: [
738
+ /* @__PURE__ */ jsxs("div", { children: [
739
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
740
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 500, fontSize: "0.875rem" }, children: snippet.title }),
741
+ snippet.required && /* @__PURE__ */ jsx(
742
+ "span",
743
+ {
744
+ style: {
745
+ fontSize: "0.625rem",
746
+ padding: "0.125rem 0.375rem",
747
+ border: "1px solid #e5e7eb",
748
+ borderRadius: "0.25rem",
749
+ textTransform: "uppercase"
750
+ },
751
+ children: "Required"
752
+ }
753
+ )
754
+ ] }),
755
+ snippet.description && /* @__PURE__ */ jsx("p", { style: { margin: "0.25rem 0 0", fontSize: "0.75rem", color: "#666" }, children: snippet.description }),
756
+ snippet.filePath && /* @__PURE__ */ jsx("p", { style: { margin: "0.25rem 0 0", fontSize: "0.75rem", color, fontFamily: "monospace" }, children: snippet.filePath })
757
+ ] }),
758
+ /* @__PURE__ */ jsx(
759
+ "button",
760
+ {
761
+ onClick: () => copyCode(snippet.code, snippetId, snippet.title),
762
+ style: {
763
+ display: "flex",
764
+ alignItems: "center",
765
+ justifyContent: "center",
766
+ width: "2rem",
767
+ height: "2rem",
768
+ border: "none",
769
+ background: "transparent",
770
+ cursor: "pointer",
771
+ borderRadius: "0.25rem"
772
+ },
773
+ title: "Copy code",
774
+ children: isCopied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-green-500" }) : /* @__PURE__ */ jsx(CopyIcon, {})
775
+ }
776
+ )
777
+ ] }),
778
+ /* @__PURE__ */ jsx(
779
+ "pre",
780
+ {
781
+ style: {
782
+ margin: 0,
783
+ padding: "0.75rem",
784
+ background: "#1f2937",
785
+ color: "#e5e7eb",
786
+ borderRadius: "0.375rem",
787
+ overflow: "auto",
788
+ fontSize: "0.75rem",
789
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
790
+ lineHeight: 1.5
791
+ },
792
+ children: /* @__PURE__ */ jsx("code", { children: snippet.code })
793
+ }
794
+ )
795
+ ]
796
+ },
797
+ idx
798
+ );
799
+ }) })
800
+ ]
801
+ },
802
+ module
803
+ );
804
+ }) })
805
+ ] });
806
+ }
807
+
808
+ export { IntegrationCodeView, generateIntegrationCode, getSnippetsByModule };
809
+ //# sourceMappingURL=chunk-AFAO3TGS.mjs.map
810
+ //# sourceMappingURL=chunk-AFAO3TGS.mjs.map