@stacksjs/defaults 0.75.233 → 0.75.236

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/ai/skills/stacks-dashboard/SKILL.md +2 -2
  2. package/ai/skills/stacks-database/SKILL.md +1 -1
  3. package/ai/skills/stacks-deploy/SKILL.md +3 -2
  4. package/ai/skills/stacks-migrations/SKILL.md +2 -2
  5. package/ai/skills/stacks-native/CATALOG.md +8 -8
  6. package/ai/skills/stacks-realtime/SKILL.md +4 -2
  7. package/app/Actions/Monitoring/error-provider.ts +129 -12
  8. package/app/Models/Error.ts +21 -0
  9. package/ide/vscode/package.json +1 -1
  10. package/package.json +2 -2
  11. package/resources/components/Dashboard/Auth/AuthCard.stx +29 -0
  12. package/resources/components/Dashboard/Auth/ForgotPassword.stx +65 -79
  13. package/resources/components/Dashboard/Auth/Login.stx +73 -82
  14. package/resources/components/Dashboard/Auth/Register.stx +121 -135
  15. package/resources/components/Dashboard/Auth/ResetPassword.stx +88 -102
  16. package/resources/components/Dashboard/Buddy/BuddyAssistant.stx +11 -15
  17. package/resources/components/Dashboard/Commerce/CommerceCategoriesDashboard.stx +8 -20
  18. package/resources/components/Dashboard/Commerce/CommerceCouponsDashboard.stx +8 -20
  19. package/resources/components/Dashboard/Commerce/CommerceCustomersDashboard.stx +8 -20
  20. package/resources/components/Dashboard/Commerce/CommerceGiftCardsDashboard.stx +8 -20
  21. package/resources/components/Dashboard/Commerce/CommerceManufacturersDashboard.stx +13 -24
  22. package/resources/components/Dashboard/Commerce/CommerceOrdersDashboard.stx +8 -20
  23. package/resources/components/Dashboard/Commerce/CommerceOverviewDashboard.stx +17 -21
  24. package/resources/components/Dashboard/Commerce/CommercePaymentsDashboard.stx +7 -19
  25. package/resources/components/Dashboard/Commerce/CommercePosDashboard.stx +4 -16
  26. package/resources/components/Dashboard/Commerce/CommerceProductsDashboard.stx +8 -20
  27. package/resources/components/Dashboard/Commerce/CommerceReviewsDashboard.stx +7 -18
  28. package/resources/components/Dashboard/Commerce/CommerceTaxesDashboard.stx +13 -24
  29. package/resources/components/Dashboard/Commerce/CommerceUnitsDashboard.stx +13 -24
  30. package/resources/components/Dashboard/Commerce/CommerceVariantsDashboard.stx +7 -18
  31. package/resources/components/Dashboard/Commerce/Delivery/CouriersDashboard.stx +7 -13
  32. package/resources/components/Dashboard/Commerce/Delivery/DeliveryOverviewDashboard.stx +12 -16
  33. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesDashboard.stx +7 -13
  34. package/resources/components/Dashboard/Commerce/Delivery/DigitalDeliveriesDashboard.stx +7 -13
  35. package/resources/components/Dashboard/Commerce/Delivery/LicenseKeysDashboard.stx +7 -13
  36. package/resources/components/Dashboard/Commerce/Delivery/ShippingMethodsDashboard.stx +7 -13
  37. package/resources/components/Dashboard/Commerce/Delivery/ShippingRatesDashboard.stx +7 -13
  38. package/resources/components/Dashboard/Commerce/Delivery/ShippingZonesDashboard.stx +7 -13
  39. package/resources/components/Dashboard/Commerce/PrintDevicesDashboard.stx +8 -20
  40. package/resources/components/Dashboard/Commerce/PrintLogsDashboard.stx +7 -19
  41. package/resources/components/Dashboard/Commerce/ProductWaitlistDashboard.stx +12 -16
  42. package/resources/components/Dashboard/Commerce/RestaurantWaitlistDashboard.stx +12 -16
  43. package/resources/components/Dashboard/Deployments/DeploymentList.stx +17 -21
  44. package/resources/components/Dashboard/Marketing/AbandonedCartsDashboard.stx +6 -10
  45. package/resources/components/Dashboard/Marketing/CampaignsDashboard.stx +6 -10
  46. package/resources/components/Dashboard/Marketing/MarketingListsDashboard.stx +9 -13
  47. package/resources/components/Dashboard/Marketing/SocialPostsDashboard.stx +6 -10
  48. package/resources/components/Dashboard/Queue/QueueDashboard.stx +12 -16
  49. package/resources/components/Dashboard/Realtime/RealtimeDashboard.stx +6 -10
  50. package/resources/components/Dashboard/Releases/ReleaseDashboard.stx +6 -10
  51. package/resources/components/Dashboard/UI/MetricCards.stx +32 -0
  52. package/resources/components/Dashboard/UI/PageHeader.stx +25 -66
  53. package/resources/components/Dashboard/UI/Table.stx +79 -6
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-dashboard
3
- description: Use when building or customizing the Stacks admin dashboard, including dashboard pages, model management views, analytics widgets, commerce dashboards, content management, settings panels, deployment monitoring, job/queue management, or the 412 built-in dashboard components. Covers the dashboard system at storage/framework/defaults/.
3
+ description: Use when building or customizing the Stacks admin dashboard, including dashboard pages, model management views, analytics widgets, commerce dashboards, content management, settings panels, deployment monitoring, job/queue management, or the 414 built-in dashboard components. Covers the dashboard system at storage/framework/defaults/.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -8,7 +8,7 @@ allowed-tools: Read Edit Write Bash Grep Glob
8
8
 
