create-snapify-app 0.0.0-stage → 1.1.1

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 (614) hide show
  1. package/LICENSE.md +24 -0
  2. package/README.md +55 -2
  3. package/bin/create-snapify-app.mjs +174 -0
  4. package/lib/args.mjs +59 -0
  5. package/lib/copy.mjs +44 -0
  6. package/lib/env.mjs +84 -0
  7. package/lib/prompt.mjs +63 -0
  8. package/package.json +35 -4
  9. package/template/.env.example +79 -0
  10. package/template/.github/workflows/ci.yml +23 -0
  11. package/template/.github/workflows/deploy.yml +26 -0
  12. package/template/.github/workflows/ping.yml +8 -0
  13. package/template/.github/workflows/release.yml +67 -0
  14. package/template/.snapify-install.json +5 -0
  15. package/template/CHANGELOG.md +28 -0
  16. package/template/LICENSE +14 -0
  17. package/template/README.md +287 -0
  18. package/template/administrator.html +23 -0
  19. package/template/apps/client/src/App.tsx +765 -0
  20. package/template/apps/client/src/auth.css +400 -0
  21. package/template/apps/client/src/lib/api.ts +22 -0
  22. package/template/apps/client/src/main.tsx +20 -0
  23. package/template/apps/community/src/App.tsx +592 -0
  24. package/template/apps/community/src/main.tsx +20 -0
  25. package/template/apps/community/src/styles.css +24 -0
  26. package/template/apps/developers/src/App.tsx +643 -0
  27. package/template/apps/developers/src/main.tsx +17 -0
  28. package/template/apps/developers/src/pages.tsx +1587 -0
  29. package/template/apps/developers/src/styles.css +98 -0
  30. package/template/apps/developers/src/ui.tsx +179 -0
  31. package/template/apps/landing/src/App.tsx +598 -0
  32. package/template/apps/landing/src/LegalPages.tsx +158 -0
  33. package/template/apps/landing/src/OrderPage.tsx +381 -0
  34. package/template/apps/landing/src/SeoPages.tsx +923 -0
  35. package/template/apps/landing/src/copy.ts +195 -0
  36. package/template/apps/landing/src/main.tsx +20 -0
  37. package/template/apps/landing/src/styles.css +803 -0
  38. package/template/apps/landing/src/types.ts +19 -0
  39. package/template/apps/marketplace/src/App.tsx +1229 -0
  40. package/template/apps/marketplace/src/developer/DeveloperApp.tsx +1266 -0
  41. package/template/apps/marketplace/src/main.tsx +20 -0
  42. package/template/apps/marketplace/src/styles.css +1001 -0
  43. package/template/apps/shared/AuthContext.tsx +65 -0
  44. package/template/apps/shared/Logo.tsx +33 -0
  45. package/template/apps/shared/api.ts +47 -0
  46. package/template/apps/shared/ui.tsx +128 -0
  47. package/template/apps/superadmin/src/App.tsx +1264 -0
  48. package/template/apps/superadmin/src/lib/api.ts +20 -0
  49. package/template/apps/superadmin/src/lib/hooks.ts +20 -0
  50. package/template/apps/superadmin/src/main.tsx +16 -0
  51. package/template/apps/superadmin/src/pages/ClientsPage.tsx +185 -0
  52. package/template/apps/superadmin/src/pages/InvoicesPage.tsx +157 -0
  53. package/template/apps/superadmin/src/pages/NewsletterPage.tsx +212 -0
  54. package/template/apps/superadmin/src/pages/OrdersPage.tsx +195 -0
  55. package/template/apps/superadmin/src/pages/PaymentsPage.tsx +150 -0
  56. package/template/apps/superadmin/src/pages/PayoutsPage.tsx +133 -0
  57. package/template/apps/superadmin/src/pages/PublishersPage.tsx +151 -0
  58. package/template/apps/superadmin/src/pages/SeoControlPage.tsx +692 -0
  59. package/template/apps/superadmin/src/pages/SettingsPage.tsx +199 -0
  60. package/template/apps/superadmin/src/pages/SystemPage.tsx +109 -0
  61. package/template/apps/superadmin/src/pages/TicketsPage.tsx +201 -0
  62. package/template/apps/superadmin/src/pages/UsersPage.tsx +167 -0
  63. package/template/client.html +21 -0
  64. package/template/community/hamdiayari/akhbar/README.md +23 -0
  65. package/template/community/hamdiayari/akhbar/screenshot.jpg +0 -0
  66. package/template/community/hamdiayari/akhbar/snapify.theme.json +76 -0
  67. package/template/community/hamdiayari/akhbar/src/Brand.tsx +26 -0
  68. package/template/community/hamdiayari/akhbar/src/Footer.tsx +182 -0
  69. package/template/community/hamdiayari/akhbar/src/Header.tsx +191 -0
  70. package/template/community/hamdiayari/akhbar/src/Layout.tsx +49 -0
  71. package/template/community/hamdiayari/akhbar/src/Social.tsx +33 -0
  72. package/template/community/hamdiayari/akhbar/src/Ticker.tsx +86 -0
  73. package/template/community/hamdiayari/akhbar/src/Views.tsx +285 -0
  74. package/template/community/hamdiayari/akhbar/src/blocks/CollectionBlocks.tsx +672 -0
  75. package/template/community/hamdiayari/akhbar/src/blocks/ContentBlocks.tsx +305 -0
  76. package/template/community/hamdiayari/akhbar/src/blocks/ConversionBlocks.tsx +569 -0
  77. package/template/community/hamdiayari/akhbar/src/blocks/HeaderBlocks.tsx +287 -0
  78. package/template/community/hamdiayari/akhbar/src/index.tsx +51 -0
  79. package/template/community/hamdiayari/akhbar/src/kit.tsx +357 -0
  80. package/template/community/hamdiayari/akhbar/src/site.ts +96 -0
  81. package/template/community/hamdiayari/akhbar/src/styles.css +566 -0
  82. package/template/community/hamdiayari/akhbar-actualites/README.md +28 -0
  83. package/template/community/hamdiayari/akhbar-actualites/screenshot.jpg +0 -0
  84. package/template/community/hamdiayari/akhbar-actualites/snapify.module.json +107 -0
  85. package/template/community/hamdiayari/akhbar-actualites/src/admin/AudiencePage.tsx +185 -0
  86. package/template/community/hamdiayari/akhbar-actualites/src/admin/index.tsx +11 -0
  87. package/template/community/hamdiayari/akhbar-actualites/src/public/Archive.tsx +142 -0
  88. package/template/community/hamdiayari/akhbar-actualites/src/public/cards.tsx +152 -0
  89. package/template/community/hamdiayari/akhbar-actualites/src/public/index.tsx +71 -0
  90. package/template/community/hamdiayari/akhbar-actualites/src/public/posts.ts +103 -0
  91. package/template/community/hamdiayari/akhbar-actualites/src/public/styles.css +568 -0
  92. package/template/community/hamdiayari/akhbar-actualites/src/public/widgets.tsx +226 -0
  93. package/template/community/hamdiayari/akhbar-actualites/src/server.ts +119 -0
  94. package/template/community/hamdiayari/akhbar-actualites/src/types.ts +25 -0
  95. package/template/community/hamdiayari/akhbar-urgent/README.md +36 -0
  96. package/template/community/hamdiayari/akhbar-urgent/screenshot.jpg +0 -0
  97. package/template/community/hamdiayari/akhbar-urgent/snapify.module.json +64 -0
  98. package/template/community/hamdiayari/akhbar-urgent/src/admin/FlashesPage.tsx +229 -0
  99. package/template/community/hamdiayari/akhbar-urgent/src/admin/index.tsx +11 -0
  100. package/template/community/hamdiayari/akhbar-urgent/src/public/Ticker.tsx +81 -0
  101. package/template/community/hamdiayari/akhbar-urgent/src/public/index.tsx +63 -0
  102. package/template/community/hamdiayari/akhbar-urgent/src/public/styles.css +142 -0
  103. package/template/community/hamdiayari/akhbar-urgent/src/server.ts +101 -0
  104. package/template/community/hamdiayari/akhbar-urgent/src/types.ts +35 -0
  105. package/template/community.html +21 -0
  106. package/template/developers.html +24 -0
  107. package/template/docker-compose.db.yml +24 -0
  108. package/template/docs/BACKOFFICE_SNAPIFY.md +130 -0
  109. package/template/docs/CI_CD.md +66 -0
  110. package/template/docs/MODULES.md +346 -0
  111. package/template/docs/PLATFORM_DEPLOY.md +54 -0
  112. package/template/docs/logo.svg +10 -0
  113. package/template/drizzle/0000_init.sql +147 -0
  114. package/template/drizzle/0001_page_project.sql +5 -0
  115. package/template/drizzle/0002_modules.sql +23 -0
  116. package/template/drizzle/0003_themes.sql +4 -0
  117. package/template/drizzle/0004_security.sql +82 -0
  118. package/template/drizzle/0005_module_records.sql +16 -0
  119. package/template/drizzle/0006_avatars.sql +4 -0
  120. package/template/drizzle/0007_platform.sql +264 -0
  121. package/template/drizzle/0008_mp_validation.sql +3 -0
  122. package/template/drizzle/0009_saas_ops.sql +77 -0
  123. package/template/drizzle/0010_cms_chrome.sql +13 -0
  124. package/template/drizzle/0011_client_portal.sql +26 -0
  125. package/template/drizzle/meta/0000_snapshot.json +998 -0
  126. package/template/drizzle/meta/0001_snapshot.json +1004 -0
  127. package/template/drizzle/meta/_journal.json +90 -0
  128. package/template/drizzle.config.ts +16 -0
  129. package/template/ecosystem.snapify.cjs +24 -0
  130. package/template/for.html +1 -0
  131. package/template/index.html +29 -0
  132. package/template/landing.html +37 -0
  133. package/template/marketplace/catalog.json +373 -0
  134. package/template/marketplace/gallery/hamdiayari.preveris/01-home.jpg +0 -0
  135. package/template/marketplace/gallery/hamdiayari.recaptcha/01-reglages.jpg +0 -0
  136. package/template/marketplace/gallery/hamdiayari.recaptcha/02-logo.jpg +0 -0
  137. package/template/marketplace/gallery/novalabs.ai-articles/01-generer.jpg +0 -0
  138. package/template/marketplace/gallery/novalabs.ai-articles/02-fournisseur-ia.jpg +0 -0
  139. package/template/marketplace/gallery/novalabs.calendar/01-agenda-site.jpg +0 -0
  140. package/template/marketplace/gallery/novalabs.calendar/02-evenements-admin.jpg +0 -0
  141. package/template/marketplace/gallery/novalabs.calendar/03-reglages.jpg +0 -0
  142. package/template/marketplace/screenshots/hamdiayari.preveris-1.0.6.jpg +0 -0
  143. package/template/marketplace/screenshots/hamdiayari.recaptcha-1.0.0.jpg +0 -0
  144. package/template/marketplace/screenshots/hamdiayari.wp-seo-migrator-1.1.1.jpg +0 -0
  145. package/template/marketplace/screenshots/novalabs.ai-articles-1.0.1.jpg +0 -0
  146. package/template/marketplace/screenshots/novalabs.ai-chat-1.0.1.jpg +0 -0
  147. package/template/marketplace/screenshots/novalabs.calendar-1.0.1.jpg +0 -0
  148. package/template/marketplace/screenshots/novalabs.cart-1.0.0.jpg +0 -0
  149. package/template/marketplace/screenshots/novalabs.checkout-1.0.0.jpg +0 -0
  150. package/template/marketplace/screenshots/novalabs.customers-1.1.0.jpg +0 -0
  151. package/template/marketplace/screenshots/novalabs.dogga-1.0.0.jpg +0 -0
  152. package/template/marketplace/screenshots/novalabs.mahdia-1.0.0.jpg +0 -0
  153. package/template/marketplace/screenshots/novalabs.shop-1.0.0.jpg +0 -0
  154. package/template/marketplace/screenshots/novalabs.sidibou-1.0.0.jpg +0 -0
  155. package/template/marketplace/screenshots/novalabs.whatsapp-1.0.1.jpg +0 -0
  156. package/template/marketplace.html +21 -0
  157. package/template/metadata.json +7 -0
  158. package/template/modules/ai-articles/screenshot.jpg +0 -0
  159. package/template/modules/ai-articles/snapify.module.json +74 -0
  160. package/template/modules/ai-articles/src/admin/ArticlesPage.tsx +162 -0
  161. package/template/modules/ai-articles/src/admin/GeneratePage.tsx +118 -0
  162. package/template/modules/ai-articles/src/admin/index.tsx +12 -0
  163. package/template/modules/ai-articles/src/public/index.tsx +119 -0
  164. package/template/modules/ai-articles/src/server.ts +287 -0
  165. package/template/modules/ai-articles/src/types.ts +30 -0
  166. package/template/modules/ai-chat/screenshot.jpg +0 -0
  167. package/template/modules/ai-chat/snapify.module.json +217 -0
  168. package/template/modules/ai-chat/src/public.tsx +198 -0
  169. package/template/modules/ai-chat/src/server.ts +142 -0
  170. package/template/modules/ai-theme-studio/README.md +15 -0
  171. package/template/modules/ai-theme-studio/screenshot.jpg +0 -0
  172. package/template/modules/ai-theme-studio/snapify.module.json +175 -0
  173. package/template/modules/ai-theme-studio/src/admin/HistoryPage.tsx +91 -0
  174. package/template/modules/ai-theme-studio/src/admin/StudioPage.tsx +414 -0
  175. package/template/modules/ai-theme-studio/src/admin/index.tsx +11 -0
  176. package/template/modules/ai-theme-studio/src/lib/images.ts +240 -0
  177. package/template/modules/ai-theme-studio/src/lib/llm.ts +123 -0
  178. package/template/modules/ai-theme-studio/src/lib/normalize.ts +714 -0
  179. package/template/modules/ai-theme-studio/src/lib/prompts.ts +198 -0
  180. package/template/modules/ai-theme-studio/src/server.ts +137 -0
  181. package/template/modules/ai-theme-studio/src/types.ts +112 -0
  182. package/template/modules/calendar/screenshot.jpg +0 -0
  183. package/template/modules/calendar/snapify.module.json +45 -0
  184. package/template/modules/calendar/src/admin/EventsPage.tsx +217 -0
  185. package/template/modules/calendar/src/admin/index.tsx +11 -0
  186. package/template/modules/calendar/src/public/index.tsx +231 -0
  187. package/template/modules/calendar/src/server.ts +143 -0
  188. package/template/modules/calendar/src/types.ts +25 -0
  189. package/template/modules/cart/screenshot.jpg +0 -0
  190. package/template/modules/cart/snapify.module.json +90 -0
  191. package/template/modules/cart/src/admin/index.tsx +265 -0
  192. package/template/modules/cart/src/public/CartPage.tsx +198 -0
  193. package/template/modules/cart/src/public/index.tsx +261 -0
  194. package/template/modules/cart/src/public/useQuote.ts +67 -0
  195. package/template/modules/cart/src/server.ts +148 -0
  196. package/template/modules/cart/src/types.ts +31 -0
  197. package/template/modules/checkout/screenshot.jpg +0 -0
  198. package/template/modules/checkout/snapify.module.json +264 -0
  199. package/template/modules/checkout/src/admin/OrderDetailPage.tsx +304 -0
  200. package/template/modules/checkout/src/admin/badges.tsx +28 -0
  201. package/template/modules/checkout/src/admin/index.tsx +236 -0
  202. package/template/modules/checkout/src/public/CheckoutPage.tsx +461 -0
  203. package/template/modules/checkout/src/public/OrderPages.tsx +153 -0
  204. package/template/modules/checkout/src/public/index.tsx +23 -0
  205. package/template/modules/checkout/src/server.ts +383 -0
  206. package/template/modules/checkout/src/types.ts +70 -0
  207. package/template/modules/customers/screenshot.jpg +0 -0
  208. package/template/modules/customers/snapify.module.json +115 -0
  209. package/template/modules/customers/src/admin/CustomerDetailPage.tsx +274 -0
  210. package/template/modules/customers/src/admin/index.tsx +194 -0
  211. package/template/modules/customers/src/public/AccountPages.tsx +470 -0
  212. package/template/modules/customers/src/public/AddressForm.tsx +115 -0
  213. package/template/modules/customers/src/public/AuthPages.tsx +349 -0
  214. package/template/modules/customers/src/public/Avatar.tsx +29 -0
  215. package/template/modules/customers/src/public/ProfileSection.tsx +291 -0
  216. package/template/modules/customers/src/public/index.tsx +137 -0
  217. package/template/modules/customers/src/public/session.ts +51 -0
  218. package/template/modules/customers/src/server.ts +421 -0
  219. package/template/modules/customers/src/types.ts +53 -0
  220. package/template/modules/recaptcha/logo.jpg +0 -0
  221. package/template/modules/recaptcha/screenshot.jpg +0 -0
  222. package/template/modules/recaptcha/snapify.module.json +99 -0
  223. package/template/modules/recaptcha/src/public/index.tsx +94 -0
  224. package/template/modules/recaptcha/src/server.ts +65 -0
  225. package/template/modules/recaptcha/src/types.ts +18 -0
  226. package/template/modules/shop/screenshot.jpg +0 -0
  227. package/template/modules/shop/snapify.module.json +340 -0
  228. package/template/modules/shop/src/admin/CategoriesPage.tsx +224 -0
  229. package/template/modules/shop/src/admin/ProductEditor.tsx +313 -0
  230. package/template/modules/shop/src/admin/ProductsPage.tsx +307 -0
  231. package/template/modules/shop/src/admin/index.tsx +14 -0
  232. package/template/modules/shop/src/public/Catalog.tsx +244 -0
  233. package/template/modules/shop/src/public/NotFound.tsx +22 -0
  234. package/template/modules/shop/src/public/ProductPage.tsx +195 -0
  235. package/template/modules/shop/src/public/index.tsx +134 -0
  236. package/template/modules/shop/src/public/useFetch.ts +26 -0
  237. package/template/modules/shop/src/server.ts +493 -0
  238. package/template/modules/shop/src/shared.ts +41 -0
  239. package/template/modules/shop/src/types.ts +60 -0
  240. package/template/modules/whatsapp/screenshot.jpg +0 -0
  241. package/template/modules/whatsapp/snapify.module.json +121 -0
  242. package/template/modules/whatsapp/src/public.tsx +119 -0
  243. package/template/modules/wp-seo-migrator/ARCHITECTURE.md +113 -0
  244. package/template/modules/wp-seo-migrator/README.md +21 -0
  245. package/template/modules/wp-seo-migrator/fixtures/aioseo-sample.csv +3 -0
  246. package/template/modules/wp-seo-migrator/fixtures/sample-exporter.json +39 -0
  247. package/template/modules/wp-seo-migrator/fixtures/sample-page.html +12 -0
  248. package/template/modules/wp-seo-migrator/fixtures/sample.htaccess +3 -0
  249. package/template/modules/wp-seo-migrator/screenshot.jpg +0 -0
  250. package/template/modules/wp-seo-migrator/snapify.module.json +87 -0
  251. package/template/modules/wp-seo-migrator/src/admin/HistoryPage.tsx +64 -0
  252. package/template/modules/wp-seo-migrator/src/admin/WizardPage.tsx +788 -0
  253. package/template/modules/wp-seo-migrator/src/admin/i18n.ts +156 -0
  254. package/template/modules/wp-seo-migrator/src/admin/index.tsx +11 -0
  255. package/template/modules/wp-seo-migrator/src/connectors/CUSTOM_CONNECTOR.md +31 -0
  256. package/template/modules/wp-seo-migrator/src/connectors/csvSeoFactory.ts +106 -0
  257. package/template/modules/wp-seo-migrator/src/connectors/exporter.ts +96 -0
  258. package/template/modules/wp-seo-migrator/src/connectors/gscCsv.ts +53 -0
  259. package/template/modules/wp-seo-migrator/src/connectors/htaccess.ts +65 -0
  260. package/template/modules/wp-seo-migrator/src/connectors/htmlCrawler.ts +90 -0
  261. package/template/modules/wp-seo-migrator/src/connectors/index.ts +113 -0
  262. package/template/modules/wp-seo-migrator/src/connectors/pluginCsv.ts +77 -0
  263. package/template/modules/wp-seo-migrator/src/connectors/rankMathCsv.ts +77 -0
  264. package/template/modules/wp-seo-migrator/src/connectors/redirection.ts +62 -0
  265. package/template/modules/wp-seo-migrator/src/connectors/sitemap.ts +44 -0
  266. package/template/modules/wp-seo-migrator/src/connectors/utils.ts +111 -0
  267. package/template/modules/wp-seo-migrator/src/connectors/wxr.ts +103 -0
  268. package/template/modules/wp-seo-migrator/src/connectors/yoastCsv.ts +56 -0
  269. package/template/modules/wp-seo-migrator/src/pipeline/analyze.ts +158 -0
  270. package/template/modules/wp-seo-migrator/src/pipeline/htmlParse.ts +58 -0
  271. package/template/modules/wp-seo-migrator/src/pipeline/remoteAuto.ts +328 -0
  272. package/template/modules/wp-seo-migrator/src/server.ts +492 -0
  273. package/template/modules/wp-seo-migrator/src/types.ts +151 -0
  274. package/template/modules/wp-seo-migrator/tests/connectors-extra.test.ts +39 -0
  275. package/template/modules/wp-seo-migrator/tests/merge.test.ts +25 -0
  276. package/template/package-lock.json +6016 -0
  277. package/template/package.json +74 -0
  278. package/template/public/images/photos/caravane-chameaux-desert.webp +0 -0
  279. package/template/public/images/photos/hammamet-medina-plage.jpg +0 -0
  280. package/template/public/images/photos/maison-campagne-collines.webp +0 -0
  281. package/template/public/images/photos/maisons-troglodytes-desert.jpg +0 -0
  282. package/template/public/images/photos/panorama-ville.jpg +0 -0
  283. package/template/public/images/photos/preveris-accessibilite-erp.jpg +0 -0
  284. package/template/public/images/photos/preveris-collectivites.jpg +0 -0
  285. package/template/public/images/photos/preveris-etudes-plans.jpg +0 -0
  286. package/template/public/images/photos/preveris-hero-erp.jpg +0 -0
  287. package/template/public/images/photos/preveris-ssi-incendie.jpg +0 -0
  288. package/template/public/images/photos/preveris-suivi-hotel.jpg +0 -0
  289. package/template/public/images/photos/ruelle-bleue-medina.jpg +0 -0
  290. package/template/public/images/photos/sidi-bou-said-port.webp +0 -0
  291. package/template/public/images/photos/terrasse-blanche-mer-voilier.jpg +0 -0
  292. package/template/public/landing/hero-ai-cms.jpg +0 -0
  293. package/template/public/landing/shot-dogga.jpg +0 -0
  294. package/template/public/landing/shot-mahdia.jpg +0 -0
  295. package/template/public/landing/shot-sidibou.jpg +0 -0
  296. package/template/public/llms.txt +35 -0
  297. package/template/public/logo.svg +10 -0
  298. package/template/scripts/app-pack.ts +155 -0
  299. package/template/scripts/app-publish.ts +123 -0
  300. package/template/scripts/apply-ecommerce-home.ts +196 -0
  301. package/template/scripts/auto-deploy-poll.sh +13 -0
  302. package/template/scripts/db-backup.sh +16 -0
  303. package/template/scripts/db-restore.sh +11 -0
  304. package/template/scripts/deploy.sh +34 -0
  305. package/template/scripts/github-webhook-deploy.sh +7 -0
  306. package/template/scripts/install-new-modules.ts +96 -0
  307. package/template/scripts/refresh-demo-baseline.ts +9 -0
  308. package/template/scripts/reinstall-marketplace-packs.ts +51 -0
  309. package/template/scripts/restore-classic-home.ts +13 -0
  310. package/template/scripts/sdk-pack.ts +289 -0
  311. package/template/scripts/sdk-publish.ts +75 -0
  312. package/template/scripts/seed-demo-products.ts +120 -0
  313. package/template/scripts/seed-theme-content-packs.ts +42 -0
  314. package/template/scripts/snapify-module.ts +207 -0
  315. package/template/scripts/test-theme-switch.ts +24 -0
  316. package/template/sdk/admin.css +18 -0
  317. package/template/sdk/admin.ts +95 -0
  318. package/template/sdk/build.ts +249 -0
  319. package/template/sdk/commerce.ts +512 -0
  320. package/template/sdk/content.ts +76 -0
  321. package/template/sdk/icons.ts +101 -0
  322. package/template/sdk/image.ts +60 -0
  323. package/template/sdk/index.ts +500 -0
  324. package/template/sdk/package.ts +298 -0
  325. package/template/sdk/recaptcha.tsx +122 -0
  326. package/template/sdk/settings.ts +84 -0
  327. package/template/sdk/theme.css +29 -0
  328. package/template/sdk/theme.ts +100 -0
  329. package/template/sdk/ui/commerce.tsx +385 -0
  330. package/template/sdk/ui/orders.tsx +136 -0
  331. package/template/sdk-kit/CHANGELOG.md +17 -0
  332. package/template/sdk-kit/LICENSE.md +47 -0
  333. package/template/sdk-kit/README.md +81 -0
  334. package/template/sdk-kit/cli.ts +339 -0
  335. package/template/sdk-kit/create-snapify/README.md +28 -0
  336. package/template/sdk-kit/create-snapify/create-snapify.mjs +11 -0
  337. package/template/sdk-kit/create-snapify/package.template.json +16 -0
  338. package/template/sdk-kit/package.template.json +95 -0
  339. package/template/sdk-kit/templates/common/README.md.tpl +27 -0
  340. package/template/sdk-kit/templates/common/_gitignore +3 -0
  341. package/template/sdk-kit/templates/common/package.json.tpl +19 -0
  342. package/template/sdk-kit/templates/common/src/snapify-env.d.ts +2 -0
  343. package/template/sdk-kit/templates/common/tsconfig.json +15 -0
  344. package/template/sdk-kit/templates/module/snapify.module.json.tpl +33 -0
  345. package/template/sdk-kit/templates/module/src/admin.tsx +53 -0
  346. package/template/sdk-kit/templates/module/src/public.tsx +49 -0
  347. package/template/sdk-kit/templates/module/src/server.ts +30 -0
  348. package/template/sdk-kit/templates/module/src/types.ts +19 -0
  349. package/template/sdk-kit/templates/theme/snapify.theme.json.tpl +22 -0
  350. package/template/sdk-kit/templates/theme/src/Footer.tsx +40 -0
  351. package/template/sdk-kit/templates/theme/src/Header.tsx +47 -0
  352. package/template/sdk-kit/templates/theme/src/Views.tsx +36 -0
  353. package/template/sdk-kit/templates/theme/src/blocks.tsx +93 -0
  354. package/template/sdk-kit/templates/theme/src/index.tsx +30 -0
  355. package/template/sdk-kit/templates/theme/src/site.tsx +59 -0
  356. package/template/sdk-kit/templates/theme/src/styles.css +71 -0
  357. package/template/server/client/routes.ts +252 -0
  358. package/template/server/cms/analyticsStore.ts +180 -0
  359. package/template/server/cms/auth.ts +155 -0
  360. package/template/server/cms/blockCatalog.ts +342 -0
  361. package/template/server/cms/blocks.ts +521 -0
  362. package/template/server/cms/contentMigration.ts +1119 -0
  363. package/template/server/cms/defaults.ts +303 -0
  364. package/template/server/cms/permissions.ts +154 -0
  365. package/template/server/cms/restoreClassicHome.ts +183 -0
  366. package/template/server/cms/revisions.ts +99 -0
  367. package/template/server/cms/scheduler.ts +78 -0
  368. package/template/server/cms/seed.ts +72 -0
  369. package/template/server/cms/seoAnalyzer.ts +213 -0
  370. package/template/server/cms/store.ts +122 -0
  371. package/template/server/cms/themeContent.ts +1386 -0
  372. package/template/server/cms/themePacks/sidibou-branding.json +1 -0
  373. package/template/server/cms/themePacks/sidibou-home.json +1 -0
  374. package/template/server/cms/themePacks/sidibou-menus.json +1 -0
  375. package/template/server/cms/types.ts +432 -0
  376. package/template/server/community/routes.ts +410 -0
  377. package/template/server/db/client.ts +43 -0
  378. package/template/server/db/repository.ts +389 -0
  379. package/template/server/db/schema.ts +726 -0
  380. package/template/server/demo/cmsReset.ts +196 -0
  381. package/template/server/developers/sdk.ts +85 -0
  382. package/template/server/geoip.ts +15 -0
  383. package/template/server/http.ts +53 -0
  384. package/template/server/mail.ts +216 -0
  385. package/template/server/marketplace/catalog.ts +74 -0
  386. package/template/server/marketplace/packageValidate.ts +475 -0
  387. package/template/server/marketplace/payments.ts +193 -0
  388. package/template/server/marketplace/routes.ts +850 -0
  389. package/template/server/marketplace/signing.ts +116 -0
  390. package/template/server/marketplace/syncOfficial.ts +282 -0
  391. package/template/server/media/images.ts +63 -0
  392. package/template/server/middleware/adminAuth.ts +134 -0
  393. package/template/server/modules/legacy.ts +44 -0
  394. package/template/server/modules/manager.ts +1122 -0
  395. package/template/server/modules/marketplace.ts +178 -0
  396. package/template/server/modules/outbound.ts +178 -0
  397. package/template/server/modules/purchases.ts +149 -0
  398. package/template/server/modules/records.ts +168 -0
  399. package/template/server/modules/themeHtml.ts +32 -0
  400. package/template/server/modules/trust.ts +16 -0
  401. package/template/server/modules/types.ts +147 -0
  402. package/template/server/platform/auth.ts +223 -0
  403. package/template/server/platform/clientWelcome.ts +168 -0
  404. package/template/server/platform/clients.ts +139 -0
  405. package/template/server/platform/dailyImprove.ts +356 -0
  406. package/template/server/platform/flouci.ts +126 -0
  407. package/template/server/platform/host.ts +69 -0
  408. package/template/server/platform/hostingProviders.ts +143 -0
  409. package/template/server/platform/licenseOrders.ts +291 -0
  410. package/template/server/platform/money.ts +42 -0
  411. package/template/server/platform/passwords.ts +41 -0
  412. package/template/server/platform/region.ts +86 -0
  413. package/template/server/platform/routes.ts +225 -0
  414. package/template/server/platform/seed.ts +82 -0
  415. package/template/server/platform/settings.ts +72 -0
  416. package/template/server/routes/adminAccount.ts +403 -0
  417. package/template/server/routes/adminCms.ts +808 -0
  418. package/template/server/routes/adminSystem.ts +243 -0
  419. package/template/server/routes/adminUsers.ts +449 -0
  420. package/template/server/routes/googleOAuth.ts +327 -0
  421. package/template/server/routes/modules.ts +323 -0
  422. package/template/server/routes/publicCms.ts +313 -0
  423. package/template/server/routes/seoPublic.ts +158 -0
  424. package/template/server/security/accounts.ts +121 -0
  425. package/template/server/security/audit.ts +143 -0
  426. package/template/server/security/authTokens.ts +74 -0
  427. package/template/server/security/ip.ts +68 -0
  428. package/template/server/security/rateLimit.ts +85 -0
  429. package/template/server/security/retention.ts +46 -0
  430. package/template/server/security/secrets.ts +44 -0
  431. package/template/server/security/sessions.ts +140 -0
  432. package/template/server/security/totp.ts +101 -0
  433. package/template/server/superadmin/analytics.ts +109 -0
  434. package/template/server/superadmin/auth.ts +92 -0
  435. package/template/server/superadmin/backlinksCatalog.ts +210 -0
  436. package/template/server/superadmin/frSeoContent.ts +165 -0
  437. package/template/server/superadmin/landingSeo.ts +675 -0
  438. package/template/server/superadmin/ops.ts +238 -0
  439. package/template/server/superadmin/routes.ts +1095 -0
  440. package/template/server/superadmin/tnSeoContent.ts +130 -0
  441. package/template/server.ts +522 -0
  442. package/template/src/App.tsx +263 -0
  443. package/template/src/admin/AdminApp.tsx +162 -0
  444. package/template/src/admin/account/AuthLayout.tsx +57 -0
  445. package/template/src/admin/account/SecurityForms.tsx +276 -0
  446. package/template/src/admin/admin.css +127 -0
  447. package/template/src/admin/context/AuthContext.tsx +147 -0
  448. package/template/src/admin/context/SiteContext.tsx +50 -0
  449. package/template/src/admin/editor/BlockLibrary.tsx +173 -0
  450. package/template/src/admin/editor/BlocksPanel.tsx +396 -0
  451. package/template/src/admin/editor/EditorBits.tsx +106 -0
  452. package/template/src/admin/editor/PreviewFrame.tsx +145 -0
  453. package/template/src/admin/editor/RichTextEditor.tsx +276 -0
  454. package/template/src/admin/editor/SeoPanel.tsx +349 -0
  455. package/template/src/admin/editor/StyleEditor.tsx +114 -0
  456. package/template/src/admin/editor/blockSchemas.ts +699 -0
  457. package/template/src/admin/editor/fields.tsx +486 -0
  458. package/template/src/admin/layout/AdminShell.tsx +418 -0
  459. package/template/src/admin/layout/nav.ts +95 -0
  460. package/template/src/admin/lib/api.ts +408 -0
  461. package/template/src/admin/lib/audit.ts +141 -0
  462. package/template/src/admin/lib/format.ts +84 -0
  463. package/template/src/admin/lib/hooks.ts +125 -0
  464. package/template/src/admin/main.tsx +16 -0
  465. package/template/src/admin/modules/InstallDialog.tsx +160 -0
  466. package/template/src/admin/modules/SettingsForm.tsx +145 -0
  467. package/template/src/admin/modules/kit.tsx +127 -0
  468. package/template/src/admin/modules/labels.tsx +226 -0
  469. package/template/src/admin/pages/AccountSetupPage.tsx +62 -0
  470. package/template/src/admin/pages/AnalyticsPage.tsx +206 -0
  471. package/template/src/admin/pages/BrandingPage.tsx +154 -0
  472. package/template/src/admin/pages/DashboardPage.tsx +239 -0
  473. package/template/src/admin/pages/EngagementPage.tsx +168 -0
  474. package/template/src/admin/pages/FormsPage.tsx +435 -0
  475. package/template/src/admin/pages/GeneralPage.tsx +120 -0
  476. package/template/src/admin/pages/LoginPage.tsx +249 -0
  477. package/template/src/admin/pages/MaintenancePage.tsx +125 -0
  478. package/template/src/admin/pages/MarketplacePage.tsx +426 -0
  479. package/template/src/admin/pages/MediaPage.tsx +251 -0
  480. package/template/src/admin/pages/MenusPage.tsx +446 -0
  481. package/template/src/admin/pages/ModuleAdminPage.tsx +113 -0
  482. package/template/src/admin/pages/ModuleDetailPage.tsx +293 -0
  483. package/template/src/admin/pages/ModulesPage.tsx +135 -0
  484. package/template/src/admin/pages/NewsletterPage.tsx +193 -0
  485. package/template/src/admin/pages/PageEditorPage.tsx +322 -0
  486. package/template/src/admin/pages/PagesListPage.tsx +277 -0
  487. package/template/src/admin/pages/PostEditorPage.tsx +292 -0
  488. package/template/src/admin/pages/PostsListPage.tsx +187 -0
  489. package/template/src/admin/pages/ProfilePage.tsx +489 -0
  490. package/template/src/admin/pages/ResetPasswordPage.tsx +110 -0
  491. package/template/src/admin/pages/SeoPage.tsx +670 -0
  492. package/template/src/admin/pages/SettingsPage.tsx +189 -0
  493. package/template/src/admin/pages/ThemeCustomizePage.tsx +170 -0
  494. package/template/src/admin/pages/ThemesPage.tsx +292 -0
  495. package/template/src/admin/pages/UsersPage.tsx +57 -0
  496. package/template/src/admin/pages/WidgetsPage.tsx +200 -0
  497. package/template/src/admin/seo/GoogleSetup.tsx +529 -0
  498. package/template/src/admin/settings/EmailTab.tsx +293 -0
  499. package/template/src/admin/settings/OtherTabs.tsx +270 -0
  500. package/template/src/admin/settings/SecurityTab.tsx +172 -0
  501. package/template/src/admin/settings/controls.tsx +133 -0
  502. package/template/src/admin/ui/Pagination.tsx +170 -0
  503. package/template/src/admin/ui/SaveBar.tsx +77 -0
  504. package/template/src/admin/ui/TagInput.tsx +54 -0
  505. package/template/src/admin/ui/charts.tsx +108 -0
  506. package/template/src/admin/ui/media.tsx +265 -0
  507. package/template/src/admin/ui/overlays.tsx +239 -0
  508. package/template/src/admin/ui/primitives.tsx +544 -0
  509. package/template/src/admin/users/AuditTab.tsx +104 -0
  510. package/template/src/admin/users/RolesTab.tsx +368 -0
  511. package/template/src/admin/users/UsersTab.tsx +723 -0
  512. package/template/src/admin/users/shared.tsx +278 -0
  513. package/template/src/cms/icons.ts +7 -0
  514. package/template/src/components/CookieBanner.tsx +166 -0
  515. package/template/src/components/MaintenanceGate.tsx +66 -0
  516. package/template/src/components/SiteAnalytics.tsx +64 -0
  517. package/template/src/components/SnapifyLogo.tsx +44 -0
  518. package/template/src/components/cms/BlockRenderer.tsx +154 -0
  519. package/template/src/components/cms/WidgetArea.tsx +193 -0
  520. package/template/src/context/SiteConfigContext.tsx +130 -0
  521. package/template/src/demoBase.ts +23 -0
  522. package/template/src/index.css +90 -0
  523. package/template/src/main.tsx +16 -0
  524. package/template/src/modules/ModuleHost.tsx +197 -0
  525. package/template/src/preview.ts +63 -0
  526. package/template/src/runtime.ts +38 -0
  527. package/template/src/themes/ThemeHost.tsx +168 -0
  528. package/template/src/themes/fallback.tsx +71 -0
  529. package/template/src/types.ts +94 -0
  530. package/template/src/views/BlogPostView.tsx +68 -0
  531. package/template/src/views/CmsPageView.tsx +34 -0
  532. package/template/start-pm2.sh +3 -0
  533. package/template/superadmin.html +20 -0
  534. package/template/themes/ai-canvas/screenshot.jpg +0 -0
  535. package/template/themes/ai-canvas/snapify.theme.json +96 -0
  536. package/template/themes/ai-canvas/src/CeeSimulator.tsx +247 -0
  537. package/template/themes/ai-canvas/src/Footer.tsx +190 -0
  538. package/template/themes/ai-canvas/src/Header.tsx +324 -0
  539. package/template/themes/ai-canvas/src/Layout.tsx +56 -0
  540. package/template/themes/ai-canvas/src/NotFound.tsx +58 -0
  541. package/template/themes/ai-canvas/src/Post.tsx +26 -0
  542. package/template/themes/ai-canvas/src/SnapifyLogo.tsx +44 -0
  543. package/template/themes/ai-canvas/src/blocks/CollectionBlocks.tsx +711 -0
  544. package/template/themes/ai-canvas/src/blocks/ContentBlocks.tsx +318 -0
  545. package/template/themes/ai-canvas/src/blocks/ConversionBlocks.tsx +559 -0
  546. package/template/themes/ai-canvas/src/blocks/HeaderBlocks.tsx +341 -0
  547. package/template/themes/ai-canvas/src/index.tsx +54 -0
  548. package/template/themes/ai-canvas/src/kit.tsx +398 -0
  549. package/template/themes/ai-canvas/src/site.ts +29 -0
  550. package/template/themes/ai-canvas/src/styles.css +317 -0
  551. package/template/themes/dogga/screenshot.jpg +0 -0
  552. package/template/themes/dogga/snapify.theme.json +55 -0
  553. package/template/themes/dogga/src/Brand.tsx +41 -0
  554. package/template/themes/dogga/src/Footer.tsx +202 -0
  555. package/template/themes/dogga/src/Header.tsx +239 -0
  556. package/template/themes/dogga/src/Layout.tsx +43 -0
  557. package/template/themes/dogga/src/Views.tsx +71 -0
  558. package/template/themes/dogga/src/blocks/CollectionBlocks.tsx +674 -0
  559. package/template/themes/dogga/src/blocks/ContentBlocks.tsx +307 -0
  560. package/template/themes/dogga/src/blocks/ConversionBlocks.tsx +571 -0
  561. package/template/themes/dogga/src/blocks/HeaderBlocks.tsx +289 -0
  562. package/template/themes/dogga/src/index.tsx +53 -0
  563. package/template/themes/dogga/src/kit.tsx +362 -0
  564. package/template/themes/dogga/src/site.ts +56 -0
  565. package/template/themes/dogga/src/styles.css +396 -0
  566. package/template/themes/mahdia/screenshot.jpg +0 -0
  567. package/template/themes/mahdia/snapify.theme.json +65 -0
  568. package/template/themes/mahdia/src/Brand.tsx +39 -0
  569. package/template/themes/mahdia/src/Footer.tsx +210 -0
  570. package/template/themes/mahdia/src/Header.tsx +291 -0
  571. package/template/themes/mahdia/src/Layout.tsx +44 -0
  572. package/template/themes/mahdia/src/Views.tsx +79 -0
  573. package/template/themes/mahdia/src/blocks/CollectionBlocks.tsx +674 -0
  574. package/template/themes/mahdia/src/blocks/ContentBlocks.tsx +307 -0
  575. package/template/themes/mahdia/src/blocks/ConversionBlocks.tsx +571 -0
  576. package/template/themes/mahdia/src/blocks/HeaderBlocks.tsx +289 -0
  577. package/template/themes/mahdia/src/index.tsx +53 -0
  578. package/template/themes/mahdia/src/kit.tsx +362 -0
  579. package/template/themes/mahdia/src/site.ts +75 -0
  580. package/template/themes/mahdia/src/styles.css +446 -0
  581. package/template/themes/preveris/screenshot.jpg +0 -0
  582. package/template/themes/preveris/snapify.theme.json +126 -0
  583. package/template/themes/preveris/src/Brand.tsx +44 -0
  584. package/template/themes/preveris/src/Footer.tsx +202 -0
  585. package/template/themes/preveris/src/Header.tsx +239 -0
  586. package/template/themes/preveris/src/Layout.tsx +42 -0
  587. package/template/themes/preveris/src/Views.tsx +71 -0
  588. package/template/themes/preveris/src/blocks/CollectionBlocks.tsx +678 -0
  589. package/template/themes/preveris/src/blocks/ContentBlocks.tsx +307 -0
  590. package/template/themes/preveris/src/blocks/ConversionBlocks.tsx +571 -0
  591. package/template/themes/preveris/src/blocks/HeaderBlocks.tsx +299 -0
  592. package/template/themes/preveris/src/index.tsx +53 -0
  593. package/template/themes/preveris/src/kit.tsx +365 -0
  594. package/template/themes/preveris/src/site.ts +79 -0
  595. package/template/themes/preveris/src/styles.css +446 -0
  596. package/template/themes/sidibou/screenshot.jpg +0 -0
  597. package/template/themes/sidibou/snapify.theme.json +21 -0
  598. package/template/themes/sidibou/src/CeeSimulator.tsx +247 -0
  599. package/template/themes/sidibou/src/Footer.tsx +203 -0
  600. package/template/themes/sidibou/src/Header.tsx +324 -0
  601. package/template/themes/sidibou/src/Layout.tsx +53 -0
  602. package/template/themes/sidibou/src/NotFound.tsx +58 -0
  603. package/template/themes/sidibou/src/Post.tsx +26 -0
  604. package/template/themes/sidibou/src/SnapifyLogo.tsx +44 -0
  605. package/template/themes/sidibou/src/blocks/CollectionBlocks.tsx +711 -0
  606. package/template/themes/sidibou/src/blocks/ContentBlocks.tsx +318 -0
  607. package/template/themes/sidibou/src/blocks/ConversionBlocks.tsx +559 -0
  608. package/template/themes/sidibou/src/blocks/HeaderBlocks.tsx +341 -0
  609. package/template/themes/sidibou/src/index.tsx +54 -0
  610. package/template/themes/sidibou/src/kit.tsx +398 -0
  611. package/template/themes/sidibou/src/site.ts +28 -0
  612. package/template/themes/sidibou/src/styles.css +317 -0
  613. package/template/tsconfig.json +33 -0
  614. package/template/vite.config.ts +42 -0
