@stacksjs/defaults 0.72.103 → 0.73.0

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 (163) hide show
  1. package/ai/AGENTS.md +25 -4
  2. package/ai/README.md +26 -4
  3. package/ai/skills/stacks-actions/SKILL.md +1 -1
  4. package/ai/skills/stacks-ai/SKILL.md +1 -1
  5. package/ai/skills/stacks-alias/SKILL.md +1 -1
  6. package/ai/skills/stacks-analytics/SKILL.md +1 -1
  7. package/ai/skills/stacks-api/SKILL.md +1 -1
  8. package/ai/skills/stacks-arrays/SKILL.md +1 -1
  9. package/ai/skills/stacks-auto-imports/SKILL.md +1 -1
  10. package/ai/skills/stacks-browse/SKILL.md +1 -1
  11. package/ai/skills/stacks-browser/SKILL.md +1 -1
  12. package/ai/skills/stacks-buddy/SKILL.md +1 -1
  13. package/ai/skills/stacks-build/SKILL.md +79 -5
  14. package/ai/skills/stacks-cache/SKILL.md +1 -1
  15. package/ai/skills/stacks-calendar/SKILL.md +1 -1
  16. package/ai/skills/stacks-chat/SKILL.md +1 -1
  17. package/ai/skills/stacks-cli/SKILL.md +1 -1
  18. package/ai/skills/stacks-cloud/SKILL.md +1 -1
  19. package/ai/skills/stacks-cms/SKILL.md +1 -1
  20. package/ai/skills/stacks-codebase-design/DEEPENING.md +79 -0
  21. package/ai/skills/stacks-codebase-design/DESIGN-IT-TWICE.md +72 -0
  22. package/ai/skills/stacks-codebase-design/SKILL.md +180 -0
  23. package/ai/skills/stacks-collections/SKILL.md +1 -1
  24. package/ai/skills/stacks-commerce/SKILL.md +141 -35
  25. package/ai/skills/stacks-composables/SKILL.md +1 -1
  26. package/ai/skills/stacks-config/SKILL.md +1 -1
  27. package/ai/skills/stacks-configuration/SKILL.md +1 -1
  28. package/ai/skills/stacks-cron/SKILL.md +1 -1
  29. package/ai/skills/stacks-crosswind/SKILL.md +1 -1
  30. package/ai/skills/stacks-database/SKILL.md +1 -1
  31. package/ai/skills/stacks-datetime/SKILL.md +1 -1
  32. package/ai/skills/stacks-dependencies/SKILL.md +1 -1
  33. package/ai/skills/stacks-deploy/SKILL.md +1 -1
  34. package/ai/skills/stacks-desktop/SKILL.md +1 -1
  35. package/ai/skills/stacks-development/SKILL.md +1 -1
  36. package/ai/skills/stacks-dns/SKILL.md +1 -1
  37. package/ai/skills/stacks-docs/SKILL.md +1 -1
  38. package/ai/skills/stacks-domain-modeling/FORMATS.md +123 -0
  39. package/ai/skills/stacks-domain-modeling/SKILL.md +109 -0
  40. package/ai/skills/stacks-enums/SKILL.md +1 -1
  41. package/ai/skills/stacks-error-handling/SKILL.md +1 -1
  42. package/ai/skills/stacks-events/SKILL.md +1 -1
  43. package/ai/skills/stacks-faker/SKILL.md +1 -1
  44. package/ai/skills/stacks-flow/PHASE-BOUNDARIES.md +91 -0
  45. package/ai/skills/stacks-flow/SKILL.md +117 -0
  46. package/ai/skills/stacks-git/SKILL.md +37 -9
  47. package/ai/skills/stacks-grilling/SKILL.md +85 -0
  48. package/ai/skills/stacks-guard/SKILL.md +86 -11
  49. package/ai/skills/stacks-guard/scripts/block-destructive.sh +67 -0
  50. package/ai/skills/stacks-handoff/SKILL.md +70 -0
  51. package/ai/skills/stacks-health/SKILL.md +1 -1
  52. package/ai/skills/stacks-http/SKILL.md +1 -1
  53. package/ai/skills/stacks-i18n/SKILL.md +1 -1
  54. package/ai/skills/stacks-investigate/SKILL.md +234 -106
  55. package/ai/skills/stacks-investigate/scripts/hitl-loop.template.sh +47 -0
  56. package/ai/skills/stacks-jobs/SKILL.md +1 -1
  57. package/ai/skills/stacks-listeners/SKILL.md +1 -1
  58. package/ai/skills/stacks-logging/SKILL.md +1 -1
  59. package/ai/skills/stacks-mail/SKILL.md +1 -1
  60. package/ai/skills/stacks-middleware/SKILL.md +1 -1
  61. package/ai/skills/stacks-migrations/SKILL.md +1 -1
  62. package/ai/skills/stacks-models/SKILL.md +1 -1
  63. package/ai/skills/stacks-new-feature/SKILL.md +65 -5
  64. package/ai/skills/stacks-notifications/SKILL.md +1 -1
  65. package/ai/skills/stacks-objects/SKILL.md +1 -1
  66. package/ai/skills/stacks-office-hours/SKILL.md +16 -2
  67. package/ai/skills/stacks-orm/SKILL.md +1 -1
  68. package/ai/skills/stacks-path/SKILL.md +1 -1
  69. package/ai/skills/stacks-payments/SKILL.md +35 -1
  70. package/ai/skills/stacks-plan-review/SKILL.md +27 -6
  71. package/ai/skills/stacks-plugins/SKILL.md +1 -1
  72. package/ai/skills/stacks-prototype/LOGIC.md +103 -0
  73. package/ai/skills/stacks-prototype/SKILL.md +66 -0
  74. package/ai/skills/stacks-prototype/UI.md +112 -0
  75. package/ai/skills/stacks-push/SKILL.md +1 -1
  76. package/ai/skills/stacks-query-builder/SKILL.md +1 -1
  77. package/ai/skills/stacks-queue/SKILL.md +1 -1
  78. package/ai/skills/stacks-realtime/SKILL.md +1 -1
  79. package/ai/skills/stacks-registry/SKILL.md +1 -1
  80. package/ai/skills/stacks-repl/SKILL.md +1 -1
  81. package/ai/skills/stacks-retro/SKILL.md +121 -75
  82. package/ai/skills/stacks-review/SKILL.md +182 -74
  83. package/ai/skills/stacks-router/SKILL.md +1 -1
  84. package/ai/skills/stacks-routes/SKILL.md +1 -1
  85. package/ai/skills/stacks-scaffolding/SKILL.md +1 -1
  86. package/ai/skills/stacks-scheduler/SKILL.md +1 -1
  87. package/ai/skills/stacks-search-engine/SKILL.md +1 -1
  88. package/ai/skills/stacks-security/SKILL.md +1 -1
  89. package/ai/skills/stacks-security-audit/SKILL.md +1 -1
  90. package/ai/skills/stacks-server/SKILL.md +1 -1
  91. package/ai/skills/stacks-shell/SKILL.md +1 -1
  92. package/ai/skills/stacks-slug/SKILL.md +1 -1
  93. package/ai/skills/stacks-sms/SKILL.md +1 -1
  94. package/ai/skills/stacks-socials/SKILL.md +1 -1
  95. package/ai/skills/stacks-storage/SKILL.md +1 -1
  96. package/ai/skills/stacks-strings/SKILL.md +1 -1
  97. package/ai/skills/stacks-stx/SKILL.md +1 -1
  98. package/ai/skills/stacks-tdd/EXAMPLES.md +136 -0
  99. package/ai/skills/stacks-tdd/SKILL.md +125 -0
  100. package/ai/skills/stacks-testing/SKILL.md +13 -3
  101. package/ai/skills/stacks-tunnel/SKILL.md +1 -1
  102. package/ai/skills/stacks-types/SKILL.md +1 -1
  103. package/ai/skills/stacks-ui/SKILL.md +1 -1
  104. package/ai/skills/stacks-utils/SKILL.md +1 -1
  105. package/ai/skills/stacks-validation/SKILL.md +1 -1
  106. package/ai/skills/stacks-whois/SKILL.md +1 -1
  107. package/ai/skills/stacks-wizard/SKILL.md +127 -0
  108. package/ai/skills/stacks-wizard/scripts/template.sh +208 -0
  109. package/ai/skills/stacks-writing-for-agents/MECHANICS.md +125 -0
  110. package/ai/skills/stacks-writing-for-agents/SKILL.md +218 -0
  111. package/app/Actions/Auth/GenerateTwoFactorSecretAction.ts +12 -2
  112. package/app/Actions/Commerce/Shipping/{DriverDestroyAction.ts → CourierDestroyAction.ts} +6 -6
  113. package/app/Actions/Commerce/Shipping/{DriverIndexAction.ts → CourierIndexAction.ts} +3 -3
  114. package/app/Actions/Commerce/Shipping/CourierPingStoreAction.ts +61 -0
  115. package/app/Actions/Commerce/Shipping/{DriverShowAction.ts → CourierShowAction.ts} +5 -5
  116. package/app/Actions/Commerce/Shipping/{DriverStoreAction.ts → CourierStoreAction.ts} +4 -4
  117. package/app/Actions/Commerce/Shipping/{DriverUpdateAction.ts → CourierUpdateAction.ts} +6 -6
  118. package/app/Actions/Commerce/Shipping/DeliveryRouteStartAction.ts +38 -0
  119. package/app/Actions/Commerce/Shipping/DeliveryStopCompleteAction.ts +40 -0
  120. package/app/Actions/Commerce/Shipping/DeliveryStopFailAction.ts +44 -0
  121. package/app/Actions/Commerce/Shipping/DeliveryStopStartAction.ts +39 -0
  122. package/app/Actions/Commerce/Shipping/courier-session.ts +75 -0
  123. package/app/Actions/Commerce/commerce-action.test.ts +5 -5
  124. package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +5 -5
  125. package/app/Actions/Dashboard/Commerce/CourierIndexAction.ts +24 -0
  126. package/app/Actions/Dashboard/Commerce/DeliveryRouteIndexAction.ts +7 -7
  127. package/app/Actions/Dashboard/Commerce/commerce-delivery.test.ts +11 -11
  128. package/app/Actions/Dashboard/Commerce/commerce-delivery.ts +29 -29
  129. package/app/Actions/Dashboard/Commerce/{driver-records.test.ts → courier-records.test.ts} +9 -9
  130. package/app/Actions/Dashboard/Commerce/{driver-records.ts → courier-records.ts} +14 -14
  131. package/app/Actions/Dashboard/Commerce/delivery-route-records.test.ts +13 -13
  132. package/app/Actions/Dashboard/Commerce/delivery-route-records.ts +25 -25
  133. package/app/Models/User.ts +1 -1
  134. package/app/Models/commerce/{Driver.ts → Courier.ts} +7 -7
  135. package/app/Models/commerce/{DriverPing.ts → CourierPing.ts} +7 -7
  136. package/app/Models/commerce/DeliveryRoute.ts +6 -6
  137. package/app/Models/commerce/DeliveryStop.ts +31 -8
  138. package/bootstrap.ts +7 -0
  139. package/functions/commerce/shippings/couriers.ts +19 -0
  140. package/ide/vscode/package.json +1 -1
  141. package/package.json +4 -3
  142. package/resources/components/Dashboard/Commerce/Delivery/{DriverDeleteDialog.stx → CourierDeleteDialog.stx} +5 -5
  143. package/resources/components/Dashboard/Commerce/Delivery/{DriverDialog.stx → CourierDialog.stx} +10 -10
  144. package/resources/components/Dashboard/Commerce/Delivery/{DriversDashboard.stx → CouriersDashboard.stx} +43 -43
  145. package/resources/components/Dashboard/Commerce/Delivery/{DriversTable.stx → CouriersTable.stx} +21 -21
  146. package/resources/components/Dashboard/Commerce/Delivery/DeliveryOverviewDashboard.stx +18 -18
  147. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDeleteDialog.stx +2 -2
  148. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDialog.stx +22 -22
  149. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesDashboard.stx +24 -24
  150. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesTable.stx +8 -8
  151. package/resources/components/Dashboard/Commerce/Delivery/TabNavigation.stx +1 -1
  152. package/resources/functions/dashboard/data.ts +1 -1
  153. package/resources/functions/dashboard/sidebar.ts +2 -2
  154. package/routes/dashboard-api.ts +6 -6
  155. package/routes/dashboard.ts +7 -7
  156. package/routes/delivery.ts +24 -0
  157. package/types/defaults.ts +3 -3
  158. package/views/dashboard/.discovered-models.json +18 -18
  159. package/views/dashboard/AUDIT.md +1 -1
  160. package/views/dashboard/commerce/delivery/{drivers.stx → couriers.stx} +2 -2
  161. package/views/dashboard/composables/useChart.ts +16 -2
  162. package/app/Actions/Dashboard/Commerce/DriverIndexAction.ts +0 -24
  163. package/functions/commerce/shippings/drivers.ts +0 -19