9
9
  # Stacks Dashboard
10
10
 
11
- The Stacks admin dashboard provides a full-featured admin panel with 100+ route views, 412 components, and a multi-section layout.
11
+ The Stacks admin dashboard provides a full-featured admin panel with 100+ route views, 414 components, and a multi-section layout.
12
12
 
13
13
  ## Key Paths
14
14
  - Dashboard components: `storage/framework/defaults/resources/components/Dashboard/`
@@ -12,7 +12,7 @@ allowed-tools: Read Edit Write Bash Grep Glob
12
12
  - Database package: `storage/framework/core/database/src/`
13
13
  - Configuration: `config/database.ts`
14
14
  - QB config: `config/query-builder.ts`
15
- - Migrations: `database/migrations/` (237 migration files, `.sql` format)
15
+ - Migrations: `database/migrations/` (239 migration files, `.sql` format)
16
16
  - QB state: `.qb/`
17
17
  - ORM: `storage/framework/orm/`
18
18
 
@@ -53,8 +53,9 @@ a versioned `STACKS_DEPLOY_PREVIEW_JSON=` line for API and tool consumers.
53
53
 
54
54
  Automated production deployments on GitHub Actions and ReviewOS require a full provider
55
55
  commit SHA and branch ref. Before prerequisite setup, Buddy verifies the checkout against
56
- that SHA, fetches the branch from `origin` (FETCH_HEAD only; a shallow checkout receives
57
- just the newer commits) and requires the commit to be on it. Before shipping over SSH it
56
+ that SHA and accepts an unchanged origin head directly. If the head moved, Buddy fetches
57
+ the branch from `origin` (FETCH_HEAD only), completes shallow history and requires the
58
+ commit to be on it. Unavailable or still-shallow history stops deployment. Before shipping over SSH it
58
59
  reads the release each site's `current` link serves and stops only when production
59
60
  already runs a commit that landed after this one, so a deploy never goes backwards. A
60
61
  verified commit newer than production deploys even when the head has moved on: requiring
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-migrations
3
- description: Use when working with database migrations in a Stacks application - creating migration files, running migrations, fresh migration (drop + recreate), seeding after migration, migration file naming conventions, or the 237 built-in migration files. For the database API itself (queries, connections, SQL helpers), see stacks-database.
3
+ description: Use when working with database migrations in a Stacks application - creating migration files, running migrations, fresh migration (drop + recreate), seeding after migration, migration file naming conventions, or the 239 built-in migration files. For the database API itself (queries, connections, SQL helpers), see stacks-database.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript, SQLite >= 3.47.2
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -203,6 +203,6 @@ lossless widenings; reports everything destructive), then
203
203
  - Do not commit a second snapshot under `.qb/`; that indicates a missing `snapshotDir` configuration
204
204
  - If a generated SQLite migration rebuilds tables, test it against a copy of the current database and run `PRAGMA integrity_check` plus `PRAGMA foreign_key_check`
205
205
  - `--seed` flag after `migrate:fresh` seeds the database with factory data
206
- - 237 migration files exist by default for all framework models
206
+ - 239 migration files exist by default for all framework models
207
207
  - SQLite >= 3.47.2 is required (system requirement)
208
208
  - For the database API (queries, connections), see the `stacks-database` skill
@@ -35,7 +35,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
35
35
  | `@stacksjs/composables` | [`stacks-composables`](../stacks-composables/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/composables/src/index.ts) | 18 |
36
36
  | `@stacksjs/config` | [`stacks-config`](../stacks-config/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/config/src/index.ts) | 16 |
37
37
  | `@stacksjs/cron` | [`stacks-cron`](../stacks-cron/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cron/src/index.ts) | 4 |
38
- | `@stacksjs/database` | [`stacks-database`](../stacks-database/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/index.ts) | 124 |
38
+ | `@stacksjs/database` | [`stacks-database`](../stacks-database/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/index.ts) | 125 |
39
39
  | `@stacksjs/datetime` | [`stacks-datetime`](../stacks-datetime/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/index.ts) | 13 |
40
40
  | `@stacksjs/defaults` | [`stacks-build`](../stacks-build/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/defaults/package.json) | 1 |
41
41
  | `@stacksjs/deploy` | [`stacks-deploy`](../stacks-deploy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/deploy/package.json) | 1 |
@@ -75,7 +75,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
75
75
  | `@stacksjs/realtime` | [`stacks-realtime`](../stacks-realtime/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/realtime/src/index.ts) | 11 |
76
76
  | `@stacksjs/registry` | [`stacks-registry`](../stacks-registry/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/registry/src/index.ts) | 1 |
77
77
  | `@stacksjs/repl` | [`stacks-repl`](../stacks-repl/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/repl/src/index.ts) | 2 |
78
- | `@stacksjs/router` | [`stacks-router`](../stacks-router/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/index.ts) | 90 |
78
+ | `@stacksjs/router` | [`stacks-router`](../stacks-router/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/index.ts) | 91 |
79
79
  | `@stacksjs/scheduler` | [`stacks-scheduler`](../stacks-scheduler/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/scheduler/src/index.ts) | 13 |
