@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,383 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ @title('Dashboard - Notifications')
5
+ <div class="py-4 lg:py-8 min-h-screen dark:bg-neutral-800">
6
+ <div class="mb-8 px-4 sm:px-6 lg:px-8">
7
+ <div>
8
+ <h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-neutral-100">Notifications Overview</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-notification-03"></div>
15
+ </div>
16
+ <p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-300">Total Notifications</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">{{ totalSentLabel() }}</p>
20
+ <p class="flex items-baseline ml-2 font-semibold text-green-600 text-sm">
21
+ <div class="flex-shrink-0 self-center h-5 w-5 text-green-500 i-hugeicons-arrow-up"></div>
22
+ <span class="sr-only">Increased by</span>
23
+ 122
24
+ </p>
25
+ </dd>
26
+ </div>
27
+
28
+ <div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
29
+ <dt>
30
+ <div class="absolute p-3 bg-blue-500 rounded-md">
31
+ <div class="h-6 w-6 text-white i-hugeicons-checkmark-circle-02"></div>
32
+ </div>
33
+ <p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-300">Delivery Rate</p>
34
+ </dt>
35
+ <dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
36
+ <p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">{{ deliveryRate() }}%</p>
37
+ <p class="flex items-baseline ml-2 font-semibold text-green-600 text-sm">
38
+ <div class="flex-shrink-0 self-center h-5 w-5 text-green-500 i-hugeicons-arrow-up"></div>
39
+ <span class="sr-only">Increased by</span>
40
+ 0.5%
41
+ </p>
42
+ </dd>
43
+ </div>
44
+
45
+ <div class="overflow-hidden relative pt-5 px-4 sm:pt-6 sm:px-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
46
+ <dt>
47
+ <div class="absolute p-3 bg-blue-500 rounded-md">
48
+ <div class="h-6 w-6 text-white i-hugeicons-clock-01"></div>
49
+ </div>
50
+ <p class="ml-16 font-medium text-gray-500 text-sm truncate dark:text-neutral-300">Average Delivery Time</p>
51
+ </dt>
52
+ <dd class="flex items-baseline ml-16 pb-6 sm:pb-7">
53
+ <p class="font-semibold text-2xl text-gray-900 dark:text-neutral-100">{{ avgDeliveryTime() }}s</p>
54
+ <p class="flex items-baseline ml-2 font-semibold text-green-600 text-sm">
55
+ <div class="flex-shrink-0 self-center h-5 w-5 text-green-500 i-hugeicons-arrow-down-02"></div>
56
+ <span class="sr-only">Decreased by</span>
57
+ 0.1s
58
+ </p>
59
+ </dd>
60
+ </div>
61
+ </dl>
62
+ </div>
63
+ </div>
64
+
65
+ <div class="my-8 px-4 sm:px-6 lg:px-8">
66
+ <div class="bg-white dark:bg-neutral-700 rounded-lg shadow">
67
+ <div class="px-4 py-5 sm:p-6">
68
+ <div class="flex items-center justify-between">
69
+ <h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-neutral-100">Recent Notifications</h3>
70
+ <StxLink to="/notifications/history" class="inline-flex items-center space-x-1 text-blue-600 text-sm dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300">
71
+ <span>View All</span>
72
+ <div class="h-4 w-4 i-hugeicons-arrow-right-01"></div>
73
+ </StxLink>
74
+ </div>
75
+ <div class="flow-root mt-4">
76
+ <div class="overflow-x-auto -mx-4 -my-2 sm:-mx-6 lg:-mx-8">
77
+ <div class="inline-block py-2 sm:px-6 lg:px-8 min-w-full align-middle">
78
+ <table class="min-w-full divide-gray-300 divide-y dark:divide-neutral-600">
79
+ <thead>
80
+ <tr>
81
+ <th scope="col" class="pl-4 pr-3 py-3.5 sm:pl-0 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Type</th>
82
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Recipient</th>
83
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Subject</th>
84
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Status</th>
85
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-right text-sm dark:text-neutral-100">Sent</th>
86
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-right text-sm dark:text-neutral-100">Delivered</th>
87
+ </tr>
88
+ </thead>
89
+ <tbody class="divide-gray-200 divide-y dark:divide-neutral-600">
90
+ <template :for="notification in recentNotifications">
91
+ <tr>
92
+ <td class="pl-4 pr-3 py-4 sm:pl-0 font-medium text-gray-900 text-sm whitespace-nowrap dark:text-neutral-100">
93
+ <div class="flex items-center">
94
+ <div class="mr-2 h-5 w-5 {{ getChannelIcon(notification.type) }}"></div>
95
+ <span class="capitalize">{{ notification.type }}</span>
96
+ </div>
97
+ </td>
98
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-400">{{ notification.recipient }}</td>
99
+ <td class="px-3 py-4 text-gray-500 text-sm dark:text-neutral-400">{{ notification.subject }}</td>
100
+ <td class="px-3 py-4 text-sm whitespace-nowrap">
101
+ <span class="{{ getStatusColor(notification.status) }} inline-flex items-center px-2 py-1 font-medium text-xs ring-1 ring-inset rounded-md">{{ notification.status }}</span>
102
+ </td>
103
+ <td class="px-3 py-4 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-400">{{ notification.sent_at }}</td>
104
+ <td class="px-3 py-4 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-400">{{ notification.delivered_at || '-' }}</td>
105
+ </tr>
106
+ </template>
107
+ </tbody>
108
+ </table>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="px-4 sm:px-6 lg:px-8">
117
+ <div class="grid gap-6 grid-cols-1 lg:grid-cols-2">
118
+ <div class="bg-white dark:bg-neutral-700 rounded-lg shadow">
119
+ <div class="p-6">
120
+ <div class="flex items-center justify-between mb-6">
121
+ <div>
122
+ <h3 class="font-medium text-base text-gray-900 dark:text-neutral-100">Notification Volume</h3>
123
+ <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Notifications sent by channel</p>
124
+ </div>
125
+ <div class="flex items-center space-x-4">
126
+ <select x-model="timeRange" 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">
127
+ <option value="hour">Last Hour</option>
128
+ <option value="day">Last 24 Hours</option>
129
+ <option value="week">Last Week</option>
130
+ </select>
131
+ </div>
132
+ </div>
133
+ <div class="relative h-[300px]">
134
+ <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">
135
+ <div class="h-8 w-8 border-b-2 border-blue-500 rounded-full animate-spin"></div>
136
+ </div>
137
+ <canvas id="notifications_volume_chart"></canvas>
138
+ </div>
139
+ </div>
140
+ </div>
141
+
142
+ <div class="bg-white dark:bg-neutral-700 rounded-lg shadow">
143
+ <div class="p-6">
144
+ <div class="flex items-center justify-between mb-6">
145
+ <div>
146
+ <h3 class="font-medium text-base text-gray-900 dark:text-neutral-100">Delivery Time</h3>
147
+ <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Average time to deliver notifications</p>
148
+ </div>
149
+ </div>
150
+ <div class="relative h-[300px]">
151
+ <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">
152
+ <div class="h-8 w-8 border-b-2 border-blue-500 rounded-full animate-spin"></div>
153
+ </div>
154
+ <canvas id="notifications_delivery_chart"></canvas>
155
+ </div>
156
+ </div>
157
+ </div>
158
+ </div>
159
+ </div>
160
+
161
+ <div class="mt-8 px-4 sm:px-6 lg:px-8">
162
+ <div class="sm:flex sm:items-center">
163
+ <div class="sm:flex-auto">
164
+ <h3 class="font-medium text-base text-gray-900 dark:text-neutral-100">Channel Statistics</h3>
165
+ <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Detailed breakdown by notification channel</p>
166
+ </div>
167
+ </div>
168
+
169
+ <div class="grid gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 mt-6">
170
+ <template :for="channel in channelStatsList">
171
+ <div class="p-6 bg-white dark:bg-neutral-700 rounded-lg shadow">
172
+ <div class="flex items-center justify-between mb-6">
173
+ <h4 class="inline-flex items-center px-2.5 py-1 space-x-2 font-medium text-gray-800 text-sm dark:text-neutral-200 bg-gray-100 dark:bg-neutral-600 rounded-full">
174
+ <div class="h-4 w-4 {{ getChannelIcon(channel.name) }}"></div>
175
+ <span class="capitalize">{{ channel.name }}</span>
176
+ </h4>
177
+ </div>
178
+
179
+ <div class="space-y-6">
180
+ <div class="grid gap-4 grid-cols-4">
181
+ <template :for="entry in channel.entries">
182
+ <div class="text-center">
183
+ <div class="font-mono font-semibold text-2xl {{ statusValueClass(entry.status) }}">{{ formatNumber(entry.value) }}</div>
184
+ <div class="capitalize text-gray-500 text-xs dark:text-neutral-400">{{ entry.status }}</div>
185
+ </div>
186
+ </template>
187
+ </div>
188
+
189
+ <div class="overflow-hidden h-2.5 bg-gray-100 dark:bg-neutral-600 rounded-full">
190
+ <div class="flex h-full">
191
+ <div class="h-full bg-green-500" style="width: {{ channel.deliveredPercent }}%"></div>
192
+ <div class="h-full bg-red-500" style="width: {{ channel.failedPercent }}%"></div>
193
+ </div>
194
+ </div>
195
+ <div class="flex justify-between text-gray-500 text-sm dark:text-neutral-400">
196
+ <span>Success Rate: {{ channel.deliveredPercent }}%</span>
197
+ <span>Failure Rate: {{ channel.failedPercent }}%</span>
198
+ </div>
199
+ </div>
200
+ </div>
201
+ </template>
202
+ </div>
203
+ </div>
204
+ </div>
205
+
206
+ <script client>
207
+
208
+ interface ChannelStats {
209
+ sent: number
210
+ delivered: number
211
+ failed: number
212
+ pending: number
213
+ }
214
+
215
+ interface NotificationEntry {
216
+ id: string
217
+ type: 'email' | 'sms' | 'push' | 'discord' | 'slack'
218
+ recipient: string
219
+ subject: string
220
+ status: 'sent' | 'delivered' | 'failed' | 'pending'
221
+ sent_at: string
222
+ delivered_at?: string
223
+ error?: string
224
+ }
225
+
226
+ interface ChartLike { destroy: () => void }
227
+ type ChartCtor = new (canvas: HTMLElement, config: { type: string, data: unknown, options?: unknown }) => ChartLike
228
+
229
+ const notificationStats = state({
230
+ total_sent: 45_678,
231
+ delivery_rate: 98.5,
232
+ avg_delivery_time: 1.2,
233
+ })
234
+
235
+ const channelStats = state<Record<string, ChannelStats>>({
236
+ email: { sent: 25_000, delivered: 24_800, failed: 150, pending: 50 },
237
+ sms: { sent: 12_000, delivered: 11_900, failed: 80, pending: 20 },
238
+ push: { sent: 5_000, delivered: 4_950, failed: 30, pending: 20 },
239
+ discord: { sent: 2_000, delivered: 1_990, failed: 5, pending: 5 },
240
+ slack: { sent: 1678, delivered: 1670, failed: 5, pending: 3 },
241
+ })
242
+
243
+ const recentNotifications = state<NotificationEntry[]>([
244
+ { id: '1', type: 'email', recipient: 'user@example.com', subject: 'Welcome to Our Platform', status: 'delivered', sent_at: '2024-03-14 10:15:23', delivered_at: '2024-03-14 10:15:25' },
245
+ { id: '2', type: 'sms', recipient: '+1 (234) 567-890', subject: 'Your verification code: 123456', status: 'failed', sent_at: '2024-03-14 10:14:00', error: 'Invalid phone number' },
246
+ { id: '3', type: 'push', recipient: 'device-token-123', subject: 'New message received', status: 'delivered', sent_at: '2024-03-14 10:16:00', delivered_at: '2024-03-14 10:16:02' },
247
+ { id: '4', type: 'discord', recipient: 'Channel #announcements', subject: 'System update completed', status: 'delivered', sent_at: '2024-03-14 10:17:00', delivered_at: '2024-03-14 10:17:01' },
248
+ { id: '5', type: 'slack', recipient: '#general', subject: 'Deployment successful', status: 'pending', sent_at: '2024-03-14 10:18:00' },
249
+ ])
250
+
251
+ const timeRange = state('hour')
252
+ const isLoading = state(false)
253
+
254
+ let chartHandles: Array<{ destroy: () => void }> = []
255
+
256
+ const notificationStatusColors: Record<string, string> = {
257
+ delivered: 'text-green-700 dark:text-green-300 bg-green-50 dark:bg-green-900/50 ring-green-600/20',
258
+ sent: 'text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-900/50 ring-blue-600/20',
259
+ pending: 'text-yellow-700 dark:text-yellow-300 bg-yellow-50 dark:bg-yellow-900/50 ring-yellow-600/20',
260
+ failed: 'text-red-700 dark:text-red-300 bg-red-50 dark:bg-red-900/50 ring-red-600/20',
261
+ }
262
+
263
+ function getStatusColor(status: string): string {
264
+ return notificationStatusColors[status] || 'text-gray-700 dark:text-neutral-300 bg-gray-50 dark:bg-neutral-900/50 ring-gray-600/20'
265
+ }
266
+
267
+ function getChannelIcon(type: string): string {
268
+ switch (type) {
269
+ case 'email': return 'i-hugeicons-mail-01'
270
+ case 'sms': return 'i-hugeicons-smart-phone-01'
271
+ case 'push': return 'i-hugeicons-notification-01'
272
+ case 'discord': return 'i-hugeicons-discord'
273
+ case 'slack': return 'i-hugeicons-slack'
274
+ default: return 'i-hugeicons-notification-03'
275
+ }
276
+ }
277
+
278
+ function formatNumber(num: number): string {
279
+ return num.toLocaleString()
280
+ }
281
+
282
+ function totalSentLabel(): string { return formatNumber(notificationStats().total_sent) }
283
+ function deliveryRate(): number { return notificationStats().delivery_rate }
284
+ function avgDeliveryTime(): number { return notificationStats().avg_delivery_time }
285
+
286
+ function statusValueClass(status: string): string {
287
+ switch (status) {
288
+ case 'delivered': return 'text-green-600 dark:text-green-400'
289
+ case 'failed': return 'text-red-600 dark:text-red-400'
290
+ case 'pending': return 'text-yellow-600 dark:text-yellow-400'
291
+ case 'sent': return 'text-blue-600 dark:text-blue-400'
292
+ default: return ''
293
+ }
294
+ }
295
+
296
+ function channelStatsList(): Array<{ name: string, deliveredPercent: string, failedPercent: string, entries: Array<{ status: string, value: number }> }> {
297
+ return Object.entries(channelStats()).map(([name, stats]) => ({
298
+ name,
299
+ deliveredPercent: ((stats.delivered / stats.sent) * 100).toFixed(1),
300
+ failedPercent: ((stats.failed / stats.sent) * 100).toFixed(1),
301
+ entries: [
302
+ { status: 'sent', value: stats.sent },
303
+ { status: 'delivered', value: stats.delivered },
304
+ { status: 'failed', value: stats.failed },
305
+ { status: 'pending', value: stats.pending },
306
+ ],
307
+ }))
308
+ }
309
+
310
+ function getVolumeData() {
311
+ const labels = Array.from({ length: 24 }, (_, i) => `${i}:00`)
312
+ return {
313
+ labels,
314
+ datasets: [
315
+ { label: 'Email', data: Array.from({ length: 24 }, () => Math.floor(Math.random() * 100) + 50), borderColor: 'rgb(59, 130, 246)', backgroundColor: 'rgba(59, 130, 246, 0.1)', fill: true },
316
+ { label: 'SMS', data: Array.from({ length: 24 }, () => Math.floor(Math.random() * 50) + 20), borderColor: 'rgb(16, 185, 129)', backgroundColor: 'rgba(16, 185, 129, 0.1)', fill: true },
317
+ { label: 'Push', data: Array.from({ length: 24 }, () => Math.floor(Math.random() * 30) + 10), borderColor: 'rgb(245, 158, 11)', backgroundColor: 'rgba(245, 158, 11, 0.1)', fill: true },
318
+ ],
319
+ }
320
+ }
321
+
322
+ function getDeliveryTimeData() {
323
+ const labels = Array.from({ length: 24 }, (_, i) => `${i}:00`)
324
+ return {
325
+ labels,
326
+ datasets: [{
327
+ label: 'Average Delivery Time (seconds)',
328
+ data: Array.from({ length: 24 }, () => Math.random() * 2 + 0.5),
329
+ borderColor: 'rgb(139, 92, 246)',
330
+ backgroundColor: 'rgba(139, 92, 246, 0.1)',
331
+ fill: true,
332
+ }],
333
+ }
334
+ }
335
+
336
+ const chartOptions = {
337
+ responsive: true,
338
+ maintainAspectRatio: false,
339
+ scales: {
340
+ y: { beginAtZero: true, grid: { color: 'rgba(200, 200, 200, 0.1)' }, ticks: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" } } },
341
+ x: { grid: { display: false }, ticks: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" } } },
342
+ },
343
+ plugins: {
344
+ legend: { display: true, position: 'top', align: 'end', labels: { color: 'rgb(156, 163, 175)', font: { family: "'JetBrains Mono', monospace" }, boxWidth: 12, padding: 15 } },
345
+ tooltip: { mode: 'index', intersect: false },
346
+ },
347
+ interaction: { mode: 'index', intersect: false },
348
+ }
349
+
350
+ onMount(async () => {
351
+ isLoading.set(true)
352
+ const { Chart, registerables } = await import('@stacksjs/charts')
353
+ Chart.register(...registerables)
354
+ const Ctor = Chart as unknown as ChartCtor
355
+
356
+ const volume = useChart({
357
+ Chart: Ctor,
358
+ id: 'notifications_volume_chart',
359
+ type: 'line',
360
+ data: getVolumeData(),
361
+ options: chartOptions,
362
+ })
363
+
364
+ const delivery = useChart({
365
+ Chart: Ctor,
366
+ id: 'notifications_delivery_chart',
367
+ type: 'line',
368
+ data: getDeliveryTimeData(),
369
+ options: chartOptions,
370
+ })
371
+
372
+ chartHandles = [volume.instance, delivery.instance].filter((c): c is ChartLike => c !== null)
373
+ await new Promise(resolve => setTimeout(resolve, 500))
374
+ isLoading.set(false)
375
+ })
376
+
377
+ onDestroy(() => {
378
+ chartHandles.forEach(c => c.destroy())
379
+ chartHandles = []
380
+ })
381
+ </script>
382
+
383
+ @endsection