@gelabs/ovr 0.4.3 → 0.4.4

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 (75) hide show
  1. package/dist/accounts.d.ts +52 -0
  2. package/dist/accounts.js +13 -0
  3. package/dist/audit.d.ts +13 -0
  4. package/dist/audit.js +11 -0
  5. package/dist/auth-auth.d.ts +1 -1
  6. package/dist/auth.d.ts +1 -1
  7. package/dist/chunk-4EDMZRGS.js +98 -0
  8. package/dist/chunk-4JMHQKMK.js +268 -0
  9. package/dist/chunk-6662IONX.js +69 -0
  10. package/dist/chunk-6WMPBAUH.js +18 -0
  11. package/dist/chunk-7GVZZWK3.js +74 -0
  12. package/dist/chunk-ACXED4UH.js +403 -0
  13. package/dist/chunk-BBTAG3FD.js +165 -0
  14. package/dist/chunk-HX7QT2FE.js +452 -0
  15. package/dist/chunk-LC3S47FM.js +468 -0
  16. package/dist/chunk-NPTR7GFZ.js +432 -0
  17. package/dist/chunk-SLQRZBMR.js +66 -0
  18. package/dist/chunk-UBUXPJLN.js +29 -0
  19. package/dist/chunk-UN6Z4WGF.js +31 -0
  20. package/dist/chunk-YE3D2DYY.js +83 -0
  21. package/dist/citizen.d.ts +5 -0
  22. package/dist/citizen.js +12 -0
  23. package/dist/config.d.ts +2 -2
  24. package/dist/core-i18n.d.ts +1 -1
  25. package/dist/core.d.ts +2 -2
  26. package/dist/dashboard.d.ts +10 -0
  27. package/dist/dashboard.js +3 -0
  28. package/dist/data-mock-store.d.ts +1 -1
  29. package/dist/{format-C7MSwUHK.d.ts → format-VyCUfF8R.d.ts} +1 -1
  30. package/dist/generated/client/edge.js +2 -2
  31. package/dist/generated/client/index.js +2 -2
  32. package/dist/generated/client/wasm.js +2 -2
  33. package/dist/index.d.ts +2 -2
  34. package/dist/notifications.d.ts +6 -0
  35. package/dist/notifications.js +11 -0
  36. package/dist/officers.d.ts +27 -0
  37. package/dist/officers.js +11 -0
  38. package/dist/offline.d.ts +1 -1
  39. package/dist/payments.d.ts +15 -0
  40. package/dist/payments.js +11 -0
  41. package/dist/roles.d.ts +37 -0
  42. package/dist/roles.js +12 -0
  43. package/dist/runtime.d.ts +1 -1
  44. package/dist/tickets.d.ts +6 -0
  45. package/dist/tickets.js +24 -0
  46. package/dist/ui-components-admin/accounts-manager.d.ts +3 -52
  47. package/dist/ui-components-admin/accounts-manager.js +11 -468
  48. package/dist/ui-components-admin/admin-nav.js +9 -81
  49. package/dist/ui-components-admin/issuance-form.js +15 -432
  50. package/dist/ui-components-admin/logs-viewer.d.ts +3 -13
  51. package/dist/ui-components-admin/logs-viewer.js +8 -98
  52. package/dist/ui-components-admin/notifications-list.js +6 -66
  53. package/dist/ui-components-admin/officers-manager.d.ts +3 -27
  54. package/dist/ui-components-admin/officers-manager.js +9 -268
  55. package/dist/ui-components-admin/roles-manager.d.ts +3 -37
  56. package/dist/ui-components-admin/roles-manager.js +10 -403
  57. package/dist/ui-components-admin/stat-card.d.ts +2 -10
  58. package/dist/ui-components-admin/stat-card.js +3 -29
  59. package/dist/ui-components-admin/ticket-preview.js +2 -2
  60. package/dist/ui-components-admin/tickets-table.js +7 -69
  61. package/dist/ui-components-admin/violations-manager.js +13 -452
  62. package/dist/ui-components-citizen/citizen-nav.js +3 -31
  63. package/dist/ui-components-citizen/payment-form.d.ts +3 -14
  64. package/dist/ui-components-citizen/payment-form.js +9 -165
  65. package/dist/ui-components-citizen/payment-qr-dialog.js +2 -2
  66. package/dist/ui-components-citizen/ticket-not-found.js +4 -18
  67. package/dist/ui-components-citizen/violation-history-table.js +6 -74
  68. package/dist/ui-config.d.ts +2 -2
  69. package/dist/ui-server.d.ts +2 -2
  70. package/dist/violations.d.ts +3 -0
  71. package/dist/violations.js +14 -0
  72. package/package.json +42 -2
  73. package/dist/{chunk-ZUMEOZ22.js → chunk-JTSTNZAB.js} +1 -1
  74. package/dist/{chunk-TLG4C2XI.js → chunk-QCAURREW.js} +1 -1
  75. package/dist/{schema-CdsFQxIg.d.ts → schema-BUhh_mKX.d.ts} +108 -108