@@ -0,0 +1,198 @@
1
+ /** Exemples + coach de prompt + consigne système (qualité pro) */
2
+
3
+ export type ThemeMarket = 'tn' | 'fr';
4
+
5
+ export const PROMPT_EXAMPLES_TN = [
6
+ {
7
+ id: 'clinic',
8
+ title: 'Cabinet médical',
9
+ prompt:
10
+ 'Site vitrine pour une clinique radiologique à Tunis : confiance, modernité, bleu médical doux, textes rassurants, prise de rendez-vous claire. Public : patients et médecins partenaires. CTA principal : Prendre rendez-vous.',
11
+ },
12
+ {
13
+ id: 'agency',
14
+ title: 'Agence digitale',
15
+ prompt:
16
+ 'Agence web créative à Sfax : énergie, contraste fort, typo moderne, portfolio et services. Ton ambitieux mais accessible. Couleurs sombre + accent vif. CTA : Demander un devis.',
17
+ },
18
+ {
19
+ id: 'shop',
20
+ title: 'Boutique artisanale',
21
+ prompt:
22
+ 'Boutique en ligne d’huile d’olive et produits du terroir tunisien : chaleur, naturel, beige/vert olive, storytelling artisanal. CTA : Découvrir la boutique.',
23
+ },
24
+ {
25
+ id: 'lawyer',
26
+ title: 'Cabinet d’avocats',
27
+ prompt:
28
+ 'Cabinet d’avocats corporate à Tunis : sobriété, navy et or discret, typographie sérieuse, expertise. CTA : Prendre conseil.',
29
+ },
30
+ {
31
+ id: 'restaurant',
32
+ title: 'Restaurant',
33
+ prompt:
34
+ 'Restaurant méditerranéen à La Marsa : ambiance soirée, photos généreuses, menu et réservation, palette terre cuite et crème. CTA : Réserver une table.',
35
+ },
36
+ ] as const;
37
+
38
+ export const PROMPT_EXAMPLES_FR = [
39
+ {
40
+ id: 'clinic',
41
+ title: 'Cabinet médical',
42
+ prompt:
43
+ 'Site vitrine pour une clinique radiologique à Lyon : confiance, modernité, bleu médical doux, textes rassurants, prise de rendez-vous claire. Public : patients et médecins partenaires. CTA principal : Prendre rendez-vous.',
44
+ },
45
+ {
46
+ id: 'agency',
47
+ title: 'Agence digitale',
48
+ prompt:
49
+ 'Agence web créative à Paris : énergie, contraste fort, typo moderne, portfolio et services. Ton ambitieux mais accessible. Couleurs sombre + accent vif. CTA : Demander un devis.',
50
+ },
51
+ {
52
+ id: 'shop',
53
+ title: 'Boutique artisanale',
54
+ prompt:
55
+ 'Boutique en ligne de produits artisanaux français (épicerie fine) : chaleur, naturel, beige/vert olive, storytelling artisanal. CTA : Découvrir la boutique.',
56
+ },
57
+ {
58
+ id: 'lawyer',
59
+ title: 'Cabinet d’avocats',
60
+ prompt:
61
+ 'Cabinet d’avocats corporate à Paris : sobriété, navy et or discret, typographie sérieuse, expertise. CTA : Prendre conseil.',
62
+ },
63
+ {
64
+ id: 'restaurant',
65
+ title: 'Restaurant',
66
+ prompt:
67
+ 'Restaurant contemporain à Bordeaux : ambiance soirée, photos généreuses, menu et réservation, palette terre cuite et crème. CTA : Réserver une table.',
68
+ },
69
+ ] as const;
70
+
71
+ /** @deprecated préférer promptExamples(market) */
72
+ export const PROMPT_EXAMPLES = PROMPT_EXAMPLES_TN;
73
+
74
+ export const PROMPT_TIPS_TN = [
75
+ 'Indiquez le secteur et la ville (ex. « dentiste à Sousse »).',
76
+ 'Décrivez le sentiment : confiance, luxe, jeunesse, tech, artisanal…',
77
+ 'Citez 1–2 couleurs ou une ambiance (« bleu nuit », « pastel »).',
78
+ 'Précisez le public (B2B, familles, étudiants…).',
79
+ 'Donnez l’action principale du bouton (RDV, devis, achat, contact).',
80
+ 'Mentionnez 2–3 services ou preuves (avis, années, certifications).',
81
+ ] as const;
82
+
83
+ export const PROMPT_TIPS_FR = [
84
+ 'Indiquez le secteur et la ville (ex. « dentiste à Lyon »).',
85
+ 'Décrivez le sentiment : confiance, luxe, jeunesse, tech, artisanal…',
86
+ 'Citez 1–2 couleurs ou une ambiance (« bleu nuit », « pastel »).',
87
+ 'Précisez le public (B2B, familles, étudiants…).',
88
+ 'Donnez l’action principale du bouton (RDV, devis, achat, contact).',
89
+ 'Mentionnez 2–3 services ou preuves (avis, années, certifications).',
90
+ ] as const;
91
+
92
+ export const PROMPT_TIPS = PROMPT_TIPS_TN;
93
+
94
+ export function promptExamples(market: ThemeMarket = 'tn') {
95
+ return market === 'fr' ? PROMPT_EXAMPLES_FR : PROMPT_EXAMPLES_TN;
96
+ }
97
+
98
+ export function promptTips(market: ThemeMarket = 'tn') {
99
+ return market === 'fr' ? PROMPT_TIPS_FR : PROMPT_TIPS_TN;
100
+ }
101
+
102
+ export function promptPlaceholder(market: ThemeMarket = 'tn') {
103
+ return market === 'fr'
104
+ ? 'Ex. Clinique dentaire à Lyon : confiance, blanc et bleu doux, prise de RDV évidente…'
105
+ : 'Ex. Clinique dentaire à Sousse : confiance, blanc et bleu doux, prise de RDV évidente…';
106
+ }
107
+
108
+ export function systemPrompt(lang: string, market: ThemeMarket = 'tn'): string {
109
+ const langLabel = lang === 'en' ? 'English' : lang === 'ar' ? 'Arabic' : 'French';
110
+ const localeRule =
111
+ market === 'fr'
112
+ ? `- Market = France / international. NEVER mention Tunisia, Tunis, Sfax, Sousse, La Marsa, dinar, Flouci, or Tunisian places/brands unless the user brief explicitly asks for Tunisia.
113
+ - Prefer French cities (Paris, Lyon, Bordeaux, Marseille…) or generic EU context when inventing location details.`
114
+ : `- Market = Tunisia. Prefer Tunisian cities and local context when inventing location details (unless the brief says otherwise).`;
115
+
116
+ return `You are an expert Snapify brand & conversion designer. Output ONE JSON object only (no markdown).
117
+
118
+ QUALITY BAR (real client deliverable — no lorem, no generic filler):
119
+ - Every title/subtitle must feel specific to THIS brief (city, sector, offer).
120
+ ${localeRule}
121
+ - Hero ALWAYS has EXACTLY 2 buttons:
122
+ 1) primary — main conversion (RDV, devis, réserver, acheter…)
123
+ 2) secondary — softer path (/services/, /a-propos/, /menu/)
124
+ Labels ≤ 28 chars, action verbs. variant primary|secondary. icon arrow|arrow-up-right|phone|mail.
125
+ - Hero trustItems: EXACTLY 3 short proof points with numbers when possible.
126
+ - Hero layout: "split". badgeText: short sector/city chip.
127
+ - Structure EXACTLY 7–8 blocks in this order:
128
+ 1) hero
129
+ 2) stats (4 KPIs with value+suffix+label)
130
+ 3) cards (3–4 services: icon, title, text 1–2 sentences, linkLabel "En savoir plus", link "/services/")
131
+ 4) textMedia (about/story: title, intro, 3–5 bullets, 1–2 buttons)
132
+ 5) steps (3–4 numbered) OR showcase
133
+ 6) testimonials (2–3 quotes author+role) OR faq (4–5 Q&A)
134
+ 7) cta — dark/gradient, EXACTLY 2 buttons (primary + light), layout "split"
135
+ 8) contactForm optional
136
+ - Alternate style.background: soft → white → surface → white → soft → white → navy.
137
+ - style: paddingTop/Bottom lg|xl, width default|wide, animation fade-up, decor none.
138
+ - Colors #RRGGBB, strong contrast. primaryHover darker than primary. accent distinct.
139
+ - Fonts ONLY: Inter, Manrope, Plus Jakarta Sans, DM Sans, Poppins, Montserrat, Roboto, Open Sans, Lato, Source Sans 3, Space Grotesk, Outfit.
140
+ - themeSettings: buttonShape pill|rounded|square ; density compact|comfortable|airy ; cardRadius 16–24 ; stickyHeader true ; animations true ; backToTop true.
141
+ - All user-facing strings in ${langLabel}.
142
+ - imagePrompts in ENGLISH, photorealistic, NO text/logos/UI:
143
+ { "hero": "wide cinematic scene…", "secondary": "lifestyle/supporting…", "cards": ["service1 scene", "service2", "service3"] }
144
+
145
+ Allowed types: hero, stats, cards, steps, showcase, faq, testimonials, cta, textMedia, checklist, contactForm, spacer.
146
+
147
+ Hero data:
148
+ {
149
+ "layout":"split",
150
+ "badgeText":"...",
151
+ "title":"...",
152
+ "highlight":"...",
153
+ "subtitle":"...",
154
+ "rotatingWords":[],
155
+ "buttons":[
156
+ {"id":"b1","label":"...","link":"/contact/","variant":"primary","icon":"arrow"},
157
+ {"id":"b2","label":"...","link":"/services/","variant":"secondary","icon":"arrow-up-right"}
158
+ ],
159
+ "trustItems":["...","...","..."],
160
+ "media":"image",
161
+ "mainImage":"",
162
+ "parallax":false,
163
+ "marquee":[]
164
+ }
165
+
166
+ CTA data: variant dark|gradient, layout split, eyebrow, title, highlight, text, buttons (primary + light).
167
+ ContactForm: formId "contact", title, intro, listItems (3), submitLabel.
168
+
169
+ Return JSON:
170
+ {
171
+ "siteName":"...",
172
+ "tagline":"...",
173
+ "industry":"...",
174
+ "mood":"...",
175
+ "rationale":"2-3 sentences in ${langLabel}",
176
+ "branding":{"colors":{primary,primaryHover,accent,navy,background,text,muted,border},"fonts":{heading,body}},
177
+ "themeSettings":{stickyHeader,headerPhone,buttonShape,cardRadius,density,animations,mobileBar,backToTop},
178
+ "imagePrompts":{"hero":"...","secondary":"...","cards":["...","...","..."]},
179
+ "homeBlocks":[ { "type":"...", "data":{...}, "style":{...} }, ... ]
180
+ }`;
181
+ }
182
+
183
+ export function userPrompt(brief: string, siteHint?: string, market: ThemeMarket = 'tn'): string {
184
+ const hint = siteHint?.trim() ? `\nContexte site actuel : ${siteHint.trim()}` : '';
185
+ const locale =
186
+ market === 'fr'
187
+ ? '\nContexte marché : France / international — pas de références tunisiennes inventées.'
188
+ : '\nContexte marché : Tunisie — contextes locaux OK si cohérents avec le brief.';
189
+ return `Brief utilisateur :\n${brief.trim()}${hint}${locale}
190
+
191
+ Produis un ThemeSpec premium conversion-ready :
192
+ - textes concrets liés au brief (pas de filler)
193
+ - hero 2 boutons + 3 trustItems
194
+ - stats chiffrées, 3–4 services avec liens
195
+ - textMedia avec bullets, steps, preuves sociales
196
+ - CTA sombre à 2 boutons (primary + light)
197
+ - imagePrompts anglais photoréalistes`;
198
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Atelier thème IA — génération structurée (identité + réglages AI Canvas + blocs accueil)
3
+ * Génération en arrière-plan pour éviter le timeout 60–120 s des routes admin.
4
+ */
5
+ import { defineServerModule, type ServerContext, type StoredRecord } from '@snapify/sdk';
6
+ import { generateThemeSpec } from './lib/llm';
7
+ import { promptExamples, promptPlaceholder, promptTips, type ThemeMarket } from './lib/prompts';
8
+ import { AI_CANVAS_THEME_ID, type GenerationRecord, type Settings, type ThemeSpec } from './types';
9
+
10
+ type GenDoc = {
11
+ prompt: string;
12
+ lang: string;
13
+ provider: GenerationRecord['provider'];
14
+ model: string;
15
+ status: 'pending' | 'ready' | 'failed';
16
+ error?: string;
17
+ spec?: ThemeSpec;
18
+ applied?: GenerationRecord['applied'];
19
+ };
20
+
21
+ function asGen(r: StoredRecord<GenDoc>): GenerationRecord {
22
+ return {
23
+ id: r.id,
24
+ createdAt: r.createdAt,
25
+ prompt: r.prompt,
26
+ lang: r.lang,
27
+ provider: r.provider,
28
+ model: r.model,
29
+ status: r.status,
30
+ error: r.error,
31
+ spec: r.spec,
32
+ applied: r.applied,
33
+ };
34
+ }
35
+
36
+ export default defineServerModule<Settings>({
37
+ activate(ctx: ServerContext<Settings>) {
38
+ const generations = ctx.db.collection<GenDoc>('generations');
39
+
40
+ ctx.admin.get('/meta', async () => {
41
+ const s = ctx.settings();
42
+ let market: ThemeMarket = 'tn';
43
+ try {
44
+ const url = (ctx.site()?.publicUrl || '').toLowerCase();
45
+ if (url.includes('.fr') || url.includes('france')) market = 'fr';
46
+ } catch {
47
+ /* ignore */
48
+ }
49
+ return {
50
+ market,
51
+ examples: promptExamples(market),
52
+ tips: promptTips(market),
53
+ placeholder: promptPlaceholder(market),
54
+ canvasThemeId: AI_CANVAS_THEME_ID,
55
+ provider: s.provider,
56
+ hasApiKey: Boolean((s.apiKey || '').trim()),
57
+ lang: s.defaultLang || 'fr',
58
+ autoApplyHome: s.autoApplyHome !== false,
59
+ generateImages: s.generateImages !== false,
60
+ };
61
+ });
62
+
63
+ ctx.admin.get('/generations', async () => {
64
+ const { items } = await generations.find({
65
+ orderBy: [{ field: 'createdAt', dir: 'desc' }],
66
+ limit: 40,
67
+ });
68
+ return { generations: items.map(asGen) };
69
+ });
70
+
71
+ ctx.admin.get('/generations/:id', async (req) => {
72
+ const row = await generations.get(req.params.id);
73
+ if (!row) throw ctx.error(404, 'Génération introuvable.');
74
+ return { generation: asGen(row) };
75
+ });
76
+
77
+ ctx.admin.post('/generate', async (req) => {
78
+ const body = (req.body || {}) as { prompt?: string; lang?: string; siteHint?: string };
79
+ const prompt = String(body.prompt || '').trim();
80
+ if (prompt.length < 12) throw ctx.error(400, 'Décrivez un peu plus votre marque (au moins une phrase).');
81
+ if (prompt.length > 2000) throw ctx.error(400, 'Prompt trop long (max 2000 caractères).');
82
+ const s = ctx.settings();
83
+ const lang = (body.lang || s.defaultLang || 'fr') as string;
84
+ const siteHint = body.siteHint;
85
+
86
+ const row = await generations.insert({
87
+ prompt,
88
+ lang,
89
+ provider: s.provider || 'openai',
90
+ model: '',
91
+ status: 'pending',
92
+ });
93
+
94
+ // Travail hors requête HTTP (évite abort / délai route admin).
95
+ void (async () => {
96
+ try {
97
+ const { spec, provider, model } = await generateThemeSpec(ctx, prompt, lang, siteHint);
98
+ await generations.update(row.id, {
99
+ status: 'ready',
100
+ provider,
101
+ model,
102
+ spec,
103
+ error: undefined,
104
+ });
105
+ } catch (e) {
106
+ const message = e instanceof Error ? e.message : 'Génération échouée';
107
+ ctx.log.warn('generate fail', message);
108
+ await generations.update(row.id, {
109
+ status: 'failed',
110
+ error: message.slice(0, 400),
111
+ });
112
+ }
113
+ })();
114
+
115
+ return { generation: asGen(row) };
116
+ });
117
+
118
+ ctx.admin.post('/generations/:id/mark-applied', async (req) => {
119
+ const row = await generations.get(req.params.id);
120
+ if (!row) throw ctx.error(404, 'Génération introuvable.');
121
+ const body = (req.body || {}) as { branding?: boolean; theme?: boolean; home?: boolean };
122
+ const applied = {
123
+ branding: !!body.branding,
124
+ theme: !!body.theme,
125
+ home: !!body.home,
126
+ at: new Date().toISOString(),
127
+ };
128
+ const updated = await generations.update(row.id, { applied });
129
+ return { generation: asGen(updated!) };
130
+ });
131
+
132
+ ctx.admin.delete('/generations/:id', async (req) => {
133
+ await generations.delete(req.params.id);
134
+ return { ok: true };
135
+ });
136
+ },
137
+ });
@@ -0,0 +1,112 @@
1
+ /** Types Atelier thème IA */
2
+
3
+ export type Provider = 'openai' | 'anthropic' | 'gemini';
4
+
5
+ export type Settings = {
6
+ provider: Provider;
7
+ apiKey: string;
8
+ openaiModel: string;
9
+ anthropicModel: string;
10
+ geminiModel: string;
11
+ defaultLang: 'fr' | 'ar' | 'en';
12
+ autoApplyHome: boolean;
13
+ /** OpenAI DALL·E / Gemini Imagen ; sinon images Unsplash adaptées au secteur. */
14
+ generateImages: boolean;
15
+ };
16
+
17
+ export type BrandColors = {
18
+ primary: string;
19
+ primaryHover: string;
20
+ accent: string;
21
+ navy: string;
22
+ background: string;
23
+ text: string;
24
+ muted: string;
25
+ border: string;
26
+ };
27
+
28
+ export type ThemeSettingsSpec = {
29
+ stickyHeader: boolean;
30
+ headerPhone: boolean;
31
+ buttonShape: 'pill' | 'rounded' | 'square';
32
+ cardRadius: number;
33
+ density: 'compact' | 'comfortable' | 'airy';
34
+ animations: boolean;
35
+ mobileBar: boolean;
36
+ backToTop: boolean;
37
+ };
38
+
39
+ /** Bloc CMS simplifié — types sûrs pour la page d’accueil. */
40
+ export type HomeBlock = {
41
+ type: string;
42
+ data: Record<string, unknown>;
43
+ style?: Record<string, unknown>;
44
+ };
45
+
46
+ export type ThemeSpec = {
47
+ siteName: string;
48
+ tagline: string;
49
+ industry: string;
50
+ mood: string;
51
+ rationale: string;
52
+ branding: {
53
+ colors: BrandColors;
54
+ fonts: { heading: string; body: string };
55
+ };
56
+ themeSettings: ThemeSettingsSpec;
57
+ homeBlocks: HomeBlock[];
58
+ };
59
+
60
+ export type GenerationRecord = {
61
+ id: string;
62
+ createdAt: string;
63
+ prompt: string;
64
+ lang: string;
65
+ provider: Provider;
66
+ model: string;
67
+ status: 'pending' | 'ready' | 'failed';
68
+ error?: string;
69
+ spec?: ThemeSpec;
70
+ applied?: {
71
+ branding: boolean;
72
+ theme: boolean;
73
+ home: boolean;
74
+ at: string;
75
+ };
76
+ };
77
+
78
+ export const AI_CANVAS_THEME_ID = 'hamdiayari.ai-canvas';
79
+
80
+ export const ALLOWED_FONTS = [
81
+ 'Inter',
82
+ 'Manrope',
83
+ 'Plus Jakarta Sans',
84
+ 'DM Sans',
85
+ 'Poppins',
86
+ 'Montserrat',
87
+ 'Roboto',
88
+ 'Open Sans',
89
+ 'Lato',
90
+ 'Source Sans 3',
91
+ 'Space Grotesk',
92
+ 'Outfit',
93
+ ] as const;
94
+
95
+ export const ALLOWED_HOME_TYPES = [
96
+ 'hero',
97
+ 'pageHeader',
98
+ 'richText',
99
+ 'textMedia',
100
+ 'stats',
101
+ 'cards',
102
+ 'showcase',
103
+ 'steps',
104
+ 'faq',
105
+ 'testimonials',
106
+ 'cta',
107
+ 'contactForm',
108
+ 'gallery',
109
+ 'checklist',
110
+ 'panels',
111
+ 'spacer',
112
+ ] as const;
@@ -0,0 +1,45 @@
1
+ {
2
+ "id": "novalabs.calendar",
3
+ "name": "Calendrier",
4
+ "version": "1.0.1",
5
+ "description": "Agenda d’événements : création et gestion dans l’administration, calendrier mensuel et liste sur le site, widget à placer dans vos pages.",
6
+ "author": { "name": "NOVALABS WEB DESIGN", "email": "contact@novalabs.tn", "url": "https://novalabs.tn" },
7
+ "pricing": "free",
8
+ "category": "Contenu",
9
+ "icon": "calendar",
10
+ "screenshot": "screenshot.jpg",
11
+ "engines": { "snapify": "^1.2.0" },
12
+ "permissions": ["http:routes", "admin:routes", "database"],
13
+ "slots": [],
14
+ "routes": ["/agenda/*", "/calendrier/*"],
15
+ "entries": { "public": "src/public/index.tsx", "server": "src/server.ts", "admin": "src/admin/index.tsx" },
16
+ "adminPages": [
17
+ { "id": "events", "label": "Événements", "icon": "calendar" }
18
+ ],
19
+ "widgets": [
20
+ {
21
+ "id": "upcoming",
22
+ "label": "Prochains événements",
23
+ "description": "Liste des prochains événements à venir.",
24
+ "fields": [
25
+ { "key": "title", "type": "text", "label": "Titre", "default": "À venir", "maxLength": 80 },
26
+ { "key": "limit", "type": "number", "label": "Nombre d’événements", "default": 5, "min": 1, "max": 20 },
27
+ { "key": "buttonLabel", "type": "text", "label": "Bouton agenda", "default": "Voir l’agenda", "maxLength": 40 }
28
+ ]
29
+ },
30
+ {
31
+ "id": "month",
32
+ "label": "Calendrier du mois",
33
+ "description": "Vue mensuelle avec les jours qui ont des événements.",
34
+ "fields": [
35
+ { "key": "title", "type": "text", "label": "Titre", "default": "Calendrier", "maxLength": 80 }
36
+ ]
37
+ }
38
+ ],
39
+ "settings": [
40
+ { "key": "pageTitle", "type": "text", "group": "Page publique", "label": "Titre de la page agenda", "default": "Agenda", "public": true, "maxLength": 80 },
41
+ { "key": "pageIntro", "type": "textarea", "group": "Page publique", "label": "Introduction", "default": "Retrouvez nos prochains événements et rendez-vous.", "public": true, "maxLength": 400, "rows": 2 },
42
+ { "key": "timezone", "type": "text", "group": "Page publique", "label": "Fuseau horaire (affichage)", "default": "Africa/Tunis", "public": true, "maxLength": 60 },
43
+ { "key": "showPast", "type": "boolean", "group": "Page publique", "label": "Afficher aussi les événements passés", "default": false, "public": true }
44
+ ]
45
+ }