@stacksjs/defaults 0.70.206 → 0.70.208

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 (408) hide show
  1. package/TODO.md +21 -0
  2. package/ai/AGENTS.md +79 -0
  3. package/ai/README.md +45 -0
  4. package/ai/claude/launch.json +12 -0
  5. package/ai/skills/stacks-actions/SKILL.md +128 -0
  6. package/ai/skills/stacks-ai/SKILL.md +276 -0
  7. package/ai/skills/stacks-alias/SKILL.md +94 -0
  8. package/ai/skills/stacks-analytics/SKILL.md +91 -0
  9. package/ai/skills/stacks-api/SKILL.md +738 -0
  10. package/ai/skills/stacks-arrays/SKILL.md +277 -0
  11. package/ai/skills/stacks-auth/SKILL.md +422 -0
  12. package/ai/skills/stacks-auto-imports/SKILL.md +138 -0
  13. package/ai/skills/stacks-brandkit/SKILL.md +811 -0
  14. package/ai/skills/stacks-browse/SKILL.md +127 -0
  15. package/ai/skills/stacks-browse/scripts/browse.ts +492 -0
  16. package/ai/skills/stacks-browser/SKILL.md +145 -0
  17. package/ai/skills/stacks-buddy/SKILL.md +676 -0
  18. package/ai/skills/stacks-build/SKILL.md +163 -0
  19. package/ai/skills/stacks-cache/SKILL.md +125 -0
  20. package/ai/skills/stacks-calendar/SKILL.md +113 -0
  21. package/ai/skills/stacks-chat/SKILL.md +371 -0
  22. package/ai/skills/stacks-cli/SKILL.md +112 -0
  23. package/ai/skills/stacks-cloud/SKILL.md +192 -0
  24. package/ai/skills/stacks-cms/SKILL.md +217 -0
  25. package/ai/skills/stacks-collections/SKILL.md +82 -0
  26. package/ai/skills/stacks-commerce/SKILL.md +114 -0
  27. package/ai/skills/stacks-composables/SKILL.md +161 -0
  28. package/ai/skills/stacks-config/SKILL.md +144 -0
  29. package/ai/skills/stacks-configuration/SKILL.md +154 -0
  30. package/ai/skills/stacks-cron/SKILL.md +123 -0
  31. package/ai/skills/stacks-crosswind/SKILL.md +190 -0
  32. package/ai/skills/stacks-dashboard/SKILL.md +173 -0
  33. package/ai/skills/stacks-database/SKILL.md +286 -0
  34. package/ai/skills/stacks-datetime/SKILL.md +269 -0
  35. package/ai/skills/stacks-dependencies/SKILL.md +111 -0
  36. package/ai/skills/stacks-deploy/SKILL.md +102 -0
  37. package/ai/skills/stacks-design-brutalist/SKILL.md +110 -0
  38. package/ai/skills/stacks-design-minimalist/SKILL.md +115 -0
  39. package/ai/skills/stacks-design-output/SKILL.md +55 -0
  40. package/ai/skills/stacks-design-soft/SKILL.md +156 -0
  41. package/ai/skills/stacks-design-taste/SKILL.md +1012 -0
  42. package/ai/skills/stacks-design-taste-codex/SKILL.md +294 -0
  43. package/ai/skills/stacks-desktop/SKILL.md +78 -0
  44. package/ai/skills/stacks-development/SKILL.md +298 -0
  45. package/ai/skills/stacks-dns/SKILL.md +149 -0
  46. package/ai/skills/stacks-docs/SKILL.md +109 -0
  47. package/ai/skills/stacks-email/SKILL.md +236 -0
  48. package/ai/skills/stacks-enums/SKILL.md +100 -0
  49. package/ai/skills/stacks-env/SKILL.md +181 -0
  50. package/ai/skills/stacks-error-handling/SKILL.md +137 -0
  51. package/ai/skills/stacks-events/SKILL.md +228 -0
  52. package/ai/skills/stacks-faker/SKILL.md +158 -0
  53. package/ai/skills/stacks-git/SKILL.md +158 -0
  54. package/ai/skills/stacks-guard/SKILL.md +98 -0
  55. package/ai/skills/stacks-health/SKILL.md +75 -0
  56. package/ai/skills/stacks-http/SKILL.md +316 -0
  57. package/ai/skills/stacks-i18n/SKILL.md +198 -0
  58. package/ai/skills/stacks-image-to-code/SKILL.md +629 -0
  59. package/ai/skills/stacks-imagegen-mobile/SKILL.md +1474 -0
  60. package/ai/skills/stacks-imagegen-web/SKILL.md +998 -0
  61. package/ai/skills/stacks-investigate/SKILL.md +119 -0
  62. package/ai/skills/stacks-jobs/SKILL.md +136 -0
  63. package/ai/skills/stacks-lint/SKILL.md +184 -0
  64. package/ai/skills/stacks-listeners/SKILL.md +99 -0
  65. package/ai/skills/stacks-logging/SKILL.md +78 -0
  66. package/ai/skills/stacks-mail/SKILL.md +120 -0
  67. package/ai/skills/stacks-middleware/SKILL.md +249 -0
  68. package/ai/skills/stacks-migrations/SKILL.md +105 -0
  69. package/ai/skills/stacks-models/SKILL.md +267 -0
  70. package/ai/skills/stacks-new-feature/SKILL.md +206 -0
  71. package/ai/skills/stacks-notifications/SKILL.md +210 -0
  72. package/ai/skills/stacks-objects/SKILL.md +205 -0
  73. package/ai/skills/stacks-office-hours/SKILL.md +134 -0
  74. package/ai/skills/stacks-orm/SKILL.md +342 -0
  75. package/ai/skills/stacks-path/SKILL.md +118 -0
  76. package/ai/skills/stacks-payments/SKILL.md +373 -0
  77. package/ai/skills/stacks-plan-review/SKILL.md +152 -0
  78. package/ai/skills/stacks-plugins/SKILL.md +149 -0
  79. package/ai/skills/stacks-push/SKILL.md +376 -0
  80. package/ai/skills/stacks-query-builder/SKILL.md +128 -0
  81. package/ai/skills/stacks-queue/SKILL.md +559 -0
  82. package/ai/skills/stacks-realtime/SKILL.md +442 -0
  83. package/ai/skills/stacks-redesign/SKILL.md +182 -0
  84. package/ai/skills/stacks-registry/SKILL.md +58 -0
  85. package/ai/skills/stacks-repl/SKILL.md +80 -0
  86. package/ai/skills/stacks-retro/SKILL.md +122 -0
  87. package/ai/skills/stacks-review/SKILL.md +135 -0
  88. package/ai/skills/stacks-router/SKILL.md +231 -0
  89. package/ai/skills/stacks-routes/SKILL.md +105 -0
  90. package/ai/skills/stacks-scaffolding/SKILL.md +162 -0
  91. package/ai/skills/stacks-scheduler/SKILL.md +363 -0
  92. package/ai/skills/stacks-search-engine/SKILL.md +112 -0
  93. package/ai/skills/stacks-security/SKILL.md +129 -0
  94. package/ai/skills/stacks-security-audit/SKILL.md +128 -0
  95. package/ai/skills/stacks-server/SKILL.md +458 -0
  96. package/ai/skills/stacks-shell/SKILL.md +62 -0
  97. package/ai/skills/stacks-slug/SKILL.md +87 -0
  98. package/ai/skills/stacks-sms/SKILL.md +385 -0
  99. package/ai/skills/stacks-socials/SKILL.md +303 -0
  100. package/ai/skills/stacks-storage/SKILL.md +576 -0
  101. package/ai/skills/stacks-strings/SKILL.md +416 -0
  102. package/ai/skills/stacks-stx/SKILL.md +176 -0
  103. package/ai/skills/stacks-technical-diagrams/LICENSE +22 -0
  104. package/ai/skills/stacks-technical-diagrams/SKILL.md +290 -0
  105. package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +4 -0
  106. package/ai/skills/stacks-technical-diagrams/assets/template.html +1252 -0
  107. package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +289 -0
  108. package/ai/skills/stacks-technical-diagrams/bunfig.toml +1 -0
  109. package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +64 -0
  110. package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +88 -0
  111. package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +75 -0
  112. package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +70 -0
  113. package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +41 -0
  114. package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +62 -0
  115. package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +371 -0
  116. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +82 -0
  117. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +295 -0
  118. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +91 -0
  119. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +384 -0
  120. package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +84 -0
  121. package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +257 -0
  122. package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +42 -0
  123. package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +13 -0
  124. package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +230 -0
  125. package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +40 -0
  126. package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +88 -0
  127. package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +40 -0
  128. package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +103 -0
  129. package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +481 -0
  130. package/ai/skills/stacks-technical-diagrams/schemas/README.md +68 -0
  131. package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +121 -0
  132. package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +43 -0
  133. package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +221 -0
  134. package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +241 -0
  135. package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +186 -0
  136. package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +332 -0
  137. package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +297 -0
  138. package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +28 -0
  139. package/ai/skills/stacks-testing/SKILL.md +129 -0
  140. package/ai/skills/stacks-tunnel/SKILL.md +125 -0
  141. package/ai/skills/stacks-types/SKILL.md +178 -0
  142. package/ai/skills/stacks-ui/SKILL.md +246 -0
  143. package/ai/skills/stacks-utils/SKILL.md +444 -0
  144. package/ai/skills/stacks-validation/SKILL.md +371 -0
  145. package/ai/skills/stacks-whois/SKILL.md +315 -0
  146. package/assets/world-map-data.ts +121 -0
  147. package/bootstrap.ts +114 -0
  148. package/docs/api-examples.md +46 -0
  149. package/docs/index.md +24 -0
  150. package/docs/markdown-examples.md +87 -0
  151. package/functions/analytics.ts +97 -0
  152. package/functions/api.ts +143 -0
  153. package/functions/auth.ts +208 -0
  154. package/functions/billing/payments.ts +149 -0
  155. package/functions/blog.ts +120 -0
  156. package/functions/cms/categorizables.ts +107 -0
  157. package/functions/cms/pages.ts +108 -0
  158. package/functions/cms/posts.ts +100 -0
  159. package/functions/cms/taggables.ts +102 -0
  160. package/functions/commerce/coupons.ts +128 -0
  161. package/functions/commerce/customers.ts +128 -0
  162. package/functions/commerce/gift-cards.ts +119 -0
  163. package/functions/commerce/orders.ts +112 -0
  164. package/functions/commerce/payments.ts +119 -0
  165. package/functions/commerce/products/categories.ts +123 -0
  166. package/functions/commerce/products/manufacturers.ts +123 -0
  167. package/functions/commerce/products/products.ts +123 -0
  168. package/functions/commerce/products/reviews.ts +123 -0
  169. package/functions/commerce/products/units.ts +123 -0
  170. package/functions/commerce/products/variants.ts +123 -0
  171. package/functions/commerce/shippings/delivery-routes.ts +123 -0
  172. package/functions/commerce/shippings/digital-deliveries.ts +119 -0
  173. package/functions/commerce/shippings/drivers.ts +123 -0
  174. package/functions/commerce/shippings/license-keys.ts +123 -0
  175. package/functions/commerce/shippings/shipping-methods.ts +123 -0
  176. package/functions/commerce/shippings/shipping-rates.ts +119 -0
  177. package/functions/commerce/shippings/shipping-zones.ts +119 -0
  178. package/functions/commerce/taxes.ts +119 -0
  179. package/functions/commerce/waitlist/products.ts +123 -0
  180. package/functions/commerce/waitlist/restaurants.ts +123 -0
  181. package/functions/craft.ts +107 -0
  182. package/functions/dashboard.ts +153 -0
  183. package/functions/inbox.ts +95 -0
  184. package/functions/jobs.ts +86 -0
  185. package/functions/monitoring/errors.ts +295 -0
  186. package/functions/queue.ts +111 -0
  187. package/functions/realtime/websockets.ts +96 -0
  188. package/functions/realtime.ts +52 -0
  189. package/functions/releases.ts +49 -0
  190. package/functions/search.ts +126 -0
  191. package/functions/toasts.ts +95 -0
  192. package/functions/uploads.ts +216 -0
  193. package/ide/.gitignore +4 -0
  194. package/ide/cursor/rules/auto-imports.mdc +574 -0
  195. package/ide/cursor/rules/code-style.mdc +12 -0
  196. package/ide/cursor/rules/documentation.mdc +9 -0
  197. package/ide/cursor/rules/error-handling-validation.mdc +11 -0
  198. package/ide/cursor/rules/key-conventions.mdc +11 -0
  199. package/ide/cursor/rules/project-structure.mdc +169 -0
  200. package/ide/cursor/rules/readme.mdc +318 -0
  201. package/ide/cursor/rules/syntax-formatting.mdc +9 -0
  202. package/ide/cursor/rules/testing.mdc +10 -0
  203. package/ide/cursor/rules/typescript.mdc +9 -0
  204. package/ide/cursor/rules/ui-styling.mdc +0 -0
  205. package/ide/dictionary.txt +397 -0
  206. package/ide/jetbrains/.fleet/settings.json +4 -0
  207. package/ide/jetbrains/.idea/.gitignore +5 -0
  208. package/ide/jetbrains/.idea/.name +1 -0
  209. package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +6 -0
  210. package/ide/jetbrains/.idea/jsLinters/eslint.xml +7 -0
  211. package/ide/jetbrains/.idea/modules.xml +8 -0
  212. package/ide/jetbrains/.idea/stacks.iml +22 -0
  213. package/ide/jetbrains/.idea/vcs.xml +6 -0
  214. package/ide/jetbrains/.idea/webResources.xml +14 -0
  215. package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
  216. package/ide/jetbrains/installed.txt +4 -0
  217. package/ide/jetbrains/options/github-copilot.xml +5 -0
  218. package/ide/jetbrains/options/nodejs.xml +7 -0
  219. package/ide/jetbrains/options/templates.xml +124 -0
  220. package/ide/jetbrains/templates/JavaScript.xml +6 -0
  221. package/ide/jetbrains/templates/Stacks.xml +8 -0
  222. package/ide/vscode/.vscode/README.md +23 -0
  223. package/ide/vscode/.vscode/extensions.json +5 -0
  224. package/ide/vscode/.vscode/settings.json +176 -0
  225. package/ide/vscode/.vscode/stacks.code-snippets +181 -0
  226. package/ide/vscode/LICENSE.md +21 -0
  227. package/ide/vscode/README.md +36 -0
  228. package/ide/vscode/logo.png +0 -0
  229. package/ide/vscode/package.json +79 -0
  230. package/ide/zed/.zed/settings.json +139 -0
  231. package/lang/README.md +28 -0
  232. package/lang/de.yml +14 -0
  233. package/lang/en.yml +15 -0
  234. package/package.json +19 -3
  235. package/project/bootstrap +161 -0
  236. package/project/buddy +175 -0
  237. package/project/storage/framework/tsconfig.app.json +50 -0
  238. package/project/storage/framework/tsconfig.base.json +58 -0
  239. package/routes/core.ts +78 -0
  240. package/routes/dashboard-api.ts +233 -0
  241. package/routes/dashboard.ts +739 -0
  242. package/routes/email.ts +129 -0
  243. package/stores/[name].stx +16 -0
  244. package/stores/git.ts +71 -0
  245. package/stores/payment.ts +474 -0
  246. package/stores/queue.ts +43 -0
  247. package/stores/user.ts +29 -0
  248. package/stx-components-plugin.ts +25 -0
  249. package/styles/design-tokens.css +597 -0
  250. package/types/dashboard.ts +70 -0
  251. package/types/defaults.ts +438 -0
  252. package/vcs/github/CODE_OF_CONDUCT.md +83 -0
  253. package/vcs/github/CONTRIBUTING.md +187 -0
  254. package/vcs/github/EXPLANATIONS.md +41 -0
  255. package/vcs/github/FUNDING.yml +1 -0
  256. package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +49 -0
  257. package/vcs/github/ISSUE_TEMPLATE/config.yml +10 -0
  258. package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +44 -0
  259. package/vcs/github/SECURITY.md +70 -0
  260. package/vcs/github/renovate.json +5 -0
  261. package/vcs/github/stale.yml +14 -0
  262. package/vcs/github/workflows/README.md +16 -0
  263. package/vcs/github/workflows/ci.yml +114 -0
  264. package/vcs/github/workflows/export-size.yml +25 -0
  265. package/vcs/github/workflows/labeler.yml +13 -0
  266. package/vcs/github/workflows/release.yml +219 -0
  267. package/views/[...all].stx +8 -0
  268. package/views/about.md +3 -0
  269. package/views/auth/login.stx +1 -0
  270. package/views/auth/signup.stx +85 -0
  271. package/views/dashboard/.discovered-models.json +542 -0
  272. package/views/dashboard/AUDIT.md +904 -0
  273. package/views/dashboard/[...all].stx +89 -0
  274. package/views/dashboard/access-tokens/index.stx +177 -0
  275. package/views/dashboard/actions/index.stx +129 -0
  276. package/views/dashboard/analytics/blog/index.stx +356 -0
  277. package/views/dashboard/analytics/browsers/index.stx +263 -0
  278. package/views/dashboard/analytics/commerce/sales/index.stx +329 -0
  279. package/views/dashboard/analytics/commerce/web/index.stx +379 -0
  280. package/views/dashboard/analytics/countries/index.stx +289 -0
  281. package/views/dashboard/analytics/devices/index.stx +305 -0
  282. package/views/dashboard/analytics/events/index.stx +536 -0
  283. package/views/dashboard/analytics/index.stx +88 -0
  284. package/views/dashboard/analytics/marketing/index.stx +315 -0
  285. package/views/dashboard/analytics/pages/index.stx +271 -0
  286. package/views/dashboard/analytics/referrers/index.stx +319 -0
  287. package/views/dashboard/analytics/web/index.stx +356 -0
  288. package/views/dashboard/buddy/index.stx +198 -0
  289. package/views/dashboard/ci/index.stx +462 -0
  290. package/views/dashboard/cloud/index.stx +452 -0
  291. package/views/dashboard/commands/index.stx +295 -0
  292. package/views/dashboard/commerce/categories/index.stx +406 -0
  293. package/views/dashboard/commerce/coupons/index.stx +485 -0
  294. package/views/dashboard/commerce/customers/index.stx +410 -0
  295. package/views/dashboard/commerce/dashboard/index.stx +287 -0
  296. package/views/dashboard/commerce/delivery/delivery-routes.stx +305 -0
  297. package/views/dashboard/commerce/delivery/digital-delivery.stx +332 -0
  298. package/views/dashboard/commerce/delivery/drivers.stx +397 -0
  299. package/views/dashboard/commerce/delivery/index.stx +18 -0
  300. package/views/dashboard/commerce/delivery/license-keys.stx +380 -0
  301. package/views/dashboard/commerce/delivery/shipping-methods.stx +346 -0
  302. package/views/dashboard/commerce/delivery/shipping-rates.stx +338 -0
  303. package/views/dashboard/commerce/delivery/shipping-zones.stx +302 -0
  304. package/views/dashboard/commerce/delivery/tabs.ts +25 -0
  305. package/views/dashboard/commerce/gift-cards/index.stx +561 -0
  306. package/views/dashboard/commerce/manufacturers/index.stx +308 -0
  307. package/views/dashboard/commerce/orders/index.stx +247 -0
  308. package/views/dashboard/commerce/payments/index.stx +535 -0
  309. package/views/dashboard/commerce/pos/index.stx +653 -0
  310. package/views/dashboard/commerce/printers/devices/index.stx +273 -0
  311. package/views/dashboard/commerce/printers/receipts/index.stx +308 -0
  312. package/views/dashboard/commerce/products/detail.stx +563 -0
  313. package/views/dashboard/commerce/products/index.stx +370 -0
  314. package/views/dashboard/commerce/reviews/index.stx +656 -0
  315. package/views/dashboard/commerce/reviews/index.ts +0 -0
  316. package/views/dashboard/commerce/taxes/index.stx +377 -0
  317. package/views/dashboard/commerce/units/index.stx +317 -0
  318. package/views/dashboard/commerce/variants/index.stx +319 -0
  319. package/views/dashboard/commerce/waitlist/products.stx +942 -0
  320. package/views/dashboard/commerce/waitlist/restaurant.stx +1024 -0
  321. package/views/dashboard/components/index.stx +330 -0
  322. package/views/dashboard/composables/index.ts +19 -0
  323. package/views/dashboard/composables/useChart.ts +77 -0
  324. package/views/dashboard/composables/useNavigation.ts +99 -0
  325. package/views/dashboard/composables/useRole.ts +58 -0
  326. package/views/dashboard/composables/useTheme.ts +74 -0
  327. package/views/dashboard/content/authors/index.stx +171 -0
  328. package/views/dashboard/content/blog/index.stx +493 -0
  329. package/views/dashboard/content/categories/index.stx +169 -0
  330. package/views/dashboard/content/comments/index.stx +189 -0
  331. package/views/dashboard/content/dashboard.stx +383 -0
  332. package/views/dashboard/content/files/index.stx +706 -0
  333. package/views/dashboard/content/pages/index.stx +174 -0
  334. package/views/dashboard/content/posts/index.stx +269 -0
  335. package/views/dashboard/content/seo/index.stx +240 -0
  336. package/views/dashboard/content/tags/index.stx +167 -0
  337. package/views/dashboard/data/activity/index.stx +261 -0
  338. package/views/dashboard/data/dashboard/index.stx +116 -0
  339. package/views/dashboard/data/subscribers.stx +270 -0
  340. package/views/dashboard/data/teams.stx +275 -0
  341. package/views/dashboard/data/users.stx +279 -0
  342. package/views/dashboard/dependencies/index.stx +178 -0
  343. package/views/dashboard/deployments/[id].stx +234 -0
  344. package/views/dashboard/deployments/index.stx +9 -0
  345. package/views/dashboard/dns/index.stx +163 -0
  346. package/views/dashboard/environment/index.stx +283 -0
  347. package/views/dashboard/errors/index.stx +274 -0
  348. package/views/dashboard/forgot-password.stx +57 -0
  349. package/views/dashboard/functions/index.stx +159 -0
  350. package/views/dashboard/health/index.stx +248 -0
  351. package/views/dashboard/inbox/activity.stx +350 -0
  352. package/views/dashboard/inbox/index.stx +452 -0
  353. package/views/dashboard/inbox/settings.stx +290 -0
  354. package/views/dashboard/index.stx +252 -0
  355. package/views/dashboard/insights/index.stx +529 -0
  356. package/views/dashboard/jobs/[id].stx +430 -0
  357. package/views/dashboard/jobs/history.stx +222 -0
  358. package/views/dashboard/jobs/index.stx +214 -0
  359. package/views/dashboard/kanban/[id].stx +899 -0
  360. package/views/dashboard/kanban/index.stx +260 -0
  361. package/views/dashboard/layouts/default.stx +565 -0
  362. package/views/dashboard/layouts/guest.stx +10 -0
  363. package/views/dashboard/login.stx +48 -0
  364. package/views/dashboard/logs/index.stx +540 -0
  365. package/views/dashboard/mailboxes/index.stx +149 -0
  366. package/views/dashboard/management/permissions/index.stx +490 -0
  367. package/views/dashboard/marketing/campaigns/index.stx +604 -0
  368. package/views/dashboard/marketing/lists/index.stx +514 -0
  369. package/views/dashboard/marketing/reviews/index.stx +475 -0
  370. package/views/dashboard/marketing/social-posts/index.stx +560 -0
  371. package/views/dashboard/models/[model].stx +195 -0
  372. package/views/dashboard/models/index.stx +159 -0
  373. package/views/dashboard/monitoring/errors/index.stx +415 -0
  374. package/views/dashboard/notifications/dashboard.stx +383 -0
  375. package/views/dashboard/notifications/email.stx +336 -0
  376. package/views/dashboard/notifications/history.stx +373 -0
  377. package/views/dashboard/notifications/sms.stx +332 -0
  378. package/views/dashboard/packages/index.stx +195 -0
  379. package/views/dashboard/queries/[id].stx +381 -0
  380. package/views/dashboard/queries/history.stx +227 -0
  381. package/views/dashboard/queries/index.stx +335 -0
  382. package/views/dashboard/queries/slow.stx +318 -0
  383. package/views/dashboard/queue/index.stx +427 -0
  384. package/views/dashboard/realtime/index.stx +429 -0
  385. package/views/dashboard/register.stx +46 -0
  386. package/views/dashboard/releases/index.stx +389 -0
  387. package/views/dashboard/requests/index.stx +462 -0
  388. package/views/dashboard/serverless/index.stx +475 -0
  389. package/views/dashboard/servers/[id].stx +299 -0
  390. package/views/dashboard/servers/index.stx +483 -0
  391. package/views/dashboard/settings/billing.stx +50 -0
  392. package/views/dashboard/settings/index.stx +256 -0
  393. package/views/dashboard/settings/mail.stx +252 -0
  394. package/views/dashboard/stores/auth.ts +123 -0
  395. package/views/dashboard/stores/ci.ts +342 -0
  396. package/views/dashboard/stores/index.ts +129 -0
  397. package/views/dashboard/stores/kanban.ts +723 -0
  398. package/views/dashboard/stores/rbac.ts +350 -0
  399. package/views/dashboard/stx.config.ts +34 -0
  400. package/views/dashboard/teams/[id].stx +170 -0
  401. package/views/forum/category.stx +92 -0
  402. package/views/forum/index.stx +209 -0
  403. package/views/forum/new-topic.stx +113 -0
  404. package/views/forum/profile.stx +1 -0
  405. package/views/forum/topic.stx +143 -0
  406. package/views/hello-world/[name].stx +47 -0
  407. package/views/index.stx +21 -0
  408. package/views/system-tray/index.stx +147 -0
