@stacksjs/defaults 0.70.207 → 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,429 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ @title('Dashboard - Realtime')
5
+ <div class="py-4 lg:py-8 min-h-screen dark:bg-neutral-800">
6
+ <div class="px-4 sm:px-6 lg:px-8">
7
+ <div class="mb-8">
8
+ <h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-neutral-100">Last 30 days</h3>
9
+
10
+ <dl class="grid gap-5 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 mt-5">
11
+ <div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
12
+ <dt>
13
+ <div class="absolute p-3 bg-blue-500 rounded-md">
14
+ <div class="h-6 w-6 text-white i-hugeicons-link-03"></div>
15
+ </div>
16
+ <p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-400">Connections Triggered</p>
17
+ </dt>
18
+ <dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
19
+ <p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">{{ connectionsTriggered() }}</p>
20
+ <p class="flex items-baseline ml-2 font-semibold text-green-600 text-sm">
21
+ <svg class="flex-shrink-0 self-center h-5 w-5 text-green-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
22
+ <path fill-rule="evenodd" d="M10 17a.75.75 0 01-.75-.75V5.612L5.29 9.77a.75.75 0 01-1.08-1.04l5.25-5.5a.75.75 0 011.08 0l5.25 5.5a.75.75 0 11-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0110 17z" clip-rule="evenodd" />
23
+ </svg>
24
+ <span class="sr-only">Increased by</span>
25
+ {{ connectionsChange() }}
26
+ </p>
27
+ </dd>
28
+ </div>
29
+
30
+ <div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
31
+ <dt>
32
+ <div class="absolute p-3 bg-blue-500 rounded-md">
33
+ <div class="h-6 w-6 text-white i-hugeicons-alarm-clock"></div>
34
+ </div>
35
+ <p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-400">Average Latency</p>
36
+ </dt>
37
+ <dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
38
+ <p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">{{ avgLatency() }}</p>
39
+ <p class="flex items-baseline ml-2 font-semibold text-green-600 text-sm">
40
+ <svg class="flex-shrink-0 self-center h-5 w-5 text-green-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
41
+ <path fill-rule="evenodd" d="M10 17a.75.75 0 01-.75-.75V5.612L5.29 9.77a.75.75 0 01-1.08-1.04l5.25-5.5a.75.75 0 011.08 0l5.25 5.5a.75.75 0 11-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0110 17z" clip-rule="evenodd" />
42
+ </svg>
43
+ <span class="sr-only">Decreased by</span>
44
+ {{ latencyChange() }}
45
+ </p>
46
+ </dd>
47
+ </div>
48
+
49
+ <div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
50
+ <dt>
51
+ <div class="absolute p-3 bg-blue-500 rounded-md">
52
+ <div class="h-6 w-6 text-white i-hugeicons-checkmark-circle-01"></div>
53
+ </div>
54
+ <p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-400">Success Rate</p>
55
+ </dt>
56
+ <dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
57
+ <p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">{{ successRate() }}</p>
58
+ <p class="flex items-baseline ml-2 font-semibold text-red-600 text-sm">
59
+ <svg class="flex-shrink-0 self-center h-5 w-5 text-red-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
60
+ <path fill-rule="evenodd" d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z" clip-rule="evenodd" />
61
+ </svg>
62
+ <span class="sr-only">Decreased by</span>
63
+ {{ successChange() }}
64
+ </p>
65
+ </dd>
66
+ </div>
67
+ </dl>
68
+ </div>
69
+
70
+ <div class="mb-8 p-4 bg-white dark:bg-neutral-700 rounded-lg shadow">
71
+ <div class="flex gap-4 items-center">
72
+ <div class="flex gap-2 items-center">
73
+ <label class="text-gray-700 text-sm dark:text-neutral-300">App:</label>
74
+ <input x-model="app" type="text" class="pl-3 pr-3 py-1.5 h-9 text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600" />
75
+ </div>
76
+ <div class="flex gap-2 items-center">
77
+ <label class="text-gray-700 text-sm dark:text-neutral-300">Port:</label>
78
+ <input x-model="port" type="text" class="pl-3 pr-3 py-1.5 h-9 text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600" />
79
+ </div>
80
+ <button type="button" @click="toggleConnection()" class="block px-3 py-2 font-semibold text-center text-sm text-white rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 shadow-sm {{ isConnected() ? 'bg-red-600 hover:bg-red-500 focus-visible:outline-red-600' : 'bg-blue-600 hover:bg-blue-500 focus-visible:outline-blue-600' }}">{{ isConnected() ? 'Disconnect' : 'Connect' }}</button>
81
+ </div>
82
+ <div class="mt-4 text-gray-500 text-sm dark:text-neutral-400">{{ channelState }}</div>
83
+ </div>
84
+
85
+ <div class="mb-8 bg-white dark:bg-neutral-700 rounded-lg shadow">
86
+ <div class="p-6">
87
+ <div class="flex items-center justify-between mb-6">
88
+ <div>
89
+ <h3 class="font-medium text-base text-gray-900 dark:text-neutral-100">Realtime Statistics</h3>
90
+ <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Live monitoring of connections and messages</p>
91
+ </div>
92
+ </div>
93
+ <div class="relative h-[300px]">
94
+ <div :show="isLoading" class="flex absolute inset-0 z-10 items-center justify-center bg-opacity-75 bg-white dark:bg-neutral-700 dark:bg-opacity-75">
95
+ <div class="h-8 w-8 border-b-2 border-blue-500 rounded-full animate-spin"></div>
96
+ </div>
97
+ <canvas id="realtime_chart"></canvas>
98
+ </div>
99
+ </div>
100
+ </div>
101
+
102
+ <div class="mb-8 bg-white dark:bg-neutral-700 rounded-lg shadow">
103
+ <div class="p-6">
104
+ <h3 class="mb-4 font-medium text-base text-gray-900 dark:text-neutral-100">Event Creator</h3>
105
+ <div class="space-y-4">
106
+ <div>
107
+ <label class="block mb-1 font-medium text-gray-700 text-sm dark:text-neutral-300">Channel</label>
108
+ <input x-model="eventChannel" type="text" placeholder="chat.1" class="block px-3 py-1.5 h-9 w-full text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600" />
109
+ </div>
110
+ <div>
111
+ <label class="block mb-1 font-medium text-gray-700 text-sm dark:text-neutral-300">Event</label>
112
+ <input x-model="eventName" type="text" placeholder="message.sent" class="block px-3 py-1.5 h-9 w-full text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600" />
113
+ </div>
114
+ <div>
115
+ <label class="block mb-1 font-medium text-gray-700 text-sm dark:text-neutral-300">Data</label>
116
+ <textarea x-model="eventData" rows="3" placeholder='{"message": "Hello World!", "user_id": 1}' class="block px-3 py-1.5 w-full text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600"></textarea>
117
+ </div>
118
+ <div class="flex justify-end">
119
+ <button @click="sendEvent()" type="button" class="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">Send event</button>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ </div>
124
+
125
+ <div class="bg-white dark:bg-neutral-700 rounded-lg shadow">
126
+ <div class="p-6">
127
+ <div class="flex items-center justify-between mb-4">
128
+ <h3 class="font-medium text-base text-gray-900 dark:text-neutral-100">Events</h3>
129
+ <div class="flex gap-4 items-center">
130
+ <div class="flex gap-2 items-center">
131
+ <label class="text-gray-700 text-sm dark:text-neutral-300">Filter:</label>
132
+ <select x-model="selectedEventType" class="pl-3 pr-8 py-1.5 h-9 text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600">
133
+ <option value="">All Events</option>
134
+ <template :for="type in eventTypes">
135
+ <option value="{{ type }}">{{ type }}</option>
136
+ </template>
137
+ </select>
138
+ </div>
139
+ <div class="flex gap-2 items-center">
140
+ <label class="text-gray-700 text-sm dark:text-neutral-300">Search:</label>
141
+ <input x-model="searchQuery" type="text" placeholder="Search events..." class="pl-3 pr-3 py-1.5 h-9 text-gray-900 text-sm dark:text-neutral-100 bg-gray-50 dark:bg-neutral-600 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 focus:ring-2 focus:ring-blue-600" />
142
+ </div>
143
+ <button @click="clearEvents()" type="button" class="px-3 py-2 font-semibold text-sm text-white bg-gray-600 hover:bg-gray-500 rounded-md focus-visible:outline-2 focus-visible:outline-gray-600 focus-visible:outline-offset-2 shadow-sm">Clear</button>
144
+ </div>
145
+ </div>
146
+ <div class="overflow-x-auto">
147
+ <table class="min-w-full divide-gray-300 divide-y dark:divide-neutral-600">
148
+ <thead>
149
+ <tr>
150
+ <th scope="col" class="py-3.5 w-32 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Type</th>
151
+ <th scope="col" class="px-3 py-3.5 w-48 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Socket</th>
152
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Details</th>
153
+ <th scope="col" class="px-3 py-3.5 w-32 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Time</th>
154
+ </tr>
155
+ </thead>
156
+ <tbody class="divide-gray-200 divide-y dark:divide-neutral-600">
157
+ <template :for="(event, index) in filteredEvents">
158
+ <tr class="hover:bg-gray-50 dark:hover:bg-neutral-600">
159
+ <td class="py-4 font-medium text-sm">
160
+ <span class="{{ eventTypeClass(event.type) }} inline-flex items-center px-2 py-1 font-medium text-xs rounded">{{ event.type }}</span>
161
+ </td>
162
+ <td class="px-3 py-4 font-mono text-gray-500 text-sm whitespace-nowrap dark:text-neutral-400">{{ event.socket || '-' }}</td>
163
+ <td class="px-3 py-4 text-gray-500 text-sm dark:text-neutral-400">
164
+ <div class="font-mono">{{ event.details }}</div>
165
+ <div :show="{{ event.data ? 'true' : 'false' }}" class="mt-1 text-xs">
166
+ <button @click="toggleEventData({{ index }})" class="text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">{{ isEventDataOpen(index) ? 'Hide Data' : 'Show Data' }}</button>
167
+ <pre :show="isEventDataOpen({{ index }})" class="overflow-x-auto mt-2 p-2 bg-gray-50 dark:bg-neutral-800 rounded">{{ JSON.stringify(event.data, null, 2) }}</pre>
168
+ </div>
169
+ </td>
170
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-400">{{ event.time }}</td>
171
+ </tr>
172
+ </template>
173
+ </tbody>
174
+ </table>
175
+ </div>
176
+ </div>
177
+ </div>
178
+ </div>
179
+ </div>
180
+
181
+ <script client>
182
+
183
+ interface WebSocketMessage {
184
+ socket_id?: string
185
+ channel?: string
186
+ event?: string
187
+ data?: unknown
188
+ }
189
+
190
+ interface RealtimeEvent {
191
+ type: string
192
+ socket: string | null
193
+ details: string | null
194
+ time: string
195
+ data?: unknown
196
+ }
197
+
198
+ interface ChartLike { destroy: () => void }
199
+ type ChartCtor = new (canvas: HTMLElement, config: { type: string, data: unknown, options?: unknown }) => ChartLike
200
+
201
+ const stats = state({
202
+ connectionsTriggered: '71,897',
203
+ connectionsChange: '+122',
204
+ avgLatency: '45ms',
205
+ latencyChange: '-12ms',
206
+ successRate: '94.57%',
207
+ successChange: '-3.2%',
208
+ })
209
+
210
+ const app = state('Stacks')
211
+ const port = state('6001')
212
+ const channelState = state('Channels current state is unavailable')
213
+
214
+ const eventChannel = state('')
215
+ const eventName = state('')
216
+ const eventData = state('')
217
+
218
+ const isConnected = state(false)
219
+ const isLoading = state(false)
220
+
221
+ const events = state<RealtimeEvent[]>([])
222
+ const expandedEventIndices = state<number[]>([])
223
+ const selectedEventType = state('')
224
+ const searchQuery = state('')
225
+
226
+ const MAX_EVENTS = 1000
227
+
228
+ let ws: WebSocket | null = null
229
+ let chartHandle: { destroy: () => void } | null = null
230
+
231
+ function connectionsTriggered(): string { return stats().connectionsTriggered }
232
+ function connectionsChange(): string { return stats().connectionsChange }
233
+ function avgLatency(): string { return stats().avgLatency }
234
+ function latencyChange(): string { return stats().latencyChange }
235
+ function successRate(): string { return stats().successRate }
236
+ function successChange(): string { return stats().successChange }
237
+
238
+ function wsUrl(): string {
239
+ return `ws://localhost:${port()}`
240
+ }
241
+
242
+ function eventTypes(): string[] {
243
+ const types = new Set(events().map(e => e.type))
244
+ return Array.from(types)
245
+ }
246
+
247
+ function filteredEvents(): RealtimeEvent[] {
248
+ let filtered = events()
249
+ const type = selectedEventType()
250
+ if (type)
251
+ filtered = filtered.filter(e => e.type === type)
252
+
253
+ const q = searchQuery().toLowerCase()
254
+ if (q) {
255
+ filtered = filtered.filter(e =>
256
+ e.type.toLowerCase().includes(q)
257
+ || (e.socket?.toLowerCase().includes(q) ?? false)
258
+ || (e.details?.toLowerCase().includes(q) ?? false),
259
+ )
260
+ }
261
+ return filtered
262
+ }
263
+
264
+ function isEventDataOpen(index: number): boolean {
265
+ return expandedEventIndices().includes(index)
266
+ }
267
+
268
+ function toggleEventData(index: number): void {
269
+ const list = expandedEventIndices()
270
+ expandedEventIndices.set(list.includes(index) ? list.filter(i => i !== index) : [...list, index])
271
+ }
272
+
273
+ function eventTypeClass(type: string): string {
274
+ switch (type) {
275
+ case 'connection': return 'bg-blue-50 text-blue-700 dark:bg-blue-900 dark:text-blue-100'
276
+ case 'disconnection': return 'bg-yellow-50 text-yellow-700 dark:bg-yellow-900 dark:text-yellow-100'
277
+ case 'error': return 'bg-red-50 text-red-700 dark:bg-red-900 dark:text-red-100'
278
+ case 'message': return 'bg-green-50 text-green-700 dark:bg-green-900 dark:text-green-100'
279
+ case 'sent': return 'bg-purple-50 text-purple-700 dark:bg-purple-900 dark:text-purple-100'
280
+ default: return 'bg-gray-50 text-gray-700 dark:bg-neutral-800 dark:text-neutral-200'
281
+ }
282
+ }
283
+
284
+ function addEvent(event: RealtimeEvent): void {
285
+ const next = [event, ...events()]
286
+ events.set(next.length > MAX_EVENTS ? next.slice(0, MAX_EVENTS) : next)
287
+ expandedEventIndices.set([])
288
+ }
289
+
290
+ function clearEvents(): void {
291
+ events.set([])
292
+ expandedEventIndices.set([])
293
+ }
294
+
295
+ function timeNow(): string {
296
+ return new Date().toLocaleTimeString('en-US', { hour12: false })
297
+ }
298
+
299
+ function connect(): void {
300
+ if (ws)
301
+ ws.close()
302
+
303
+ try {
304
+ const url = wsUrl()
305
+ ws = new WebSocket(url)
306
+
307
+ ws.onopen = () => {
308
+ isConnected.set(true)
309
+ channelState.set('Connected to WebSocket server')
310
+ addEvent({ type: 'connection', socket: null, details: `Connected to ${url}`, time: timeNow() })
311
+ }
312
+
313
+ ws.onclose = () => {
314
+ isConnected.set(false)
315
+ channelState.set('Disconnected from WebSocket server')
316
+ addEvent({ type: 'disconnection', socket: null, details: 'WebSocket connection closed', time: timeNow() })
317
+ }
318
+
319
+ ws.onerror = () => {
320
+ channelState.set('Error connecting to WebSocket server')
321
+ addEvent({ type: 'error', socket: null, details: 'WebSocket connection error', time: timeNow() })
322
+ }
323
+
324
+ ws.onmessage = (message: MessageEvent) => {
325
+ try {
326
+ const data = JSON.parse(message.data) as WebSocketMessage
327
+ addEvent({
328
+ type: 'message',
329
+ socket: data.socket_id || null,
330
+ details: `Channel: ${data.channel}, Event: ${data.event}`,
331
+ time: timeNow(),
332
+ data,
333
+ })
334
+ }
335
+ catch {
336
+ addEvent({ type: 'message', socket: null, details: String(message.data), time: timeNow() })
337
+ }
338
+ }
339
+ }
340
+ catch {
341
+ channelState.set('Failed to connect to WebSocket server')
342
+ }
343
+ }
344
+
345
+ function disconnect(): void {
346
+ if (ws) {
347
+ ws.close()
348
+ ws = null
349
+ }
350
+ }
351
+
352
+ function toggleConnection(): void {
353
+ if (isConnected())
354
+ disconnect()
355
+ else
356
+ connect()
357
+ }
358
+
359
+ function sendEvent(): void {
360
+ if (!ws || !eventChannel() || !eventName())
361
+ return
362
+ try {
363
+ const message = {
364
+ channel: eventChannel(),
365
+ event: eventName(),
366
+ data: eventData() ? JSON.parse(eventData()) : {},
367
+ }
368
+ ws.send(JSON.stringify(message))
369
+ addEvent({
370
+ type: 'sent',
371
+ socket: null,
372
+ details: `Sent event to channel: ${eventChannel()}, Event: ${eventName()}`,
373
+ time: timeNow(),
374
+ data: message,
375
+ })
376
+ eventChannel.set('')
377
+ eventName.set('')
378
+ eventData.set('')
379
+ }
380
+ catch (error) {
381
+ addEvent({ type: 'error', socket: null, details: `Failed to send event: ${(error as Error).message}`, time: timeNow() })
382
+ }
383
+ }
384
+
385
+ function getRealtimeData() {
386
+ const now = new Date()
387
+ const labels = Array.from({ length: 60 }, (_, i) => {
388
+ const d = new Date(now.getTime() - (59 - i) * 1000)
389
+ return `${d.getMinutes()}:${d.getSeconds().toString().padStart(2, '0')}`
390
+ })
391
+ return {
392
+ labels,
393
+ datasets: [
394
+ { label: 'Peak Connections', data: Array.from({ length: 60 }, () => Math.floor(Math.random() * 15)), borderColor: 'rgb(59, 130, 246)', backgroundColor: 'rgba(59, 130, 246, 0.1)', fill: false, tension: 0.4 },
395
+ { label: 'WebSocket Messages', data: Array.from({ length: 60 }, () => Math.floor(Math.random() * 5)), borderColor: 'rgb(245, 158, 11)', backgroundColor: 'rgba(245, 158, 11, 0.1)', fill: false, tension: 0.4 },
396
+ { label: 'API Messages', data: Array.from({ length: 60 }, () => Math.floor(Math.random() * 2)), borderColor: 'rgb(16, 185, 129)', backgroundColor: 'rgba(16, 185, 129, 0.1)', fill: false, tension: 0.4 },
397
+ ],
398
+ }
399
+ }
400
+
401
+ const chartOptions = {
402
+ responsive: true,
403
+ maintainAspectRatio: false,
404
+ scales: {
405
+ y: { beginAtZero: true, grid: { color: 'rgba(200, 200, 200, 0.1)' }, ticks: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" } } },
406
+ x: { grid: { display: false }, ticks: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" } } },
407
+ },
408
+ plugins: {
409
+ legend: { display: true, position: 'top', align: 'end', labels: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" }, boxWidth: 12, padding: 15 } },
410
+ tooltip: { mode: 'index', intersect: false },
411
+ },
412
+ }
413
+
414
+ onMount(async () => {
415
+ const { Chart, registerables } = await import('@stacksjs/charts')
416
+ Chart.register(...registerables)
417
+ const Ctor = Chart as unknown as ChartCtor
418
+ chartHandle = useChart({ Chart: Ctor, id: 'realtime_chart', type: 'line', data: getRealtimeData(), options: chartOptions })
419
+ connect()
420
+ })
421
+
422
+ onDestroy(() => {
423
+ disconnect()
424
+ chartHandle?.destroy()
425
+ chartHandle = null
426
+ })
427
+ </script>
428
+
429
+ @endsection
@@ -0,0 +1,46 @@
1
+ @extends('layouts/guest')
2
+
3
+ @section('content')
4
+ <script client>
5
+ // Register form (stacksjs/stacks#1838) — see comment on login.stx; same
6
+ // shape, same broken-`const`-reassignment fix.
7
+ import { useAuth } from '../../functions/auth'
8
+
9
+ const { register } = useAuth()
10
+
11
+ const isLoading = state(false)
12
+ const error = state('')
13
+
14
+ async function handleRegister(credentials) {
15
+ isLoading.set(true)
16
+ error.set('')
17
+
18
+ try {
19
+ const result = await register(credentials)
20
+
21
+ if (result && 'errors' in result) {
22
+ error.set(result.message || 'Registration failed')
23
+ return
24
+ }
25
+
26
+ navigate('/')
27
+ }
28
+ catch (err) {
29
+ error.set(err.message || 'An error occurred during registration')
30
+ // eslint-disable-next-line no-console
31
+ console.error(err)
32
+ }
33
+ finally {
34
+ isLoading.set(false)
35
+ }
36
+ }
37
+ </script>
38
+
39
+ @title('Register - Stacks Dashboard')
40
+ <Register
41
+ @submit="handleRegister"
42
+ :isLoading="isLoading()"
43
+ :error="error()"
44
+ />
45
+
46
+ @endsection