80
80
  | `@stacksjs/search-engine` | [`stacks-search-engine`](../stacks-search-engine/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/search-engine/src/index.ts) | 10 |
81
81
  | `@stacksjs/security` | [`stacks-security`](../stacks-security/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/security/src/index.ts) | 11 |
@@ -88,7 +88,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
88
88
  | `@stacksjs/socials` | [`stacks-socials`](../stacks-socials/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/socials/src/index.ts) | 17 |
89
89
  | `@stacksjs/storage` | [`stacks-storage`](../stacks-storage/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/index.ts) | 42 |
90
90
  | `@stacksjs/strings` | [`stacks-strings`](../stacks-strings/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/strings/src/index.ts) | 7 |
91
- | `@stacksjs/testing` | [`stacks-testing`](../stacks-testing/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/index.ts) | 15 |
91
+ | `@stacksjs/testing` | [`stacks-testing`](../stacks-testing/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/index.ts) | 16 |
92
92
  | `@stacksjs/tinker` | [`stacks-repl`](../stacks-repl/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tinker/src/index.ts) | 1 |
93
93
  | `@stacksjs/tunnel` | [`stacks-tunnel`](../stacks-tunnel/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tunnel/src/index.ts) | 1 |
94
94
  | `@stacksjs/types` | [`stacks-types`](../stacks-types/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/types/src/index.ts) | 2 |