@@ -1,406 +1,13 @@
1
1
  "use client";
2
- import { Checkbox } from '../chunk-BBQBKQA4.js';
3
- import { Card, CardContent } from '../chunk-SETIN6XP.js';
4
- import { Badge } from '../chunk-55FQP2DO.js';
5
- import { Label } from '../chunk-XQTVSNHC.js';
6
- import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose } from '../chunk-M35R6JLA.js';
7
- import { Input } from '../chunk-K3KIBHJF.js';
8
- import { Button } from '../chunk-I4WDVYHX.js';
9
- import { useCopy } from '../chunk-TJSNVTVB.js';
2
+ export { RolesManager } from '../chunk-ACXED4UH.js';
3
+ import '../chunk-BBQBKQA4.js';
4
+ import '../chunk-XQTVSNHC.js';
5
+ import '../chunk-M35R6JLA.js';
6
+ import '../chunk-K3KIBHJF.js';
7
+ import '../chunk-QZRRFE6E.js';
8
+ import '../chunk-55FQP2DO.js';
9
+ import '../chunk-I4WDVYHX.js';
10
+ import '../chunk-TJSNVTVB.js';
11
+ import '../chunk-SETIN6XP.js';
10
12
  import '../chunk-77QBZC7J.js';
11
- import { PERMISSION_CATALOG, SUPER_ADMIN_LOCKED_PERMISSIONS } from '../chunk-QZRRFE6E.js';
12
13
  import '../chunk-BI4EGLPG.js';
