@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,123 @@
1
+ import type { WaitlistProduct } from '../../../types/defaults'
2
+ import { useStorage } from '@stacksjs/browser'
3
+ import { pushToast } from '../../toasts'
4
+
5
+ // Create a persistent waitlist products array using STX useStorage
6
+ const waitlistProducts = useStorage<WaitlistProduct[]>('waitlist_products', [])
7
+
8
+ const baseURL = process.env.VITE_API_URL || `http://localhost:${process.env.PORT_API || '3008'}`
9
+
10
+ // Basic fetch function to get all waitlist products
11
+ async function fetchWaitlistProducts() {
12
+ try {
13
+ const response = await fetch(`${baseURL}/commerce/waitlist/products`)
14
+ if (!response.ok) {
15
+ throw new Error(`HTTP error! status: ${response.status}`)
16
+ }
17
+ const data = await response.json() as WaitlistProduct[]
18
+
19
+ if (Array.isArray(data)) {
20
+ waitlistProducts.value = data
21
+ return data
22
+ }
23
+ else {
24
+ pushToast('error', 'Couldn\'t load waitlist products', { detail: 'Server returned a non-array response' })
25
+ return []
26
+ }
27
+ }
28
+ catch (error) {
29
+ pushToast('error', 'Error fetching waitlist products', { detail: String(error) })
30
+ return []
31
+ }
32
+ }
33
+
34
+ async function createWaitlistProduct(waitlistProduct: WaitlistProduct) {
35
+ try {
36
+ const response = await fetch(`${baseURL}/commerce/waitlist/products`, {
37
+ method: 'POST',
38
+ headers: {
39
+ 'Content-Type': 'application/json',
40
+ },
41
+ body: JSON.stringify(waitlistProduct),
42
+ })
43
+
44
+ if (!response.ok) {
45
+ throw new Error(`HTTP error! status: ${response.status}`)
46
+ }
47
+
48
+ const data = await response.json() as WaitlistProduct
49
+ if (data) {
50
+ waitlistProducts.value.push(data)
51
+ return data
52
+ }
53
+ return null
54
+ }
55
+ catch (error) {
56
+ pushToast('error', 'Error creating waitlist product', { detail: String(error) })
57
+ return null
58
+ }
59
+ }
60
+
61
+ async function updateWaitlistProduct(waitlistProduct: WaitlistProduct) {
62
+ try {
63
+ const response = await fetch(`${baseURL}/commerce/waitlist/products/${waitlistProduct.id}`, {
64
+ method: 'PATCH',
65
+ headers: {
66
+ 'Content-Type': 'application/json',
67
+ },
68
+ body: JSON.stringify(waitlistProduct),
69
+ })
70
+
71
+ if (!response.ok) {
72
+ throw new Error(`HTTP error! status: ${response.status}`)
73
+ }
74
+
75
+ const data = await response.json() as WaitlistProduct
76
+ if (data) {
77
+ const index = waitlistProducts.value.findIndex(wp => wp.id === waitlistProduct.id)
78
+ if (index !== -1) {
79
+ waitlistProducts.value[index] = data
80
+ }
81
+ return data
82
+ }
83
+ return null
84
+ }
85
+ catch (error) {
86
+ pushToast('error', 'Error updating waitlist product', { detail: String(error) })
87
+ return null
88
+ }
89
+ }
90
+
91
+ async function deleteWaitlistProduct(id: number) {
92
+ try {
93
+ const response = await fetch(`${baseURL}/commerce/waitlist/products/${id}`, {
94
+ method: 'DELETE',
95
+ })
96
+
97
+ if (!response.ok) {
98
+ throw new Error(`HTTP error! status: ${response.status}`)
99
+ }
100
+
101
+ const index = waitlistProducts.value.findIndex(wp => wp.id === id)
102
+ if (index !== -1) {
103
+ waitlistProducts.value.splice(index, 1)
104
+ }
105
+
106
+ return true
107
+ }
108
+ catch (error) {
109
+ pushToast('error', 'Error deleting waitlist product', { detail: String(error) })
110
+ return false
111
+ }
112
+ }
113
+
114
+ // Export the composable
115
+ export function useWaitlistProducts() {
116
+ return {
117
+ waitlistProducts,
118
+ fetchWaitlistProducts,
119
+ createWaitlistProduct,
120
+ updateWaitlistProduct,
121
+ deleteWaitlistProduct,
122
+ }
123
+ }
@@ -0,0 +1,123 @@
1
+ import type { WaitlistRestaurant } from '../../../types/defaults'
2
+ import { useStorage } from '@stacksjs/browser'
3
+ import { pushToast } from '../../toasts'
4
+
5
+ // Create a persistent waitlist restaurants array using STX useStorage
6
+ const waitlistRestaurants = useStorage<WaitlistRestaurant[]>('waitlist_restaurants', [])
7
+
8
+ const baseURL = process.env.VITE_API_URL || `http://localhost:${process.env.PORT_API || '3008'}`
9
+
10
+ // Basic fetch function to get all waitlist restaurants
11
+ async function fetchWaitlistRestaurants() {
12
+ try {
13
+ const response = await fetch(`${baseURL}/commerce/waitlist/restaurants`)
14
+ if (!response.ok) {
15
+ throw new Error(`HTTP error! status: ${response.status}`)
16
+ }
17
+ const data = await response.json() as WaitlistRestaurant[]
18
+
19
+ if (Array.isArray(data)) {
20
+ waitlistRestaurants.value = data
21
+ return data
22
+ }
23
+ else {
24
+ pushToast('error', 'Couldn\'t load waitlist restaurants', { detail: 'Server returned a non-array response' })
25
+ return []
26
+ }
27
+ }
28
+ catch (error) {
29
+ pushToast('error', 'Error fetching waitlist restaurants', { detail: String(error) })
30
+ return []
31
+ }
32
+ }
33
+
34
+ async function createWaitlistRestaurant(waitlistRestaurant: WaitlistRestaurant) {
35
+ try {
36
+ const response = await fetch(`${baseURL}/commerce/waitlist/restaurants`, {
37
+ method: 'POST',
38
+ headers: {
39
+ 'Content-Type': 'application/json',
40
+ },
41
+ body: JSON.stringify(waitlistRestaurant),
42
+ })
43
+
44
+ if (!response.ok) {
45
+ throw new Error(`HTTP error! status: ${response.status}`)
46
+ }
47
+
48
+ const data = await response.json() as WaitlistRestaurant
49
+ if (data) {
50
+ waitlistRestaurants.value.push(data)
51
+ return data
52
+ }
53
+ return null
54
+ }
55
+ catch (error) {
56
+ pushToast('error', 'Error creating waitlist restaurant', { detail: String(error) })
57
+ return null
58
+ }
59
+ }
60
+
61
+ async function updateWaitlistRestaurant(waitlistRestaurant: WaitlistRestaurant) {
62
+ try {
63
+ const response = await fetch(`${baseURL}/commerce/waitlist/restaurants/${waitlistRestaurant.id}`, {
64
+ method: 'PATCH',
65
+ headers: {
66
+ 'Content-Type': 'application/json',
67
+ },
68
+ body: JSON.stringify(waitlistRestaurant),
69
+ })
70
+
71
+ if (!response.ok) {
72
+ throw new Error(`HTTP error! status: ${response.status}`)
73
+ }
74
+
75
+ const data = await response.json() as WaitlistRestaurant
76
+ if (data) {
77
+ const index = waitlistRestaurants.value.findIndex(wr => wr.id === waitlistRestaurant.id)
78
+ if (index !== -1) {
79
+ waitlistRestaurants.value[index] = data
80
+ }
81
+ return data
82
+ }
83
+ return null
84
+ }
85
+ catch (error) {
86
+ pushToast('error', 'Error updating waitlist restaurant', { detail: String(error) })
87
+ return null
88
+ }
89
+ }
90
+
91
+ async function deleteWaitlistRestaurant(id: number) {
92
+ try {
93
+ const response = await fetch(`${baseURL}/commerce/waitlist/restaurants/${id}`, {
94
+ method: 'DELETE',
95
+ })
96
+
97
+ if (!response.ok) {
98
+ throw new Error(`HTTP error! status: ${response.status}`)
99
+ }
100
+
101
+ const index = waitlistRestaurants.value.findIndex(wr => wr.id === id)
102
+ if (index !== -1) {
103
+ waitlistRestaurants.value.splice(index, 1)
104
+ }
105
+
106
+ return true
107
+ }
108
+ catch (error) {
109
+ pushToast('error', 'Error deleting waitlist restaurant', { detail: String(error) })
110
+ return false
111
+ }
112
+ }
113
+
114
+ // Export the composable
115
+ export function useWaitlistRestaurants() {
116
+ return {
117
+ waitlistRestaurants,
118
+ fetchWaitlistRestaurants,
119
+ createWaitlistRestaurant,
120
+ updateWaitlistRestaurant,
121
+ deleteWaitlistRestaurant,
122
+ }
123
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Craft Native App Composable
3
+ *
4
+ * Provides utilities for interacting with the Craft native app environment.
5
+ * These functions are safe to call in both web and native environments.
6
+ */
7
+
8
+ /**
9
+ * Check if running in Craft native environment
10
+ */
11
+ export function isCraftNative(): boolean {
12
+ return typeof window !== 'undefined' && window.craft?.window !== undefined
13
+ }
14
+
15
+ /**
16
+ * Get the Craft bridge API (returns undefined in web environment)
17
+ */
18
+ export function useCraft() {
19
+ if (!isCraftNative()) {
20
+ return {
21
+ isNative: false,
22
+ window: undefined,
23
+ app: undefined,
24
+ tray: undefined,
25
+ }
26
+ }
27
+
28
+ return {
29
+ isNative: true,
30
+ window: window.craft?.window,
31
+ app: window.craft?.app,
32
+ tray: window.craft?.tray,
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Window control functions that work in both web and native environments
38
+ */
39
+ export function useWindowControls() {
40
+ const { isNative, window: craftWindow } = useCraft()
41
+
42
+ return {
43
+ isNative,
44
+
45
+ minimize: async () => {
46
+ if (isNative && craftWindow) {
47
+ await craftWindow.minimize()
48
+ }
49
+ },
50
+
51
+ close: async () => {
52
+ if (isNative && craftWindow) {
53
+ await craftWindow.close()
54
+ }
55
+ },
56
+
57
+ toggle: async () => {
58
+ if (isNative && craftWindow) {
59
+ await craftWindow.toggle()
60
+ }
61
+ },
62
+
63
+ show: async () => {
64
+ if (isNative && craftWindow) {
65
+ await craftWindow.show()
66
+ }
67
+ },
68
+
69
+ hide: async () => {
70
+ if (isNative && craftWindow) {
71
+ await craftWindow.hide()
72
+ }
73
+ },
74
+ }
75
+ }
76
+
77
+ /**
78
+ * App control functions
79
+ */
80
+ export function useAppControls() {
81
+ const { isNative, app } = useCraft()
82
+
83
+ return {
84
+ isNative,
85
+
86
+ quit: async () => {
87
+ if (isNative && app) {
88
+ await app.quit()
89
+ }
90
+ },
91
+
92
+ notify: async (title: string, body?: string) => {
93
+ if (isNative && app) {
94
+ await app.notify({ title, body })
95
+ } else if (typeof Notification !== 'undefined' && Notification.permission === 'granted') {
96
+ new Notification(title, { body })
97
+ }
98
+ },
99
+
100
+ getInfo: async () => {
101
+ if (isNative && app) {
102
+ return app.getInfo()
103
+ }
104
+ return { name: 'Stacks Dashboard', version: '0.0.0', platform: 'web' }
105
+ },
106
+ }
107
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Dashboard Composable
3
+ *
4
+ * Provides data fetching for the main dashboard overview.
5
+ */
6
+
7
+ import { ref } from '@stacksjs/stx'
8
+
9
+ const baseUrl = process.env.VITE_API_URL || `http://localhost:${process.env.PORT_API || '3008'}`
10
+
11
+ export interface DashboardStats {
12
+ title: string
13
+ value: string
14
+ trend: number
15
+ trendLabel: string
16
+ icon: string
17
+ iconBg: string
18
+ }
19
+
20
+ export interface ActivityItem {
21
+ id: number
22
+ type: string
23
+ title: string
24
+ time: string
25
+ status: 'success' | 'error' | 'warning'
26
+ }
27
+
28
+ export interface SystemHealthItem {
29
+ name: string
30
+ status: 'healthy' | 'degraded' | 'critical'
31
+ latency: string
32
+ uptime: string
33
+ }
34
+
35
+ // Default fallback data
36
+ const defaultStats: DashboardStats[] = [
37
+ { title: 'Total Users', value: '0', trend: 0, trendLabel: 'vs last period', icon: 'i-hugeicons-user-group', iconBg: 'primary' },
38
+ { title: 'Active Projects', value: '0', trend: 0, trendLabel: 'vs last period', icon: 'i-hugeicons-folder-02', iconBg: 'success' },
39
+ { title: 'Cloud Uptime', value: '0%', trend: 0, trendLabel: 'vs last period', icon: 'i-hugeicons-cloud', iconBg: 'info' },
40
+ { title: 'Response Time', value: '0ms', trend: 0, trendLabel: 'vs last period', icon: 'i-hugeicons-time-02', iconBg: 'warning' },
41
+ ]
42
+
43
+ const defaultActivity: ActivityItem[] = []
44
+
45
+ const defaultHealth: SystemHealthItem[] = [
46
+ { name: 'API', status: 'healthy', latency: '0ms', uptime: '0%' },
47
+ { name: 'Database', status: 'healthy', latency: '0ms', uptime: '0%' },
48
+ { name: 'Storage', status: 'healthy', latency: '0ms', uptime: '0%' },
49
+ { name: 'Cache', status: 'healthy', latency: '0ms', uptime: '0%' },
50
+ { name: 'Queue', status: 'healthy', latency: '0ms', uptime: '0%' },
51
+ { name: 'Notifications', status: 'healthy', latency: '0ms', uptime: '0%' },
52
+ ]
53
+
54
+ export function useDashboard() {
55
+ const stats = ref<DashboardStats[]>(defaultStats)
56
+ const recentActivity = ref<ActivityItem[]>(defaultActivity)
57
+ const systemHealth = ref<SystemHealthItem[]>(defaultHealth)
58
+ const isLoading = ref(false)
59
+ const error = ref<string | null>(null)
60
+
61
+ async function fetchDashboardStats(timeRange = '7d') {
62
+ try {
63
+ const response = await fetch(`${baseUrl}/dashboard/stats?range=${timeRange}`, {
64
+ headers: {
65
+ 'Accept': 'application/json',
66
+ },
67
+ })
68
+
69
+ if (response.ok) {
70
+ const data = await response.json()
71
+ stats.value = data.stats || defaultStats
72
+ }
73
+ }
74
+ catch (e) {
75
+ console.error('Failed to fetch dashboard stats:', e)
76
+ throw e
77
+ }
78
+ }
79
+
80
+ async function fetchRecentActivity() {
81
+ try {
82
+ const response = await fetch(`${baseUrl}/dashboard/activity`, {
83
+ headers: {
84
+ 'Accept': 'application/json',
85
+ },
86
+ })
87
+
88
+ if (response.ok) {
89
+ const data = await response.json()
90
+ recentActivity.value = data.activity || defaultActivity
91
+ }
92
+ }
93
+ catch (e) {
94
+ console.error('Failed to fetch recent activity:', e)
95
+ throw e
96
+ }
97
+ }
98
+
99
+ async function fetchSystemHealth() {
100
+ try {
101
+ const response = await fetch(`${baseUrl}/health`, {
102
+ headers: {
103
+ 'Accept': 'application/json',
104
+ },
105
+ })
106
+
107
+ if (response.ok) {
108
+ const data = await response.json()
109
+ systemHealth.value = data.services || defaultHealth
110
+ }
111
+ }
112
+ catch (e) {
113
+ console.error('Failed to fetch system health:', e)
114
+ throw e
115
+ }
116
+ }
117
+
118
+ async function fetchAll(timeRange = '7d') {
119
+ isLoading.value = true
120
+ error.value = null
121
+
122
+ try {
123
+ await Promise.all([
124
+ fetchDashboardStats(timeRange),
125
+ fetchRecentActivity(),
126
+ fetchSystemHealth(),
127
+ ])
128
+ }
129
+ catch (e) {
130
+ error.value = 'Failed to load dashboard data. Please try again.'
131
+ }
132
+ finally {
133
+ isLoading.value = false
134
+ }
135
+ }
136
+
137
+ function retry(timeRange = '7d') {
138
+ return fetchAll(timeRange)
139
+ }
140
+
141
+ return {
142
+ stats,
143
+ recentActivity,
144
+ systemHealth,
145
+ isLoading,
146
+ error,
147
+ fetchDashboardStats,
148
+ fetchRecentActivity,
149
+ fetchSystemHealth,
150
+ fetchAll,
151
+ retry,
152
+ }
153
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Inbox Composable
3
+ *
4
+ * Reads captured transactional emails from the framework's mail log driver
5
+ * (in-memory + storage/logs/mail/*.html) for the dashboard inbox view.
6
+ */
7
+
8
+ import { ref } from '@stacksjs/stx'
9
+ import { get } from './api'
10
+
11
+ export interface InboxEntry {
12
+ id: string
13
+ source: 'memory' | 'disk'
14
+ from: string
15
+ to: string
16
+ subject: string
17
+ preview: string
18
+ sent_at: string
19
+ has_html: boolean
20
+ has_text: boolean
21
+ size: number
22
+ }
23
+
24
+ export interface InboxBody {
25
+ id: string
26
+ from: string
27
+ to: string
28
+ cc?: string
29
+ bcc?: string
30
+ subject: string
31
+ sent_at: string
32
+ html: string
33
+ text: string
34
+ error?: string
35
+ }
36
+
37
+ export function useInbox() {
38
+ const emails = ref<InboxEntry[]>([])
39
+ const driver = ref<string>('log')
40
+ const total = ref(0)
41
+ const isLoading = ref(false)
42
+ const error = ref<string | null>(null)
43
+ const selected = ref<InboxBody | null>(null)
44
+
45
+ async function fetchEmails() {
46
+ isLoading.value = true
47
+ error.value = null
48
+ try {
49
+ const data = await get<{ data: InboxEntry[], total: number, driver: string }>('/inbox')
50
+ emails.value = data.data || []
51
+ total.value = data.total || 0
52
+ driver.value = data.driver || 'log'
53
+ }
54
+ catch (e) {
55
+ error.value = 'Failed to load inbox.'
56
+ console.error('Failed to fetch inbox:', e)
57
+ }
58
+ finally {
59
+ isLoading.value = false
60
+ }
61
+ }
62
+
63
+ async function openEmail(id: string) {
64
+ error.value = null
65
+ try {
66
+ const data = await get<InboxBody>(`/inbox/${encodeURIComponent(id)}`)
67
+ if (data.error) {
68
+ error.value = data.error
69
+ selected.value = null
70
+ return
71
+ }
72
+ selected.value = data
73
+ }
74
+ catch (e) {
75
+ error.value = 'Failed to open email.'
76
+ console.error('Failed to fetch email:', e)
77
+ }
78
+ }
79
+
80
+ function closeEmail() {
81
+ selected.value = null
82
+ }
83
+
84
+ return {
85
+ emails,
86
+ driver,
87
+ total,
88
+ isLoading,
89
+ error,
90
+ selected,
91
+ fetchEmails,
92
+ openEmail,
93
+ closeEmail,
94
+ }
95
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Jobs Composable
3
+ *
4
+ * Provides data fetching for job history and queue management.
5
+ */
6
+
7
+ import { ref } from '@stacksjs/stx'
8
+ import { get, post } from './api'
9
+
10
+ export interface JobHistoryEntry {
11
+ id: string
12
+ name: string
13
+ queue: string
14
+ status: 'queued' | 'processing' | 'failed' | 'completed'
15
+ attempts: number
16
+ runtime?: number
17
+ started_at?: string
18
+ finished_at?: string
19
+ error?: string
20
+ payload: any
21
+ }
22
+
23
+ export function useJobs() {
24
+ const jobs = ref<JobHistoryEntry[]>([])
25
+ const totalJobs = ref(0)
26
+ const isLoading = ref(false)
27
+ const error = ref<string | null>(null)
28
+
29
+ async function fetchJobs(params?: { page?: number, perPage?: number, queue?: string, status?: string, search?: string }) {
30
+ isLoading.value = true
31
+ error.value = null
32
+
33
+ try {
34
+ const query = new URLSearchParams()
35
+ if (params?.page) query.set('page', String(params.page))
36
+ if (params?.perPage) query.set('per_page', String(params.perPage))
37
+ if (params?.queue && params.queue !== 'all') query.set('queue', params.queue)
38
+ if (params?.status && params.status !== 'all') query.set('status', params.status)
39
+ if (params?.search) query.set('search', params.search)
40
+
41
+ const data = await get<{ data: JobHistoryEntry[], total: number }>(`/jobs?${query.toString()}`)
42
+ jobs.value = data.data || []
43
+ totalJobs.value = data.total || 0
44
+ }
45
+ catch (e) {
46
+ error.value = 'Failed to load job history.'
47
+ console.error('Failed to fetch jobs:', e)
48
+ }
49
+ finally {
50
+ isLoading.value = false
51
+ }
52
+ }
53
+
54
+ async function retryJob(jobId: string) {
55
+ try {
56
+ await post(`/jobs/${jobId}/retry`)
57
+ // Refresh the job list after retry
58
+ await fetchJobs()
59
+ }
60
+ catch (e) {
61
+ error.value = `Failed to retry job ${jobId}.`
62
+ console.error('Failed to retry job:', e)
63
+ }
64
+ }
65
+
66
+ async function retryFailedJobs() {
67
+ try {
68
+ await post('/queue/retry-failed')
69
+ await fetchJobs()
70
+ }
71
+ catch (e) {
72
+ error.value = 'Failed to retry failed jobs.'
73
+ console.error('Failed to retry failed jobs:', e)
74
+ }
75
+ }
76
+
77
+ return {
78
+ jobs,
79
+ totalJobs,
80
+ isLoading,
81
+ error,
82
+ fetchJobs,
83
+ retryJob,
84
+ retryFailedJobs,
85
+ }
86
+ }