@stacksjs/defaults 0.70.207 → 0.70.208
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/TODO.md +21 -0
- package/ai/AGENTS.md +79 -0
- package/ai/README.md +45 -0
- package/ai/claude/launch.json +12 -0
- package/ai/skills/stacks-actions/SKILL.md +128 -0
- package/ai/skills/stacks-ai/SKILL.md +276 -0
- package/ai/skills/stacks-alias/SKILL.md +94 -0
- package/ai/skills/stacks-analytics/SKILL.md +91 -0
- package/ai/skills/stacks-api/SKILL.md +738 -0
- package/ai/skills/stacks-arrays/SKILL.md +277 -0
- package/ai/skills/stacks-auth/SKILL.md +422 -0
- package/ai/skills/stacks-auto-imports/SKILL.md +138 -0
- package/ai/skills/stacks-brandkit/SKILL.md +811 -0
- package/ai/skills/stacks-browse/SKILL.md +127 -0
- package/ai/skills/stacks-browse/scripts/browse.ts +492 -0
- package/ai/skills/stacks-browser/SKILL.md +145 -0
- package/ai/skills/stacks-buddy/SKILL.md +676 -0
- package/ai/skills/stacks-build/SKILL.md +163 -0
- package/ai/skills/stacks-cache/SKILL.md +125 -0
- package/ai/skills/stacks-calendar/SKILL.md +113 -0
- package/ai/skills/stacks-chat/SKILL.md +371 -0
- package/ai/skills/stacks-cli/SKILL.md +112 -0
- package/ai/skills/stacks-cloud/SKILL.md +192 -0
- package/ai/skills/stacks-cms/SKILL.md +217 -0
- package/ai/skills/stacks-collections/SKILL.md +82 -0
- package/ai/skills/stacks-commerce/SKILL.md +114 -0
- package/ai/skills/stacks-composables/SKILL.md +161 -0
- package/ai/skills/stacks-config/SKILL.md +144 -0
- package/ai/skills/stacks-configuration/SKILL.md +154 -0
- package/ai/skills/stacks-cron/SKILL.md +123 -0
- package/ai/skills/stacks-crosswind/SKILL.md +190 -0
- package/ai/skills/stacks-dashboard/SKILL.md +173 -0
- package/ai/skills/stacks-database/SKILL.md +286 -0
- package/ai/skills/stacks-datetime/SKILL.md +269 -0
- package/ai/skills/stacks-dependencies/SKILL.md +111 -0
- package/ai/skills/stacks-deploy/SKILL.md +102 -0
- package/ai/skills/stacks-design-brutalist/SKILL.md +110 -0
- package/ai/skills/stacks-design-minimalist/SKILL.md +115 -0
- package/ai/skills/stacks-design-output/SKILL.md +55 -0
- package/ai/skills/stacks-design-soft/SKILL.md +156 -0
- package/ai/skills/stacks-design-taste/SKILL.md +1012 -0
- package/ai/skills/stacks-design-taste-codex/SKILL.md +294 -0
- package/ai/skills/stacks-desktop/SKILL.md +78 -0
- package/ai/skills/stacks-development/SKILL.md +298 -0
- package/ai/skills/stacks-dns/SKILL.md +149 -0
- package/ai/skills/stacks-docs/SKILL.md +109 -0
- package/ai/skills/stacks-email/SKILL.md +236 -0
- package/ai/skills/stacks-enums/SKILL.md +100 -0
- package/ai/skills/stacks-env/SKILL.md +181 -0
- package/ai/skills/stacks-error-handling/SKILL.md +137 -0
- package/ai/skills/stacks-events/SKILL.md +228 -0
- package/ai/skills/stacks-faker/SKILL.md +158 -0
- package/ai/skills/stacks-git/SKILL.md +158 -0
- package/ai/skills/stacks-guard/SKILL.md +98 -0
- package/ai/skills/stacks-health/SKILL.md +75 -0
- package/ai/skills/stacks-http/SKILL.md +316 -0
- package/ai/skills/stacks-i18n/SKILL.md +198 -0
- package/ai/skills/stacks-image-to-code/SKILL.md +629 -0
- package/ai/skills/stacks-imagegen-mobile/SKILL.md +1474 -0
- package/ai/skills/stacks-imagegen-web/SKILL.md +998 -0
- package/ai/skills/stacks-investigate/SKILL.md +119 -0
- package/ai/skills/stacks-jobs/SKILL.md +136 -0
- package/ai/skills/stacks-lint/SKILL.md +184 -0
- package/ai/skills/stacks-listeners/SKILL.md +99 -0
- package/ai/skills/stacks-logging/SKILL.md +78 -0
- package/ai/skills/stacks-mail/SKILL.md +120 -0
- package/ai/skills/stacks-middleware/SKILL.md +249 -0
- package/ai/skills/stacks-migrations/SKILL.md +105 -0
- package/ai/skills/stacks-models/SKILL.md +267 -0
- package/ai/skills/stacks-new-feature/SKILL.md +206 -0
- package/ai/skills/stacks-notifications/SKILL.md +210 -0
- package/ai/skills/stacks-objects/SKILL.md +205 -0
- package/ai/skills/stacks-office-hours/SKILL.md +134 -0
- package/ai/skills/stacks-orm/SKILL.md +342 -0
- package/ai/skills/stacks-path/SKILL.md +118 -0
- package/ai/skills/stacks-payments/SKILL.md +373 -0
- package/ai/skills/stacks-plan-review/SKILL.md +152 -0
- package/ai/skills/stacks-plugins/SKILL.md +149 -0
- package/ai/skills/stacks-push/SKILL.md +376 -0
- package/ai/skills/stacks-query-builder/SKILL.md +128 -0
- package/ai/skills/stacks-queue/SKILL.md +559 -0
- package/ai/skills/stacks-realtime/SKILL.md +442 -0
- package/ai/skills/stacks-redesign/SKILL.md +182 -0
- package/ai/skills/stacks-registry/SKILL.md +58 -0
- package/ai/skills/stacks-repl/SKILL.md +80 -0
- package/ai/skills/stacks-retro/SKILL.md +122 -0
- package/ai/skills/stacks-review/SKILL.md +135 -0
- package/ai/skills/stacks-router/SKILL.md +231 -0
- package/ai/skills/stacks-routes/SKILL.md +105 -0
- package/ai/skills/stacks-scaffolding/SKILL.md +162 -0
- package/ai/skills/stacks-scheduler/SKILL.md +363 -0
- package/ai/skills/stacks-search-engine/SKILL.md +112 -0
- package/ai/skills/stacks-security/SKILL.md +129 -0
- package/ai/skills/stacks-security-audit/SKILL.md +128 -0
- package/ai/skills/stacks-server/SKILL.md +458 -0
- package/ai/skills/stacks-shell/SKILL.md +62 -0
- package/ai/skills/stacks-slug/SKILL.md +87 -0
- package/ai/skills/stacks-sms/SKILL.md +385 -0
- package/ai/skills/stacks-socials/SKILL.md +303 -0
- package/ai/skills/stacks-storage/SKILL.md +576 -0
- package/ai/skills/stacks-strings/SKILL.md +416 -0
- package/ai/skills/stacks-stx/SKILL.md +176 -0
- package/ai/skills/stacks-technical-diagrams/LICENSE +22 -0
- package/ai/skills/stacks-technical-diagrams/SKILL.md +290 -0
- package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +4 -0
- package/ai/skills/stacks-technical-diagrams/assets/template.html +1252 -0
- package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +289 -0
- package/ai/skills/stacks-technical-diagrams/bunfig.toml +1 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +64 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +88 -0
- package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +75 -0
- package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +70 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +41 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +62 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +371 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +82 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +295 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +91 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +384 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +84 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +257 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +42 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +13 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +230 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +88 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +103 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +481 -0
- package/ai/skills/stacks-technical-diagrams/schemas/README.md +68 -0
- package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +121 -0
- package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +43 -0
- package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +221 -0
- package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +241 -0
- package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +186 -0
- package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +332 -0
- package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +297 -0
- package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +28 -0
- package/ai/skills/stacks-testing/SKILL.md +129 -0
- package/ai/skills/stacks-tunnel/SKILL.md +125 -0
- package/ai/skills/stacks-types/SKILL.md +178 -0
- package/ai/skills/stacks-ui/SKILL.md +246 -0
- package/ai/skills/stacks-utils/SKILL.md +444 -0
- package/ai/skills/stacks-validation/SKILL.md +371 -0
- package/ai/skills/stacks-whois/SKILL.md +315 -0
- package/assets/world-map-data.ts +121 -0
- package/bootstrap.ts +114 -0
- package/docs/api-examples.md +46 -0
- package/docs/index.md +24 -0
- package/docs/markdown-examples.md +87 -0
- package/functions/analytics.ts +97 -0
- package/functions/api.ts +143 -0
- package/functions/auth.ts +208 -0
- package/functions/billing/payments.ts +149 -0
- package/functions/blog.ts +120 -0
- package/functions/cms/categorizables.ts +107 -0
- package/functions/cms/pages.ts +108 -0
- package/functions/cms/posts.ts +100 -0
- package/functions/cms/taggables.ts +102 -0
- package/functions/commerce/coupons.ts +128 -0
- package/functions/commerce/customers.ts +128 -0
- package/functions/commerce/gift-cards.ts +119 -0
- package/functions/commerce/orders.ts +112 -0
- package/functions/commerce/payments.ts +119 -0
- package/functions/commerce/products/categories.ts +123 -0
- package/functions/commerce/products/manufacturers.ts +123 -0
- package/functions/commerce/products/products.ts +123 -0
- package/functions/commerce/products/reviews.ts +123 -0
- package/functions/commerce/products/units.ts +123 -0
- package/functions/commerce/products/variants.ts +123 -0
- package/functions/commerce/shippings/delivery-routes.ts +123 -0
- package/functions/commerce/shippings/digital-deliveries.ts +119 -0
- package/functions/commerce/shippings/drivers.ts +123 -0
- package/functions/commerce/shippings/license-keys.ts +123 -0
- package/functions/commerce/shippings/shipping-methods.ts +123 -0
- package/functions/commerce/shippings/shipping-rates.ts +119 -0
- package/functions/commerce/shippings/shipping-zones.ts +119 -0
- package/functions/commerce/taxes.ts +119 -0
- package/functions/commerce/waitlist/products.ts +123 -0
- package/functions/commerce/waitlist/restaurants.ts +123 -0
- package/functions/craft.ts +107 -0
- package/functions/dashboard.ts +153 -0
- package/functions/inbox.ts +95 -0
- package/functions/jobs.ts +86 -0
- package/functions/monitoring/errors.ts +295 -0
- package/functions/queue.ts +111 -0
- package/functions/realtime/websockets.ts +96 -0
- package/functions/realtime.ts +52 -0
- package/functions/releases.ts +49 -0
- package/functions/search.ts +126 -0
- package/functions/toasts.ts +95 -0
- package/functions/uploads.ts +216 -0
- package/ide/.gitignore +4 -0
- package/ide/cursor/rules/auto-imports.mdc +574 -0
- package/ide/cursor/rules/code-style.mdc +12 -0
- package/ide/cursor/rules/documentation.mdc +9 -0
- package/ide/cursor/rules/error-handling-validation.mdc +11 -0
- package/ide/cursor/rules/key-conventions.mdc +11 -0
- package/ide/cursor/rules/project-structure.mdc +169 -0
- package/ide/cursor/rules/readme.mdc +318 -0
- package/ide/cursor/rules/syntax-formatting.mdc +9 -0
- package/ide/cursor/rules/testing.mdc +10 -0
- package/ide/cursor/rules/typescript.mdc +9 -0
- package/ide/cursor/rules/ui-styling.mdc +0 -0
- package/ide/dictionary.txt +397 -0
- package/ide/jetbrains/.fleet/settings.json +4 -0
- package/ide/jetbrains/.idea/.gitignore +5 -0
- package/ide/jetbrains/.idea/.name +1 -0
- package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/ide/jetbrains/.idea/jsLinters/eslint.xml +7 -0
- package/ide/jetbrains/.idea/modules.xml +8 -0
- package/ide/jetbrains/.idea/stacks.iml +22 -0
- package/ide/jetbrains/.idea/vcs.xml +6 -0
- package/ide/jetbrains/.idea/webResources.xml +14 -0
- package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
- package/ide/jetbrains/installed.txt +4 -0
- package/ide/jetbrains/options/github-copilot.xml +5 -0
- package/ide/jetbrains/options/nodejs.xml +7 -0
- package/ide/jetbrains/options/templates.xml +124 -0
- package/ide/jetbrains/templates/JavaScript.xml +6 -0
- package/ide/jetbrains/templates/Stacks.xml +8 -0
- package/ide/vscode/.vscode/README.md +23 -0
- package/ide/vscode/.vscode/extensions.json +5 -0
- package/ide/vscode/.vscode/settings.json +176 -0
- package/ide/vscode/.vscode/stacks.code-snippets +181 -0
- package/ide/vscode/LICENSE.md +21 -0
- package/ide/vscode/README.md +36 -0
- package/ide/vscode/logo.png +0 -0
- package/ide/vscode/package.json +79 -0
- package/ide/zed/.zed/settings.json +139 -0
- package/lang/README.md +28 -0
- package/lang/de.yml +14 -0
- package/lang/en.yml +15 -0
- package/package.json +19 -3
- package/project/bootstrap +161 -0
- package/project/buddy +175 -0
- package/project/storage/framework/tsconfig.app.json +50 -0
- package/project/storage/framework/tsconfig.base.json +58 -0
- package/routes/core.ts +78 -0
- package/routes/dashboard-api.ts +233 -0
- package/routes/dashboard.ts +739 -0
- package/routes/email.ts +129 -0
- package/stores/[name].stx +16 -0
- package/stores/git.ts +71 -0
- package/stores/payment.ts +474 -0
- package/stores/queue.ts +43 -0
- package/stores/user.ts +29 -0
- package/stx-components-plugin.ts +25 -0
- package/styles/design-tokens.css +597 -0
- package/types/dashboard.ts +70 -0
- package/types/defaults.ts +438 -0
- package/vcs/github/CODE_OF_CONDUCT.md +83 -0
- package/vcs/github/CONTRIBUTING.md +187 -0
- package/vcs/github/EXPLANATIONS.md +41 -0
- package/vcs/github/FUNDING.yml +1 -0
- package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +49 -0
- package/vcs/github/ISSUE_TEMPLATE/config.yml +10 -0
- package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +44 -0
- package/vcs/github/SECURITY.md +70 -0
- package/vcs/github/renovate.json +5 -0
- package/vcs/github/stale.yml +14 -0
- package/vcs/github/workflows/README.md +16 -0
- package/vcs/github/workflows/ci.yml +114 -0
- package/vcs/github/workflows/export-size.yml +25 -0
- package/vcs/github/workflows/labeler.yml +13 -0
- package/vcs/github/workflows/release.yml +219 -0
- package/views/[...all].stx +8 -0
- package/views/about.md +3 -0
- package/views/auth/login.stx +1 -0
- package/views/auth/signup.stx +85 -0
- package/views/dashboard/.discovered-models.json +542 -0
- package/views/dashboard/AUDIT.md +904 -0
- package/views/dashboard/[...all].stx +89 -0
- package/views/dashboard/access-tokens/index.stx +177 -0
- package/views/dashboard/actions/index.stx +129 -0
- package/views/dashboard/analytics/blog/index.stx +356 -0
- package/views/dashboard/analytics/browsers/index.stx +263 -0
- package/views/dashboard/analytics/commerce/sales/index.stx +329 -0
- package/views/dashboard/analytics/commerce/web/index.stx +379 -0
- package/views/dashboard/analytics/countries/index.stx +289 -0
- package/views/dashboard/analytics/devices/index.stx +305 -0
- package/views/dashboard/analytics/events/index.stx +536 -0
- package/views/dashboard/analytics/index.stx +88 -0
- package/views/dashboard/analytics/marketing/index.stx +315 -0
- package/views/dashboard/analytics/pages/index.stx +271 -0
- package/views/dashboard/analytics/referrers/index.stx +319 -0
- package/views/dashboard/analytics/web/index.stx +356 -0
- package/views/dashboard/buddy/index.stx +198 -0
- package/views/dashboard/ci/index.stx +462 -0
- package/views/dashboard/cloud/index.stx +452 -0
- package/views/dashboard/commands/index.stx +295 -0
- package/views/dashboard/commerce/categories/index.stx +406 -0
- package/views/dashboard/commerce/coupons/index.stx +485 -0
- package/views/dashboard/commerce/customers/index.stx +410 -0
- package/views/dashboard/commerce/dashboard/index.stx +287 -0
- package/views/dashboard/commerce/delivery/delivery-routes.stx +305 -0
- package/views/dashboard/commerce/delivery/digital-delivery.stx +332 -0
- package/views/dashboard/commerce/delivery/drivers.stx +397 -0
- package/views/dashboard/commerce/delivery/index.stx +18 -0
- package/views/dashboard/commerce/delivery/license-keys.stx +380 -0
- package/views/dashboard/commerce/delivery/shipping-methods.stx +346 -0
- package/views/dashboard/commerce/delivery/shipping-rates.stx +338 -0
- package/views/dashboard/commerce/delivery/shipping-zones.stx +302 -0
- package/views/dashboard/commerce/delivery/tabs.ts +25 -0
- package/views/dashboard/commerce/gift-cards/index.stx +561 -0
- package/views/dashboard/commerce/manufacturers/index.stx +308 -0
- package/views/dashboard/commerce/orders/index.stx +247 -0
- package/views/dashboard/commerce/payments/index.stx +535 -0
- package/views/dashboard/commerce/pos/index.stx +653 -0
- package/views/dashboard/commerce/printers/devices/index.stx +273 -0
- package/views/dashboard/commerce/printers/receipts/index.stx +308 -0
- package/views/dashboard/commerce/products/detail.stx +563 -0
- package/views/dashboard/commerce/products/index.stx +370 -0
- package/views/dashboard/commerce/reviews/index.stx +656 -0
- package/views/dashboard/commerce/reviews/index.ts +0 -0
- package/views/dashboard/commerce/taxes/index.stx +377 -0
- package/views/dashboard/commerce/units/index.stx +317 -0
- package/views/dashboard/commerce/variants/index.stx +319 -0
- package/views/dashboard/commerce/waitlist/products.stx +942 -0
- package/views/dashboard/commerce/waitlist/restaurant.stx +1024 -0
- package/views/dashboard/components/index.stx +330 -0
- package/views/dashboard/composables/index.ts +19 -0
- package/views/dashboard/composables/useChart.ts +77 -0
- package/views/dashboard/composables/useNavigation.ts +99 -0
- package/views/dashboard/composables/useRole.ts +58 -0
- package/views/dashboard/composables/useTheme.ts +74 -0
- package/views/dashboard/content/authors/index.stx +171 -0
- package/views/dashboard/content/blog/index.stx +493 -0
- package/views/dashboard/content/categories/index.stx +169 -0
- package/views/dashboard/content/comments/index.stx +189 -0
- package/views/dashboard/content/dashboard.stx +383 -0
- package/views/dashboard/content/files/index.stx +706 -0
- package/views/dashboard/content/pages/index.stx +174 -0
- package/views/dashboard/content/posts/index.stx +269 -0
- package/views/dashboard/content/seo/index.stx +240 -0
- package/views/dashboard/content/tags/index.stx +167 -0
- package/views/dashboard/data/activity/index.stx +261 -0
- package/views/dashboard/data/dashboard/index.stx +116 -0
- package/views/dashboard/data/subscribers.stx +270 -0
- package/views/dashboard/data/teams.stx +275 -0
- package/views/dashboard/data/users.stx +279 -0
- package/views/dashboard/dependencies/index.stx +178 -0
- package/views/dashboard/deployments/[id].stx +234 -0
- package/views/dashboard/deployments/index.stx +9 -0
- package/views/dashboard/dns/index.stx +163 -0
- package/views/dashboard/environment/index.stx +283 -0
- package/views/dashboard/errors/index.stx +274 -0
- package/views/dashboard/forgot-password.stx +57 -0
- package/views/dashboard/functions/index.stx +159 -0
- package/views/dashboard/health/index.stx +248 -0
- package/views/dashboard/inbox/activity.stx +350 -0
- package/views/dashboard/inbox/index.stx +452 -0
- package/views/dashboard/inbox/settings.stx +290 -0
- package/views/dashboard/index.stx +252 -0
- package/views/dashboard/insights/index.stx +529 -0
- package/views/dashboard/jobs/[id].stx +430 -0
- package/views/dashboard/jobs/history.stx +222 -0
- package/views/dashboard/jobs/index.stx +214 -0
- package/views/dashboard/kanban/[id].stx +899 -0
- package/views/dashboard/kanban/index.stx +260 -0
- package/views/dashboard/layouts/default.stx +565 -0
- package/views/dashboard/layouts/guest.stx +10 -0
- package/views/dashboard/login.stx +48 -0
- package/views/dashboard/logs/index.stx +540 -0
- package/views/dashboard/mailboxes/index.stx +149 -0
- package/views/dashboard/management/permissions/index.stx +490 -0
- package/views/dashboard/marketing/campaigns/index.stx +604 -0
- package/views/dashboard/marketing/lists/index.stx +514 -0
- package/views/dashboard/marketing/reviews/index.stx +475 -0
- package/views/dashboard/marketing/social-posts/index.stx +560 -0
- package/views/dashboard/models/[model].stx +195 -0
- package/views/dashboard/models/index.stx +159 -0
- package/views/dashboard/monitoring/errors/index.stx +415 -0
- package/views/dashboard/notifications/dashboard.stx +383 -0
- package/views/dashboard/notifications/email.stx +336 -0
- package/views/dashboard/notifications/history.stx +373 -0
- package/views/dashboard/notifications/sms.stx +332 -0
- package/views/dashboard/packages/index.stx +195 -0
- package/views/dashboard/queries/[id].stx +381 -0
- package/views/dashboard/queries/history.stx +227 -0
- package/views/dashboard/queries/index.stx +335 -0
- package/views/dashboard/queries/slow.stx +318 -0
- package/views/dashboard/queue/index.stx +427 -0
- package/views/dashboard/realtime/index.stx +429 -0
- package/views/dashboard/register.stx +46 -0
- package/views/dashboard/releases/index.stx +389 -0
- package/views/dashboard/requests/index.stx +462 -0
- package/views/dashboard/serverless/index.stx +475 -0
- package/views/dashboard/servers/[id].stx +299 -0
- package/views/dashboard/servers/index.stx +483 -0
- package/views/dashboard/settings/billing.stx +50 -0
- package/views/dashboard/settings/index.stx +256 -0
- package/views/dashboard/settings/mail.stx +252 -0
- package/views/dashboard/stores/auth.ts +123 -0
- package/views/dashboard/stores/ci.ts +342 -0
- package/views/dashboard/stores/index.ts +129 -0
- package/views/dashboard/stores/kanban.ts +723 -0
- package/views/dashboard/stores/rbac.ts +350 -0
- package/views/dashboard/stx.config.ts +34 -0
- package/views/dashboard/teams/[id].stx +170 -0
- package/views/forum/category.stx +92 -0
- package/views/forum/index.stx +209 -0
- package/views/forum/new-topic.stx +113 -0
- package/views/forum/profile.stx +1 -0
- package/views/forum/topic.stx +143 -0
- package/views/hello-world/[name].stx +47 -0
- package/views/index.stx +21 -0
- 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
|