13
- import * as React from 'react';
14
- import { toast } from 'sonner';
15
- import { useRouter } from 'next/navigation';
16
- import { ShieldCheck, SlidersHorizontal, Loader2, Trash2, Plus, Lock } from 'lucide-react';
17
- import { jsxs, jsx } from 'react/jsx-runtime';
18
-
19
- function RolesManager({
20
- roles,
21
- usage = {},
22
- createAction,
23
- updateAction,
24
- deleteAction
25
- }) {
26
- const t = useCopy().admin.rolesPage;
27
- const router = useRouter();
28
- return /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-3xl p-4 sm:p-6 lg:p-8", children: [
29
- /* @__PURE__ */ jsxs("div", { className: "mb-6 flex items-center justify-between gap-3", children: [
30
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
31
- /* @__PURE__ */ jsx("h1", { className: "font-heading text-2xl font-semibold tracking-tight", children: t.title }),
32
- /* @__PURE__ */ jsx("p", { className: "max-w-2xl text-sm text-muted-foreground", children: t.subtitle })
33
- ] }),
34
- /* @__PURE__ */ jsx(
35
- NewRoleDialog,
36
- {
37
- createAction,
38
- onChanged: () => router.refresh()
39
- }
40
- )
41
- ] }),
42
- roles.length === 0 ? /* @__PURE__ */ jsx("p", { className: "rounded-xl border bg-card p-8 text-center text-sm text-muted-foreground", children: t.empty }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: roles.map((role) => /* @__PURE__ */ jsx(
43
- RoleCard,
44
- {
45
- role,
46
- inUse: usage[role.name] ?? 0,
47
- updateAction,
48
- deleteAction,
49
- onChanged: () => router.refresh()
50
- },
51
- role.name
52
- )) })
53
- ] });
54
- }
55
- function PermissionChecklist({
56
- selected,
57
- onToggle,
58
- locked
59
- }) {
60
- return /* @__PURE__ */ jsx("div", { className: "grid gap-2 sm:grid-cols-2", children: PERMISSION_CATALOG.map((perm) => {
61
- const isLocked = locked?.(perm.key) ?? false;
62
- const checked = selected.has(perm.key) || isLocked;
63
- return /* @__PURE__ */ jsxs(
64
- "label",
65
- {
66
- className: "flex items-start gap-2.5 rounded-lg border p-2.5",
67
- children: [
68
- /* @__PURE__ */ jsx(
69
- Checkbox,
70
- {
71
- checked,
72
- disabled: isLocked,
73
- onCheckedChange: (v) => onToggle(perm.key, v === true),
74
- className: "mt-0.5"
75
- }
76
- ),
77
- /* @__PURE__ */ jsxs("span", { className: "flex-1", children: [
78
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-sm font-medium", children: [
79
- perm.label,
80
- isLocked ? /* @__PURE__ */ jsx(Lock, { className: "size-3 text-muted-foreground" }) : null
81
- ] }),
82
- /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: perm.description })
83
- ] })
84
- ]
85
- },
86
- perm.key
87
- );
88
- }) });
89
- }
90
- function RoleCard({
91
- role,
92
- inUse,
93
- updateAction,
94
- deleteAction,
95
- onChanged
96
- }) {
97
- const t = useCopy().admin.rolesPage;
98
- const grantedLabels = PERMISSION_CATALOG.filter(
99
- (p) => role.permissions.includes(p.key)
100
- ).map((p) => p.label);
101
- return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardContent, { className: "flex items-center justify-between gap-3 py-4", children: [
102
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
103
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
104
- /* @__PURE__ */ jsx(ShieldCheck, { className: "size-4 shrink-0 text-muted-foreground" }),
105
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: role.label }),
106
- /* @__PURE__ */ jsx(Badge, { variant: role.isSystem ? "secondary" : "outline", children: role.isSystem ? t.system : t.custom }),
107
- inUse > 0 ? /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
108
- inUse,
109
- " ",
110
- t.inUseSuffix
111
- ] }) : null
112
- ] }),
113
- /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: grantedLabels.length ? grantedLabels.join(" \xB7 ") : t.noPermissions })
114
- ] }),
115
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
116
- /* @__PURE__ */ jsx(
117
- EditRolePermissionsDialog,
118
- {
119
- role,
120
- updateAction,
121
- onChanged
122
- }
123
- ),
124
- !role.isSystem ? /* @__PURE__ */ jsx(
125
- DeleteRoleButton,
126
- {
127
- role,
128
- inUse,
129
- deleteAction,
130
- onChanged
131
- }
132
- ) : null
133
- ] })
134
- ] }) });
135
- }
136
- function EditRolePermissionsDialog({
137
- role,
138
- updateAction,
139
- onChanged
140
- }) {
141
- const t = useCopy().admin.rolesPage;
142
- const [open, setOpen] = React.useState(false);
143
- const [label, setLabel] = React.useState(role.label);
144
- const [perms, setPerms] = React.useState(
145
- () => new Set(role.permissions)
146
- );
147
- const [saving, setSaving] = React.useState(false);
148
- const isLocked = (p) => role.name === "SUPER_ADMIN" && SUPER_ADMIN_LOCKED_PERMISSIONS.includes(p);
149
- function toggle(p, checked) {
150
- if (isLocked(p)) return;
151
- setPerms((prev) => {
152
- const next = new Set(prev);
153
- if (checked) next.add(p);
154
- else next.delete(p);
155
- return next;
156
- });
157
- }
158
- async function submit(e) {
159
- e.preventDefault();
160
- setSaving(true);
161
- try {
162
- const res = await updateAction(role.name, {
163
- label: role.isSystem ? void 0 : label.trim(),
164
- permissions: [...perms]
165
- });
166
- if (res?.error) {
167
- toast.error(res.error);
168
- return;
169
- }
170
- toast.success(`${t.saved}: ${role.isSystem ? role.label : label.trim()}`);
171
- setOpen(false);
172
- onChanged();
173
- } finally {
174
- setSaving(false);
175
- }
176
- }
177
- return /* @__PURE__ */ jsxs(
178
- Dialog,
179
- {
180
- open,
181
- onOpenChange: (o) => {
182
- if (o) {
183
- setLabel(role.label);
184
- setPerms(new Set(role.permissions));
185
- }
186
- setOpen(o);
187
- },
188
- children: [
189
- /* @__PURE__ */ jsxs(
190
- DialogTrigger,
191
- {
192
- render: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: "gap-1.5" }),
193
- children: [
194
- /* @__PURE__ */ jsx(SlidersHorizontal, { className: "size-3.5" }),
195
- /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: t.editPermissions })
196
- ]
197
- }
198
- ),
199
- /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-lg", children: [
200
- /* @__PURE__ */ jsxs(DialogHeader, { children: [
201
- /* @__PURE__ */ jsx(DialogTitle, { children: role.label }),
202
- /* @__PURE__ */ jsx(DialogDescription, { children: t.editPermissions })
203
- ] }),
204
- /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "space-y-4", children: [
205
- !role.isSystem ? /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
206
- /* @__PURE__ */ jsx(Label, { htmlFor: `role-label-${role.name}`, children: t.roleName }),
207
- /* @__PURE__ */ jsx(
208
- Input,
209
- {
210
- id: `role-label-${role.name}`,
211
- value: label,
212
- onChange: (e) => setLabel(e.target.value),
213
- autoComplete: "off"
214
- }
215
- )
216
- ] }) : null,
217
- /* @__PURE__ */ jsx(
218
- PermissionChecklist,
219
- {
220
- selected: perms,
221
- onToggle: toggle,
222
- locked: isLocked
223
- }
224
- ),
225
- role.name === "SUPER_ADMIN" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t.lockedHint }) : null,
226
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
227
- /* @__PURE__ */ jsx(DialogClose, { render: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline" }), children: t.cancel }),
228
- /* @__PURE__ */ jsxs(Button, { type: "submit", disabled: saving, className: "gap-1.5", children: [
229
- saving ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }) : null,
230
- saving ? t.saving : t.save
231
- ] })
232
- ] })
233
- ] })
234
- ] })
235
- ]
236
- }
237
- );
238
- }
239
- function DeleteRoleButton({
240
- role,
241
- inUse,
242
- deleteAction,
243
- onChanged
244
- }) {
245
- const t = useCopy().admin.rolesPage;
246
- const [deleting, setDeleting] = React.useState(false);
247
- async function remove() {
248
- setDeleting(true);
249
- try {
250
- const res = await deleteAction(role.name);
251
- if (res?.error) {
252
- toast.error(res.error);
253
- return;
254
- }
255
- toast.success(`${t.delete}: ${role.label}`);
256
- onChanged();
257
- } finally {
258
- setDeleting(false);
259
- }
260
- }
261
- return /* @__PURE__ */ jsxs(Dialog, { children: [
262
- /* @__PURE__ */ jsxs(
263
- DialogTrigger,
264
- {
265
- render: /* @__PURE__ */ jsx(
266
- Button,
267
- {
268
- variant: "destructive",
269
- size: "sm",
270
- className: "gap-1.5",
271
- disabled: inUse > 0
272
- }
273
- ),
274
- children: [
275
- /* @__PURE__ */ jsx(Trash2, { className: "size-3.5" }),
276
- /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: t.delete })
277
- ]
278
- }
279
- ),
280
- /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-sm", children: [
281
- /* @__PURE__ */ jsxs(DialogHeader, { children: [
282
- /* @__PURE__ */ jsx(DialogTitle, { children: t.deleteConfirmTitle }),
283
- /* @__PURE__ */ jsxs(DialogDescription, { children: [
284
- role.label,
285
- " \u2014 ",
286
- t.deleteConfirmBody
287
- ] })
288
- ] }),
289
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
290
- /* @__PURE__ */ jsx(DialogClose, { render: /* @__PURE__ */ jsx(Button, { variant: "outline" }), children: t.cancel }),
291
- /* @__PURE__ */ jsxs(
292
- DialogClose,
293
- {
294
- render: /* @__PURE__ */ jsx(
295
- Button,
296
- {
297
- variant: "destructive",
298
- className: "gap-2",
299
- disabled: deleting
300
- }
301
- ),
302
- onClick: remove,
303
- children: [
304
- /* @__PURE__ */ jsx(Trash2, { className: "size-4" }),
305
- t.delete
306
- ]
307
- }
308
- )
309
- ] })
310
- ] })
311
- ] });
312
- }
313
- function NewRoleDialog({
314
- createAction,
315
- onChanged
316
- }) {
317
- const t = useCopy().admin.rolesPage;
318
- const [open, setOpen] = React.useState(false);
319
- const [label, setLabel] = React.useState("");
320
- const [perms, setPerms] = React.useState(() => /* @__PURE__ */ new Set());
321
- const [submitting, setSubmitting] = React.useState(false);
322
- function reset() {
323
- setLabel("");
324
- setPerms(/* @__PURE__ */ new Set());
325
- }
326
- function toggle(p, checked) {
327
- setPerms((prev) => {
328
- const next = new Set(prev);
329
- if (checked) next.add(p);
330
- else next.delete(p);
331
- return next;
332
- });
333
- }
334
- async function submit(e) {
335
- e.preventDefault();
336
- if (!label.trim()) return toast.error(`${t.roleName} is required.`);
337
- setSubmitting(true);
338
- try {
339
- const res = await createAction({
340
- label: label.trim(),
341
- permissions: [...perms]
342
- });
343
- if (res?.error) {
344
- toast.error(res.error);
345
- return;
346
- }
347
- toast.success(`${t.create}: ${label.trim()}`);
348
- reset();
349
- setOpen(false);
350
- onChanged();
351
- } finally {
352
- setSubmitting(false);
353
- }
354
- }
355
- return /* @__PURE__ */ jsxs(
356
- Dialog,
357
- {
358
- open,
359
- onOpenChange: (o) => {
360
- if (!o) reset();
361
- setOpen(o);
362
- },
363
- children: [
364
- /* @__PURE__ */ jsxs(DialogTrigger, { render: /* @__PURE__ */ jsx(Button, { className: "gap-1.5" }), children: [
365
- /* @__PURE__ */ jsx(Plus, { className: "size-4" }),
366
- t.newRole
367
- ] }),
368
- /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-lg", children: [
369
- /* @__PURE__ */ jsxs(DialogHeader, { children: [
370
- /* @__PURE__ */ jsx(DialogTitle, { children: t.newRole }),
371
- /* @__PURE__ */ jsx(DialogDescription, { children: t.subtitle })
372
- ] }),
373
- /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "space-y-4", children: [
374
- /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
375
- /* @__PURE__ */ jsx(Label, { htmlFor: "role-label", children: t.roleName }),
376
- /* @__PURE__ */ jsx(
377
- Input,
378
- {
379
- id: "role-label",
380
- value: label,
381
- onChange: (e) => setLabel(e.target.value),
382
- placeholder: t.roleNamePlaceholder,
383
- autoComplete: "off",
384
- autoFocus: true
385
- }
386
- )
387
- ] }),
388
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
389
- /* @__PURE__ */ jsx(Label, { children: t.permissions }),
390
- /* @__PURE__ */ jsx(PermissionChecklist, { selected: perms, onToggle: toggle })
391
- ] }),
392
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
393
- /* @__PURE__ */ jsx(DialogClose, { render: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline" }), children: t.cancel }),
394
- /* @__PURE__ */ jsxs(Button, { type: "submit", disabled: submitting, className: "gap-1.5", children: [
395
- submitting ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsx(Plus, { className: "size-4" }),
396
- submitting ? t.creating : t.create
397
- ] })
398
- ] })
399
- ] })
400
- ] })
401
- ]
402
- }
403
- );
404
- }
405
-
406
- export { RolesManager };
@@ -1,10 +1,2 @@
1
- import * as React$1 from 'react';
2
-
3
- declare function StatCard({ label, value, icon, accent, }: {
4
- label: string;
5
- value: string | number;
6
- icon: React.ReactNode;
7
- accent?: string;
8
- }): React$1.JSX.Element;
9
-
10
- export { StatCard };
1
+ export { StatCard } from '../dashboard.js';
2
+ import 'react';
@@ -1,29 +1,3 @@
1
- import { Card, CardContent } from '../chunk-SETIN6XP.js';
2
- import { cn } from '../chunk-77QBZC7J.js';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
4
-
5
- function StatCard({
6
- label,
7
- value,
8
- icon,
9
- accent = "bg-muted text-muted-foreground"
10
- }) {
11
- return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardContent, { className: "flex items-center gap-3", children: [
12
- /* @__PURE__ */ jsx(
13
- "div",
14
- {
15
- className: cn(
16
- "flex size-10 shrink-0 items-center justify-center rounded-lg",
17
- accent
18
- ),
19
- children: icon
20
- }
21
- ),
22
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
23
- /* @__PURE__ */ jsx("p", { className: "truncate text-2xl font-semibold tabular-nums", children: value }),
24
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: label })
25
- ] })
26
- ] }) });
27
- }
28
-
29
- export { StatCard };
1
+ export { StatCard } from '../chunk-UBUXPJLN.js';
2
+ import '../chunk-SETIN6XP.js';
3
+ import '../chunk-77QBZC7J.js';
@@ -1,13 +1,13 @@
1
1
  "use client";