@@ -351,7 +351,7 @@ Declared runtime exports: `BUN_BROKEN_MYSQL_POOL_MESSAGE`, `BUN_BROKEN_POSTGRES_
351
351
 
352
352
  Local source modules: [src/affected-rows.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/affected-rows.ts), [src/auth-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/auth-tables.ts), [src/broken-pool.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/broken-pool.ts), [src/custom/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/custom/index.ts), [src/database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/database.ts), [src/datetime-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/datetime-columns.ts), [src/ddl-constraints.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/ddl-constraints.ts), [src/defaults.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/defaults.ts), [src/dialect.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/dialect.ts), [src/driver-config.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/driver-config.ts), [src/drivers/dynamodb.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/drivers/dynamodb.ts), [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/drivers/index.ts), [src/ensure-database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/ensure-database.ts), [src/erd.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/erd.ts), [src/fk-audit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/fk-audit.ts), [src/framework-renames.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/framework-renames.ts), [src/hand-written-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/hand-written-migrations.ts), [src/ignored-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/ignored-migrations.ts), [src/index-shape.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/index-shape.ts), [src/managed-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/managed-columns.ts), [src/migration-dialect.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-dialect.ts), [src/migration-ledger.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-ledger.ts), [src/migration-names.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-names.ts), [src/migration-path.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migration-path.ts), [src/migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/migrations.ts), [src/model-sources.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/model-sources.ts), [src/notification-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/notification-tables.ts), [src/package-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/package-migrations.ts), [src/package-models.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/package-models.ts), [src/query-logger.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/query-logger.ts), [src/rbac-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/rbac-tables.ts), [src/relation-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/relation-columns.ts), [src/replicas.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/replicas.ts), [src/row-lock.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/row-lock.ts), [src/safe-migrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/safe-migrations.ts), [src/schema-align.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/schema-align.ts), [src/schema-drift.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/schema-drift.ts), [src/seeder.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/seeder.ts), [src/shadowed-models.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/shadowed-models.ts), [src/sql-helpers.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/sql-helpers.ts), [src/trait-tables.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/trait-tables.ts), [src/transaction-context.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/transaction-context.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/types.ts), [src/unique-audit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/unique-audit.ts), [src/utc-defaults.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/utc-defaults.ts), [src/utils.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/utils.ts), [src/uuid-columns.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/uuid-columns.ts), [src/vschema.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/vschema.ts).
353
353
 
354
- Evidence directory: [124 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
354
+ Evidence directory: [125 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
355
355
 
356
356
  ### @stacksjs/datetime
357
357
 
@@ -719,11 +719,11 @@ Evidence directory: [2 retained tests](https://github.com/stacksjs/stacks/blob/m
719
719
 
720
720
  Guidance: [`stacks-router`](../stacks-router/SKILL.md). Source: [storage/framework/core/router/src/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/index.ts).
721
721
 
722
- Declared runtime exports: `DASHBOARD_ROUTE_GROUPS`, `DEFAULT_ROUTE_BUNDLE_FEATURES`, `DEFAULT_ROUTE_REGISTRY`, `DatabaseSessionStore`, `EncryptedSessionStore`, `FileSessionStore`, `JSON_CONTENT_TYPE`, `MemorySessionStore`, `Middleware`, `PathParamError`, `RedisSessionStore`, `RequestBodyError`, `appRouteRegistry`, `assertRouteMiddlewareResolvable`, `bundleMounts`, `cacheRedisConnection`, `cacheRequestQuery`, `checkApplicationHealth`, `clearCsrfModuleCache`, `clearCurrentRequest`, `clearMiddlewareCache`, `clearRateLimit`, `clearRouteModelBindings`, `clearTrackedQueries`, `clientAddress`, `configureViewDirectories`, `createErrorResponse`, `createMiddlewareErrorResponse`, `createNotFoundResponse`, `createSessionStore`, `createStacksRouter`, `createStacksSessionStore`, `createTypedRouter`, `createValidationErrorResponse`, `dashboardGroupMiddleware`, `defineMiddleware`, `defineRouteModelBinding`, `describeUnknownDashboardGroups`, `disableViewRouting`, `enhanceRequest`, `fallbackStorage`, `findUnresolvableRouteMiddleware`, `getCurrentRequest`, `getQueryShapeCounts`, `getTraceId`, `installMiddlewareHotReload`, `isApiRequest`, `isRouterAction`, `listNamedRoutes`, `listRegisteredRoutes`, `listRootMountedAppRoutes`, `loadMiddlewareHandlers`, `loadRoutes`, `mountedDefaultRouteBundles`, `rateLimit`, `rateLimitScale`, `rateLimitStatus`, `readJsonBody`, `readTextBody`, `request`, `resetBootHooks`, `resetRateLimiters`, `resetSharedRateLimitStorage`, `resolveDashboardAccess`, `resolveRouteModel`, `route`, `routeModelBindings`, `routeParams`, `runBootHooks`, `runHealthProbes`, `runWithRequest`, `safePathParam`, `sanitizePathParam`, `scaledLimit`, `serve`, `serverResponse`, `setCurrentRequest`, `setRouteModelFallback`, `sharedRateLimitStorage`, `signUrl`, `signedUrl`, `stream`, `trackQuery`, `trustedProxies`, `url`, `useRateLimitStorage`, `verifySignedUrl`, `verifySignedUrlMiddleware`, `warnOnMultipleRouterInstances`, `withTraceId`, `wrapAction`.
722
+ Declared runtime exports: `DASHBOARD_ROUTE_GROUPS`, `DEFAULT_ROUTE_BUNDLE_FEATURES`, `DEFAULT_ROUTE_REGISTRY`, `DatabaseSessionStore`, `EncryptedSessionStore`, `FileSessionStore`, `JSON_CONTENT_TYPE`, `MemorySessionStore`, `Middleware`, `PathParamError`, `RedisSessionStore`, `RequestBodyError`, `appRouteRegistry`, `assertRouteMiddlewareResolvable`, `bundleMounts`, `cacheRedisConnection`, `cacheRequestQuery`, `checkApplicationHealth`, `clearCsrfModuleCache`, `clearCurrentRequest`, `clearMiddlewareCache`, `clearRateLimit`, `clearRouteModelBindings`, `clearTrackedQueries`, `clientAddress`, `configureViewDirectories`, `createErrorResponse`, `createMiddlewareErrorResponse`, `createNotFoundResponse`, `createSessionStore`, `createStacksRouter`, `createStacksSessionStore`, `createTypedRouter`, `createValidationErrorResponse`, `dashboardGroupMiddleware`, `defineMiddleware`, `defineRouteModelBinding`, `describeUnknownDashboardGroups`, `disableViewRouting`, `enhanceRequest`, `fallbackStorage`, `findUnresolvableRouteMiddleware`, `getCurrentRequest`, `getQueryShapeCounts`, `getTraceId`, `installMiddlewareHotReload`, `isApiRequest`, `isRouterAction`, `listNamedRoutes`, `listRegisteredRoutes`, `listRootMountedAppRoutes`, `loadMiddlewareHandlers`, `loadRoutes`, `mountedDefaultRouteBundles`, `parseJsonText`, `rateLimit`, `rateLimitScale`, `rateLimitStatus`, `readJsonBody`, `readTextBody`, `request`, `resetBootHooks`, `resetRateLimiters`, `resetSharedRateLimitStorage`, `resolveDashboardAccess`, `resolveRouteModel`, `route`, `routeModelBindings`, `routeParams`, `runBootHooks`, `runHealthProbes`, `runWithRequest`, `safePathParam`, `sanitizePathParam`, `scaledLimit`, `serve`, `serverResponse`, `setCurrentRequest`, `setRouteModelFallback`, `sharedRateLimitStorage`, `signUrl`, `signedUrl`, `stream`, `trackQuery`, `trustedProxies`, `url`, `useRateLimitStorage`, `verifySignedUrl`, `verifySignedUrlMiddleware`, `warnOnMultipleRouterInstances`, `withTraceId`, `wrapAction`.
723
723
 
724
- Local source modules: [src/api-shape.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/api-shape.ts), [src/body.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/body.ts), [src/dashboard-access.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/dashboard-access.ts), [src/encrypted-session-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/encrypted-session-store.ts), [src/error-handler.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/error-handler.ts), [src/health.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/health.ts), [src/middleware.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/middleware.ts), [src/path-sanitize.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/path-sanitize.ts), [src/rate-limit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/rate-limit.ts), [src/request-augmentation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/request-augmentation.ts), [src/request-context.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/request-context.ts), [src/route-loader.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/route-loader.ts), [src/route-model-binding.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/route-model-binding.ts), [src/security-settings.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/security-settings.ts), [src/session-factory.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/session-factory.ts), [src/signed-url.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/signed-url.ts), [src/stacks-router.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/stacks-router.ts), [src/typed-router.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/typed-router.ts).
724
+ Local source modules: [src/api-shape.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/api-shape.ts), [src/body.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/body.ts), [src/dashboard-access.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/dashboard-access.ts), [src/encrypted-session-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/encrypted-session-store.ts), [src/error-handler.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/error-handler.ts), [src/health.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/health.ts), [src/json.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/json.ts), [src/middleware.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/middleware.ts), [src/path-sanitize.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/path-sanitize.ts), [src/rate-limit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/rate-limit.ts), [src/request-augmentation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/request-augmentation.ts), [src/request-context.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/request-context.ts), [src/route-loader.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/route-loader.ts), [src/route-model-binding.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/route-model-binding.ts), [src/security-settings.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/security-settings.ts), [src/session-factory.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/session-factory.ts), [src/signed-url.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/signed-url.ts), [src/stacks-router.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/stacks-router.ts), [src/typed-router.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/typed-router.ts).
725
725
 
726
- Evidence directory: [90 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
726
+ Evidence directory: [91 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
727
727
 
728
728
  ### @stacksjs/scheduler
729
729
 
@@ -851,7 +851,7 @@ Read the entrypoint and package export map for re-exported or type-only surfaces
851
851
 
852
852
  Local source modules: [src/console.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/console.ts), [src/disposable-database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/disposable-database.ts), [src/events.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/events.ts), [src/feature.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/feature.ts), [src/isolated.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/isolated.ts), [src/mail.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/mail.ts), [src/time.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/time.ts).
853
853
 
854
- Evidence directory: [15 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
854
+ Evidence directory: [16 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
855
855
 
856
856
  ### @stacksjs/tinker
857
857
 
@@ -385,8 +385,10 @@ single-process HTTP transport; it does not initialize Redis or a cluster.
385
385
 
386
386
  `createBroadcastResponse({ channels, authorize, signal })` returns an SSE Response.
387
387
  Select channel names on the server. Authorization is mandatory and runs before
388
- subscription, before each event, and at every heartbeat. Pass the request's abort
389
- signal. Cancellation, failed authorization and slow consumers remove the hook.
388
+ subscription, before each event, and at every heartbeat. The callback retains the
389
+ subscriber's async context even when another request broadcasts. It must still
390
+ resolve current credentials, grants and expiry on every call; context binding
391
+ does not freeze authorization facts. Pass the request's abort signal. Cancellation, failed authorization and slow consumers remove the hook.
390
392
  Streams bound both queued events and pending authorization work (64 by default).
391
393
 
392
394
  STX's `useBroadcastStream({ request, endpoint, onMessage, onConnected })` makes
@@ -20,16 +20,78 @@ import { HQ_READ_UNAVAILABLE, readThroughProvider, resolveDashboardDriver } from
20
20
  */
21
21
 
22
22
  /**
23
- * The record shapes the error store deals in.
23
+ * The shapes the Errors section renders.
24
24
  *
25
- * Derived from the store's own functions rather than imported, because
26
- * `@stacksjs/commerce` exposes its errors module as a value and keeps these
27
- * interfaces inside it. Deriving them means the provider contract follows the
28
- * store automatically, and it keeps this refactor out of the commerce package.
25
+ * These used to be derived from the local store:
26
+ *
27
+ * export type DashboardErrorRecord = NonNullable<Awaited<ReturnType<typeof errors.fetchById>>>
28
+ *
29
+ * which made the contract whatever `@stacksjs/commerce`'s ORM row happened to
30
+ * be. That is fine while the only provider IS the commerce store, and wrong
31
+ * the moment a second one exists: a remote provider has to be told what to
32
+ * serve, and "whatever a shopping package's table looks like this week" is
33
+ * not something anyone can be told (stacksjs/stacks#2921).
34
+ *
35
+ * Declared here instead, so the section's contract is a decision rather than
36
+ * a consequence. Field names are deliberately the ones already on the wire -
37
+ * these actions serialize straight to JSON and the dashboard reads
38
+ * `first_seen`, `last_seen` and `last_24h` today, so renaming them to
39
+ * camelCase would be a breaking change to a shipped response rather than the
40
+ * decoupling this is for.
29
41
  */
30
- export type DashboardErrorRecord = NonNullable<Awaited<ReturnType<typeof errors.fetchById>>>
31
- export type DashboardGroupedError = Awaited<ReturnType<typeof errors.fetchGrouped>>[number]
32
- export type DashboardErrorStats = Awaited<ReturnType<typeof errors.fetchStats>>
42
+
43
+ /** Where a grouped error sits in the triage workflow. */
44
+ export type DashboardErrorStatus = 'unresolved' | 'resolved' | 'ignored'
45
+
46
+ export interface DashboardErrorRecord {
47
+ /**
48
+ * Opaque. A number from the local store's autoincrement, a string from a
49
+ * hosted one - bughq's issue ids are varchar (stacksjs/stacks#2915).
50
+ * Compare with `String(a.id) === String(b.id)` rather than `===`.
51
+ */
52
+ id: string | number
53
+ type: string
54
+ message: string
55
+ stack: string | null
56
+ /**
57
+ * The HTTP status the error reported, and only that.
58
+ *
59
+ * It used to be overloaded: `resolveError` and `ignoreError` wrote 1 and 2
60
+ * into this column to mean resolved and ignored, which destroyed the status
61
+ * and meant a seeded error could never read as resolved. Split in
62
+ * stacksjs/stacks#2923; triage is `resolution` below.
63
+ */
64
+ status: number | null
65
+ /** Where this error sits in triage. */
66
+ resolution: DashboardErrorStatus
67
+ /** Free text. Nothing in the dashboard reads it; it is carried, not shown. */
68
+ additional_info: string | null
69
+ created_at: string
70
+ updated_at: string | null
71
+ }
72
+
73
+ export interface DashboardGroupedError {
74
+ /** Opaque, as on {@link DashboardErrorRecord}. */
75
+ id: string | number
76
+ type: string
77
+ message: string
78
+ stack: string | null
79
+ /** The triage state, unlike `status` on a single record. See above. */
80
+ status: DashboardErrorStatus
81
+ count: number
82
+ first_seen: string
83
+ last_seen: string
84
+ error_ids: number[]
85
+ }
86
+
87
+ export interface DashboardErrorStats {
88
+ total: number
89
+ unresolved: number
90
+ resolved: number
91
+ ignored: number
92
+ last_24h: number
93
+ trend: number
94
+ }
33
95
 
34
96
  export interface DashboardErrorTimelinePoint {
35
97
  hour: string
@@ -41,7 +103,7 @@ export interface DashboardErrorsProvider {
41
103
  stats: () => Promise<DashboardErrorStats>
42
104
  timeline: () => Promise<DashboardErrorTimelinePoint[]>
43
105
  byGroup: (type: string, message: string) => Promise<DashboardErrorRecord[]>
44
- byId: (id: number) => Promise<DashboardErrorRecord | undefined>
106
+ byId: (id: string | number) => Promise<DashboardErrorRecord | undefined>
45
107
  }
46
108
 
47
109
  /** Wraps a payload with the reason its section is empty. */
@@ -54,12 +116,67 @@ export type DashboardErrorsEnvelope<T> = { data: T } & Partial<DashboardProvider
54
116
  * adding one here would convert today's error response into a misleading empty
55
117
  * list, which is a behaviour change rather than the refactor this is meant to be.
56
118
  */
119
+ const ERROR_STATUSES: readonly DashboardErrorStatus[] = ['unresolved', 'resolved', 'ignored']
120
+
121
+ /**
122
+ * Narrow the store's `status` onto the three states the section renders.
123
+ *
124
+ * `fetchGrouped` types this as `string` while deriving it from exactly those
125
+ * three labels, so the widening is incidental. An unknown value reads as
126
+ * unresolved, which is the store's own default for a status it cannot
127
+ * interpret, and is the safe direction: an error wrongly shown as needing
128
+ * attention is noticed, one wrongly shown as handled is not.
129
+ */
130
+ function toErrorStatus(value: string): DashboardErrorStatus {
131
+ return ERROR_STATUSES.includes(value as DashboardErrorStatus)
132
+ ? value as DashboardErrorStatus
133
+ : 'unresolved'
134
+ }
135
+
136
+ /**
137
+ * The commerce row, as the section's contract.
138
+ *
139
+ * Written out rather than passed through. Every field here is currently an
140
+ * identity, and saying so explicitly is the point: when the store's shape
141
+ * next moves, this file stops compiling instead of quietly changing what a
142
+ * remote provider is required to match.
143
+ */
144
+ function toGroupedError(row: Awaited<ReturnType<typeof errors.fetchGrouped>>[number]): DashboardGroupedError {
145
+ return {
146
+ id: row.id,
147
+ type: row.type,
148
+ message: row.message,
149
+ stack: row.stack,
150
+ status: toErrorStatus(row.status),
151
+ count: row.count,
152
+ first_seen: row.first_seen,
153
+ last_seen: row.last_seen,
154
+ error_ids: row.error_ids,
155
+ }
156
+ }
157
+
158
+ /**
159
+ * The local store's id for a requested one, or undefined when it cannot have it.
160
+ *
161
+ * Its ids are an autoincrement, so a non-integer id is not one of its rows
162
+ * rather than a bad request, and the caller answers 404. Route params arrive
163
+ * as strings even when the id is a number, which is why a numeric string is
164
+ * accepted (stacksjs/stacks#2915).
165
+ */
166
+ export function localErrorId(id: string | number): number | undefined {
167
+ const numeric = typeof id === 'number' ? id : Number.parseInt(String(id), 10)
168
+ return Number.isInteger(numeric) ? numeric : undefined
169
+ }
170
+
57
171
  export const localErrorsProvider: DashboardErrorsProvider = {
58
- grouped: () => errors.fetchGrouped(),
172
+ grouped: async () => (await errors.fetchGrouped()).map(toGroupedError),
59
173
  stats: () => errors.fetchStats(),
60
174
  timeline: () => errors.fetchTimeline(),
61
175
  byGroup: (type, message) => errors.fetchByGroup(type, message),
62
- byId: id => errors.fetchById(id),
176
+ byId: async (id) => {
177
+ const numeric = localErrorId(id)
178
+ return numeric === undefined ? undefined : errors.fetchById(numeric)
179
+ },
63
180
  }
64
181
 
65
182
  /**
@@ -125,6 +242,6 @@ export function readErrorsByGroup(type: string, message: string): Promise<Dashbo
125
242
  return readErrors([], provider => provider.byGroup(type, message), Array.isArray)
126
243
  }
127
244
 
128
- export function readErrorById(id: number): Promise<DashboardErrorsEnvelope<DashboardErrorRecord | undefined>> {
245
+ export function readErrorById(id: string | number): Promise<DashboardErrorsEnvelope<DashboardErrorRecord | undefined>> {
129
246
  return readErrors<DashboardErrorRecord | undefined>(undefined, provider => provider.byId(id), () => true)
130
247
  }
@@ -52,6 +52,16 @@ export default defineModel({
52
52
  factory: faker => faker.system.filePath(),
53
53
  },
54
54
 
55
+ /**
56
+ * The HTTP status the error carried, and only that.
57
+ *
58
+ * It used to mean two things: the factory seeds an HTTP status while
59
+ * `resolveGroup` wrote 1 and `ignoreGroup` wrote 2 into the same column
60
+ * to mean resolved and ignored. So resolving an error destroyed its
61
+ * status, and a seeded error could never read as resolved because no
62
+ * factory row is ever 1 (stacksjs/stacks#2923). Triage now lives in
63
+ * `resolution`.
64
+ */
55
65
  status: {
56
66
  fillable: true,
57
67
  validation: {
@@ -63,6 +73,17 @@ export default defineModel({
63
73
  factory: faker => faker.number.int({ min: 400, max: 500 }),
64
74
  },
65
75
 
76
+ /** Where this error sits in triage. Separate from `status`, see above. */
77
+ resolution: {
78
+ required: true,
79
+ fillable: true,
80
+ default: 'unresolved',
81
+ validation: {
82
+ rule: schema.enum(['unresolved', 'resolved', 'ignored']),
83
+ },
84
+ factory: () => 'unresolved',
85
+ },
86
+
66
87
  additional_info: {
67
88
  fillable: true,
68
89
  validation: {
@@ -2,7 +2,7 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.75.233",
5
+ "version": "0.75.236",
6
6
  "description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
7
7
  "license": "MIT",
8
8
  "funding": "https://github.com/sponsors/chrisbbreuer",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/defaults",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.233",
5
+ "version": "0.75.236",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/stacksjs/stacks.git",
@@ -44,7 +44,7 @@
44
44
  "dependencies": {
45
45
  "@iconify-json/f7": "^1.2.2",
46
46
  "@iconify-json/hugeicons": "^1.2.35",
47
- "@stacksjs/mobile": "0.75.233",
47
+ "@stacksjs/mobile": "0.75.236",
48
48
  "@stacksjs/sanitizer": "^0.2.534",
49
49
  "@xterm/addon-fit": "^0.11.0",
50
50
  "@xterm/xterm": "^6.0.0",
@@ -0,0 +1,29 @@
1
+ <script client>
2
+ /**
3
+ * The centred card the signed-out auth pages sit in.
4
+ *
5
+ * Login, Register, ForgotPassword and ResetPassword each carried this
6
+ * markup (stacksjs/stacks#2917): the same full-height centring, the same
7
+ * 24rem column, the same logo tile, and the same heading pair. They differ
8
+ * only in what goes below it, which is the slot.
9
+ *
10
+ * Four pages the user moves between in one flow is the worst place for a
11
+ * shell to drift, because the drift is visible as a jump between steps.
12
+ */
13
+ const title = useReactiveProp('title', '')
14
+ const subtitle = useReactiveProp('subtitle', '')
15
+ </script>
16
+
17
+ <div class="flex items-center justify-center px-4 py-12 min-h-screen">
18
+ <div class="max-w-sm w-full">
19
+ <div class="mb-8 text-center">
20
+ <div class="inline-flex items-center justify-center mb-4 h-12 w-12 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl shadow-blue-500/25 shadow-lg">
21
+ <span class="h-7 w-7 text-white i-hugeicons-cube"></span>
22
+ </div>
23
+ <h1 class="font-semibold text-2xl text-neutral-900 dark:text-white">{{ title() }}</h1>
24
+ <p class="mt-2 text-neutral-500 text-sm dark:text-neutral-400">{{ subtitle() }}</p>
25
+ </div>
26
+
27
+ <slot />
28
+ </div>
29
+ </div>
@@ -19,91 +19,77 @@ function retry(): void {
19
19
  emit('retry')
20
20
  }
21
21
  </script>
22
- <div class="flex items-center justify-center px-4 py-12 min-h-screen">
23
- <div class="max-w-sm w-full">
24
- <!-- Logo/Brand -->
25
- <div class="mb-8 text-center">
26
- <div class="inline-flex items-center justify-center mb-4 h-12 w-12 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl shadow-blue-500/25 shadow-lg">
27
- <span class="h-7 w-7 text-white i-hugeicons-cube"></span>
28
- </div>
29
- <h1 class="font-semibold text-2xl text-neutral-900 dark:text-white">
30
- {{ title() }}
31
- </h1>
32
- <p class="mt-2 text-neutral-500 text-sm dark:text-neutral-400">
33
- {{ subtitle() }}
34
- </p>
35
- </div>
22
+ <AuthCard :title="title()" :subtitle="subtitle()">
36
23
 
37
- <!-- Form Card -->
38
- <div class="p-6 bg-white dark:bg-neutral-900 border border-neutral-200/60 rounded-2xl dark:border-neutral-800 shadow-black/5 shadow-xl dark:shadow-black/20">
39
- <div :if="success()">
40
- <!-- Success Message -->
41
- <div class="py-4 text-center">
42
- <div class="inline-flex items-center justify-center mb-4 h-12 w-12 bg-green-100 dark:bg-green-900/30 rounded-full">
43
- <div class="h-6 w-6 text-green-600 dark:text-green-400 i-hugeicons-checkmark-circle-02"></div>
44
- </div>
45
- <h2 class="mb-2 font-medium text-lg text-neutral-900 dark:text-white">
46
- Check your email
47
- </h2>
48
- <p class="mb-6 text-neutral-500 text-sm dark:text-neutral-400">
49
- We've sent a password reset link to <strong class="text-neutral-700 dark:text-neutral-200">{{ email() }}</strong>
50
- </p>
51
- <p class="text-neutral-400 text-xs dark:text-neutral-500">
52
- Didn't receive the email? Check your spam folder or
53
- <Button
54
- type="button"
55
- variant="ghost"
56
- size="xs"
57
- @click="retry"
58
- >
59
- try again
60
- </Button>
61
- </p>
24
+ <!-- Form Card -->
25
+ <div class="p-6 bg-white dark:bg-neutral-900 border border-neutral-200/60 rounded-2xl dark:border-neutral-800 shadow-black/5 shadow-xl dark:shadow-black/20">
26
+ <div :if="success()">
27
+ <!-- Success Message -->
28
+ <div class="py-4 text-center">
29
+ <div class="inline-flex items-center justify-center mb-4 h-12 w-12 bg-green-100 dark:bg-green-900/30 rounded-full">
30
+ <div class="h-6 w-6 text-green-600 dark:text-green-400 i-hugeicons-checkmark-circle-02"></div>
62
31
  </div>
63
- </div>
64
- <div :if="!success()">
65
- <!-- Error Message -->
66
- <div :if="error()" role="alert" class="mb-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 rounded-lg dark:border-red-800">
67
- <div class="flex gap-2 items-center">
68
- <div class="h-4 w-4 text-red-600 dark:text-red-400 i-hugeicons-alert-circle"></div>
69
- <p class="text-red-600 text-sm dark:text-red-400">{{ error() }}</p>
70
- </div>
71
- </div>
72
- <form @submit.prevent="handleSubmit">
73
- <!-- Email Field -->
74
- <div class="mb-6">
75
- <Input
76
- type="email"
77
- label="Email address"
78
- placeholder="you@example.com"
79
- v-model:value="email"
80
- required
81
- :disabled="isLoading()"
82
- />
83
- </div>
84
-
85
- <!-- Submit Button -->
32
+ <h2 class="mb-2 font-medium text-lg text-neutral-900 dark:text-white">
33
+ Check your email
34
+ </h2>
35
+ <p class="mb-6 text-neutral-500 text-sm dark:text-neutral-400">
36
+ We've sent a password reset link to <strong class="text-neutral-700 dark:text-neutral-200">{{ email() }}</strong>
37
+ </p>
38
+ <p class="text-neutral-400 text-xs dark:text-neutral-500">
39
+ Didn't receive the email? Check your spam folder or
86
40
  <Button
87
- type="submit"
88
- variant="primary"
89
- size="lg"
90
- fullWidth
91
- :loading="isLoading()"
92
- :disabled="isLoading() || !email().trim()"
41
+ type="button"
42
+ variant="ghost"
43
+ size="xs"
44
+ @click="retry"
93
45
  >
94
- <span :if="isLoading()">Sending...</span>
95
- <span :if="!isLoading()">Send reset link</span>
46
+ try again
96
47
  </Button>
97
- </form>
48
+ </p>
98
49
  </div>
99
50
  </div>
51
+ <div :if="!success()">
52
+ <!-- Error Message -->
53
+ <div :if="error()" role="alert" class="mb-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 rounded-lg dark:border-red-800">
54
+ <div class="flex gap-2 items-center">
55
+ <div class="h-4 w-4 text-red-600 dark:text-red-400 i-hugeicons-alert-circle"></div>
56
+ <p class="text-red-600 text-sm dark:text-red-400">{{ error() }}</p>
57
+ </div>
58
+ </div>
59
+ <form @submit.prevent="handleSubmit">
60
+ <!-- Email Field -->
61
+ <div class="mb-6">
62
+ <Input
63
+ type="email"
64
+ label="Email address"
65
+ placeholder="you@example.com"
66
+ v-model:value="email"
67
+ required
68
+ :disabled="isLoading()"
69
+ />
70
+ </div>
100
71
 
101
- <!-- Back to Login -->
102
- <p class="mt-6 text-center text-neutral-500 text-sm dark:text-neutral-400">
103
- <a href="/login" class="inline-flex gap-1 items-center font-medium text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300">
104
- <div class="h-4 w-4 i-hugeicons-arrow-left-01"></div>
105
- Back to sign in
106
- </a>
107
- </p>
72
+ <!-- Submit Button -->
73
+ <Button
74
+ type="submit"
75
+ variant="primary"
76
+ size="lg"
77
+ fullWidth
78
+ :loading="isLoading()"
79
+ :disabled="isLoading() || !email().trim()"
80
+ >
81
+ <span :if="isLoading()">Sending...</span>
82
+ <span :if="!isLoading()">Send reset link</span>
83
+ </Button>
84
+ </form>
85
+ </div>
108
86
  </div>
109
- </div>
87
+
88
+ <!-- Back to Login -->
89
+ <p class="mt-6 text-center text-neutral-500 text-sm dark:text-neutral-400">
90
+ <a href="/login" class="inline-flex gap-1 items-center font-medium text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300">
91
+ <div class="h-4 w-4 i-hugeicons-arrow-left-01"></div>
92
+ Back to sign in
93
+ </a>
94
+ </p>
95
+ </AuthCard>