@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.
- 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,338 @@
|
|
|
1
|
+
@extends('layouts/default')
|
|
2
|
+
|
|
3
|
+
@section('content')
|
|
4
|
+
@title('Dashboard - Shipping Rates')
|
|
5
|
+
<div class="py-6">
|
|
6
|
+
<div class="mx-auto px-4 sm:px-6 md:px-8 max-w-7xl">
|
|
7
|
+
<TabNavigation modelValue="rates" :tabs="tabs" />
|
|
8
|
+
|
|
9
|
+
<div class="overflow-hidden mt-6 bg-white dark:bg-neutral-800 rounded-lg shadow">
|
|
10
|
+
<div class="px-4 py-5 sm:px-6 border-b border-gray-200 dark:border-neutral-700">
|
|
11
|
+
<div class="flex items-center justify-between">
|
|
12
|
+
<h2 class="font-medium text-gray-900 text-lg dark:text-white">Shipping Rates</h2>
|
|
13
|
+
<button @click="openAddModal()" type="button" class="inline-flex items-center px-3 py-2 font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">
|
|
14
|
+
<div class="mr-2 h-5 w-5 i-hugeicons-plus-sign"></div>
|
|
15
|
+
Add Rate
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="mt-4">
|
|
19
|
+
<div class="w-full md:w-96"><SearchFilter placeholder="Search shipping rates..." @search="handleSearch" /></div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<ShippingRatesTable :rates="paginatedShippingRates" @edit="openEditModal" @delete="handleDeleteRate" />
|
|
24
|
+
|
|
25
|
+
<div class="px-4 py-3 bg-gray-50 dark:bg-neutral-900 border-gray-200 border-t dark:border-neutral-700">
|
|
26
|
+
<Pagination :currentPage="currentPage" :totalItems="totalItems" :itemsPerPage="itemsPerPage" @prev="handlePrevPage" @next="handleNextPage" @page="handlePageChange" />
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<!-- Add Shipping Rate Modal -->
|
|
32
|
+
<div :show="showAddModal" class="fixed inset-0 overflow-y-auto z-10">
|
|
33
|
+
<div class="flex items-end justify-center sm:items-center p-4 sm:p-0 min-h-full text-center">
|
|
34
|
+
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" @click="closeAddModal()"></div>
|
|
35
|
+
<div class="overflow-hidden relative pb-4 pt-5 px-4 sm:my-8 sm:p-6 sm:max-w-lg sm:w-full text-left bg-white dark:bg-neutral-800 rounded-lg shadow-xl transition-all transform">
|
|
36
|
+
<div>
|
|
37
|
+
<div class="mt-3 sm:mt-5 text-center">
|
|
38
|
+
<h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-white">Add New Shipping Rate</h3>
|
|
39
|
+
<div class="mt-4">
|
|
40
|
+
<div class="space-y-4">
|
|
41
|
+
<div>
|
|
42
|
+
<label for="rate-method" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Method</label>
|
|
43
|
+
<div class="mt-2">
|
|
44
|
+
<select id="rate-method" x-model.number="newMethodId" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-700 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 shadow-sm">
|
|
45
|
+
<option value="">Select a shipping method</option>
|
|
46
|
+
<template :for="method in methodOptions">
|
|
47
|
+
<option value="{{ method.id }}">{{ method.name }}</option>
|
|
48
|
+
</template>
|
|
49
|
+
</select>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<div>
|
|
53
|
+
<label for="rate-zone" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Zone</label>
|
|
54
|
+
<div class="mt-2">
|
|
55
|
+
<select id="rate-zone" x-model.number="newZoneId" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-700 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 shadow-sm">
|
|
56
|
+
<option value="">Select a shipping zone</option>
|
|
57
|
+
<template :for="zone in zoneOptions">
|
|
58
|
+
<option value="{{ zone.id }}">{{ zone.name }}</option>
|
|
59
|
+
</template>
|
|
60
|
+
</select>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="grid gap-4 grid-cols-2">
|
|
64
|
+
<div>
|
|
65
|
+
<label for="rate-weight-from" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Weight From</label>
|
|
66
|
+
<div class="mt-2">
|
|
67
|
+
<input type="number" id="rate-weight-from" x-model.number="newWeightFrom" placeholder="0" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
<div>
|
|
71
|
+
<label for="rate-weight-to" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Weight To</label>
|
|
72
|
+
<div class="mt-2">
|
|
73
|
+
<input type="number" id="rate-weight-to" x-model.number="newWeightTo" placeholder="10" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
<div>
|
|
78
|
+
<label for="rate-rate" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Rate (in cents)</label>
|
|
79
|
+
<div class="mt-2">
|
|
80
|
+
<input type="number" id="rate-rate" x-model.number="newRate" placeholder="599" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="sm:grid sm:gap-3 sm:grid-cols-2 sm:grid-flow-row-dense mt-5 sm:mt-6">
|
|
88
|
+
<button type="button" @click="addShippingRate()" class="inline-flex justify-center sm:col-start-2 px-3 py-2 w-full font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">Add Rate</button>
|
|
89
|
+
<button type="button" @click="closeAddModal()" class="inline-flex justify-center sm:col-start-1 mt-3 px-3 py-2 sm:mt-0 w-full font-semibold text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-700 hover:bg-gray-50 dark:hover:bg-neutral-600 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">Cancel</button>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<!-- Edit Shipping Rate Modal -->
|
|
96
|
+
<div :show="showEditModal" class="fixed inset-0 overflow-y-auto z-10">
|
|
97
|
+
<div class="flex items-end justify-center sm:items-center p-4 sm:p-0 min-h-full text-center">
|
|
98
|
+
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" @click="closeEditModal()"></div>
|
|
99
|
+
<div class="overflow-hidden relative pb-4 pt-5 px-4 sm:my-8 sm:p-6 sm:max-w-lg sm:w-full text-left bg-white dark:bg-neutral-800 rounded-lg shadow-xl transition-all transform">
|
|
100
|
+
<div>
|
|
101
|
+
<div class="mt-3 sm:mt-5 text-center">
|
|
102
|
+
<h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-white">Edit Shipping Rate</h3>
|
|
103
|
+
<div class="mt-4">
|
|
104
|
+
<div class="space-y-4">
|
|
105
|
+
<div>
|
|
106
|
+
<label for="edit-rate-method" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Method</label>
|
|
107
|
+
<div class="mt-2">
|
|
108
|
+
<select id="edit-rate-method" x-model.number="newMethodId" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-700 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 shadow-sm">
|
|
109
|
+
<option value="">Select a shipping method</option>
|
|
110
|
+
<template :for="method in methodOptions">
|
|
111
|
+
<option value="{{ method.id }}">{{ method.name }}</option>
|
|
112
|
+
</template>
|
|
113
|
+
</select>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
<div>
|
|
117
|
+
<label for="edit-rate-zone" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Zone</label>
|
|
118
|
+
<div class="mt-2">
|
|
119
|
+
<select id="edit-rate-zone" x-model.number="newZoneId" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-700 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 shadow-sm">
|
|
120
|
+
<option value="">Select a shipping zone</option>
|
|
121
|
+
<template :for="zone in zoneOptions">
|
|
122
|
+
<option value="{{ zone.id }}">{{ zone.name }}</option>
|
|
123
|
+
</template>
|
|
124
|
+
</select>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="grid gap-4 grid-cols-2">
|
|
128
|
+
<div>
|
|
129
|
+
<label for="edit-rate-weight-from" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Weight From</label>
|
|
130
|
+
<div class="mt-2">
|
|
131
|
+
<input type="number" id="edit-rate-weight-from" x-model.number="newWeightFrom" placeholder="0" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
<div>
|
|
135
|
+
<label for="edit-rate-weight-to" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Weight To</label>
|
|
136
|
+
<div class="mt-2">
|
|
137
|
+
<input type="number" id="edit-rate-weight-to" x-model.number="newWeightTo" placeholder="10" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
<div>
|
|
142
|
+
<label for="edit-rate-rate" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Rate (in cents)</label>
|
|
143
|
+
<div class="mt-2">
|
|
144
|
+
<input type="number" id="edit-rate-rate" x-model.number="newRate" placeholder="599" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
<div class="sm:grid sm:gap-3 sm:grid-cols-2 sm:grid-flow-row-dense mt-5 sm:mt-6">
|
|
152
|
+
<button type="button" @click="saveShippingRate()" class="inline-flex justify-center sm:col-start-2 px-3 py-2 w-full font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">Save Changes</button>
|
|
153
|
+
<button type="button" @click="closeEditModal()" class="inline-flex justify-center sm:col-start-1 mt-3 px-3 py-2 sm:mt-0 w-full font-semibold text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-700 hover:bg-gray-50 dark:hover:bg-neutral-600 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">Cancel</button>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<script client>
|
|
161
|
+
import { useShippingMethods } from '../../../../functions/commerce/shippings/shipping-methods'
|
|
162
|
+
// Shared tab nav config — formerly duplicated in every delivery page's
|
|
163
|
+
// `<script server>` block (stacksjs/stacks#1838).
|
|
164
|
+
import { deliveryTabs as tabs } from './tabs'
|
|
165
|
+
import { useShippingRates } from '../../../../functions/commerce/shippings/shipping-rates'
|
|
166
|
+
import { useShippingZones } from '../../../../functions/commerce/shippings/shipping-zones'
|
|
167
|
+
|
|
168
|
+
interface ShippingRate {
|
|
169
|
+
id?: number
|
|
170
|
+
shipping_method_id: number
|
|
171
|
+
shipping_zone_id: number
|
|
172
|
+
weight_from: number
|
|
173
|
+
weight_to: number
|
|
174
|
+
rate: number
|
|
175
|
+
method?: string
|
|
176
|
+
zone?: string
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const { shippingRates, createShippingRate, fetchShippingRates, updateShippingRate, deleteShippingRate } = useShippingRates()
|
|
180
|
+
const { shippingMethods, fetchShippingMethods } = useShippingMethods()
|
|
181
|
+
const { shippingZones, fetchShippingZones } = useShippingZones()
|
|
182
|
+
|
|
183
|
+
const showAddModal = state(false)
|
|
184
|
+
const showEditModal = state(false)
|
|
185
|
+
const editingRate = state<ShippingRate | null>(null)
|
|
186
|
+
|
|
187
|
+
const newMethodId = state(0)
|
|
188
|
+
const newZoneId = state(0)
|
|
189
|
+
const newWeightFrom = state(0)
|
|
190
|
+
const newWeightTo = state(0)
|
|
191
|
+
const newRate = state(0)
|
|
192
|
+
|
|
193
|
+
const searchQuery = state('')
|
|
194
|
+
const currentPage = state(1)
|
|
195
|
+
const itemsPerPage = state(5)
|
|
196
|
+
|
|
197
|
+
function methodOptions(): Array<{ id: number, name: string }> {
|
|
198
|
+
return (shippingMethods.value as Array<{ id: number, name: string }>) || []
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function zoneOptions(): Array<{ id: number, name: string }> {
|
|
202
|
+
return (shippingZones.value as Array<{ id: number, name: string }>) || []
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const filteredShippingRates = derived(() => {
|
|
206
|
+
const list = (shippingRates.value as ShippingRate[]) || []
|
|
207
|
+
const q = searchQuery().toLowerCase()
|
|
208
|
+
if (!q)
|
|
209
|
+
return list
|
|
210
|
+
return list.filter(r =>
|
|
211
|
+
(r.method?.toLowerCase().includes(q) ?? false)
|
|
212
|
+
|| (r.zone?.toLowerCase().includes(q) ?? false)
|
|
213
|
+
|| r.weight_from.toString().includes(q)
|
|
214
|
+
|| r.weight_to.toString().includes(q)
|
|
215
|
+
|| r.rate.toString().includes(q),
|
|
216
|
+
)
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
const paginatedShippingRates = derived(() => {
|
|
220
|
+
const start = (currentPage() - 1) * itemsPerPage()
|
|
221
|
+
return filteredShippingRates().slice(start, start + itemsPerPage())
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
const totalItems = derived(() => filteredShippingRates().length)
|
|
225
|
+
|
|
226
|
+
function resetForm(): void {
|
|
227
|
+
newMethodId.set(0)
|
|
228
|
+
newZoneId.set(0)
|
|
229
|
+
newWeightFrom.set(0)
|
|
230
|
+
newWeightTo.set(0)
|
|
231
|
+
newRate.set(0)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function openAddModal(): void {
|
|
235
|
+
resetForm()
|
|
236
|
+
showAddModal.set(true)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function closeAddModal(): void {
|
|
240
|
+
showAddModal.set(false)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function openEditModal(rate: ShippingRate): void {
|
|
244
|
+
editingRate.set(rate)
|
|
245
|
+
newMethodId.set(rate.shipping_method_id)
|
|
246
|
+
newZoneId.set(rate.shipping_zone_id)
|
|
247
|
+
newWeightFrom.set(rate.weight_from)
|
|
248
|
+
newWeightTo.set(rate.weight_to)
|
|
249
|
+
newRate.set(rate.rate)
|
|
250
|
+
showEditModal.set(true)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function closeEditModal(): void {
|
|
254
|
+
showEditModal.set(false)
|
|
255
|
+
editingRate.set(null)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async function addShippingRate(): Promise<void> {
|
|
259
|
+
try {
|
|
260
|
+
await createShippingRate({
|
|
261
|
+
shipping_method_id: newMethodId(),
|
|
262
|
+
shipping_zone_id: newZoneId(),
|
|
263
|
+
weight_from: newWeightFrom(),
|
|
264
|
+
weight_to: newWeightTo(),
|
|
265
|
+
rate: newRate(),
|
|
266
|
+
} as ShippingRate)
|
|
267
|
+
closeAddModal()
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
// eslint-disable-next-line no-console
|
|
271
|
+
console.error('Failed to create shipping rate:', error)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async function saveShippingRate(): Promise<void> {
|
|
276
|
+
const target = editingRate()
|
|
277
|
+
if (!target)
|
|
278
|
+
return
|
|
279
|
+
try {
|
|
280
|
+
await updateShippingRate({
|
|
281
|
+
...target,
|
|
282
|
+
shipping_method_id: newMethodId(),
|
|
283
|
+
shipping_zone_id: newZoneId(),
|
|
284
|
+
weight_from: newWeightFrom(),
|
|
285
|
+
weight_to: newWeightTo(),
|
|
286
|
+
rate: newRate(),
|
|
287
|
+
})
|
|
288
|
+
closeEditModal()
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
// eslint-disable-next-line no-console
|
|
292
|
+
console.error('Failed to update shipping rate:', error)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function handleSearch(query: string): void {
|
|
297
|
+
searchQuery.set(query)
|
|
298
|
+
currentPage.set(1)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async function handleDeleteRate(rate: ShippingRate): Promise<void> {
|
|
302
|
+
// eslint-disable-next-line no-alert
|
|
303
|
+
if (!confirm('Are you sure you want to delete this shipping rate?'))
|
|
304
|
+
return
|
|
305
|
+
try {
|
|
306
|
+
await deleteShippingRate(rate.id as number)
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
// eslint-disable-next-line no-console
|
|
310
|
+
console.error('Failed to delete shipping rate:', error)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function handlePrevPage(): void {
|
|
315
|
+
if (currentPage() > 1)
|
|
316
|
+
currentPage.update(p => p - 1)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function handleNextPage(): void {
|
|
320
|
+
const totalPages = Math.ceil(totalItems() / itemsPerPage())
|
|
321
|
+
if (currentPage() < totalPages)
|
|
322
|
+
currentPage.update(p => p + 1)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function handlePageChange(page: number): void {
|
|
326
|
+
currentPage.set(page)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
onMount(async () => {
|
|
330
|
+
await Promise.all([
|
|
331
|
+
fetchShippingRates(),
|
|
332
|
+
fetchShippingMethods(),
|
|
333
|
+
fetchShippingZones(),
|
|
334
|
+
])
|
|
335
|
+
})
|
|
336
|
+
</script>
|
|
337
|
+
|
|
338
|
+
@endsection
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
@extends('layouts/default')
|
|
2
|
+
|
|
3
|
+
@section('content')
|
|
4
|
+
@title('Dashboard - Shipping Zones')
|
|
5
|
+
<div class="py-6">
|
|
6
|
+
<div class="mx-auto px-4 sm:px-6 md:px-8 max-w-7xl">
|
|
7
|
+
<TabNavigation modelValue="zones" :tabs="tabs" />
|
|
8
|
+
|
|
9
|
+
<div class="overflow-hidden mt-6 bg-white dark:bg-neutral-800 rounded-lg shadow">
|
|
10
|
+
<div class="px-4 py-5 sm:px-6 border-b border-gray-200 dark:border-neutral-700">
|
|
11
|
+
<div class="flex items-center justify-between">
|
|
12
|
+
<h2 class="font-medium text-gray-900 text-lg dark:text-white">Shipping Zones</h2>
|
|
13
|
+
<button @click="openAddModal()" type="button" class="inline-flex items-center px-3 py-2 font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">
|
|
14
|
+
<div class="mr-2 h-5 w-5 i-hugeicons-plus-sign"></div>
|
|
15
|
+
Add Zone
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="mt-4">
|
|
19
|
+
<div class="w-full md:w-96"><SearchFilter placeholder="Search shipping zones..." @search="handleSearch" /></div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<ShippingZonesTable :zones="paginatedShippingZones" @edit="openEditModal" @delete="handleDeleteZone" />
|
|
24
|
+
|
|
25
|
+
<div class="px-4 py-3 bg-gray-50 dark:bg-neutral-900 border-gray-200 border-t dark:border-neutral-700">
|
|
26
|
+
<Pagination :currentPage="currentPage" :totalItems="totalItems" :itemsPerPage="itemsPerPage" @prev="handlePrevPage" @next="handleNextPage" @page="handlePageChange" />
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<!-- Add Shipping Zone Modal -->
|
|
32
|
+
<div :show="showAddModal" class="fixed inset-0 overflow-y-auto z-10">
|
|
33
|
+
<div class="flex items-end justify-center sm:items-center p-4 sm:p-0 min-h-full text-center">
|
|
34
|
+
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" @click="closeAddModal()"></div>
|
|
35
|
+
<div class="overflow-hidden relative pb-4 pt-5 px-4 sm:my-8 sm:p-6 sm:max-w-lg sm:w-full text-left bg-white dark:bg-neutral-800 rounded-lg shadow-xl transition-all transform">
|
|
36
|
+
<div>
|
|
37
|
+
<div class="mt-3 sm:mt-5 text-center">
|
|
38
|
+
<h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-white">Add New Shipping Zone</h3>
|
|
39
|
+
<div class="mt-4">
|
|
40
|
+
<div class="space-y-4">
|
|
41
|
+
<div>
|
|
42
|
+
<label for="zone-name" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Zone Name</label>
|
|
43
|
+
<div class="mt-2">
|
|
44
|
+
<input type="text" id="zone-name" x-model="newName" placeholder="Enter zone name" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div>
|
|
48
|
+
<label for="zone-countries" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Countries</label>
|
|
49
|
+
<div class="mt-2">
|
|
50
|
+
<textarea id="zone-countries" x-model="newCountries" rows="3" placeholder="Enter countries (comma-separated)" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm"></textarea>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div>
|
|
54
|
+
<label for="zone-regions" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Regions</label>
|
|
55
|
+
<div class="mt-2">
|
|
56
|
+
<textarea id="zone-regions" x-model="newRegions" rows="3" placeholder="Enter regions (comma-separated)" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm"></textarea>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
<div>
|
|
60
|
+
<label for="zone-postal-codes" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Postal Codes</label>
|
|
61
|
+
<div class="mt-2">
|
|
62
|
+
<textarea id="zone-postal-codes" x-model="newPostalCodes" rows="3" placeholder="Enter postal codes (comma-separated)" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm"></textarea>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
<div>
|
|
66
|
+
<label for="zone-status" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Status</label>
|
|
67
|
+
<div class="mt-2">
|
|
68
|
+
<select id="zone-status" x-model="newStatus" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-700 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 shadow-sm">
|
|
69
|
+
<option value="Active">Active</option>
|
|
70
|
+
<option value="Inactive">Inactive</option>
|
|
71
|
+
</select>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="sm:grid sm:gap-3 sm:grid-cols-2 sm:grid-flow-row-dense mt-5 sm:mt-6">
|
|
79
|
+
<button type="button" @click="addShippingZone()" class="inline-flex justify-center sm:col-start-2 px-3 py-2 w-full font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">Add Zone</button>
|
|
80
|
+
<button type="button" @click="closeAddModal()" class="inline-flex justify-center sm:col-start-1 mt-3 px-3 py-2 sm:mt-0 w-full font-semibold text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-700 hover:bg-gray-50 dark:hover:bg-neutral-600 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">Cancel</button>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<!-- Edit Shipping Zone Modal -->
|
|
87
|
+
<div :show="showEditModal" class="fixed inset-0 overflow-y-auto z-10">
|
|
88
|
+
<div class="flex items-end justify-center sm:items-center p-4 sm:p-0 min-h-full text-center">
|
|
89
|
+
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" @click="closeEditModal()"></div>
|
|
90
|
+
<div class="overflow-hidden relative pb-4 pt-5 px-4 sm:my-8 sm:p-6 sm:max-w-lg sm:w-full text-left bg-white dark:bg-neutral-800 rounded-lg shadow-xl transition-all transform">
|
|
91
|
+
<div>
|
|
92
|
+
<div class="mt-3 sm:mt-5 text-center">
|
|
93
|
+
<h3 class="font-semibold leading-6 text-base text-gray-900 dark:text-white">Edit Shipping Zone</h3>
|
|
94
|
+
<div class="mt-4">
|
|
95
|
+
<div class="space-y-4">
|
|
96
|
+
<div>
|
|
97
|
+
<label for="edit-zone-name" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Zone Name</label>
|
|
98
|
+
<div class="mt-2">
|
|
99
|
+
<input type="text" id="edit-zone-name" x-model="newName" placeholder="Enter zone name" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm" />
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<div>
|
|
103
|
+
<label for="edit-zone-countries" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Countries</label>
|
|
104
|
+
<div class="mt-2">
|
|
105
|
+
<textarea id="edit-zone-countries" x-model="newCountries" rows="3" placeholder="Enter countries (comma-separated)" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm"></textarea>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
<div>
|
|
109
|
+
<label for="edit-zone-regions" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Regions</label>
|
|
110
|
+
<div class="mt-2">
|
|
111
|
+
<textarea id="edit-zone-regions" x-model="newRegions" rows="3" placeholder="Enter regions (comma-separated)" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm"></textarea>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<div>
|
|
115
|
+
<label for="edit-zone-postal-codes" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Postal Codes</label>
|
|
116
|
+
<div class="mt-2">
|
|
117
|
+
<textarea id="edit-zone-postal-codes" x-model="newPostalCodes" rows="3" placeholder="Enter postal codes (comma-separated)" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white placeholder:text-gray-400 dark:bg-neutral-700 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 shadow-sm"></textarea>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<div>
|
|
121
|
+
<label for="edit-zone-status" class="block font-medium leading-6 text-gray-900 text-left text-sm dark:text-neutral-200">Status</label>
|
|
122
|
+
<div class="mt-2">
|
|
123
|
+
<select id="edit-zone-status" x-model="newStatus" class="block py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-700 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 shadow-sm">
|
|
124
|
+
<option value="Active">Active</option>
|
|
125
|
+
<option value="Inactive">Inactive</option>
|
|
126
|
+
</select>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
<div class="sm:grid sm:gap-3 sm:grid-cols-2 sm:grid-flow-row-dense mt-5 sm:mt-6">
|
|
134
|
+
<button type="button" @click="saveShippingZone()" class="inline-flex justify-center sm:col-start-2 px-3 py-2 w-full font-semibold text-sm text-white bg-blue-600 hover:bg-blue-500 rounded-md focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 shadow-sm">Save Changes</button>
|
|
135
|
+
<button type="button" @click="closeEditModal()" class="inline-flex justify-center sm:col-start-1 mt-3 px-3 py-2 sm:mt-0 w-full font-semibold text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-700 hover:bg-gray-50 dark:hover:bg-neutral-600 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-600 shadow-sm">Cancel</button>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<script client>
|
|
143
|
+
import { useShippingZones } from '../../../../functions/commerce/shippings/shipping-zones'
|
|
144
|
+
// Shared tab nav config — formerly duplicated in every delivery page's
|
|
145
|
+
// `<script server>` block (stacksjs/stacks#1838).
|
|
146
|
+
import { deliveryTabs as tabs } from './tabs'
|
|
147
|
+
|
|
148
|
+
interface ShippingZone {
|
|
149
|
+
id?: number
|
|
150
|
+
name: string
|
|
151
|
+
countries?: string
|
|
152
|
+
regions?: string
|
|
153
|
+
postal_codes?: string
|
|
154
|
+
shipping_method_id: number
|
|
155
|
+
status: string
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const { shippingZones, createShippingZone, fetchShippingZones, updateShippingZone, deleteShippingZone } = useShippingZones()
|
|
159
|
+
|
|
160
|
+
const showAddModal = state(false)
|
|
161
|
+
const showEditModal = state(false)
|
|
162
|
+
const editingZone = state<ShippingZone | null>(null)
|
|
163
|
+
|
|
164
|
+
const newName = state('')
|
|
165
|
+
const newCountries = state('')
|
|
166
|
+
const newRegions = state('')
|
|
167
|
+
const newPostalCodes = state('')
|
|
168
|
+
const newStatus = state('Active')
|
|
169
|
+
|
|
170
|
+
const searchQuery = state('')
|
|
171
|
+
const currentPage = state(1)
|
|
172
|
+
const itemsPerPage = state(5)
|
|
173
|
+
|
|
174
|
+
const filteredShippingZones = derived(() => {
|
|
175
|
+
const list = (shippingZones.value as ShippingZone[]) || []
|
|
176
|
+
const q = searchQuery().toLowerCase()
|
|
177
|
+
if (!q)
|
|
178
|
+
return list
|
|
179
|
+
return list.filter(z =>
|
|
180
|
+
z.name.toLowerCase().includes(q)
|
|
181
|
+
|| (z.countries?.toLowerCase().includes(q) ?? false)
|
|
182
|
+
|| (z.regions?.toLowerCase().includes(q) ?? false),
|
|
183
|
+
)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
const paginatedShippingZones = derived(() => {
|
|
187
|
+
const start = (currentPage() - 1) * itemsPerPage()
|
|
188
|
+
return filteredShippingZones().slice(start, start + itemsPerPage())
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
const totalItems = derived(() => filteredShippingZones().length)
|
|
192
|
+
|
|
193
|
+
function resetForm(): void {
|
|
194
|
+
newName.set('')
|
|
195
|
+
newCountries.set('')
|
|
196
|
+
newRegions.set('')
|
|
197
|
+
newPostalCodes.set('')
|
|
198
|
+
newStatus.set('Active')
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function openAddModal(): void {
|
|
202
|
+
resetForm()
|
|
203
|
+
showAddModal.set(true)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function closeAddModal(): void {
|
|
207
|
+
showAddModal.set(false)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function openEditModal(zone: ShippingZone): void {
|
|
211
|
+
editingZone.set(zone)
|
|
212
|
+
newName.set(zone.name)
|
|
213
|
+
newCountries.set(zone.countries ?? '')
|
|
214
|
+
newRegions.set(zone.regions ?? '')
|
|
215
|
+
newPostalCodes.set(zone.postal_codes ?? '')
|
|
216
|
+
newStatus.set(zone.status)
|
|
217
|
+
showEditModal.set(true)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function closeEditModal(): void {
|
|
221
|
+
showEditModal.set(false)
|
|
222
|
+
editingZone.set(null)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async function addShippingZone(): Promise<void> {
|
|
226
|
+
try {
|
|
227
|
+
await createShippingZone({
|
|
228
|
+
name: newName(),
|
|
229
|
+
countries: newCountries(),
|
|
230
|
+
regions: newRegions(),
|
|
231
|
+
postal_codes: newPostalCodes(),
|
|
232
|
+
shipping_method_id: 1,
|
|
233
|
+
status: newStatus(),
|
|
234
|
+
} as ShippingZone)
|
|
235
|
+
closeAddModal()
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
// eslint-disable-next-line no-console
|
|
239
|
+
console.error('Failed to create shipping zone:', error)
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function saveShippingZone(): Promise<void> {
|
|
244
|
+
const target = editingZone()
|
|
245
|
+
if (!target)
|
|
246
|
+
return
|
|
247
|
+
try {
|
|
248
|
+
await updateShippingZone({
|
|
249
|
+
...target,
|
|
250
|
+
name: newName(),
|
|
251
|
+
countries: newCountries(),
|
|
252
|
+
regions: newRegions(),
|
|
253
|
+
postal_codes: newPostalCodes(),
|
|
254
|
+
status: newStatus(),
|
|
255
|
+
})
|
|
256
|
+
closeEditModal()
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
// eslint-disable-next-line no-console
|
|
260
|
+
console.error('Failed to update shipping zone:', error)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function handleSearch(query: string): void {
|
|
265
|
+
searchQuery.set(query)
|
|
266
|
+
currentPage.set(1)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function handleDeleteZone(zone: ShippingZone): Promise<void> {
|
|
270
|
+
// eslint-disable-next-line no-alert
|
|
271
|
+
if (!confirm(`Are you sure you want to delete ${zone.name}?`))
|
|
272
|
+
return
|
|
273
|
+
try {
|
|
274
|
+
await deleteShippingZone(zone.id as number)
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
// eslint-disable-next-line no-console
|
|
278
|
+
console.error('Failed to delete shipping zone:', error)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function handlePrevPage(): void {
|
|
283
|
+
if (currentPage() > 1)
|
|
284
|
+
currentPage.update(p => p - 1)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function handleNextPage(): void {
|
|
288
|
+
const totalPages = Math.ceil(totalItems() / itemsPerPage())
|
|
289
|
+
if (currentPage() < totalPages)
|
|
290
|
+
currentPage.update(p => p + 1)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function handlePageChange(page: number): void {
|
|
294
|
+
currentPage.set(page)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
onMount(async () => {
|
|
298
|
+
await fetchShippingZones()
|
|
299
|
+
})
|
|
300
|
+
</script>
|
|
301
|
+
|
|
302
|
+
@endsection
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared TabNavigation config for every `/commerce/delivery/*` page.
|
|
3
|
+
*
|
|
4
|
+
* The seven sub-pages under this directory (shipping methods, zones,
|
|
5
|
+
* rates, digital delivery, license keys, delivery routes, drivers) all
|
|
6
|
+
* render the same top-tab bar. Lifting the array here lets each page
|
|
7
|
+
* import it once via `<script client>` instead of redeclaring the same
|
|
8
|
+
* list in every file (stacksjs/stacks#1838).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface DeliveryTab {
|
|
12
|
+
name: string
|
|
13
|
+
value: string
|
|
14
|
+
href: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const deliveryTabs: readonly DeliveryTab[] = Object.freeze([
|
|
18
|
+
{ name: 'Shipping Methods', value: 'methods', href: '/commerce/delivery/shipping-methods' },
|
|
19
|
+
{ name: 'Shipping Zones', value: 'zones', href: '/commerce/delivery/shipping-zones' },
|
|
20
|
+
{ name: 'Shipping Rates', value: 'rates', href: '/commerce/delivery/shipping-rates' },
|
|
21
|
+
{ name: 'Digital Delivery', value: 'digital', href: '/commerce/delivery/digital-delivery' },
|
|
22
|
+
{ name: 'License Keys', value: 'license', href: '/commerce/delivery/license-keys' },
|
|
23
|
+
{ name: 'Delivery Routes', value: 'routes', href: '/commerce/delivery/delivery-routes' },
|
|
24
|
+
{ name: 'Drivers', value: 'drivers', href: '/commerce/delivery/drivers' },
|
|
25
|
+
])
|