2
- export { TicketPreview } from '../chunk-ZUMEOZ22.js';
2
+ export { TicketPreview } from '../chunk-JTSTNZAB.js';
3
3
  import '../chunk-IBZVIUNI.js';
4
4
  import '../chunk-GLIK5BHP.js';
5
5
  import '../chunk-NSCIBSCW.js';
6
6
  import '../chunk-OE525ZER.js';
7
7
  import '../chunk-BVI5XDDA.js';
8
- import '../chunk-SETIN6XP.js';
9
8
  import '../chunk-OWCGEEAZ.js';
10
9
  import '../chunk-55FQP2DO.js';
11
10
  import '../chunk-TJSNVTVB.js';
11
+ import '../chunk-SETIN6XP.js';
12
12
  import '../chunk-77QBZC7J.js';
13
13
  import '../chunk-BI4EGLPG.js';
@@ -1,73 +1,11 @@
1
1
  "use client";
2
- import { StatusBadge } from '../chunk-OE525ZER.js';
3
- import { Money } from '../chunk-BVI5XDDA.js';
4
- import { usePagination, Pagination } from '../chunk-6YFZLXFP.js';
5
- import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from '../chunk-OWCGEEAZ.js';
2
+ export { TicketsTable } from '../chunk-6662IONX.js';
3
+ import '../chunk-6YFZLXFP.js';
4
+ import '../chunk-OE525ZER.js';
5
+ import '../chunk-BVI5XDDA.js';
6
+ import '../chunk-OWCGEEAZ.js';
6
7
  import '../chunk-55FQP2DO.js';
