@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,332 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ @title('Dashboard - SMS Notifications')
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="sm:flex sm:items-center">
8
+ <div class="sm:flex-auto">
9
+ <h1 class="font-semibold leading-6 text-base text-gray-900 dark:text-neutral-100">SMS Notifications</h1>
10
+ <p class="mt-2 text-gray-700 text-sm dark:text-neutral-300">Manage and monitor all SMS notifications sent through the system</p>
11
+ </div>
12
+ <div class="sm:flex-none mt-4 sm:ml-16 sm:mt-0">
13
+ <button @click="toggleFilters()" type="button" class="inline-flex items-center px-3 py-2 font-semibold text-gray-900 text-sm dark:text-neutral-100 bg-white dark:bg-neutral-600 hover:bg-gray-50 dark:hover:bg-neutral-500 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">
14
+ <div class="mr-2 h-5 w-5 i-hugeicons-filter"></div>
15
+ {{ filtersToggleLabel() }}
16
+ </button>
17
+ </div>
18
+ </div>
19
+
20
+ <div :show="showFilters" class="grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 mt-4">
21
+ <div class="flex-1 min-w-0">
22
+ <label for="search" class="sr-only">Search SMS notifications</label>
23
+ <div class="relative rounded-md shadow-sm">
24
+ <div class="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none">
25
+ <div class="h-5 w-5 text-gray-400 i-hugeicons-search-01"></div>
26
+ </div>
27
+ <input x-model="searchQuery" type="search" name="search" id="search" placeholder="Search by phone number or message..." class="block pl-10 py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-neutral-100 placeholder:text-gray-400 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 focus:ring-inset" />
28
+ </div>
29
+ </div>
30
+
31
+ <div>
32
+ <select x-model="selectedStatus" class="block pl-3 pr-10 py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-neutral-100 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">
33
+ <option value="all">All Statuses</option>
34
+ <option value="sent">Sent</option>
35
+ <option value="delivered">Delivered</option>
36
+ <option value="failed">Failed</option>
37
+ <option value="pending">Pending</option>
38
+ </select>
39
+ </div>
40
+
41
+ <div class="flex items-end">
42
+ <button @click="resetFilters()" type="button" class="px-3 py-2 font-semibold text-gray-900 text-sm dark:text-neutral-100 bg-white dark:bg-neutral-600 hover:bg-gray-50 dark:hover:bg-neutral-500 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">Reset Filters</button>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="flow-root mt-8">
47
+ <div class="overflow-x-auto -mx-4 -my-2 sm:-mx-6 lg:-mx-8">
48
+ <div class="inline-block py-2 sm:px-6 lg:px-8 min-w-full align-middle">
49
+ <div class="overflow-hidden ring-1 ring-black ring-opacity-5 sm:rounded-lg dark:ring-opacity-20 shadow">
50
+ <table class="min-w-full divide-gray-300 divide-y dark:divide-neutral-600">
51
+ <thead class="bg-gray-50 dark:bg-neutral-600">
52
+ <tr>
53
+ <th scope="col" class="pl-4 pr-3 py-3.5 sm:pl-6 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Recipient</th>
54
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Message</th>
55
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Status</th>
56
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-left text-sm dark:text-neutral-100">Provider</th>
57
+ <th scope="col" class="px-3 py-3.5 font-semibold text-gray-900 text-right text-sm dark:text-neutral-100 cursor-pointer" @click="toggleSort('sent_at')">
58
+ <div class="flex items-center justify-end">
59
+ Sent
60
+ <div :show="isSortedBy('sent_at')" class="ml-2">
61
+ <div :show="sortDirection() === 'desc'" class="h-4 w-4 i-hugeicons-chevron-down"></div>
62
+ <div :show="sortDirection() === 'asc'" class="h-4 w-4 i-hugeicons-chevron-up"></div>
63
+ </div>
64
+ <div :show="isUnsorted('sent_at')" class="ml-2">
65
+ <div class="h-4 w-4 text-gray-400 i-hugeicons-arrows-up-down"></div>
66
+ </div>
67
+ </div>
68
+ </th>
69
+ <th scope="col" class="relative pl-3 pr-4 py-3.5 sm:pr-6"><span class="sr-only">Actions</span></th>
70
+ </tr>
71
+ </thead>
72
+ <tbody class="bg-white dark:bg-neutral-700 divide-gray-200 divide-y dark:divide-neutral-600">
73
+ <tr :show="isLoading">
74
+ <td colspan="6" class="px-3 py-4 text-center text-gray-500 text-sm dark:text-neutral-400">
75
+ <div class="flex justify-center">
76
+ <div class="h-8 w-8 border-b-2 border-blue-500 rounded-full animate-spin"></div>
77
+ </div>
78
+ </td>
79
+ </tr>
80
+ <tr :show="hasNoNotifications">
81
+ <td colspan="6" class="px-3 py-4 text-center text-gray-500 text-sm dark:text-neutral-400">No SMS notifications found matching your criteria</td>
82
+ </tr>
83
+ <template :for="notification in paginatedNotifications">
84
+ <tr class="hover:bg-gray-50 dark:hover:bg-neutral-600/50">
85
+ <td class="pl-4 pr-3 py-4 sm:pl-6 font-medium text-gray-900 text-sm whitespace-nowrap dark:text-neutral-100">{{ notification.recipient }}</td>
86
+ <td class="px-3 py-4 text-gray-500 text-sm dark:text-neutral-400">
87
+ <div class="max-w-xs truncate">{{ notification.message }}</div>
88
+ </td>
89
+ <td class="px-3 py-4 text-sm whitespace-nowrap">
90
+ <NotificationStatusBadge :status="notification.status" />
91
+ </td>
92
+ <td class="px-3 py-4 text-gray-500 text-sm whitespace-nowrap dark:text-neutral-400">{{ notification.metadata?.provider }}</td>
93
+ <td class="px-3 py-4 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-400">{{ formatDate(notification.sent_at) }}</td>
94
+ <td class="relative pl-3 pr-4 py-4 sm:pr-6 font-medium text-right text-sm whitespace-nowrap">
95
+ <div class="flex justify-end space-x-2">
96
+ <button :show="{{ notification.status === 'failed' ? 'true' : 'false' }}" @click="handleRetry('{{ notification.id }}')" type="button" class="text-blue-600 hover:text-blue-900 dark:hover:text-blue-400">Retry</button>
97
+ <button @click="openErrorModal('{{ notification.id }}')" type="button" class="text-gray-600 dark:text-neutral-400 hover:text-gray-900 dark:hover:text-gray-200">View Logs</button>
98
+ </div>
99
+ </td>
100
+ </tr>
101
+ </template>
102
+ </tbody>
103
+ </table>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="flex items-center justify-between mt-4">
110
+ <div class="flex items-center">
111
+ <p class="text-gray-700 text-sm dark:text-neutral-300">
112
+ Showing <span class="font-medium">{{ rangeStart() }}</span> to <span class="font-medium">{{ rangeEnd() }}</span> of <span class="font-medium">{{ totalFiltered() }}</span> results
113
+ </p>
114
+ </div>
115
+ <div class="flex items-center space-x-2">
116
+ <button :show="canGoBack" type="button" class="inline-flex relative focus:z-10 items-center px-3 py-2 font-semibold text-gray-900 text-sm dark:text-neutral-100 bg-white dark:bg-neutral-600 hover:bg-gray-50 dark:hover:bg-neutral-500 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600" @click="previousPage()">Previous</button>
117
+ <button type="button" class="inline-flex relative focus:z-10 items-center px-3 py-2 font-semibold text-gray-900 text-sm dark:text-neutral-100 bg-white dark:bg-neutral-600 hover:bg-gray-50 dark:hover:bg-neutral-500 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 disabled:opacity-50" :disabled="isLastPage" @click="nextPage()">Next</button>
118
+ </div>
119
+ </div>
120
+ </div>
121
+
122
+ <NotificationErrorModal
123
+ :isOpen="isErrorModalOpen"
124
+ :notificationId="errorModalId"
125
+ notificationType="sms"
126
+ :errorMessage="errorModalMessage"
127
+ :sentAt="errorModalSentAt"
128
+ @close="closeErrorModal"
129
+ />
130
+ </div>
131
+
132
+ <script client>
133
+ interface SMSNotification {
134
+ id: string
135
+ recipient: string
136
+ message: string
137
+ status: 'sent' | 'delivered' | 'failed' | 'pending'
138
+ sent_at: string
139
+ delivered_at?: string
140
+ error?: string
141
+ metadata?: {
142
+ sender: string
143
+ country: string
144
+ provider: string
145
+ segments: number
146
+ cost: number
147
+ }
148
+ }
149
+
150
+ const notifications = state<SMSNotification[]>([])
151
+ const currentPage = state(1)
152
+ const perPage = state(10)
153
+ const isLoading = state(true)
154
+ const searchQuery = state('')
155
+ const selectedStatus = state('all')
156
+ const showFilters = state(false)
157
+ const sortField = state<string | null>(null)
158
+ const sortDirection = state<'asc' | 'desc'>('desc')
159
+
160
+ const isErrorModalOpen = state(false)
161
+ const errorModalId = state('')
162
+ const errorModalMessage = state('')
163
+ const errorModalSentAt = state('')
164
+
165
+ function generateMockSMSNotifications(): SMSNotification[] {
166
+ const statuses: Array<SMSNotification['status']> = ['sent', 'delivered', 'failed', 'pending']
167
+ const messages = [
168
+ 'Your verification code is: 123456',
169
+ 'Your appointment is confirmed for tomorrow at 2 PM',
170
+ 'Your order has been shipped',
171
+ 'Your payment of $99.99 has been processed',
172
+ 'Your password has been reset',
173
+ 'Your account has been updated',
174
+ 'Your subscription will renew in 3 days',
175
+ 'Your 2FA code is: 987654',
176
+ ]
177
+ const countries = ['US', 'UK', 'CA', 'AU', 'DE', 'FR', 'JP', 'BR']
178
+ const providers = ['Twilio', 'Nexmo', 'MessageBird', 'Plivo', 'Sinch']
179
+
180
+ return Array.from({ length: 100 }, (_, i) => {
181
+ const status = statuses[Math.floor(Math.random() * statuses.length)] as SMSNotification['status']
182
+ const message = messages[Math.floor(Math.random() * messages.length)] || 'SMS notification'
183
+ const country = countries[Math.floor(Math.random() * countries.length)] || 'US'
184
+ const provider = providers[Math.floor(Math.random() * providers.length)] || 'Twilio'
185
+ const sent_at = new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString()
186
+ const delivered_at = status === 'delivered' ? new Date(new Date(sent_at).getTime() + Math.random() * 60000).toISOString() : undefined
187
+
188
+ return {
189
+ id: `${i + 1}`,
190
+ recipient: `+1${Math.floor(Math.random() * 900) + 100}${Math.floor(Math.random() * 900) + 100}${Math.floor(Math.random() * 9000) + 1000}`,
191
+ message,
192
+ status,
193
+ sent_at,
194
+ delivered_at,
195
+ error: status === 'failed' ? 'Failed to deliver SMS' : undefined,
196
+ metadata: {
197
+ sender: `+1${Math.floor(Math.random() * 900) + 100}${Math.floor(Math.random() * 900) + 100}${Math.floor(Math.random() * 9000) + 1000}`,
198
+ country,
199
+ provider,
200
+ segments: Math.floor(Math.random() * 3) + 1,
201
+ cost: Number.parseFloat((Math.random() * 0.05 + 0.01).toFixed(4)),
202
+ },
203
+ }
204
+ })
205
+ }
206
+
207
+ const filteredNotifications = derived(() => {
208
+ const list = notifications()
209
+ const status = selectedStatus()
210
+ const q = searchQuery().toLowerCase()
211
+ return list.filter((n) => {
212
+ if (status !== 'all' && n.status !== status)
213
+ return false
214
+ if (q)
215
+ return n.message.toLowerCase().includes(q) || n.recipient.toLowerCase().includes(q)
216
+ return true
217
+ })
218
+ })
219
+
220
+ const sortedNotifications = derived(() => {
221
+ const field = sortField()
222
+ if (!field)
223
+ return filteredNotifications()
224
+ const dir = sortDirection()
225
+ return [...filteredNotifications()].sort((a, b) => {
226
+ const aValue = (a as Record<string, unknown>)[field] as string | undefined
227
+ const bValue = (b as Record<string, unknown>)[field] as string | undefined
228
+ if (!aValue && !bValue)
229
+ return 0
230
+ if (!aValue)
231
+ return 1
232
+ if (!bValue)
233
+ return -1
234
+ const comparison = new Date(aValue).getTime() - new Date(bValue).getTime()
235
+ return dir === 'asc' ? comparison : -comparison
236
+ })
237
+ })
238
+
239
+ const paginatedNotifications = derived(() => {
240
+ const start = (currentPage() - 1) * perPage()
241
+ return sortedNotifications().slice(start, start + perPage())
242
+ })
243
+
244
+ const totalPages = derived(() => Math.max(1, Math.ceil(filteredNotifications().length / perPage())))
245
+ const totalFiltered = derived(() => filteredNotifications().length)
246
+ const rangeStart = derived(() => totalFiltered() === 0 ? 0 : (currentPage() - 1) * perPage() + 1)
247
+ const rangeEnd = derived(() => Math.min(currentPage() * perPage(), totalFiltered()))
248
+ const hasNoNotifications = derived(() => !isLoading() && paginatedNotifications().length === 0)
249
+ const canGoBack = derived(() => currentPage() > 1)
250
+ const isLastPage = derived(() => currentPage() >= totalPages())
251
+
252
+ function isSortedBy(field: string): boolean {
253
+ return sortField() === field
254
+ }
255
+
256
+ function isUnsorted(field: string): boolean {
257
+ return sortField() !== field
258
+ }
259
+
260
+ function filtersToggleLabel(): string {
261
+ return showFilters() ? 'Hide Filters' : 'Show Filters'
262
+ }
263
+
264
+ function toggleFilters(): void {
265
+ showFilters.update(v => !v)
266
+ }
267
+
268
+ function previousPage(): void {
269
+ if (currentPage() > 1)
270
+ currentPage.update(p => p - 1)
271
+ }
272
+
273
+ function nextPage(): void {
274
+ if (currentPage() < totalPages())
275
+ currentPage.update(p => p + 1)
276
+ }
277
+
278
+ function resetFilters(): void {
279
+ selectedStatus.set('all')
280
+ searchQuery.set('')
281
+ currentPage.set(1)
282
+ }
283
+
284
+ function formatDate(date: string): string {
285
+ return new Date(date).toLocaleString()
286
+ }
287
+
288
+ function toggleSort(field: string): void {
289
+ if (sortField() === field)
290
+ sortDirection.set(sortDirection() === 'asc' ? 'desc' : 'asc')
291
+ else {
292
+ sortField.set(field)
293
+ sortDirection.set('desc')
294
+ }
295
+ }
296
+
297
+ function handleRetry(id: string): void {
298
+ // eslint-disable-next-line no-console
299
+ console.log('Retrying SMS notification:', id)
300
+ }
301
+
302
+ function openErrorModal(id: string): void {
303
+ const target = notifications().find(n => n.id === id)
304
+ if (!target)
305
+ return
306
+ errorModalId.set(target.id)
307
+ errorModalMessage.set(target.error || 'Unknown error')
308
+ errorModalSentAt.set(target.sent_at)
309
+ isErrorModalOpen.set(true)
310
+ }
311
+
312
+ function closeErrorModal(): void {
313
+ isErrorModalOpen.set(false)
314
+ }
315
+
316
+ onMount(async () => {
317
+ isLoading.set(true)
318
+ try {
319
+ await new Promise(resolve => setTimeout(resolve, 1000))
320
+ notifications.set(generateMockSMSNotifications())
321
+ }
322
+ catch (error) {
323
+ // eslint-disable-next-line no-console
324
+ console.error('Failed to load SMS notifications:', error)
325
+ }
326
+ finally {
327
+ isLoading.set(false)
328
+ }
329
+ })
330
+ </script>
331
+
332
+ @endsection
@@ -0,0 +1,195 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ <script client>
5
+
6
+ interface PackageRow {
7
+ name: string
8
+ version: string
9
+ description: string
10
+ downloads: number
11
+ contributors: number
12
+ issues: number
13
+ size: string
14
+ createdAt: string
15
+ url: string
16
+ }
17
+
18
+ // Placeholder data — moved out of the former `<script server>` block
19
+ // (stacksjs/stacks#1838). Wire this up to the npm registry once the
20
+ // dashboard exposes a `GET /api/dashboard/packages` endpoint that
21
+ // returns the same shape (`name/version/downloads/...`). Until then,
22
+ // this snapshot mirrors what stacks-org publishes.
23
+ const packages: PackageRow[] = [
24
+ { name: 'stacks', version: 'v0.71.1', description: 'A modern Full Stack TypeScript framework', downloads: 1001897, contributors: 24, issues: 12, size: '5.2 kB', createdAt: '2024-01-15', url: 'https://github.com/stacksjs/stacks' },
25
+ { name: 'qrx', version: 'v1.0.0', description: 'High-performance QR code generator and reader', downloads: 71897, contributors: 24, issues: 12, size: '5.2 kB', createdAt: '2024-01-15', url: 'https://github.com/stacksjs/qrx' },
26
+ { name: 'rpx', version: 'v2.1.3', description: 'Reverse proxy for the modern web', downloads: 52438, contributors: 16, issues: 8, size: '4.8 kB', createdAt: '2024-01-20', url: 'https://github.com/stacksjs/rpx' },
27
+ { name: 'tlsx', version: 'v0.9.0', description: 'Modern TLS/SSL toolkit for Node.js', downloads: 23567, contributors: 9, issues: 15, size: '7.1 kB', createdAt: '2024-01-25', url: 'https://github.com/stacksjs/tlsx' },
28
+ { name: 'dtsx', version: 'v1.2.0', description: 'Advanced TypeScript .d.ts tooling', downloads: 34892, contributors: 12, issues: 6, size: '3.9 kB', createdAt: '2024-01-30', url: 'https://github.com/stacksjs/dtsx' },
29
+ { name: 'bunfig', version: 'v0.8.0', description: 'Configuration management for Bun projects', downloads: 18234, contributors: 7, issues: 10, size: '2.8 kB', createdAt: '2024-02-05', url: 'https://github.com/stacksjs/bunfig' },
30
+ { name: 'localtunnels', version: 'v1.5.0', description: 'Secure local tunnel creation made easy', downloads: 45673, contributors: 19, issues: 14, size: '6.3 kB', createdAt: '2024-02-10', url: 'https://github.com/stacksjs/localtunnels' },
31
+ { name: 'ts-collect', version: 'v2.0.1', description: 'Collection utilities for TypeScript', downloads: 28945, contributors: 11, issues: 9, size: '4.1 kB', createdAt: '2024-02-15', url: 'https://github.com/stacksjs/ts-collect' },
32
+ { name: 'ts-spreadsheets', version: 'v1.3.2', description: 'TypeScript spreadsheet generation', downloads: 39567, contributors: 15, issues: 11, size: '8.2 kB', createdAt: '2024-02-20', url: 'https://github.com/stacksjs/ts-spreadsheets' },
33
+ { name: 'bun-plugin-auto-imports', version: 'v0.6.0', description: 'Automatic import handling for Bun', downloads: 15678, contributors: 5, issues: 7, size: '3.4 kB', createdAt: '2024-02-25', url: 'https://github.com/stacksjs/bun-plugin-auto-imports' },
34
+ { name: 'bun-plugin-dtsx', version: 'v0.5.0', description: 'DTSX support for Bun', downloads: 12345, contributors: 4, issues: 5, size: '2.9 kB', createdAt: '2024-03-01', url: 'https://github.com/stacksjs/bun-plugin-dtsx' },
35
+ { name: 'vite-plugin-local', version: 'v1.1.0', description: 'Local development enhancements for Vite', downloads: 31456, contributors: 8, issues: 13, size: '4.7 kB', createdAt: '2024-03-05', url: 'https://github.com/stacksjs/vite-plugin-local' },
36
+ ]
37
+
38
+ const totalDownloads = packages.reduce((s, p) => s + p.downloads, 0)
39
+ const totalContributors = packages.reduce((s, p) => s + p.contributors, 0)
40
+ const totalIssues = packages.reduce((s, p) => s + p.issues, 0)
41
+ const totalPackages = packages.length
42
+
43
+ function formatNumber(n: number): string {
44
+ if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`
45
+ if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`
46
+ return n.toString()
47
+ }
48
+
49
+ function downloadsBadgeVariant(n: number) {
50
+ if (n >= 100_000) return 'success'
51
+ if (n >= 10_000) return 'primary'
52
+ return 'default'
53
+ }
54
+
55
+ const sortedPackages = [...packages].sort((a, b) => b.downloads - a.downloads)
56
+ </script>
57
+
58
+ <div class="mx-auto pb-12 pt-6 px-6 space-y-6 max-w-6xl">
59
+
60
+ <PageHeader
61
+ title="Packages"
62
+ description="Open-source packages published from this monorepo"
63
+ >
64
+ <template #actions>
65
+ <Button variant="primary" size="md">Add package</Button>
66
+ </template>
67
+ </PageHeader>
68
+
69
+ <!-- Stats -->
70
+ <div class="grid gap-3 grid-cols-2 lg:grid-cols-4">
71
+ <Card variant="default" padding="md">
72
+ <div class="flex gap-3 items-center">
73
+ <div class="flex flex-shrink-0 items-center justify-center h-10 w-10 text-blue-600 dark:text-blue-400 bg-blue-500/10 dark:bg-blue-400/15 rounded-lg">
74
+ <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
75
+ <path stroke-linecap="round" stroke-linejoin="round" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/>
76
+ </svg>
77
+ </div>
78
+ <div class="min-w-0">
79
+ <p class="text-[11px] text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Packages</p>
80
+ <p class="font-semibold leading-tight text-2xl text-neutral-900 tracking-tight dark:text-white">{{ totalPackages }}</p>
81
+ </div>
82
+ </div>
83
+ </Card>
84
+ <Card variant="default" padding="md">
85
+ <div class="flex gap-3 items-center">
86
+ <div class="flex flex-shrink-0 items-center justify-center h-10 w-10 text-green-600 dark:text-green-400 bg-green-500/10 dark:bg-green-400/15 rounded-lg">
87
+ <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
88
+ <path stroke-linecap="round" stroke-linejoin="round" d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5 5-5M12 15V3"/>
89
+ </svg>
90
+ </div>
91
+ <div class="min-w-0">
92
+ <p class="text-[11px] text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Downloads</p>
93
+ <p class="font-semibold leading-tight text-2xl text-neutral-900 tracking-tight dark:text-white">{{ formatNumber(totalDownloads) }}</p>
94
+ </div>
95
+ </div>
96
+ </Card>
97
+ <Card variant="default" padding="md">
98
+ <div class="flex gap-3 items-center">
99
+ <div class="flex flex-shrink-0 items-center justify-center h-10 w-10 text-purple-600 dark:text-purple-400 bg-purple-500/10 dark:bg-purple-400/15 rounded-lg">
100
+ <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
101
+ <path stroke-linecap="round" stroke-linejoin="round" d="M17 20h5v-2a4 4 0 00-3-3.87M9 20H4v-2a4 4 0 013-3.87m6-5.13a4 4 0 11-8 0 4 4 0 018 0zm6 0a3 3 0 11-6 0 3 3 0 016 0z"/>
102
+ </svg>
103
+ </div>
104
+ <div class="min-w-0">
105
+ <p class="text-[11px] text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Contributors</p>
106
+ <p class="font-semibold leading-tight text-2xl text-neutral-900 tracking-tight dark:text-white">{{ totalContributors }}</p>
107
+ </div>
108
+ </div>
109
+ </Card>
110
+ <Card variant="default" padding="md">
111
+ <div class="flex gap-3 items-center">
112
+ <div class="flex flex-shrink-0 items-center justify-center h-10 w-10 text-amber-600 dark:text-amber-400 bg-amber-500/10 dark:bg-amber-400/15 rounded-lg">
113
+ <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
114
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01M5.07 19h13.86c1.54 0 2.5-1.67 1.73-3L13.73 4a2 2 0 00-3.46 0L3.34 16c-.77 1.33.19 3 1.73 3z"/>
115
+ </svg>
116
+ </div>
117
+ <div class="min-w-0">
118
+ <p class="text-[11px] text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Open issues</p>
119
+ <p class="font-semibold leading-tight text-2xl text-neutral-900 tracking-tight dark:text-white">{{ totalIssues }}</p>
120
+ </div>
121
+ </div>
122
+ </Card>
123
+ </div>
124
+
125
+ <!-- Packages table -->
126
+ <Card variant="default" padding="none">
127
+ <div class="flex items-baseline justify-between px-5 py-4 border-b border-neutral-200/60 dark:border-white/5">
128
+ <div>
129
+ <h3 class="font-semibold text-base text-neutral-900 dark:text-white">All packages</h3>
130
+ <p class="mt-0.5 text-neutral-500 text-xs dark:text-neutral-400">
131
+ {{ totalPackages }} packages, sorted by downloads
132
+ </p>
133
+ </div>
134
+ </div>
135
+
136
+ @if(packages.length === 0)
137
+ <div class="p-8">
138
+ <EmptyState
139
+ title="No packages yet"
140
+ description="Publish your first package from the monorepo."
141
+ />
142
+ </div>
143
+ @else
144
+ <div class="overflow-x-auto">
145
+ <table class="min-w-full divide-neutral-200/60 divide-y dark:divide-white/5">
146
+ <thead class="bg-neutral-50/60 dark:bg-white/[0.02]">
147
+ <tr>
148
+ <th class="px-5 py-2.5 font-medium text-[11px] text-left text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Package</th>
149
+ <th class="px-5 py-2.5 font-medium text-[11px] text-left text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Version</th>
150
+ <th class="px-5 py-2.5 font-medium text-[11px] text-neutral-500 text-right tracking-wider uppercase dark:text-neutral-400">Downloads</th>
151
+ <th class="px-5 py-2.5 font-medium text-[11px] text-neutral-500 text-right tracking-wider uppercase dark:text-neutral-400">Contributors</th>
152
+ <th class="px-5 py-2.5 font-medium text-[11px] text-neutral-500 text-right tracking-wider uppercase dark:text-neutral-400">Issues</th>
153
+ <th class="px-5 py-2.5 font-medium text-[11px] text-left text-neutral-500 tracking-wider uppercase dark:text-neutral-400">Size</th>
154
+ <th class="px-5 py-2.5 text-right">
155
+ <span class="sr-only">Actions</span>
156
+ </th>
157
+ </tr>
158
+ </thead>
159
+ <tbody class="divide-neutral-200/60 divide-y dark:divide-white/5">
160
+ <template :for="pkg in sortedPackages">
161
+ <tr class="hover:bg-neutral-50/60 dark:hover:bg-white/[0.02] transition-colors">
162
+ <td class="px-5 py-3 whitespace-nowrap">
163
+ <div class="font-medium text-neutral-900 text-sm dark:text-white">{{ pkg.name }}</div>
164
+ <div class="mt-0.5 max-w-xs text-neutral-500 text-xs truncate dark:text-neutral-400">{{ pkg.description }}</div>
165
+ </td>
166
+ <td class="px-5 py-3 font-mono text-neutral-600 text-xs whitespace-nowrap dark:text-neutral-300">
167
+ {{ pkg.version }}
168
+ </td>
169
+ <td class="px-5 py-3 text-right whitespace-nowrap">
170
+ <Badge :variant="downloadsBadgeVariant(pkg.downloads)" size="sm">{{ formatNumber(pkg.downloads) }}</Badge>
171
+ </td>
172
+ <td class="px-5 py-3 text-neutral-600 text-right text-sm whitespace-nowrap dark:text-neutral-300">
173
+ {{ pkg.contributors }}
174
+ </td>
175
+ <td class="px-5 py-3 text-neutral-600 text-right text-sm whitespace-nowrap dark:text-neutral-300">
176
+ {{ pkg.issues }}
177
+ </td>
178
+ <td class="px-5 py-3 font-mono text-neutral-500 text-xs whitespace-nowrap dark:text-neutral-400">
179
+ {{ pkg.size }}
180
+ </td>
181
+ <td class="px-5 py-3 text-right whitespace-nowrap">
182
+ <a :href="pkg.url" target="_blank" rel="noopener" class="text-blue-600 text-sm dark:text-blue-400 hover:underline">
183
+ GitHub
184
+ </a>
185
+ </td>
186
+ </tr>
187
+ </template>
188
+ </tbody>
189
+ </table>
190
+ </div>
191
+ @endif
192
+ </Card>
193
+
194
+ </div>
195
+ @endsection