@@ -0,0 +1,308 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ @title('Dashboard - Food Vendors')
5
+ <PageLayout>
6
+ <div class="sm:flex sm:items-center sm:justify-between">
7
+ <PageHeader title="Manufacturers" description="Manage your product manufacturers" />
8
+ <div class="mt-4 sm:mt-0">
9
+ <button
10
+ type="button"
11
+ @click="openAddModal()"
12
+ class="inline-flex items-center px-3 py-2 font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm"
13
+ >
14
+ <div class="mr-1 h-5 w-5 i-hugeicons-plus-sign"></div>
15
+ Add manufacturer
16
+ </button>
17
+ </div>
18
+ </div>
19
+
20
+ <!-- Filters -->
21
+ <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between mt-6">
22
+ <div class="relative max-w-sm">
23
+ <div class="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none">
24
+ <div class="h-5 w-5 text-gray-400 i-hugeicons-search-01"></div>
25
+ </div>
26
+ <input
27
+ x-model="searchQuery"
28
+ type="text"
29
+ class="block pl-10 pr-3 py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:placeholder:text-neutral-500 dark:bg-neutral-800 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-700 focus:ring-2 focus:ring-blue-600 focus:ring-inset"
30
+ placeholder="Search manufacturers..."
31
+ />
32
+ </div>
33
+
34
+ <div class="flex flex-col gap-4 sm:flex-row">
35
+ <select
36
+ x-model="featuredFilter"
37
+ class="block pl-3 pr-10 py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-800 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-700 focus:ring-2 focus:ring-blue-600 focus:ring-inset"
38
+ >
39
+ <option value="all">All Manufacturers</option>
40
+ <option value="featured">Featured Only</option>
41
+ <option value="not-featured">Not Featured</option>
42
+ </select>
43
+
44
+ <select
45
+ x-model="countryFilter"
46
+ class="block pl-3 pr-10 py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-800 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-700 focus:ring-2 focus:ring-blue-600 focus:ring-inset"
47
+ >
48
+ <option value="all">All Countries</option>
49
+ <template :for="country in countries">
50
+ <option value="{{ country }}">{{ country }}</option>
51
+ </template>
52
+ </select>
53
+ </div>
54
+ </div>
55
+
56
+ <!-- Manufacturers table -->
57
+ <div class="flow-root mt-6">
58
+ <div class="overflow-x-auto -mx-4 -my-2 sm:-mx-6 lg:-mx-8">
59
+ <div class="inline-block py-2 sm:px-6 lg:px-8 min-w-full align-middle">
60
+ <div class="overflow-hidden ring-1 ring-black ring-opacity-5 sm:rounded-lg shadow">
61
+ <table class="min-w-full divide-gray-300 divide-y dark:divide-neutral-700">
62
+ <thead class="bg-gray-50 dark:bg-neutral-700">
63
+ <tr>
64
+ <th scope="col" class="pl-4 pr-3 py-3.5 sm:pl-6 font-semibold text-gray-900 text-left text-sm dark:text-neutral-200">
65
+ <button @click="toggleSort('name')" class="inline-flex items-center group">
66
+ Manufacturer
67
+ <span class="group-focus:visible group-hover:visible flex-none ml-2 text-gray-400 rounded">
68
+ <div class="h-4 w-4 {{ sortBy() === 'name' ? (sortOrder() === 'asc' ? 'i-hugeicons-arrow-up-02' : 'i-hugeicons-arrow-down-02') : 'i-hugeicons-arrows-up-down' }}"></div>
69
+ </span>
70
+ </button>
71
+ </th>
72
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-200">Description</th>
73
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-200">
74
+ <button @click="toggleSort('country')" class="inline-flex items-center group">
75
+ Country
76
+ <span class="group-focus:visible group-hover:visible flex-none ml-2 text-gray-400 rounded">
77
+ <div class="h-4 w-4 {{ sortBy() === 'country' ? (sortOrder() === 'asc' ? 'i-hugeicons-arrow-up-02' : 'i-hugeicons-arrow-down-02') : 'i-hugeicons-arrows-up-down' }}"></div>
78
+ </span>
79
+ </button>
80
+ </th>
81
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-200">
82
+ <button @click="toggleSort('productCount')" class="inline-flex items-center group">
83
+ Products
84
+ <span class="group-focus:visible group-hover:visible flex-none ml-2 text-gray-400 rounded">
85
+ <div class="h-4 w-4 {{ sortBy() === 'productCount' ? (sortOrder() === 'asc' ? 'i-hugeicons-arrow-up-02' : 'i-hugeicons-arrow-down-02') : 'i-hugeicons-arrows-up-down' }}"></div>
86
+ </span>
87
+ </button>
88
+ </th>
89
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-200">Featured</th>
90
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-right text-sm dark:text-neutral-200">
91
+ <button @click="toggleSort('createdAt')" class="inline-flex items-center text-right group">
92
+ Created
93
+ <span class="group-focus:visible group-hover:visible flex-none ml-2 text-gray-400 rounded">
94
+ <div class="h-4 w-4 {{ sortBy() === 'createdAt' ? (sortOrder() === 'asc' ? 'i-hugeicons-arrow-up-02' : 'i-hugeicons-arrow-down-02') : 'i-hugeicons-arrows-up-down' }}"></div>
95
+ </span>
96
+ </button>
97
+ </th>
98
+ <th scope="col" class="relative pl-3 pr-4 py-3.5 sm:pr-6">
99
+ <span class="sr-only">Actions</span>
100
+ </th>
101
+ </tr>
102
+ </thead>
103
+ <tbody class="bg-white dark:bg-neutral-800 divide-gray-200 divide-y dark:divide-neutral-700">
104
+ <template :for="manufacturer in filteredManufacturers">
105
+ <tr>
106
+ <td class="pl-4 pr-3 py-4 sm:pl-6 font-medium text-gray-900 text-sm whitespace-nowrap dark:text-white">{{ manufacturer.name }}</td>
107
+ <td class="px-3 py-4 text-gray-500 text-sm dark:text-neutral-300">{{ manufacturer.description }}</td>
108
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-300">{{ manufacturer.country }}</td>
109
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-300">{{ manufacturer.productCount }}</td>
110
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-300">
111
+ @if(manufacturer.featured)
112
+ <div class="h-5 w-5 text-green-500 i-hugeicons-checkmark-circle-02"></div>
113
+ @else
114
+ <div class="h-5 w-5 text-gray-400 i-hugeicons-cancel-circle"></div>
115
+ @endif
116
+ </td>
117
+ <td class="px-3 py-4 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300">{{ manufacturer.createdAt }}</td>
118
+ <td class="relative pl-3 pr-4 py-4 sm:pr-6 font-medium text-right text-sm whitespace-nowrap">
119
+ <div class="flex items-center justify-end space-x-2">
120
+ <button type="button" class="text-gray-400 dark:text-blue-400 hover:text-blue-900 dark:hover:text-blue-300 duration-150 transition-colors">
121
+ <div class="h-5 w-5 i-hugeicons-edit-01"></div>
122
+ </button>
123
+ <button type="button" class="text-gray-400 dark:text-red-400 hover:text-red-900 dark:hover:text-red-300 duration-150 transition-colors">
124
+ <div class="h-5 w-5 i-hugeicons-waste"></div>
125
+ </button>
126
+ </div>
127
+ </td>
128
+ </tr>
129
+ </template>
130
+ @if(filteredManufacturers().length === 0)
131
+ <tr>
132
+ <td colspan="7" class="px-6 py-4 text-center text-gray-500 text-sm dark:text-neutral-400">
133
+ No manufacturers found matching your criteria
134
+ </td>
135
+ </tr>
136
+ @endif
137
+ </tbody>
138
+ </table>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ <!-- Add Manufacturer Modal -->
147
+ <div :show="showAddModal" class="fixed inset-0 overflow-y-auto z-10">
148
+ <div class="flex items-end justify-center sm:items-center p-4 sm:p-0 min-h-full text-center">
149
+ <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" @click="closeAddModal()"></div>
150
+
151
+ <div class="overflow-hidden relative pb-4 pt-5 px-4 sm:my-8 sm:p-6 sm:max-w-lg sm:w-full text-left bg-white dark:bg-neutral-800 rounded-lg shadow-xl transition-all transform">
152
+ <div>
153
+ <div class="mt-3 sm:mt-5 text-center">
154
+ <h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-white">Add New Manufacturer</h3>
155
+ <div class="mt-4">
156
+ <div class="space-y-4">
157
+ <div>
158
+ <label for="manufacturer-name" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Name</label>
159
+ <div class="mt-2">
160
+ <input type="text" id="manufacturer-name" x-model="newName" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600 focus:ring-inset shadow-sm" />
161
+ </div>
162
+ </div>
163
+ <div>
164
+ <label for="manufacturer-description" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Description</label>
165
+ <div class="mt-2">
166
+ <textarea id="manufacturer-description" x-model="newDescription" rows="3" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600 focus:ring-inset shadow-sm"></textarea>
167
+ </div>
168
+ </div>
169
+ <div>
170
+ <label for="manufacturer-country" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Country</label>
171
+ <div class="mt-2">
172
+ <input type="text" id="manufacturer-country" x-model="newCountry" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600 focus:ring-inset shadow-sm" />
173
+ </div>
174
+ </div>
175
+ <div>
176
+ <label for="manufacturer-website" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Website</label>
177
+ <div class="mt-2">
178
+ <input type="url" id="manufacturer-website" x-model="newWebsite" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600 focus:ring-inset shadow-sm" />
179
+ </div>
180
+ </div>
181
+ <div class="flex items-center">
182
+ <input id="manufacturer-featured" type="checkbox" x-model="newFeatured" class="h-4 w-4 text-blue-600 dark:bg-neutral-700 border-gray-300 rounded dark:border-neutral-600 focus:ring-blue-600" />
183
+ <label for="manufacturer-featured" class="block ml-2 text-gray-900 text-sm dark:text-neutral-200">Featured manufacturer</label>
184
+ </div>
185
+ </div>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ <div class="sm:grid sm:gap-3 sm:grid-cols-2 sm:grid-flow-row-dense mt-5 sm:mt-6">
190
+ <button type="button" @click="addManufacturer()" class="inline-flex justify-center sm:col-start-2 px-3 py-2 w-full font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">Add</button>
191
+ <button type="button" @click="closeAddModal()" class="inline-flex justify-center sm:col-start-1 mt-3 px-3 py-2 sm:mt-0 w-full font-semibold text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-700 hover:bg-gray-50 dark:hover:bg-neutral-600 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">Cancel</button>
192
+ </div>
193
+ </div>
194
+ </PageLayout>
195
+ <script client>
196
+ interface Manufacturer {
197
+ id: number
198
+ name: string
199
+ slug: string
200
+ description: string
201
+ productCount: number
202
+ featured: boolean
203
+ country: string
204
+ website: string
205
+ createdAt: string
206
+ }
207
+
208
+ const initialManufacturers: Manufacturer[] = [
209
+ { id: 1, name: 'Pizza Palace', slug: 'pizza-palace', description: 'Authentic Italian pizzeria with handcrafted pizzas and fresh ingredients', productCount: 24, featured: true, country: 'United States', website: 'https://pizzapalace.foodmarket.org', createdAt: '2023-05-10' },
210
+ { id: 2, name: 'Burger Bistro', slug: 'burger-bistro', description: 'Gourmet burgers made with locally sourced ingredients', productCount: 18, featured: true, country: 'United States', website: 'https://burgerbistro.foodmarket.org', createdAt: '2023-05-15' },
211
+ { id: 3, name: 'Sushi Supreme', slug: 'sushi-supreme', description: 'Premium sushi and Japanese cuisine prepared by master chefs', productCount: 32, featured: true, country: 'United States', website: 'https://sushisupreme.foodmarket.org', createdAt: '2023-06-01' },
212
+ { id: 4, name: 'Taco Tiempo', slug: 'taco-tiempo', description: 'Authentic Mexican street food with fresh, bold flavors', productCount: 22, featured: false, country: 'United States', website: 'https://tacotime.foodmarket.org', createdAt: '2023-06-10' },
213
+ { id: 5, name: 'Pasta Paradise', slug: 'pasta-paradise', description: 'Handmade pasta and traditional Italian recipes', productCount: 16, featured: false, country: 'United States', website: 'https://pastaparadise.foodmarket.org', createdAt: '2023-06-20' },
214
+ { id: 6, name: 'Healthy Harvest', slug: 'healthy-harvest', description: 'Nutritious, plant-based meals for health-conscious customers', productCount: 28, featured: true, country: 'United States', website: 'https://healthyharvest.foodmarket.org', createdAt: '2023-07-05' },
215
+ { id: 7, name: 'Sweet Sensations', slug: 'sweet-sensations', description: 'Artisanal desserts, cakes, and pastries for every occasion', productCount: 35, featured: false, country: 'United States', website: 'https://sweetsensations.foodmarket.org', createdAt: '2023-07-15' },
216
+ { id: 8, name: 'Beverage Boutique', slug: 'beverage-boutique', description: 'Specialty coffees, teas, smoothies, and craft beverages', productCount: 19, featured: false, country: 'United States', website: 'https://beverageboutique.foodmarket.org', createdAt: '2023-08-01' },
217
+ ]
218
+
219
+ const manufacturers = state(initialManufacturers)
220
+ const searchQuery = state('')
221
+ const sortBy = state<'name' | 'productCount' | 'country' | 'createdAt'>('name')
222
+ const sortOrder = state<'asc' | 'desc'>('asc')
223
+ const featuredFilter = state<'all' | 'featured' | 'not-featured'>('all')
224
+ const countryFilter = state<string>('all')
225
+
226
+ const showAddModal = state(false)
227
+ const newName = state('')
228
+ const newDescription = state('')
229
+ const newFeatured = state(false)
230
+ const newCountry = state('')
231
+ const newWebsite = state('')
232
+
233
+ function countries(): string[] {
234
+ return Array.from(new Set(manufacturers().map(m => m.country))).sort()
235
+ }
236
+
237
+ const filteredManufacturers = derived(() => {
238
+ const q = searchQuery().toLowerCase()
239
+ const fFilter = featuredFilter()
240
+ const cFilter = countryFilter()
241
+ const by = sortBy()
242
+ const dir = sortOrder()
243
+
244
+ return manufacturers()
245
+ .filter((m) => {
246
+ const matchesSearch
247
+ = m.name.toLowerCase().includes(q)
248
+ || m.description.toLowerCase().includes(q)
249
+ const matchesFeatured
250
+ = fFilter === 'all'
251
+ || (fFilter === 'featured' && m.featured)
252
+ || (fFilter === 'not-featured' && !m.featured)
253
+ const matchesCountry = cFilter === 'all' || m.country === cFilter
254
+ return matchesSearch && matchesFeatured && matchesCountry
255
+ })
256
+ .sort((a, b) => {
257
+ let cmp = 0
258
+ if (by === 'name') cmp = a.name.localeCompare(b.name)
259
+ else if (by === 'productCount') cmp = a.productCount - b.productCount
260
+ else if (by === 'country') cmp = a.country.localeCompare(b.country)
261
+ else if (by === 'createdAt') cmp = new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
262
+ return dir === 'asc' ? cmp : -cmp
263
+ })
264
+ })
265
+
266
+ function toggleSort(column: 'name' | 'productCount' | 'country' | 'createdAt'): void {
267
+ if (sortBy() === column) {
268
+ sortOrder.update(d => d === 'asc' ? 'desc' : 'asc')
269
+ }
270
+ else {
271
+ sortBy.set(column)
272
+ sortOrder.set('asc')
273
+ }
274
+ }
275
+
276
+ function openAddModal(): void {
277
+ newName.set('')
278
+ newDescription.set('')
279
+ newFeatured.set(false)
280
+ newCountry.set('')
281
+ newWebsite.set('')
282
+ showAddModal.set(true)
283
+ }
284
+
285
+ function closeAddModal(): void {
286
+ showAddModal.set(false)
287
+ }
288
+
289
+ function addManufacturer(): void {
290
+ const list = manufacturers()
291
+ const id = list.length > 0 ? Math.max(...list.map(m => m.id)) + 1 : 1
292
+ const name = newName()
293
+ manufacturers.set([...list, {
294
+ id,
295
+ name,
296
+ slug: name.toLowerCase().replace(/\s+/g, '-'),
297
+ description: newDescription(),
298
+ productCount: 0,
299
+ featured: newFeatured(),
300
+ country: newCountry(),
301
+ website: newWebsite(),
302
+ createdAt: new Date().toISOString().split('T')[0] || '',
303
+ }])
304
+ closeAddModal()
305
+ }
306
+ </script>
307
+
308
+ @endsection
@@ -0,0 +1,247 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ <div class="p-6 space-y-6">
5
+
6
+ <PageHeader title="Orders" description="Manage commerce orders">
7
+ <template #actions>
8
+ <Button variant="primary" @click="openAddModal()">
9
+ <div class="h-4 w-4 i-hugeicons-plus-sign"></div>
10
+ Add Order
11
+ </Button>
12
+ </template>
13
+ </PageHeader>
14
+
15
+ <div class="bg-white dark:bg-neutral-800/90 border border-black/5 rounded-xl dark:border-white/5">
16
+ <!-- Filters -->
17
+ <div class="p-4 border-b border-neutral-200/60 dark:border-white/5">
18
+ <FilterBar :searchPlaceholder="'Search orders...'" :searchValue="searchQuery" :itemsPerPage="itemsPerPage">
19
+ <Select
20
+ placeholder="All Statuses"
21
+ :options="statuses.map(s => ({ value: s, label: s === 'all' ? 'All Statuses' : s }))"
22
+ size="sm"
23
+ />
24
+ </FilterBar>
25
+ </div>
26
+
27
+ <!-- Orders Table -->
28
+ <OrdersTable
29
+ :orders="paginatedOrders"
30
+ :searchQuery="searchQuery"
31
+ :statusFilter="statusFilter"
32
+ :sortBy="sortBy"
33
+ :sortOrder="sortOrder"
34
+ :currentPage="currentPage"
35
+ :itemsPerPage="itemsPerPage"
36
+ :statuses="statuses"
37
+ @toggle-sort="toggleSort"
38
+ />
39
+
40
+ <!-- Pagination -->
41
+ <div class="p-4 border-neutral-200/60 border-t dark:border-white/5">
42
+ <Pagination
43
+ :currentPage="currentPage"
44
+ :totalPages="totalPages"
45
+ :totalItems="totalItems"
46
+ :itemsPerPage="itemsPerPage"
47
+ showItemsPerPage
48
+ />
49
+ </div>
50
+ </div>
51
+
52
+ <!-- Add Order Modal -->
53
+ <Modal :isOpen="showAddModal" title="Add New Order" @close="closeAddModal">
54
+ <form @submit.prevent="addOrder()" class="space-y-4">
55
+ <Input label="Customer ID" name="customer_id" type="number" placeholder="Enter customer ID" :value="newCustomerId" required />
56
+ <Input label="Total Amount" name="total_amount" type="number" placeholder="0.00" :value="newTotalAmount" required />
57
+ <Select
58
+ label="Order Type"
59
+ :options="orderTypes"
60
+ :value="newOrderType"
61
+ />
62
+ <Select
63
+ label="Status"
64
+ :options="newOrderStatusOptions"
65
+ :value="newStatus"
66
+ />
67
+ <div class="flex gap-2 justify-end pt-4 border-neutral-200 border-t dark:border-neutral-700">
68
+ <Button variant="secondary" @click.prevent="closeAddModal()">Cancel</Button>
69
+ <Button variant="primary" type="submit">Add Order</Button>
70
+ </div>
71
+ </form>
72
+ </Modal>
73
+
74
+ <!-- Delete Confirmation -->
75
+ <ConfirmDialog
76
+ :isOpen="showDeleteModal"
77
+ title="Delete Order"
78
+ description="Are you sure you want to delete this order? This action cannot be undone."
79
+ confirmLabel="Delete Order"
80
+ variant="danger"
81
+ @confirm="confirmDelete"
82
+ @cancel="closeDeleteModal"
83
+ />
84
+ </div>
85
+
86
+ <script client>
87
+ import { useOrders } from '../../../../functions/commerce/orders'
88
+ // Filter options — moved out of the former `<script server>` block
89
+ // (stacksjs/stacks#1838).
90
+ const statuses = ['all', 'Completed', 'Processing', 'Shipped', 'Cancelled', 'Refunded'] as const
91
+ const orderTypes = [
92
+ { value: 'delivery', label: 'Delivery' },
93
+ { value: 'pickup', label: 'Pickup' },
94
+ { value: 'dine-in', label: 'Dine-in' },
95
+ ] as const
96
+
97
+ interface Order {
98
+ id: number
99
+ customer_id: number
100
+ total_amount: number
101
+ status: string
102
+ order_type: string
103
+ coupon_id?: number
104
+ }
105
+
106
+ const { orders, createOrder, fetchOrders, deleteOrder } = useOrders()
107
+
108
+ const statusFilter = state<string>('all')
109
+ const sortBy = state<'date' | 'total_amount' | 'customer_id'>('date')
110
+ const sortOrder = state<'asc' | 'desc'>('desc')
111
+ const searchQuery = state('')
112
+ const currentPage = state(1)
113
+ const itemsPerPage = state(10)
114
+
115
+ // Modal state.
116
+ const showAddModal = state(false)
117
+ const showDeleteModal = state(false)
118
+ const orderToDelete = state<Order | null>(null)
119
+
120
+ // New-order form fields — flat signals keep each x-model binding 1:1.
121
+ const newCustomerId = state(1)
122
+ const newTotalAmount = state(0)
123
+ const newStatus = state<'Completed' | 'Processing' | 'Shipped' | 'Cancelled' | 'Refunded'>('Processing')
124
+ const newOrderType = state<'delivery' | 'pickup' | 'dine-in'>('delivery')
125
+
126
+ // Status list for the modal excludes the 'all' filter sentinel.
127
+ const newOrderStatusOptions = derived(() =>
128
+ ['Completed', 'Processing', 'Shipped', 'Cancelled', 'Refunded']
129
+ .map(s => ({ value: s, label: s })),
130
+ )
131
+
132
+ const filteredOrders = derived(() => {
133
+ const q = searchQuery().toLowerCase()
134
+ const filter = statusFilter()
135
+ const by = sortBy()
136
+ const dir = sortOrder()
137
+
138
+ return (orders.value as Order[])
139
+ .filter((o) => {
140
+ const matchesSearch
141
+ = o.id.toString().toLowerCase().includes(q)
142
+ || o.customer_id.toString().toLowerCase().includes(q)
143
+ || o.order_type.toLowerCase().includes(q)
144
+ const matchesStatus = filter === 'all' || o.status === filter
145
+ return matchesSearch && matchesStatus
146
+ })
147
+ .sort((a, b) => {
148
+ let cmp = 0
149
+ if (by === 'total_amount')
150
+ cmp = a.total_amount - b.total_amount
151
+ else if (by === 'customer_id')
152
+ cmp = a.customer_id - b.customer_id
153
+ return dir === 'asc' ? cmp : -cmp
154
+ })
155
+ })
156
+
157
+ const paginatedOrders = derived(() => {
158
+ const start = (currentPage() - 1) * itemsPerPage()
159
+ return filteredOrders().slice(start, start + itemsPerPage())
160
+ })
161
+
162
+ const totalItems = derived(() => filteredOrders().length)
163
+ const totalPages = derived(() => Math.ceil(totalItems() / itemsPerPage()))
164
+
165
+ function toggleSort(column: 'date' | 'total_amount' | 'customer_id'): void {
166
+ if (sortBy() === column) {
167
+ sortOrder.update(d => d === 'asc' ? 'desc' : 'asc')
168
+ }
169
+ else {
170
+ sortBy.set(column)
171
+ sortOrder.set('desc')
172
+ }
173
+ }
174
+
175
+ function openAddModal(): void {
176
+ newCustomerId.set(1)
177
+ newTotalAmount.set(0)
178
+ newStatus.set('Processing')
179
+ newOrderType.set('delivery')
180
+ showAddModal.set(true)
181
+ }
182
+
183
+ function closeAddModal(): void {
184
+ showAddModal.set(false)
185
+ }
186
+
187
+ function closeDeleteModal(): void {
188
+ showDeleteModal.set(false)
189
+ orderToDelete.set(null)
190
+ }
191
+
192
+ async function addOrder(): Promise<void> {
193
+ const list = orders.value as Order[]
194
+ const id = list.length > 0 ? Math.max(...list.map(o => o.id || 0)) + 1 : 1
195
+ const optimistic: Order = {
196
+ id,
197
+ customer_id: newCustomerId(),
198
+ coupon_id: 0,
199
+ status: newStatus(),
200
+ total_amount: newTotalAmount(),
201
+ order_type: newOrderType(),
202
+ }
203
+ orders.value = [optimistic, ...list]
204
+
205
+ try {
206
+ const created = await createOrder(optimistic)
207
+ if (created) {
208
+ closeAddModal()
209
+ }
210
+ else {
211
+ orders.value = (orders.value as Order[]).filter(o => o.id !== id)
212
+ }
213
+ }
214
+ catch {
215
+ orders.value = (orders.value as Order[]).filter(o => o.id !== id)
216
+ }
217
+ }
218
+
219
+ async function confirmDelete(): Promise<void> {
220
+ const target = orderToDelete()
221
+ if (!target)
222
+ return
223
+
224
+ const id = target.id
225
+ const list = orders.value as Order[]
226
+ orders.value = list.filter(o => o.id !== id)
227
+
228
+ try {
229
+ const ok = await deleteOrder(id)
230
+ if (ok) {
231
+ closeDeleteModal()
232
+ }
233
+ else {
234
+ orders.value = [...orders.value, target]
235
+ }
236
+ }
237
+ catch {
238
+ orders.value = [...orders.value, target]
239
+ }
240
+ }
241
+
242
+ onMount(async () => {
243
+ await fetchOrders()
244
+ })
245
+ </script>
246
+
247
+ @endsection