7
8
  import '../chunk-I4WDVYHX.js';
8
- import { useFormatters } from '../chunk-TJSNVTVB.js';
9
+ import '../chunk-TJSNVTVB.js';
9
10
  import '../chunk-77QBZC7J.js';
10
- import { formalName } from '../chunk-BI4EGLPG.js';
11
- import { useRouter } from 'next/navigation';
12
- import { ChevronRight } from 'lucide-react';
13
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
14
-
15
- function TicketsTable({ tickets }) {
16
- const { formatDate } = useFormatters();
17
- const router = useRouter();
18
- const { pageItems, page, setPage, totalPages, from, to, total } = usePagination(tickets, 15);
19
- if (tickets.length === 0) {
20
- return /* @__PURE__ */ jsx("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "No tickets match this view." });
21
- }
22
- return /* @__PURE__ */ jsxs(Fragment, { children: [
23
- /* @__PURE__ */ jsxs(Table, { children: [
24
- /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
25
- /* @__PURE__ */ jsx(TableHead, { children: "Ticket No." }),
26
- /* @__PURE__ */ jsx(TableHead, { children: "Violator" }),
27
- /* @__PURE__ */ jsx(TableHead, { className: "hidden sm:table-cell", children: "Apprehended" }),
28
- /* @__PURE__ */ jsx(TableHead, { children: "Status" }),
29
- /* @__PURE__ */ jsx(TableHead, { className: "text-right", children: "Amount" }),
30
- /* @__PURE__ */ jsx(TableHead, { className: "w-8" })
31
- ] }) }),
32
- /* @__PURE__ */ jsx(TableBody, { children: pageItems.map((t) => {
33
- const href = `/admin/tickets/${encodeURIComponent(t.ovrTicketNo)}`;
34
- const amount = t.status === "PAID" ? t.payment?.amount ?? 0 : t.totalAmountDue;
35
- return /* @__PURE__ */ jsxs(
36
- TableRow,
37
- {
38
- onClick: () => router.push(href),
39
- onKeyDown: (e) => {
40
- if (e.key === "Enter") router.push(href);
41
- },
42
- role: "link",
43
- tabIndex: 0,
44
- "aria-label": `Open ticket ${t.ovrTicketNo}`,
45
- className: "cursor-pointer",
46
- children: [
47
- /* @__PURE__ */ jsx(TableCell, { className: "font-mono text-xs", children: t.ovrTicketNo }),
48
- /* @__PURE__ */ jsx(TableCell, { className: "font-medium", children: formalName(t.violator) }),
49
- /* @__PURE__ */ jsx(TableCell, { className: "hidden text-muted-foreground sm:table-cell", children: formatDate(t.apprehendedAt) }),
50
- /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(StatusBadge, { status: t.status }) }),
51
- /* @__PURE__ */ jsx(TableCell, { className: "text-right", children: /* @__PURE__ */ jsx(Money, { value: amount }) }),
52
- /* @__PURE__ */ jsx(TableCell, { className: "text-muted-foreground", children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" }) })
53
- ]
54
- },
55
- t.ovrTicketNo
56
- );
57
- }) })
58
- ] }),
59
- /* @__PURE__ */ jsx(
60
- Pagination,
61
- {
62
- page,
63
- totalPages,
64
- from,
65
- to,
66
- total,
67
- onPage: setPage
68
- }
69
- )
70
- ] });
71
- }
72
-
73
- export { TicketsTable };
11
+ import '../chunk-BI4EGLPG.js';