@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,356 @@
|
|
|
1
|
+
@extends('layouts/default')
|
|
2
|
+
|
|
3
|
+
@section('content')
|
|
4
|
+
@title('Dashboard - Web Analytics')
|
|
5
|
+
<PageLayout>
|
|
6
|
+
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between mb-6">
|
|
7
|
+
<div class="flex items-center space-x-2">
|
|
8
|
+
<div class="h-5 w-5 text-gray-500 dark:text-neutral-400 i-hugeicons-calendar-03"></div>
|
|
9
|
+
<span class="font-medium text-gray-700 text-sm dark:text-neutral-300">{{ dateRangeDisplay }}</span>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="flex flex-wrap gap-2 items-center">
|
|
12
|
+
<span class="text-gray-500 text-sm dark:text-neutral-400">compared to</span>
|
|
13
|
+
<div class="relative">
|
|
14
|
+
<select x-model="comparisonType" class="block pl-3 pr-10 py-1.5 w-full text-gray-900 sm:leading-6 sm:text-sm dark:text-white dark:bg-neutral-800 border-0 ring-1 ring-gray-300 ring-inset rounded-md dark:ring-neutral-700 focus:ring-2 focus:ring-blue-600 focus:ring-inset">
|
|
15
|
+
<option value="no-comparison">No comparison</option>
|
|
16
|
+
<option value="previous-period">Previous period</option>
|
|
17
|
+
<option value="previous-year">Previous year</option>
|
|
18
|
+
</select>
|
|
19
|
+
</div>
|
|
20
|
+
<button type="button" class="inline-flex items-center px-3 py-1.5 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">
|
|
21
|
+
<div class="mr-1 h-4 w-4 i-hugeicons-settings-01"></div>
|
|
22
|
+
Auto
|
|
23
|
+
</button>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div class="grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-6 mb-8 p-4 bg-black dark:bg-neutral-900 rounded-lg">
|
|
28
|
+
<div class="flex flex-col items-center justify-center">
|
|
29
|
+
<div class="font-bold text-4xl text-white">{{ analyticsOverview.realtime }}</div>
|
|
30
|
+
<div class="text-gray-400 text-sm">Realtime</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="flex flex-col items-center justify-center">
|
|
33
|
+
<div class="font-bold text-4xl text-white">2.2k</div>
|
|
34
|
+
<div class="text-gray-400 text-sm">People</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="flex flex-col items-center justify-center">
|
|
37
|
+
<div class="font-bold text-4xl text-white">3k</div>
|
|
38
|
+
<div class="text-gray-400 text-sm">Views</div>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="flex flex-col items-center justify-center">
|
|
41
|
+
<div class="font-bold text-4xl text-white">{{ analyticsOverview.avgTimeOnSite }}</div>
|
|
42
|
+
<div class="text-gray-400 text-sm">Avg time on site</div>
|
|
43
|
+
</div>
|
|
44
|
+
<div class="flex flex-col items-center justify-center">
|
|
45
|
+
<div class="font-bold text-4xl text-white">{{ analyticsOverview.bounceRate }}</div>
|
|
46
|
+
<div class="text-gray-400 text-sm">Bounce rate</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="flex flex-col items-center justify-center">
|
|
49
|
+
<div class="font-bold text-4xl text-white">{{ analyticsOverview.eventCompletions }}</div>
|
|
50
|
+
<div class="text-gray-400 text-sm">Event completions</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="mb-8 p-4 bg-white dark:bg-neutral-800 rounded-lg shadow">
|
|
55
|
+
<div class="mb-4">
|
|
56
|
+
<h3 class="font-medium leading-6 text-gray-900 text-lg dark:text-white">Traffic Overview</h3>
|
|
57
|
+
<p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Daily page views and unique visitors</p>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="h-80 w-full"><canvas id="traffic_chart"></canvas></div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div class="grid gap-8 grid-cols-1 lg:grid-cols-2">
|
|
63
|
+
<div>
|
|
64
|
+
<div class="mb-4"><h3 class="font-medium text-gray-900 text-lg dark:text-white">Pages</h3></div>
|
|
65
|
+
<div class="overflow-hidden border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
66
|
+
<table class="min-w-full divide-gray-200 divide-y dark:divide-neutral-700">
|
|
67
|
+
<thead class="bg-gray-50 dark:bg-neutral-700/50">
|
|
68
|
+
<tr>
|
|
69
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-left text-xs tracking-wider uppercase dark:text-neutral-300">Pages</th>
|
|
70
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Entries</th>
|
|
71
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Visitors</th>
|
|
72
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Views</th>
|
|
73
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">%</th>
|
|
74
|
+
</tr>
|
|
75
|
+
</thead>
|
|
76
|
+
<tbody class="bg-white dark:bg-neutral-800 divide-gray-200 divide-y dark:divide-neutral-700">
|
|
77
|
+
<template :for="page in pagesData">
|
|
78
|
+
<tr class="relative hover:bg-gray-50 dark:hover:bg-neutral-700/50">
|
|
79
|
+
<td class="px-4 py-3 text-gray-900 text-sm whitespace-nowrap dark:text-white">
|
|
80
|
+
<div class="absolute inset-0 bg-blue-100/50 dark:bg-blue-900/50" :style="'width: ' + page.percentage + '%'"></div>
|
|
81
|
+
<span class="relative z-10">{{ page.path }}</span>
|
|
82
|
+
</td>
|
|
83
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ page.entries }}</span></td>
|
|
84
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ page.visitors }}</span></td>
|
|
85
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ page.views }}</span></td>
|
|
86
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ page.percentage }}%</span></td>
|
|
87
|
+
</tr>
|
|
88
|
+
</template>
|
|
89
|
+
</tbody>
|
|
90
|
+
</table>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="flex justify-end mt-2"><StxLink to="/analytics/pages" class="text-blue-600 text-sm dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">View all pages</StxLink></div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div>
|
|
96
|
+
<div class="mb-4"><h3 class="font-medium text-gray-900 text-lg dark:text-white">Referrers</h3></div>
|
|
97
|
+
<div class="overflow-hidden border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
98
|
+
<table class="min-w-full divide-gray-200 divide-y dark:divide-neutral-700">
|
|
99
|
+
<thead class="bg-gray-50 dark:bg-neutral-700/50">
|
|
100
|
+
<tr>
|
|
101
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-left text-xs tracking-wider uppercase dark:text-neutral-300">Sources</th>
|
|
102
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Visitors</th>
|
|
103
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Views</th>
|
|
104
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">%</th>
|
|
105
|
+
</tr>
|
|
106
|
+
</thead>
|
|
107
|
+
<tbody class="bg-white dark:bg-neutral-800 divide-gray-200 divide-y dark:divide-neutral-700">
|
|
108
|
+
<template :for="referrer in referrersData">
|
|
109
|
+
<tr class="relative hover:bg-gray-50 dark:hover:bg-neutral-700/50">
|
|
110
|
+
<td class="px-4 py-3 text-gray-900 text-sm whitespace-nowrap dark:text-white">
|
|
111
|
+
<div class="absolute inset-0 bg-green-100/50 dark:bg-green-900/50" :style="'width: ' + referrer.percentage + '%'"></div>
|
|
112
|
+
<span class="relative z-10">{{ referrer.name }}</span>
|
|
113
|
+
</td>
|
|
114
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ referrer.visitors }}</span></td>
|
|
115
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ referrer.views }}</span></td>
|
|
116
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ referrer.percentage }}%</span></td>
|
|
117
|
+
</tr>
|
|
118
|
+
</template>
|
|
119
|
+
</tbody>
|
|
120
|
+
</table>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="flex justify-end mt-2"><StxLink to="/analytics/referrers" class="text-blue-600 text-sm dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">View all referrers</StxLink></div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div class="grid gap-8 grid-cols-1 lg:grid-cols-3 mt-8">
|
|
127
|
+
<div>
|
|
128
|
+
<div class="mb-4"><h3 class="font-medium text-gray-900 text-lg dark:text-white">Device Types</h3></div>
|
|
129
|
+
<div class="overflow-hidden border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
130
|
+
<table class="min-w-full divide-gray-200 divide-y dark:divide-neutral-700">
|
|
131
|
+
<thead class="bg-gray-50 dark:bg-neutral-700/50">
|
|
132
|
+
<tr>
|
|
133
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-left text-xs tracking-wider uppercase dark:text-neutral-300">Device Types</th>
|
|
134
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Visitors</th>
|
|
135
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">%</th>
|
|
136
|
+
</tr>
|
|
137
|
+
</thead>
|
|
138
|
+
<tbody class="bg-white dark:bg-neutral-800 divide-gray-200 divide-y dark:divide-neutral-700">
|
|
139
|
+
<template :for="device in deviceData">
|
|
140
|
+
<tr class="relative hover:bg-gray-50 dark:hover:bg-neutral-700/50">
|
|
141
|
+
<td class="px-4 py-3 text-gray-900 text-sm whitespace-nowrap dark:text-white">
|
|
142
|
+
<div class="absolute inset-0 bg-purple-100/50 dark:bg-purple-900/50" :style="'width: ' + device.percentage + '%'"></div>
|
|
143
|
+
<span class="relative z-10">{{ device.name }}</span>
|
|
144
|
+
</td>
|
|
145
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ device.visitors }}</span></td>
|
|
146
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ device.percentage }}%</span></td>
|
|
147
|
+
</tr>
|
|
148
|
+
</template>
|
|
149
|
+
</tbody>
|
|
150
|
+
</table>
|
|
151
|
+
</div>
|
|
152
|
+
<div class="flex justify-end mt-2"><StxLink to="/analytics/devices" class="text-blue-600 text-sm dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">View all devices</StxLink></div>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div>
|
|
156
|
+
<div class="mb-4"><h3 class="font-medium text-gray-900 text-lg dark:text-white">Browsers</h3></div>
|
|
157
|
+
<div class="overflow-hidden border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
158
|
+
<table class="min-w-full divide-gray-200 divide-y dark:divide-neutral-700">
|
|
159
|
+
<thead class="bg-gray-50 dark:bg-neutral-700/50">
|
|
160
|
+
<tr>
|
|
161
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-left text-xs tracking-wider uppercase dark:text-neutral-300">Browsers</th>
|
|
162
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Visitors</th>
|
|
163
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">%</th>
|
|
164
|
+
</tr>
|
|
165
|
+
</thead>
|
|
166
|
+
<tbody class="bg-white dark:bg-neutral-800 divide-gray-200 divide-y dark:divide-neutral-700">
|
|
167
|
+
<template :for="browser in browserData">
|
|
168
|
+
<tr class="relative hover:bg-gray-50 dark:hover:bg-neutral-700/50">
|
|
169
|
+
<td class="px-4 py-3 text-gray-900 text-sm whitespace-nowrap dark:text-white">
|
|
170
|
+
<div class="absolute inset-0 bg-amber-100/50 dark:bg-amber-900/50" :style="'width: ' + browser.percentage + '%'"></div>
|
|
171
|
+
<span class="relative z-10">{{ browser.name }}</span>
|
|
172
|
+
</td>
|
|
173
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ browser.visitors }}</span></td>
|
|
174
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ browser.percentage }}%</span></td>
|
|
175
|
+
</tr>
|
|
176
|
+
</template>
|
|
177
|
+
</tbody>
|
|
178
|
+
</table>
|
|
179
|
+
</div>
|
|
180
|
+
<div class="flex justify-end mt-2"><StxLink to="/analytics/browsers" class="text-blue-600 text-sm dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">View all browsers</StxLink></div>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<div>
|
|
184
|
+
<div class="mb-4"><h3 class="font-medium text-gray-900 text-lg dark:text-white">Countries</h3></div>
|
|
185
|
+
<div class="overflow-hidden border border-gray-200 rounded-lg dark:border-neutral-700">
|
|
186
|
+
<table class="min-w-full divide-gray-200 divide-y dark:divide-neutral-700">
|
|
187
|
+
<thead class="bg-gray-50 dark:bg-neutral-700/50">
|
|
188
|
+
<tr>
|
|
189
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-left text-xs tracking-wider uppercase dark:text-neutral-300">Countries</th>
|
|
190
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">Visitors</th>
|
|
191
|
+
<th class="px-4 py-3 font-medium text-gray-500 text-right text-xs tracking-wider uppercase dark:text-neutral-300">%</th>
|
|
192
|
+
</tr>
|
|
193
|
+
</thead>
|
|
194
|
+
<tbody class="bg-white dark:bg-neutral-800 divide-gray-200 divide-y dark:divide-neutral-700">
|
|
195
|
+
<template :for="country in countriesData">
|
|
196
|
+
<tr class="relative hover:bg-gray-50 dark:hover:bg-neutral-700/50">
|
|
197
|
+
<td class="px-4 py-3 text-gray-900 text-sm whitespace-nowrap dark:text-white">
|
|
198
|
+
<div class="absolute inset-0 bg-rose-100/50 dark:bg-rose-900/50" :style="'width: ' + country.percentage + '%'"></div>
|
|
199
|
+
<span class="relative z-10"><span class="mr-2">{{ country.flag }}</span>{{ country.name }}</span>
|
|
200
|
+
</td>
|
|
201
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ country.visitors }}</span></td>
|
|
202
|
+
<td class="relative px-4 py-3 text-gray-500 text-right text-sm whitespace-nowrap dark:text-neutral-300"><span class="relative z-10">{{ country.percentage }}%</span></td>
|
|
203
|
+
</tr>
|
|
204
|
+
</template>
|
|
205
|
+
</tbody>
|
|
206
|
+
</table>
|
|
207
|
+
</div>
|
|
208
|
+
<div class="flex justify-end mt-2"><StxLink to="/analytics/countries" class="text-blue-600 text-sm dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">View all countries</StxLink></div>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
</PageLayout>
|
|
212
|
+
<script client>
|
|
213
|
+
|
|
214
|
+
interface ChartLike { destroy: () => void }
|
|
215
|
+
type ChartCtor = new (canvas: HTMLElement, config: { type: string, data: unknown, options?: unknown }) => ChartLike
|
|
216
|
+
|
|
217
|
+
// Static analytics tables + overview — moved out of the former
|
|
218
|
+
// `<script server>` block (stacksjs/stacks#1838).
|
|
219
|
+
const pagesRaw = [
|
|
220
|
+
{ path: '/', entries: 1800, visitors: 1800, views: 2100 },
|
|
221
|
+
{ path: '/blog', entries: 113, visitors: 113, views: 139 },
|
|
222
|
+
{ path: '/about', entries: 51, visitors: 51, views: 77 },
|
|
223
|
+
{ path: '/contact', entries: 42, visitors: 42, views: 51 },
|
|
224
|
+
{ path: '/products', entries: 37, visitors: 37, views: 60 },
|
|
225
|
+
{ path: '/guide/get-started.html', entries: 21, visitors: 29, views: 45 },
|
|
226
|
+
{ path: '/docs', entries: 16, visitors: 17, views: 202 },
|
|
227
|
+
{ path: '/guide/intro.html', entries: 12, visitors: 17, views: 22 },
|
|
228
|
+
{ path: '/guide/get-started', entries: 9, visitors: 12, views: 13 },
|
|
229
|
+
{ path: '/team', entries: 9, visitors: 10, views: 15 },
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
const referrersRaw = [
|
|
233
|
+
{ name: 'Direct / Unknown', visitors: 1400, views: 2100 },
|
|
234
|
+
{ name: 'X/Twitter', visitors: 545, views: 580 },
|
|
235
|
+
{ name: 'Google', visitors: 46, views: 50 },
|
|
236
|
+
{ name: 'stacksjs.com', visitors: 45, views: 63 },
|
|
237
|
+
{ name: 'stacksjs.netlify.app', visitors: 38, views: 60 },
|
|
238
|
+
{ name: 'github.com', visitors: 34, views: 47 },
|
|
239
|
+
{ name: 'DuckDuckGo', visitors: 32, views: 35 },
|
|
240
|
+
{ name: 'Bing', visitors: 22, views: 24 },
|
|
241
|
+
{ name: 'Baidu', visitors: 8, views: 8 },
|
|
242
|
+
{ name: 'npmjs.com', visitors: 7, views: 7 },
|
|
243
|
+
]
|
|
244
|
+
|
|
245
|
+
const deviceData = [
|
|
246
|
+
{ name: 'Desktop', visitors: 1300, percentage: 60 },
|
|
247
|
+
{ name: 'Phone', visitors: 874, percentage: 38 },
|
|
248
|
+
{ name: 'Tablet', visitors: 5, percentage: 2 },
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
const browserData = [
|
|
252
|
+
{ name: 'Chrome', visitors: 1300, percentage: 58 },
|
|
253
|
+
{ name: 'Safari', visitors: 579, percentage: 26 },
|
|
254
|
+
{ name: 'Edge', visitors: 129, percentage: 6 },
|
|
255
|
+
{ name: 'Firefox', visitors: 92, percentage: 4 },
|
|
256
|
+
{ name: 'Mozilla', visitors: 24, percentage: 1 },
|
|
257
|
+
]
|
|
258
|
+
|
|
259
|
+
const countriesRaw = [
|
|
260
|
+
{ name: 'United States of America', visitors: 768, flag: '🇺🇸' },
|
|
261
|
+
{ name: 'Germany', visitors: 140, flag: '🇩🇪' },
|
|
262
|
+
{ name: 'United Kingdom', visitors: 87, flag: '🇬🇧' },
|
|
263
|
+
{ name: 'India', visitors: 83, flag: '🇮🇳' },
|
|
264
|
+
{ name: 'Indonesia', visitors: 80, flag: '🇮🇩' },
|
|
265
|
+
]
|
|
266
|
+
|
|
267
|
+
const totalPageViews = pagesRaw.reduce((s, p) => s + p.views, 0)
|
|
268
|
+
const totalReferrerViews = referrersRaw.reduce((s, r) => s + r.views, 0)
|
|
269
|
+
const totalCountryVisitors = countriesRaw.reduce((s, c) => s + c.visitors, 0)
|
|
270
|
+
|
|
271
|
+
const pagesData = pagesRaw.map(p => ({ ...p, percentage: Math.round((p.views / totalPageViews) * 100) }))
|
|
272
|
+
const referrersData = referrersRaw.map(r => ({ ...r, percentage: Math.round((r.views / totalReferrerViews) * 100) }))
|
|
273
|
+
const countriesData = countriesRaw.map(c => ({ ...c, percentage: Math.round((c.visitors / totalCountryVisitors) * 100) }))
|
|
274
|
+
|
|
275
|
+
const analyticsOverview = {
|
|
276
|
+
realtime: 0,
|
|
277
|
+
people: 2200,
|
|
278
|
+
views: 3000,
|
|
279
|
+
avgTimeOnSite: '03:36',
|
|
280
|
+
bounceRate: '89%',
|
|
281
|
+
eventCompletions: 0,
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const dateRangeDisplay = state('All Time: Sep 7, 2023 to Mar 6, 2025')
|
|
285
|
+
const comparisonType = state('no-comparison')
|
|
286
|
+
|
|
287
|
+
const trafficData = state<Array<{ date: string, pageViews: number, visitors: number }>>([
|
|
288
|
+
{ date: '2023-11-01', pageViews: 100, visitors: 80 },
|
|
289
|
+
{ date: '2023-11-15', pageViews: 250, visitors: 180 },
|
|
290
|
+
{ date: '2023-12-01', pageViews: 150, visitors: 120 },
|
|
291
|
+
{ date: '2023-12-15', pageViews: 220, visitors: 170 },
|
|
292
|
+
{ date: '2024-01-01', pageViews: 180, visitors: 140 },
|
|
293
|
+
{ date: '2024-01-15', pageViews: 320, visitors: 240 },
|
|
294
|
+
{ date: '2024-02-01', pageViews: 280, visitors: 210 },
|
|
295
|
+
{ date: '2024-02-15', pageViews: 400, visitors: 300 },
|
|
296
|
+
{ date: '2024-03-01', pageViews: 350, visitors: 270 },
|
|
297
|
+
{ date: '2024-03-15', pageViews: 300, visitors: 230 },
|
|
298
|
+
{ date: '2024-04-01', pageViews: 250, visitors: 190 },
|
|
299
|
+
{ date: '2024-04-15', pageViews: 200, visitors: 150 },
|
|
300
|
+
{ date: '2024-05-01', pageViews: 150, visitors: 120 },
|
|
301
|
+
{ date: '2024-05-15', pageViews: 120, visitors: 90 },
|
|
302
|
+
{ date: '2024-06-01', pageViews: 100, visitors: 80 },
|
|
303
|
+
{ date: '2024-06-15', pageViews: 130, visitors: 100 },
|
|
304
|
+
{ date: '2024-07-01', pageViews: 150, visitors: 120 },
|
|
305
|
+
{ date: '2024-07-15', pageViews: 120, visitors: 90 },
|
|
306
|
+
{ date: '2024-08-01', pageViews: 100, visitors: 80 },
|
|
307
|
+
{ date: '2024-08-15', pageViews: 80, visitors: 60 },
|
|
308
|
+
{ date: '2024-09-01', pageViews: 100, visitors: 80 },
|
|
309
|
+
{ date: '2024-09-15', pageViews: 120, visitors: 90 },
|
|
310
|
+
{ date: '2024-10-01', pageViews: 150, visitors: 120 },
|
|
311
|
+
{ date: '2024-10-15', pageViews: 100, visitors: 80 },
|
|
312
|
+
{ date: '2024-11-01', pageViews: 80, visitors: 60 },
|
|
313
|
+
{ date: '2024-11-15', pageViews: 120, visitors: 90 },
|
|
314
|
+
{ date: '2024-12-01', pageViews: 300, visitors: 230 },
|
|
315
|
+
{ date: '2024-12-15', pageViews: 150, visitors: 120 },
|
|
316
|
+
{ date: '2025-01-01', pageViews: 100, visitors: 80 },
|
|
317
|
+
{ date: '2025-01-15', pageViews: 80, visitors: 60 },
|
|
318
|
+
{ date: '2025-02-01', pageViews: 60, visitors: 40 },
|
|
319
|
+
])
|
|
320
|
+
|
|
321
|
+
let chartHandle: { destroy: () => void } | null = null
|
|
322
|
+
|
|
323
|
+
onMount(async () => {
|
|
324
|
+
const { Chart, registerables } = await import('@stacksjs/charts')
|
|
325
|
+
Chart.register(...registerables)
|
|
326
|
+
const Ctor = Chart as unknown as ChartCtor
|
|
327
|
+
chartHandle = useChart({
|
|
328
|
+
Chart: Ctor,
|
|
329
|
+
id: 'traffic_chart',
|
|
330
|
+
type: 'line',
|
|
331
|
+
data: {
|
|
332
|
+
labels: trafficData().map(item => item.date),
|
|
333
|
+
datasets: [
|
|
334
|
+
{ label: 'Page Views', data: trafficData().map(item => item.pageViews), backgroundColor: 'rgba(147, 197, 253, 0.3)', borderColor: 'rgba(59, 130, 246, 0.8)', borderWidth: 2, tension: 0.4, fill: true },
|
|
335
|
+
{ label: 'Visitors', data: trafficData().map(item => item.visitors), backgroundColor: 'rgba(147, 197, 253, 0.1)', borderColor: 'rgba(96, 165, 250, 0.8)', borderWidth: 2, tension: 0.4, fill: false },
|
|
336
|
+
],
|
|
337
|
+
},
|
|
338
|
+
options: {
|
|
339
|
+
responsive: true,
|
|
340
|
+
maintainAspectRatio: false,
|
|
341
|
+
scales: {
|
|
342
|
+
x: { grid: { display: false }, ticks: { maxTicksLimit: 4 } },
|
|
343
|
+
y: { beginAtZero: true, grid: { borderDash: [2, 4], color: 'rgba(160, 174, 192, 0.2)' }, ticks: { maxTicksLimit: 6 } },
|
|
344
|
+
},
|
|
345
|
+
plugins: { legend: { display: true, position: 'top' }, tooltip: { mode: 'index', intersect: false } },
|
|
346
|
+
},
|
|
347
|
+
})
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
onDestroy(() => {
|
|
351
|
+
chartHandle?.destroy()
|
|
352
|
+
chartHandle = null
|
|
353
|
+
})
|
|
354
|
+
</script>
|
|
355
|
+
|
|
356
|
+
@endsection
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
@extends('layouts/default')
|
|
2
|
+
|
|
3
|
+
@section('content')
|
|
4
|
+
<div class="flex overflow-hidden h-screen bg-gray-100 dark:bg-neutral-900">
|
|
5
|
+
<div class="flex flex-col w-80 bg-white dark:bg-neutral-800 border-gray-200 border-r">
|
|
6
|
+
<div class="flex-none p-4 border-b border-gray-200 dark:border-neutral-700">
|
|
7
|
+
<h2 class="font-semibold text-gray-900 text-lg dark:text-white">Conversations</h2>
|
|
8
|
+
<p class="text-gray-500 text-sm dark:text-neutral-400">Ask any question you may have.</p>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="overflow-y-auto flex-1">
|
|
12
|
+
<template :for="chat in conversations">
|
|
13
|
+
<div @click="selectConversation({{ chat.id }})" class="p-4 cursor-pointer border-b border-gray-200 {{ isActive(chat.id) ? 'bg-blue-50' : 'hover:bg-gray-50' }}">
|
|
14
|
+
<div class="flex items-start justify-between">
|
|
15
|
+
<div class="flex items-center space-x-3">
|
|
16
|
+
<div class="relative">
|
|
17
|
+
<div class="flex items-center justify-center h-10 w-10 bg-gradient-to-r from-blue-400 to-blue-600 rounded-full">
|
|
18
|
+
<span class="font-medium text-sm text-white">{{ chat.name.charAt(0) }}</span>
|
|
19
|
+
</div>
|
|
20
|
+
<div :show="{{ chat.status === 'online' ? 'true' : 'false' }}" class="absolute h-3 w-3 bg-green-400 border-2 border-white rounded-full -bottom-0.5 -right-0.5"></div>
|
|
21
|
+
</div>
|
|
22
|
+
<div>
|
|
23
|
+
<h3 class="font-medium text-gray-900 text-sm">{{ chat.name }}</h3>
|
|
24
|
+
<p class="mt-1 line-clamp-1 text-gray-500 text-sm">{{ chat.lastMessage }}</p>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="flex items-center space-x-2">
|
|
28
|
+
<span class="text-gray-500 text-xs whitespace-nowrap">{{ chat.timestamp }}</span>
|
|
29
|
+
<span :show="{{ chat.unread ? 'true' : 'false' }}" class="h-2 w-2 bg-blue-500 rounded-full"></span>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="flex flex-1 flex-col">
|
|
38
|
+
<div class="flex-none p-4 bg-white dark:bg-neutral-800 border-b border-gray-200">
|
|
39
|
+
<div class="flex items-center justify-between">
|
|
40
|
+
<div class="flex items-center space-x-4">
|
|
41
|
+
<div class="flex items-center justify-center h-10 w-10 bg-gradient-to-r from-blue-400 to-blue-600 rounded-full">
|
|
42
|
+
<span class="font-medium text-sm text-white">AI</span>
|
|
43
|
+
</div>
|
|
44
|
+
<div>
|
|
45
|
+
<h2 class="font-semibold text-gray-900 text-lg">Buddy</h2>
|
|
46
|
+
<p class="text-gray-500 text-sm">Always here to help</p>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="overflow-y-auto flex-1 p-4 bg-gray-50 dark:bg-neutral-900">
|
|
53
|
+
<div class="flex flex-col mx-auto space-y-4 max-w-3xl">
|
|
54
|
+
<template :for="message in messages">
|
|
55
|
+
<div class="flex items-start space-x-4 {{ message.type === 'ai' ? '' : 'justify-end' }}">
|
|
56
|
+
<div :show="{{ message.type === 'ai' ? 'true' : 'false' }}" class="flex items-center justify-center h-10 w-10 bg-gradient-to-r from-blue-400 to-blue-600 rounded-full">
|
|
57
|
+
<span class="font-medium text-sm text-white">AI</span>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="rounded-lg p-4 shadow max-w-lg {{ message.type === 'ai' ? 'bg-white dark:bg-neutral-800' : 'bg-blue-500 text-white' }}">
|
|
61
|
+
<div class="flex items-center justify-between mb-1">
|
|
62
|
+
<span class="font-medium">{{ message.user.name }}</span>
|
|
63
|
+
<span class="text-sm opacity-75">{{ message.timestamp }}</span>
|
|
64
|
+
</div>
|
|
65
|
+
<p>{{ message.content }}</p>
|
|
66
|
+
|
|
67
|
+
<div :show="{{ message.codeSnippet ? 'true' : 'false' }}" class="mt-3 p-4 text-white bg-gray-800 rounded-md">
|
|
68
|
+
<pre><code>{{ message.codeSnippet?.code }}</code></pre>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<img :show="{{ message.type === 'human' ? 'true' : 'false' }}" src="{{ message.user.avatar }}" alt="{{ message.user.name }}" class="h-10 w-10 rounded-full" />
|
|
73
|
+
</div>
|
|
74
|
+
</template>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div class="flex-none p-4 bg-white dark:bg-neutral-800 border-gray-200 border-t">
|
|
79
|
+
<div class="mx-auto max-w-3xl">
|
|
80
|
+
<div class="flex items-center space-x-4">
|
|
81
|
+
<input x-model="newMessage" type="text" placeholder="Ask anything about your project..." @keyup.enter="sendMessage()" class="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
|
|
82
|
+
<button @click="sendMessage()" class="px-6 py-2 text-white bg-blue-500 hover:bg-blue-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">Send</button>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<script client>
|
|
90
|
+
interface User {
|
|
91
|
+
id: number
|
|
92
|
+
name: string
|
|
93
|
+
email: string
|
|
94
|
+
avatar: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface Conversation {
|
|
98
|
+
id: number
|
|
99
|
+
name: string
|
|
100
|
+
lastMessage: string
|
|
101
|
+
timestamp: string
|
|
102
|
+
unread: boolean
|
|
103
|
+
type: 'ai' | 'human'
|
|
104
|
+
status: 'online' | 'offline'
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface Message {
|
|
108
|
+
id: number
|
|
109
|
+
content: string
|
|
110
|
+
timestamp: string
|
|
111
|
+
type: 'ai' | 'human'
|
|
112
|
+
codeSnippet?: { language: string, code: string }
|
|
113
|
+
user: User
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const activeConversation = state(1)
|
|
117
|
+
const newMessage = state('')
|
|
118
|
+
|
|
119
|
+
const conversations = state<Conversation[]>([
|
|
120
|
+
{ id: 1, name: 'New Project Setup', lastMessage: 'I can help you set up a new Stacks.js project with TypeScript', timestamp: 'Moments ago', unread: true, type: 'ai', status: 'online' },
|
|
121
|
+
{ id: 2, name: 'Database Migration', lastMessage: 'Here\'s how to run your first migration in Stacks.js', timestamp: '2h ago', unread: false, type: 'ai', status: 'online' },
|
|
122
|
+
{ id: 3, name: 'API Documentation', lastMessage: 'Generated API documentation for your endpoints', timestamp: '1d ago', unread: false, type: 'ai', status: 'online' },
|
|
123
|
+
])
|
|
124
|
+
|
|
125
|
+
const messages = state<Message[]>([
|
|
126
|
+
{
|
|
127
|
+
id: 1,
|
|
128
|
+
type: 'human',
|
|
129
|
+
user: { id: 1, name: 'Chris', email: 'chris@stacksjs.com', avatar: 'https://avatars.githubusercontent.com/u/6228425?v=4' },
|
|
130
|
+
content: 'How do I create a new Stacks.js project with TypeScript?',
|
|
131
|
+
timestamp: '2:30 PM',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 2,
|
|
135
|
+
type: 'ai',
|
|
136
|
+
user: { id: 0, name: 'Buddy', email: 'ai@stacksjs.com', avatar: '' },
|
|
137
|
+
content: 'I can help you set up a new Stacks.js project. First, let\'s create a new project using the CLI:',
|
|
138
|
+
timestamp: '2:31 PM',
|
|
139
|
+
codeSnippet: { language: 'bash', code: 'npm create stacks@latest my-app\ncd my-app\npnpm install' },
|
|
140
|
+
},
|
|
141
|
+
])
|
|
142
|
+
|
|
143
|
+
function isActive(id: number): boolean {
|
|
144
|
+
return activeConversation() === id
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function selectConversation(id: number): void {
|
|
148
|
+
activeConversation.set(id)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function nowTime(): string {
|
|
152
|
+
return new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function sendMessage(): void {
|
|
156
|
+
const content = newMessage().trim()
|
|
157
|
+
if (!content)
|
|
158
|
+
return
|
|
159
|
+
const list = messages()
|
|
160
|
+
const human: Message = {
|
|
161
|
+
id: list.length + 1,
|
|
162
|
+
type: 'human',
|
|
163
|
+
user: { id: 1, name: 'Chris', email: 'chris@stacksjs.com', avatar: '/avatars/chris.jpg' },
|
|
164
|
+
content,
|
|
165
|
+
timestamp: nowTime(),
|
|
166
|
+
}
|
|
167
|
+
messages.set([...list, human])
|
|
168
|
+
newMessage.set('')
|
|
169
|
+
|
|
170
|
+
setTimeout(() => {
|
|
171
|
+
const next = messages()
|
|
172
|
+
const ai: Message = {
|
|
173
|
+
id: next.length + 1,
|
|
174
|
+
type: 'ai',
|
|
175
|
+
user: { id: 0, name: 'Buddy', email: 'ai@stacksjs.com', avatar: '/avatars/stacks-ai.jpg' },
|
|
176
|
+
content: 'I\'m processing your request. How can I help you with Stacks.js?',
|
|
177
|
+
timestamp: nowTime(),
|
|
178
|
+
}
|
|
179
|
+
messages.set([...next, ai])
|
|
180
|
+
}, 1000)
|
|
181
|
+
}
|
|
182
|
+
</script>
|
|
183
|
+
|
|
184
|
+
<style scoped>
|
|
185
|
+
.h-screen {
|
|
186
|
+
height: 100vh;
|
|
187
|
+
max-height: 100vh;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.line-clamp-1 {
|
|
191
|
+
display: -webkit-box;
|
|
192
|
+
-webkit-line-clamp: 1;
|
|
193
|
+
-webkit-box-orient: vertical;
|
|
194
|
+
overflow: hidden;
|
|
195
|
+
}
|
|
196
|
+
</style>
|
|
197
|
+
|
|
198
|
+
@endsection
|