@@ -2,7 +2,7 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.72.103",
5
+ "version": "0.73.0",
6
6
  "description": "A modern Stacks development environment.",
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.72.103",
5
+ "version": "0.73.0",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/stacksjs/stacks.git",
@@ -51,8 +51,9 @@
51
51
  "dependencies": {
52
52
  "@iconify-json/f7": "^1.2.2",
53
53
  "@iconify-json/hugeicons": "^1.2.27",
54
- "@stacksjs/mobile": "^0.72.103",
55
- "@stacksjs/sanitizer": "^0.2.113"
54
+ "@stacksjs/mobile": "^0.73.0",
55
+ "@stacksjs/sanitizer": "^0.2.113",
56
+ "ts-qr-codes": "^0.1.8"
56
57
  },
57
58
  "scripts": {
58
59
  "build": "bun build.ts"
@@ -1,22 +1,22 @@
1
1
  <script client>
2
- interface DriverRecord {
2
+ interface CourierRecord {
3
3
  id: number
4
4
  name: string
5
5
  }
6
6
 
7
7
  const open = useReactiveProp('open', false)
8
- const record = useReactiveProp('record', null as DriverRecord | null)
8
+ const record = useReactiveProp('record', null as CourierRecord | null)
9
9
  const busy = useReactiveProp('busy', false)
10
10
  const error = useReactiveProp('error', '')
11
11
  const emit = defineEmits()
12
- const description = derived(() => `Delete ${record()?.name || 'the selected driver'} permanently. Drivers referenced by delivery routes may be protected by the database.`)
12
+ const description = derived(() => `Delete ${record()?.name || 'the selected courier'} permanently. Couriers referenced by delivery routes may be protected by the database.`)
13
13
  </script>
14
14
 
15
15
  <ConfirmDialog
16
16
  :isOpen="open() && Boolean(record())"
17
- title="Delete driver?"
17
+ title="Delete courier?"
18
18
  :description="description()"
19
- confirmLabel="Delete driver"
19
+ confirmLabel="Delete courier"
20
20
  :busy="busy()"
21
21
  :error="error()"
22
22
  @close="emit('close')"
@@ -1,5 +1,5 @@
1
1
  <script client>
2
- type DriverStatus = 'active' | 'on_delivery' | 'on_break'
2
+ type CourierStatus = 'active' | 'on_delivery' | 'on_break'
3
3
 
4
4
  interface UserOption {
5
5
  id: number
@@ -7,19 +7,19 @@ interface UserOption {
7
7
  email?: string
8
8
  }
9
9
 
10
- interface DriverRecord {
10
+ interface CourierRecord {
11
11
  id: number
12
12
  name: string
13
13
  phone: string
14
14
  vehicle_number: string
15
15
  license: string
16
- status: DriverStatus
16
+ status: CourierStatus
17
17
  user_id?: number | null
18
18
  }
19
19
 
20
20
  const open = useReactiveProp('open', false)
21
21
  const mode = useReactiveProp('mode', 'create')
22
- const record = useReactiveProp('record', null as DriverRecord | null)
22
+ const record = useReactiveProp('record', null as CourierRecord | null)
23
23
  const users = useReactiveProp('users', [] as UserOption[])
24
24
  const busy = useReactiveProp('busy', false)
25
25
  const error = useReactiveProp('error', '')
@@ -28,7 +28,7 @@ const name = state('')
28
28
  const phone = state('')
29
29
  const vehicleNumber = state('')
30
30
  const license = state('')
31
- const status = state<DriverStatus>('active')
31
+ const status = state<CourierStatus>('active')
32
32
  const userId = state('')
33
33
  let hydrationKey = ''
34
34
 
@@ -53,7 +53,7 @@ effect(() => {
53
53
  function submit(): void {
54
54
  const selectedUserId = userId() ? Number(userId()) : null
55
55
  if (!name().trim()) {
56
- emit('invalid', 'Driver name is required.')
56
+ emit('invalid', 'Courier name is required.')
57
57
  return
58
58
  }
59
59
  if (!phone().trim()) {
@@ -86,16 +86,16 @@ function submit(): void {
86
86
 
87
87
  <Modal
88
88
  :isOpen="open()"
89
- :title="mode() === 'edit' ? 'Edit driver' : 'Add driver'"
89
+ :title="mode() === 'edit' ? 'Edit courier' : 'Add courier'"
90
90
  description="Manage operational identity, vehicle assignment, availability, and the optional User relationship."
91
91
  size="md"
92
92
  @close="emit('close')"
93
93
  >
94
- <form id="driver-form" @submit.prevent="submit()">
94
+ <form id="courier-form" @submit.prevent="submit()">
95
95
  <div :if="error()" class="mb-5 p-3 text-red-700 text-sm dark:text-red-300 bg-red-50 dark:bg-red-950/30 border border-red-200 rounded-lg dark:border-red-900">{{ error() }}</div>
96
96
 
97
97
  <div class="space-y-4">
98
- <label class="block"><span class="font-medium text-gray-700 text-sm dark:text-neutral-200">Driver name</span><input x-model="name" type="text" required maxlength="255" autocomplete="name" placeholder="Alex Morgan" class="mt-1 px-3 py-2 w-full text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-900 border border-gray-300 rounded-md dark:border-neutral-700" /></label>
98
+ <label class="block"><span class="font-medium text-gray-700 text-sm dark:text-neutral-200">Courier name</span><input x-model="name" type="text" required maxlength="255" autocomplete="name" placeholder="Alex Morgan" class="mt-1 px-3 py-2 w-full text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-900 border border-gray-300 rounded-md dark:border-neutral-700" /></label>
99
99
  <label class="block"><span class="font-medium text-gray-700 text-sm dark:text-neutral-200">Phone</span><input x-model="phone" type="tel" required maxlength="255" autocomplete="tel" placeholder="+1 555 0100" class="mt-1 px-3 py-2 w-full text-gray-900 text-sm dark:text-white bg-white dark:bg-neutral-900 border border-gray-300 rounded-md dark:border-neutral-700" /></label>
100
100
  <div class="grid gap-4 grid-cols-1 sm:grid-cols-2">
101
101
  <label class="block"><span class="font-medium text-gray-700 text-sm dark:text-neutral-200">Vehicle number</span><input x-model="vehicleNumber" type="text" required maxlength="255" autocomplete="off" placeholder="VAN-204" class="mt-1 px-3 py-2 w-full font-mono text-gray-900 text-sm uppercase dark:text-white bg-white dark:bg-neutral-900 border border-gray-300 rounded-md dark:border-neutral-700" /></label>
@@ -114,7 +114,7 @@ function submit(): void {
114
114
  <template #footer>
115
115
  <div class="flex gap-2 justify-end w-full">
116
116
  <Button :disabled="busy()" variant="secondary" @click="emit('close')">Cancel</Button>
117
- <Button type="submit" form="driver-form" :loading="busy()">{{ mode() === 'edit' ? 'Save changes' : 'Add driver' }}</Button>
117
+ <Button type="submit" form="courier-form" :loading="busy()">{{ mode() === 'edit' ? 'Save changes' : 'Add courier' }}</Button>
118
118
  </div>
119
119
  </template>
120
120
  </Modal>
@@ -2,7 +2,7 @@
2
2
  import { dashboardApi } from '../../../../../functions/dashboard-api'
3
3
  import { pushToast } from '../../../../../functions/toasts'
4
4
 
5
- type DriverStatus = 'active' | 'on_delivery' | 'on_break'
5
+ type CourierStatus = 'active' | 'on_delivery' | 'on_break'
6
6
 
7
7
  interface UserOption {
8
8
  id: number
@@ -14,27 +14,27 @@ interface UserIndexResponse {
14
14
  users: UserOption[]
15
15
  }
16
16
 
17
- interface DriverRecord {
17
+ interface CourierRecord {
18
18
  id: number
19
19
  name: string
20
20
  phone: string
21
21
  vehicle_number: string
22
22
  license: string
23
- status: DriverStatus
23
+ status: CourierStatus
24
24
  user_id?: number | null
25
25
  user?: UserOption
26
26
  }
27
27
 
28
- interface DriverPayload {
28
+ interface CourierPayload {
29
29
  name: string
30
30
  phone: string
31
31
  vehicleNumber: string
32
32
  license: string
33
- status: DriverStatus
33
+ status: CourierStatus
34
34
  userId: number | null
35
35
  }
36
36
 
37
- const records = state<DriverRecord[]>([])
37
+ const records = state<CourierRecord[]>([])
38
38
  const users = state<UserOption[]>([])
39
39
  const loading = state(true)
40
40
  const loadError = state('')
@@ -43,10 +43,10 @@ const page = state(1)
43
43
  const perPage = state(10)
44
44
  const editorOpen = state(false)
45
45
  const editorMode = state<'create' | 'edit'>('create')
46
- const editing = state<DriverRecord | null>(null)
46
+ const editing = state<CourierRecord | null>(null)
47
47
  const saving = state(false)
48
48
  const editorError = state('')
49
- const deleting = state<DriverRecord | null>(null)
49
+ const deleting = state<CourierRecord | null>(null)
50
50
  const deleteBusy = state(false)
51
51
  const deleteError = state('')
52
52
 
@@ -54,14 +54,14 @@ function userFor(id?: number | null): UserOption | undefined {
54
54
  return id ? users().find(user => user.id === id) : undefined
55
55
  }
56
56
 
57
- function withUser(record: DriverRecord): DriverRecord {
57
+ function withUser(record: CourierRecord): CourierRecord {
58
58
  return {
59
59
  ...record,
60
60
  user: userFor(record.user_id) || record.user,
61
61
  }
62
62
  }
63
63
 
64
- function filteredRecords(): DriverRecord[] {
64
+ function filteredRecords(): CourierRecord[] {
65
65
  const query = search().trim().toLowerCase()
66
66
  if (!query)
67
67
  return records()
@@ -76,43 +76,43 @@ function filteredRecords(): DriverRecord[] {
76
76
  ].some(value => String(value || '').toLowerCase().includes(query)))
77
77
  }
78
78
 
79
- function paginatedRecords(): DriverRecord[] {
79
+ function paginatedRecords(): CourierRecord[] {
80
80
  const start = (page() - 1) * perPage()
81
81
  return filteredRecords().slice(start, start + perPage())
82
82
  }
83
83
 
84
- function statusCount(status: DriverStatus): number {
84
+ function statusCount(status: CourierStatus): number {
85
85
  return records().filter(record => record.status === status).length
86
86
  }
87
87
 
88
88
  function metricCards(): Array<{ label: string, value: string, detail: string }> {
89
89
  return [
90
- { label: 'Drivers', value: records().length.toLocaleString(), detail: 'Persisted Driver records' },
90
+ { label: 'Couriers', value: records().length.toLocaleString(), detail: 'Persisted Courier records' },
91
91
  { label: 'Available', value: statusCount('active').toLocaleString(), detail: 'Ready for assignment' },
92
92
  { label: 'On delivery', value: statusCount('on_delivery').toLocaleString(), detail: 'Currently operating' },
93
93
  { label: 'On break', value: statusCount('on_break').toLocaleString(), detail: `${records().filter(record => record.user_id).length} linked users` },
94
94
  ]
95
95
  }
96
96
 
97
- async function loadDrivers(): Promise<void> {
97
+ async function loadCouriers(): Promise<void> {
98
98
  loading.set(true)
99
99
  loadError.set('')
100
100
  try {
101
- const [driverData, userData] = await Promise.all([
102
- dashboardApi<DriverRecord[]>('/api/dashboard/commerce/drivers'),
101
+ const [courierData, userData] = await Promise.all([
102
+ dashboardApi<CourierRecord[]>('/api/dashboard/commerce/couriers'),
103
103
  dashboardApi<UserIndexResponse>('/api/dashboard/data/users'),
104
104
  ])
105
- if (!Array.isArray(driverData) || !Array.isArray(userData?.users))
106
- throw new TypeError('Driver resources were not returned in the expected shape.')
105
+ if (!Array.isArray(courierData) || !Array.isArray(userData?.users))
106
+ throw new TypeError('Courier resources were not returned in the expected shape.')
107
107
  users.set(userData.users)
108
- records.set(driverData.map(withUser))
108
+ records.set(courierData.map(withUser))
109
109
  const lastPage = Math.max(1, Math.ceil(filteredRecords().length / perPage()))
110
110
  if (page() > lastPage)
111
111
  page.set(lastPage)
112
112
  }
113
113
  catch (error) {
114
114
  loadError.set(error instanceof Error ? error.message : String(error))
115
- pushToast('error', 'Could not load drivers', { detail: loadError() })
115
+ pushToast('error', 'Could not load couriers', { detail: loadError() })
116
116
  }
117
117
  finally {
118
118
  loading.set(false)
@@ -131,7 +131,7 @@ function openCreate(): void {
131
131
  editorOpen.set(true)
132
132
  }
133
133
 
134
- function openEdit(record: DriverRecord): void {
134
+ function openEdit(record: CourierRecord): void {
135
135
  editing.set(record)
136
136
  editorMode.set('edit')
137
137
  editorError.set('')
@@ -150,15 +150,15 @@ function setEditorError(message: string): void {
150
150
  editorError.set(message)
151
151
  }
152
152
 
153
- async function saveDriver(payload: DriverPayload): Promise<void> {
153
+ async function saveCourier(payload: CourierPayload): Promise<void> {
154
154
  saving.set(true)
155
155
  editorError.set('')
156
156
  try {
157
157
  const current = editing()
158
- const updated = await dashboardApi<DriverRecord>(
158
+ const updated = await dashboardApi<CourierRecord>(
159
159
  current
160
- ? `/api/dashboard/commerce/drivers/${current.id}`
161
- : '/api/dashboard/commerce/drivers',
160
+ ? `/api/dashboard/commerce/couriers/${current.id}`
161
+ : '/api/dashboard/commerce/couriers',
162
162
  {
163
163
  method: current ? 'PATCH' : 'POST',
164
164
  body: payload,
@@ -175,7 +175,7 @@ async function saveDriver(payload: DriverPayload): Promise<void> {
175
175
  }
176
176
  editorOpen.set(false)
177
177
  editing.set(null)
178
- pushToast('success', current ? 'Driver updated' : 'Driver added', { detail: hydrated.name })
178
+ pushToast('success', current ? 'Courier updated' : 'Courier added', { detail: hydrated.name })
179
179
  }
180
180
  catch (error) {
181
181
  editorError.set(error instanceof Error ? error.message : String(error))
@@ -185,7 +185,7 @@ async function saveDriver(payload: DriverPayload): Promise<void> {
185
185
  }
186
186
  }
187
187
 
188
- function requestDelete(record: DriverRecord): void {
188
+ function requestDelete(record: CourierRecord): void {
189
189
  deleting.set(record)
190
190
  deleteError.set('')
191
191
  }
@@ -204,7 +204,7 @@ async function confirmDelete(): Promise<void> {
204
204
  deleteBusy.set(true)
205
205
  deleteError.set('')
206
206
  try {
207
- await dashboardApi(`/api/dashboard/commerce/drivers/${current.id}`, {
207
+ await dashboardApi(`/api/dashboard/commerce/couriers/${current.id}`, {
208
208
  method: 'DELETE',
209
209
  })
210
210
  records.set(records().filter(record => record.id !== current.id))
@@ -212,7 +212,7 @@ async function confirmDelete(): Promise<void> {
212
212
  const lastPage = Math.max(1, Math.ceil(filteredRecords().length / perPage()))
213
213
  if (page() > lastPage)
214
214
  page.set(lastPage)
215
- pushToast('success', 'Driver deleted', { detail: current.name })
215
+ pushToast('success', 'Courier deleted', { detail: current.name })
216
216
  }
217
217
  catch (error) {
218
218
  deleteError.set(error instanceof Error ? error.message : String(error))
@@ -227,42 +227,42 @@ function goToPage(value: number): void {
227
227
  }
228
228
 
229
229
  onMount(() => {
230
- void loadDrivers()
230
+ void loadCouriers()
231
231
  })
232
232
  </script>
233
233
 
234
234
  <div class="space-y-6">
235
- <TabNavigation model-value="drivers" />
235
+ <TabNavigation model-value="couriers" />
236
236
 
237
237
  <header class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
238
238
  <div>
239
- <h1 class="font-bold text-2xl text-gray-900 dark:text-white">Delivery drivers</h1>
240
- <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Manage driver availability, vehicles, licenses, and optional user accounts.</p>
239
+ <h1 class="font-bold text-2xl text-gray-900 dark:text-white">Delivery couriers</h1>
240
+ <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Manage courier availability, vehicles, licenses, and optional user accounts.</p>
241
241
  </div>
242
242
  <div class="flex gap-2">
243
- <Button :loading="loading()" variant="secondary" @click="loadDrivers()"><span :if="!loading()" aria-hidden="true" class="h-4 w-4 i-hugeicons-refresh"></span>Refresh</Button>
244
- <Button :disabled="loading()" @click="openCreate()"><span aria-hidden="true" class="h-4 w-4 i-hugeicons-add-01"></span>Add driver</Button>
243
+ <Button :loading="loading()" variant="secondary" @click="loadCouriers()"><span :if="!loading()" aria-hidden="true" class="h-4 w-4 i-hugeicons-refresh"></span>Refresh</Button>
244
+ <Button :disabled="loading()" @click="openCreate()"><span aria-hidden="true" class="h-4 w-4 i-hugeicons-add-01"></span>Add courier</Button>
245
245
  </div>
246
246
  </header>
247
247
 
248
- <div :if="loadError()" class="flex gap-4 items-center justify-between p-4 text-red-700 text-sm dark:text-red-300 bg-red-50 dark:bg-red-950/30 border border-red-200 rounded-lg dark:border-red-900"><span>{{ loadError() }}</span><Button variant="secondary" size="sm" @click="loadDrivers()">Retry</Button></div>
248
+ <div :if="loadError()" class="flex gap-4 items-center justify-between p-4 text-red-700 text-sm dark:text-red-300 bg-red-50 dark:bg-red-950/30 border border-red-200 rounded-lg dark:border-red-900"><span>{{ loadError() }}</span><Button variant="secondary" size="sm" @click="loadCouriers()">Retry</Button></div>
249
249
 
250
- <section aria-label="Driver metrics" class="grid gap-3 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
250
+ <section aria-label="Courier metrics" class="grid gap-3 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
251
251
  <template :for="item in metricCards()" :key="item.label"><article class="p-4 bg-white dark:bg-neutral-800 border border-gray-200 rounded-lg dark:border-neutral-700"><p class="text-gray-500 text-xs dark:text-neutral-400">{{ item.label }}</p><p class="mt-2 font-semibold text-2xl text-gray-900 dark:text-white">{{ item.value }}</p><p class="mt-1 text-gray-400 text-xs dark:text-neutral-500">{{ item.detail }}</p></article></template>
252
252
  </section>
253
253
 
254
254
  <section class="overflow-hidden bg-white dark:bg-neutral-800 border border-gray-200 rounded-xl dark:border-neutral-700">
255
255
  <div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between px-4 py-4 border-b border-gray-200 dark:border-neutral-700">
256
- <div><h2 class="font-semibold text-gray-900 dark:text-white">Driver roster</h2><p class="mt-0.5 text-gray-500 text-xs dark:text-neutral-400">{{ filteredRecords().length }} matching records</p></div>
257
- <SearchFilter placeholder="Search drivers" class="w-full sm:w-80" @search="handleSearch" />
256
+ <div><h2 class="font-semibold text-gray-900 dark:text-white">Courier roster</h2><p class="mt-0.5 text-gray-500 text-xs dark:text-neutral-400">{{ filteredRecords().length }} matching records</p></div>
257
+ <SearchFilter placeholder="Search couriers" class="w-full sm:w-80" @search="handleSearch" />
258
258
  </div>
259
- <div :if="loading()" class="flex items-center justify-center py-24 text-gray-500 text-sm dark:text-neutral-400"><span class="mr-2 h-4 w-4 animate-spin i-hugeicons-loading-03"></span>Loading drivers</div>
260
- <DriversTable :if="!loading()" :drivers="paginatedRecords()" @edit="openEdit" @delete="requestDelete" />
259
+ <div :if="loading()" class="flex items-center justify-center py-24 text-gray-500 text-sm dark:text-neutral-400"><span class="mr-2 h-4 w-4 animate-spin i-hugeicons-loading-03"></span>Loading couriers</div>
260
+ <CouriersTable :if="!loading()" :couriers="paginatedRecords()" @edit="openEdit" @delete="requestDelete" />
261
261
  <div :if="!loading()" class="px-4 py-3 bg-gray-50 dark:bg-neutral-900/50 border-gray-200 border-t dark:border-neutral-700">
262
262
  <DeliveryPagination :current-page="page()" :total-items="filteredRecords().length" :items-per-page="perPage()" @select="goToPage" />
263
263
  </div>
264
264
  </section>
265
265
  </div>
266
266
 
267
- <DriverDialog :open="editorOpen()" :mode="editorMode()" :record="editing()" :users="users()" :busy="saving()" :error="editorError()" @submit="saveDriver" @invalid="setEditorError" @close="closeEditor()" />
268
- <DriverDeleteDialog :open="Boolean(deleting())" :record="deleting()" :busy="deleteBusy()" :error="deleteError()" @confirm="confirmDelete()" @close="closeDelete()" />
267
+ <CourierDialog :open="editorOpen()" :mode="editorMode()" :record="editing()" :users="users()" :busy="saving()" :error="editorError()" @submit="saveCourier" @invalid="setEditorError" @close="closeEditor()" />
268
+ <CourierDeleteDialog :open="Boolean(deleting())" :record="deleting()" :busy="deleteBusy()" :error="deleteError()" @confirm="confirmDelete()" @close="closeDelete()" />
@@ -1,21 +1,21 @@
1
1
  <script client>
2
- type DriverStatus = 'active' | 'on_delivery' | 'on_break'
2
+ type CourierStatus = 'active' | 'on_delivery' | 'on_break'
3
3
 
4
- interface DriverRow {
4
+ interface CourierRow {
5
5
  id: number
6
6
  name: string
7
7
  phone: string
8
8
  vehicle_number: string
9
9
  license: string
10
- status: DriverStatus
10
+ status: CourierStatus
11
11
  user_id?: number | null
12
12
  user?: { id: number, name: string, email?: string }
13
13
  }
14
14
 
15
- const drivers = useReactiveProp('drivers', [] as DriverRow[])
15
+ const couriers = useReactiveProp('couriers', [] as CourierRow[])
16
16
  const emit = defineEmits()
17
17
 
18
- function statusLabel(status: DriverStatus): string {
18
+ function statusLabel(status: CourierStatus): string {
19
19
  return {
20
20
  active: 'Available',
21
21
  on_delivery: 'On delivery',
@@ -23,7 +23,7 @@ function statusLabel(status: DriverStatus): string {
23
23
  }[status] || status
24
24
  }
25
25
 
26
- function statusClass(status: DriverStatus): string {
26
+ function statusClass(status: CourierStatus): string {
27
27
  if (status === 'active')
28
28
  return 'bg-green-50 text-green-700 ring-green-600/20 dark:bg-green-900/30 dark:text-green-300'
29
29
  if (status === 'on_delivery')
@@ -36,7 +36,7 @@ function statusClass(status: DriverStatus): string {
36
36
  <table class="min-w-full divide-stone-100 divide-y dark:divide-neutral-700">
37
37
  <thead class="bg-stone-50/80 dark:bg-neutral-800">
38
38
  <tr>
39
- <th scope="col" class="pl-6 pr-3 py-3.5 font-semibold text-left text-stone-500 text-xs tracking-wider uppercase dark:text-neutral-400">Driver</th>
39
+ <th scope="col" class="pl-6 pr-3 py-3.5 font-semibold text-left text-stone-500 text-xs tracking-wider uppercase dark:text-neutral-400">Courier</th>
40
40
  <th scope="col" class="px-4 py-3.5 font-semibold text-left text-stone-500 text-xs tracking-wider uppercase dark:text-neutral-400">Phone</th>
41
41
  <th scope="col" class="px-4 py-3.5 font-semibold text-left text-stone-500 text-xs tracking-wider uppercase dark:text-neutral-400">Vehicle</th>
42
42
  <th scope="col" class="px-4 py-3.5 font-semibold text-left text-stone-500 text-xs tracking-wider uppercase dark:text-neutral-400">License</th>
@@ -48,26 +48,26 @@ function statusClass(status: DriverStatus): string {
48
48
  </tr>
49
49
  </thead>
50
50
  <tbody class="bg-white dark:bg-neutral-800 divide-stone-100 divide-y dark:divide-neutral-700">
51
- <template :for="driver in drivers" :key="driver.id">
51
+ <template :for="courier in couriers" :key="courier.id">
52
52
  <tr class="hover:bg-stone-50/50 dark:hover:bg-neutral-700/50 transition-colors">
53
53
  <td class="pl-6 pr-3 py-3.5 font-medium text-sm text-stone-800 whitespace-nowrap dark:text-white">
54
- {{ driver.name }}
54
+ {{ courier.name }}
55
55
  </td>
56
56
  <td class="px-4 py-3.5 text-sm text-stone-500 whitespace-nowrap dark:text-neutral-300">
57
- {{ driver.phone }}
57
+ {{ courier.phone }}
58
58
  </td>
59
59
  <td class="px-4 py-3.5 font-mono text-sm text-stone-500 whitespace-nowrap dark:text-neutral-300">
60
- {{ driver.vehicle_number }}
60
+ {{ courier.vehicle_number }}
61
61
  </td>
62
62
  <td class="px-4 py-3.5 font-mono text-sm text-stone-500 whitespace-nowrap dark:text-neutral-300">
63
- {{ driver.license }}
63
+ {{ courier.license }}
64
64
  </td>
65
65
  <td class="px-4 py-3.5 text-sm text-stone-500 whitespace-nowrap dark:text-neutral-300">
66
- {{ driver.user?.name || (driver.user_id ? 'User #' + driver.user_id : 'Not linked') }}
66
+ {{ courier.user?.name || (courier.user_id ? 'User #' + courier.user_id : 'Not linked') }}
67
67
  </td>
68
68
  <td class="px-4 py-3.5 text-sm whitespace-nowrap">
69
- <span :class="'inline-flex items-center px-2 py-1 font-medium text-xs ring-1 ring-inset rounded-md ' + statusClass(driver.status)">
70
- {{ statusLabel(driver.status) }}
69
+ <span :class="'inline-flex items-center px-2 py-1 font-medium text-xs ring-1 ring-inset rounded-md ' + statusClass(courier.status)">
70
+ {{ statusLabel(courier.status) }}
71
71
  </span>
72
72
  </td>
73
73
  <td class="relative pl-3 pr-6 py-3.5 font-medium text-right text-sm whitespace-nowrap">
@@ -75,8 +75,8 @@ function statusClass(status: DriverStatus): string {
75
75
  variant="ghost"
76
76
  size="sm"
77
77
  iconOnly
78
- @click="emit('edit', driver)"
79
- :ariaLabel="'Edit driver ' + driver.name + ', record ' + driver.id"
78
+ @click="emit('edit', courier)"
79
+ :ariaLabel="'Edit courier ' + courier.name + ', record ' + courier.id"
80
80
  >
81
81
  <span class="block h-4 w-4 text-blue-500 i-hugeicons-edit-01"></span>
82
82
  </Button>
@@ -84,8 +84,8 @@ function statusClass(status: DriverStatus): string {
84
84
  variant="ghost"
85
85
  size="sm"
86
86
  iconOnly
87
- @click="emit('delete', driver)"
88
- :ariaLabel="'Delete driver ' + driver.name + ', record ' + driver.id"
87
+ @click="emit('delete', courier)"
88
+ :ariaLabel="'Delete courier ' + courier.name + ', record ' + courier.id"
89
89
  >
90
90
  <span class="block h-4 w-4 text-red-500 i-hugeicons-waste"></span>
91
91
  </Button>
@@ -93,9 +93,9 @@ function statusClass(status: DriverStatus): string {
93
93
  </tr>
94
94
  </template>
95
95
 
96
- <tr :if="drivers().length === 0">
96
+ <tr :if="couriers().length === 0">
97
97
  <td colspan="7" class="px-6 py-12 text-center text-sm text-stone-500 dark:text-neutral-400">
98
- No drivers found.
98
+ No couriers found.
99
99
  </td>
100
100
  </tr>
101
101
  </tbody>
@@ -10,7 +10,7 @@ interface DeliveryStat {
10
10
 
11
11
  interface DeliveryRoute {
12
12
  id: number
13
- driver: string
13
+ courier: string
14
14
  vehicle: string
15
15
  stops: number
16
16
  duration: string
@@ -34,7 +34,7 @@ interface ShippingZone {
34
34
  regions: number
35
35
  }
36
36
 
37
- interface DriverSummary {
37
+ interface CourierSummary {
38
38
  total: number
39
39
  active: number
40
40
  onDelivery: number
@@ -46,14 +46,14 @@ interface DeliveryOverviewResponse {
46
46
  routes: DeliveryRoute[]
47
47
  methods: ShippingMethod[]
48
48
  zones: ShippingZone[]
49
- drivers: DriverSummary
49
+ couriers: CourierSummary
50
50
  }
51
51
 
52
52
  const stats = state<DeliveryStat[]>([])
53
53
  const routes = state<DeliveryRoute[]>([])
54
54
  const methods = state<ShippingMethod[]>([])
55
55
  const zones = state<ShippingZone[]>([])
56
- const drivers = state<DriverSummary>({
56
+ const couriers = state<CourierSummary>({
57
57
  total: 0,
58
58
  active: 0,
59
59
  onDelivery: 0,
@@ -65,7 +65,7 @@ const loadError = state('')
65
65
  function statIcon(label: string): string {
66
66
  const icons: Record<string, string> = {
67
67
  'Active Routes': 'i-hugeicons-route-02',
68
- 'Drivers on Delivery': 'i-hugeicons-delivery-truck-02',
68
+ 'Couriers on Delivery': 'i-hugeicons-delivery-truck-02',
69
69
  'Average Route': 'i-hugeicons-clock-01',
70
70
  'Active Zones': 'i-hugeicons-maps-global-02',
71
71
  }
@@ -114,7 +114,7 @@ async function loadOverview(): Promise<void> {
114
114
  || !Array.isArray(data.routes)
115
115
  || !Array.isArray(data.methods)
116
116
  || !Array.isArray(data.zones)
117
- || !data.drivers
117
+ || !data.couriers
118
118
  ) {
119
119
  throw new TypeError('Delivery resources were not returned in the expected shape.')
120
120
  }
@@ -123,7 +123,7 @@ async function loadOverview(): Promise<void> {
123
123
  routes.set(data.routes)
124
124
  methods.set(data.methods)
125
125
  zones.set(data.zones)
126
- drivers.set(data.drivers)
126
+ couriers.set(data.couriers)
127
127
  }
128
128
  catch (error) {
129
129
  loadError.set(error instanceof Error ? error.message : String(error))
@@ -145,7 +145,7 @@ onMount(() => {
145
145
  <header class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
146
146
  <div>
147
147
  <h1 class="font-bold text-2xl text-gray-900 dark:text-white">Delivery</h1>
148
- <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Monitor active routes, driver availability, shipping methods, and coverage.</p>
148
+ <p class="mt-1 text-gray-500 text-sm dark:text-neutral-400">Monitor active routes, courier availability, shipping methods, and coverage.</p>
149
149
  </div>
150
150
  <div class="flex gap-2">
151
151
  <Button :loading="loading()" variant="secondary" @click="loadOverview()">
@@ -211,7 +211,7 @@ onMount(() => {
211
211
  <table class="min-w-full divide-gray-200 divide-y dark:divide-neutral-700">
212
212
  <thead class="bg-gray-50 dark:bg-neutral-900/40">
213
213
  <tr>
214
- <th scope="col" class="px-5 py-3 font-medium text-gray-500 text-left text-xs tracking-wide uppercase dark:text-neutral-400">Driver</th>
214
+ <th scope="col" class="px-5 py-3 font-medium text-gray-500 text-left text-xs tracking-wide uppercase dark:text-neutral-400">Courier</th>
215
215
  <th scope="col" class="px-4 py-3 font-medium text-gray-500 text-left text-xs tracking-wide uppercase dark:text-neutral-400">Plan</th>
216
216
  <th scope="col" class="px-4 py-3 font-medium text-gray-500 text-left text-xs tracking-wide uppercase dark:text-neutral-400">Distance</th>
217
217
  <th scope="col" class="px-5 py-3 font-medium text-gray-500 text-right text-xs tracking-wide uppercase dark:text-neutral-400">Last active</th>
@@ -221,7 +221,7 @@ onMount(() => {
221
221
  <template :for="route in routes()" :key="route.id">
222
222
  <tr class="hover:bg-gray-50/70 dark:hover:bg-neutral-700/40">
223
223
  <td class="px-5 py-3.5">
224
- <p class="font-medium text-gray-900 text-sm dark:text-white">{{ route.driver }}</p>
224
+ <p class="font-medium text-gray-900 text-sm dark:text-white">{{ route.courier }}</p>
225
225
  <p class="mt-0.5 text-gray-500 text-xs dark:text-neutral-400">{{ route.vehicle }}</p>
226
226
  </td>
227
227
  <td class="px-4 py-3.5 text-gray-600 text-sm whitespace-nowrap dark:text-neutral-300">
@@ -243,30 +243,30 @@ onMount(() => {
243
243
  <div class="flex items-start justify-between">
244
244
  <div>
245
245
  <h2 class="font-semibold">Fleet availability</h2>
246
- <p class="mt-1 text-sm text-stone-400">Current persisted driver statuses.</p>
246
+ <p class="mt-1 text-sm text-stone-400">Current persisted courier statuses.</p>
247
247
  </div>
248
248
  <span class="h-5 w-5 text-blue-400 i-hugeicons-delivery-truck-02"></span>
249
249
  </div>
250
250
  <div class="mt-7">
251
- <p class="font-semibold tabular-nums text-4xl tracking-tight">{{ drivers().total }}</p>
252
- <p class="mt-1 text-sm text-stone-400">Drivers in the fleet</p>
251
+ <p class="font-semibold tabular-nums text-4xl tracking-tight">{{ couriers().total }}</p>
252
+ <p class="mt-1 text-sm text-stone-400">Couriers in the fleet</p>
253
253
  </div>
254
254
  <dl class="mt-7 space-y-3">
255
255
  <div class="flex items-center justify-between py-2 border-b border-stone-800">
256
256
  <dt class="flex gap-2 items-center text-sm text-stone-300"><span class="h-2 w-2 bg-emerald-400 rounded-full"></span>Available</dt>
257
- <dd class="font-semibold tabular-nums">{{ drivers().active }}</dd>
257
+ <dd class="font-semibold tabular-nums">{{ couriers().active }}</dd>
258
258
  </div>
259
259
  <div class="flex items-center justify-between py-2 border-b border-stone-800">
260
260
  <dt class="flex gap-2 items-center text-sm text-stone-300"><span class="h-2 w-2 bg-blue-400 rounded-full"></span>On delivery</dt>
261
- <dd class="font-semibold tabular-nums">{{ drivers().onDelivery }}</dd>
261
+ <dd class="font-semibold tabular-nums">{{ couriers().onDelivery }}</dd>
262
262
  </div>
263
263
  <div class="flex items-center justify-between py-2">
264
264
  <dt class="flex gap-2 items-center text-sm text-stone-300"><span class="h-2 w-2 bg-amber-400 rounded-full"></span>On break</dt>
265
- <dd class="font-semibold tabular-nums">{{ drivers().onBreak }}</dd>
265
+ <dd class="font-semibold tabular-nums">{{ couriers().onBreak }}</dd>
266
266
  </div>
267
267
  </dl>
268
- <a href="/commerce/delivery/drivers" class="inline-flex gap-2 items-center mt-6 font-semibold text-blue-300 text-sm hover:text-blue-200">
269
- Manage drivers
268
+ <a href="/commerce/delivery/couriers" class="inline-flex gap-2 items-center mt-6 font-semibold text-blue-300 text-sm hover:text-blue-200">
269
+ Manage couriers
270
270
  <span class="h-4 w-4 i-hugeicons-arrow-right-01"></span>
271
271
  </a>
272
272
  </section>
@@ -1,7 +1,7 @@
1
1
  <script client>
2
2
  interface DeliveryRouteRecord {
3
3
  id: number
4
- driver: string
4
+ courier: string
5
5
  }
6
6
 
7
7
  const open = useReactiveProp('open', false)
@@ -9,7 +9,7 @@ const record = useReactiveProp('record', null as DeliveryRouteRecord | null)
9
9
  const busy = useReactiveProp('busy', false)
10
10
  const error = useReactiveProp('error', '')
11
11
  const emit = defineEmits()
12
- const description = derived(() => `Delete route #${record()?.id} for ${record()?.driver || 'the selected driver'} permanently.`)
12
+ const description = derived(() => `Delete route #${record()?.id} for ${record()?.courier || 'the selected courier'} permanently.`)
13
13
  </script>
14
14
 
15
15
  <ConfirmDialog