@gelabs/ovr 0.2.2 → 0.4.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.
- package/dist/auth-auth.js +1 -1
- package/dist/auth.js +1 -1
- package/dist/{chunk-MDTRBOPQ.js → chunk-2C3VCTYJ.js} +1 -1
- package/dist/chunk-3YKVH4Y7.js +126 -0
- package/dist/chunk-6YFZLXFP.js +84 -0
- package/dist/{chunk-3NZ2XUBO.js → chunk-AJ2RZTVX.js} +9 -2
- package/dist/chunk-BI4EGLPG.js +298 -0
- package/dist/{chunk-3KIDW4LT.js → chunk-BVI5XDDA.js} +1 -1
- package/dist/chunk-DJMUW5T2.js +298 -0
- package/dist/{chunk-BIQ2J75Y.js → chunk-GLIK5BHP.js} +2 -2
- package/dist/{chunk-JEYT63LE.js → chunk-IBZVIUNI.js} +1 -1
- package/dist/{chunk-4SZXBT56.js → chunk-NT72CQAI.js} +2 -2
- package/dist/{chunk-E2D7QT6N.js → chunk-TJSNVTVB.js} +1 -1
- package/dist/{chunk-5Z2IAD5I.js → chunk-TLG4C2XI.js} +2 -2
- package/dist/chunk-V7VQVDWS.js +237 -0
- package/dist/chunk-WUNTHINH.js +98 -0
- package/dist/{chunk-IF5UAVIE.js → chunk-YC7G2IOZ.js} +1 -1
- package/dist/{chunk-IB4JVGKJ.js → chunk-YGYA7KEG.js} +47 -3
- package/dist/{chunk-GDOCD7LT.js → chunk-ZUMEOZ22.js} +5 -5
- package/dist/core-i18n.d.ts +2 -2
- package/dist/core-i18n.js +1 -1
- package/dist/core.d.ts +61 -1
- package/dist/core.js +1 -1
- package/dist/data-mock-store.js +330 -12
- package/dist/data-prisma-store.js +319 -9
- package/dist/data-seed-runner.js +18 -15
- package/dist/data.d.ts +64 -3
- package/dist/generated/client/edge.js +31 -10
- package/dist/generated/client/index-browser.js +28 -7
- package/dist/generated/client/index.d.ts +3583 -577
- package/dist/generated/client/index.js +31 -10
- package/dist/generated/client/package.json +1 -1
- package/dist/generated/client/schema.prisma +48 -9
- package/dist/generated/client/wasm.js +31 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/offline.d.ts +34 -1
- package/dist/offline.js +2 -2
- package/dist/types-B8MopM4b.d.ts +281 -0
- package/dist/types.d.ts +104 -1
- package/dist/types.js +1 -1
- package/dist/ui-components-admin/accounts-manager.d.ts +52 -0
- package/dist/ui-components-admin/accounts-manager.js +471 -0
- package/dist/ui-components-admin/admin-nav.d.ts +15 -1
- package/dist/ui-components-admin/admin-nav.js +388 -60
- package/dist/ui-components-admin/issuance-form.js +72 -13
- package/dist/ui-components-admin/logs-viewer.d.ts +13 -0
- package/dist/ui-components-admin/logs-viewer.js +102 -0
- package/dist/ui-components-admin/notifications-list.d.ts +5 -0
- package/dist/ui-components-admin/notifications-list.js +70 -0
- package/dist/ui-components-admin/officers-manager.d.ts +27 -0
- package/dist/ui-components-admin/officers-manager.js +271 -0
- package/dist/ui-components-admin/roles-manager.d.ts +37 -0
- package/dist/ui-components-admin/roles-manager.js +406 -0
- package/dist/ui-components-admin/ticket-preview.js +7 -7
- package/dist/ui-components-admin/tickets-table.js +56 -33
- package/dist/ui-components-admin/violations-manager.d.ts +32 -0
- package/dist/ui-components-admin/violations-manager.js +385 -0
- package/dist/ui-components-citizen/citizen-nav.js +2 -2
- package/dist/ui-components-citizen/payment-form.js +5 -5
- package/dist/ui-components-citizen/payment-qr-dialog.js +4 -4
- package/dist/ui-components-citizen/ticket-not-found.js +2 -2
- package/dist/ui-components-citizen/violation-history-table.js +3 -3
- package/dist/ui-components-shared/amount-summary.js +4 -4
- package/dist/ui-components-shared/money.js +3 -3
- package/dist/ui-components-shared/municipal-seal.js +3 -3
- package/dist/ui-components-shared/official-header.js +4 -4
- package/dist/ui-components-shared/site-header.js +4 -4
- package/dist/ui-components-shared/sonner.js +2 -2
- package/dist/ui-components-shared/theme-toggle.js +3 -3
- package/dist/ui-components-shared/ticket-receipt.js +13 -6
- package/dist/ui-components-shared/violations-table.js +4 -4
- package/dist/ui-components-ui/badge.d.ts +1 -1
- package/dist/ui-components-ui/button.d.ts +1 -1
- package/dist/ui-components-ui/dropdown-menu.js +2 -237
- package/dist/ui-components-ui/sheet.js +3 -126
- package/dist/ui-config.d.ts +1 -1
- package/dist/ui-config.js +2 -2
- package/dist/ui-server.d.ts +1 -1
- package/dist/ui-server.js +2 -2
- package/package.json +6 -6
- package/prisma/migrations/20260622010000_add_super_admin_role/migration.sql +3 -0
- package/prisma/migrations/20260622020000_add_apprehending_enforcer/migration.sql +4 -0
- package/prisma/migrations/20260622030000_custom_roles/migration.sql +30 -0
- package/prisma/migrations/20260622040000_add_activity_log/migration.sql +18 -0
- package/prisma/migrations/20260622050000_violation_catalog_management/migration.sql +5 -0
- package/prisma/schema.prisma +48 -9
- package/dist/chunk-5YYR37CF.js +0 -146
- package/dist/chunk-B634JHKZ.js +0 -181
- package/dist/types-CtBC5-TW.d.ts +0 -129
|
@@ -1,238 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import { ChevronRightIcon, CheckIcon } from 'lucide-react';
|
|
5
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
-
|
|
7
|
-
function DropdownMenu({ ...props }) {
|
|
8
|
-
return /* @__PURE__ */ jsx(Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
9
|
-
}
|
|
10
|
-
function DropdownMenuPortal({ ...props }) {
|
|
11
|
-
return /* @__PURE__ */ jsx(Menu.Portal, { "data-slot": "dropdown-menu-portal", ...props });
|
|
12
|
-
}
|
|
13
|
-
function DropdownMenuTrigger({ ...props }) {
|
|
14
|
-
return /* @__PURE__ */ jsx(Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
15
|
-
}
|
|
16
|
-
function DropdownMenuContent({
|
|
17
|
-
align = "start",
|
|
18
|
-
alignOffset = 0,
|
|
19
|
-
side = "bottom",
|
|
20
|
-
sideOffset = 4,
|
|
21
|
-
className,
|
|
22
|
-
...props
|
|
23
|
-
}) {
|
|
24
|
-
return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(
|
|
25
|
-
Menu.Positioner,
|
|
26
|
-
{
|
|
27
|
-
className: "isolate z-50 outline-none",
|
|
28
|
-
align,
|
|
29
|
-
alignOffset,
|
|
30
|
-
side,
|
|
31
|
-
sideOffset,
|
|
32
|
-
children: /* @__PURE__ */ jsx(
|
|
33
|
-
Menu.Popup,
|
|
34
|
-
{
|
|
35
|
-
"data-slot": "dropdown-menu-content",
|
|
36
|
-
className: cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95", className),
|
|
37
|
-
...props
|
|
38
|
-
}
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
) });
|
|
42
|
-
}
|
|
43
|
-
function DropdownMenuGroup({ ...props }) {
|
|
44
|
-
return /* @__PURE__ */ jsx(Menu.Group, { "data-slot": "dropdown-menu-group", ...props });
|
|
45
|
-
}
|
|
46
|
-
function DropdownMenuLabel({
|
|
47
|
-
className,
|
|
48
|
-
inset,
|
|
49
|
-
...props
|
|
50
|
-
}) {
|
|
51
|
-
return /* @__PURE__ */ jsx(
|
|
52
|
-
Menu.GroupLabel,
|
|
53
|
-
{
|
|
54
|
-
"data-slot": "dropdown-menu-label",
|
|
55
|
-
"data-inset": inset,
|
|
56
|
-
className: cn(
|
|
57
|
-
"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
|
|
58
|
-
className
|
|
59
|
-
),
|
|
60
|
-
...props
|
|
61
|
-
}
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
function DropdownMenuItem({
|
|
65
|
-
className,
|
|
66
|
-
inset,
|
|
67
|
-
variant = "default",
|
|
68
|
-
...props
|
|
69
|
-
}) {
|
|
70
|
-
return /* @__PURE__ */ jsx(
|
|
71
|
-
Menu.Item,
|
|
72
|
-
{
|
|
73
|
-
"data-slot": "dropdown-menu-item",
|
|
74
|
-
"data-inset": inset,
|
|
75
|
-
"data-variant": variant,
|
|
76
|
-
className: cn(
|
|
77
|
-
"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
|
|
78
|
-
className
|
|
79
|
-
),
|
|
80
|
-
...props
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
function DropdownMenuSub({ ...props }) {
|
|
85
|
-
return /* @__PURE__ */ jsx(Menu.SubmenuRoot, { "data-slot": "dropdown-menu-sub", ...props });
|
|
86
|
-
}
|
|
87
|
-
function DropdownMenuSubTrigger({
|
|
88
|
-
className,
|
|
89
|
-
inset,
|
|
90
|
-
children,
|
|
91
|
-
...props
|
|
92
|
-
}) {
|
|
93
|
-
return /* @__PURE__ */ jsxs(
|
|
94
|
-
Menu.SubmenuTrigger,
|
|
95
|
-
{
|
|
96
|
-
"data-slot": "dropdown-menu-sub-trigger",
|
|
97
|
-
"data-inset": inset,
|
|
98
|
-
className: cn(
|
|
99
|
-
"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
100
|
-
className
|
|
101
|
-
),
|
|
102
|
-
...props,
|
|
103
|
-
children: [
|
|
104
|
-
children,
|
|
105
|
-
/* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto" })
|
|
106
|
-
]
|
|
107
|
-
}
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
function DropdownMenuSubContent({
|
|
111
|
-
align = "start",
|
|
112
|
-
alignOffset = -3,
|
|
113
|
-
side = "right",
|
|
114
|
-
sideOffset = 0,
|
|
115
|
-
className,
|
|
116
|
-
...props
|
|
117
|
-
}) {
|
|
118
|
-
return /* @__PURE__ */ jsx(
|
|
119
|
-
DropdownMenuContent,
|
|
120
|
-
{
|
|
121
|
-
"data-slot": "dropdown-menu-sub-content",
|
|
122
|
-
className: cn("w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
|
|
123
|
-
align,
|
|
124
|
-
alignOffset,
|
|
125
|
-
side,
|
|
126
|
-
sideOffset,
|
|
127
|
-
...props
|
|
128
|
-
}
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
function DropdownMenuCheckboxItem({
|
|
132
|
-
className,
|
|
133
|
-
children,
|
|
134
|
-
checked,
|
|
135
|
-
inset,
|
|
136
|
-
...props
|
|
137
|
-
}) {
|
|
138
|
-
return /* @__PURE__ */ jsxs(
|
|
139
|
-
Menu.CheckboxItem,
|
|
140
|
-
{
|
|
141
|
-
"data-slot": "dropdown-menu-checkbox-item",
|
|
142
|
-
"data-inset": inset,
|
|
143
|
-
className: cn(
|
|
144
|
-
"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
145
|
-
className
|
|
146
|
-
),
|
|
147
|
-
checked,
|
|
148
|
-
...props,
|
|
149
|
-
children: [
|
|
150
|
-
/* @__PURE__ */ jsx(
|
|
151
|
-
"span",
|
|
152
|
-
{
|
|
153
|
-
className: "pointer-events-none absolute right-2 flex items-center justify-center",
|
|
154
|
-
"data-slot": "dropdown-menu-checkbox-item-indicator",
|
|
155
|
-
children: /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { children: /* @__PURE__ */ jsx(
|
|
156
|
-
CheckIcon,
|
|
157
|
-
{}
|
|
158
|
-
) })
|
|
159
|
-
}
|
|
160
|
-
),
|
|
161
|
-
children
|
|
162
|
-
]
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
function DropdownMenuRadioGroup({ ...props }) {
|
|
167
|
-
return /* @__PURE__ */ jsx(
|
|
168
|
-
Menu.RadioGroup,
|
|
169
|
-
{
|
|
170
|
-
"data-slot": "dropdown-menu-radio-group",
|
|
171
|
-
...props
|
|
172
|
-
}
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
function DropdownMenuRadioItem({
|
|
176
|
-
className,
|
|
177
|
-
children,
|
|
178
|
-
inset,
|
|
179
|
-
...props
|
|
180
|
-
}) {
|
|
181
|
-
return /* @__PURE__ */ jsxs(
|
|
182
|
-
Menu.RadioItem,
|
|
183
|
-
{
|
|
184
|
-
"data-slot": "dropdown-menu-radio-item",
|
|
185
|
-
"data-inset": inset,
|
|
186
|
-
className: cn(
|
|
187
|
-
"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
188
|
-
className
|
|
189
|
-
),
|
|
190
|
-
...props,
|
|
191
|
-
children: [
|
|
192
|
-
/* @__PURE__ */ jsx(
|
|
193
|
-
"span",
|
|
194
|
-
{
|
|
195
|
-
className: "pointer-events-none absolute right-2 flex items-center justify-center",
|
|
196
|
-
"data-slot": "dropdown-menu-radio-item-indicator",
|
|
197
|
-
children: /* @__PURE__ */ jsx(Menu.RadioItemIndicator, { children: /* @__PURE__ */ jsx(
|
|
198
|
-
CheckIcon,
|
|
199
|
-
{}
|
|
200
|
-
) })
|
|
201
|
-
}
|
|
202
|
-
),
|
|
203
|
-
children
|
|
204
|
-
]
|
|
205
|
-
}
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
function DropdownMenuSeparator({
|
|
209
|
-
className,
|
|
210
|
-
...props
|
|
211
|
-
}) {
|
|
212
|
-
return /* @__PURE__ */ jsx(
|
|
213
|
-
Menu.Separator,
|
|
214
|
-
{
|
|
215
|
-
"data-slot": "dropdown-menu-separator",
|
|
216
|
-
className: cn("-mx-1 my-1 h-px bg-border", className),
|
|
217
|
-
...props
|
|
218
|
-
}
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
function DropdownMenuShortcut({
|
|
222
|
-
className,
|
|
223
|
-
...props
|
|
224
|
-
}) {
|
|
225
|
-
return /* @__PURE__ */ jsx(
|
|
226
|
-
"span",
|
|
227
|
-
{
|
|
228
|
-
"data-slot": "dropdown-menu-shortcut",
|
|
229
|
-
className: cn(
|
|
230
|
-
"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
|
|
231
|
-
className
|
|
232
|
-
),
|
|
233
|
-
...props
|
|
234
|
-
}
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
|
|
2
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from '../chunk-V7VQVDWS.js';
|
|
3
|
+
import '../chunk-77QBZC7J.js';
|
|
@@ -1,127 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { XIcon } from 'lucide-react';
|
|
6
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
-
|
|
8
|
-
function Sheet({ ...props }) {
|
|
9
|
-
return /* @__PURE__ */ jsx(Dialog.Root, { "data-slot": "sheet", ...props });
|
|
10
|
-
}
|
|
11
|
-
function SheetTrigger({ ...props }) {
|
|
12
|
-
return /* @__PURE__ */ jsx(Dialog.Trigger, { "data-slot": "sheet-trigger", ...props });
|
|
13
|
-
}
|
|
14
|
-
function SheetClose({ ...props }) {
|
|
15
|
-
return /* @__PURE__ */ jsx(Dialog.Close, { "data-slot": "sheet-close", ...props });
|
|
16
|
-
}
|
|
17
|
-
function SheetPortal({ ...props }) {
|
|
18
|
-
return /* @__PURE__ */ jsx(Dialog.Portal, { "data-slot": "sheet-portal", ...props });
|
|
19
|
-
}
|
|
20
|
-
function SheetOverlay({ className, ...props }) {
|
|
21
|
-
return /* @__PURE__ */ jsx(
|
|
22
|
-
Dialog.Backdrop,
|
|
23
|
-
{
|
|
24
|
-
"data-slot": "sheet-overlay",
|
|
25
|
-
className: cn(
|
|
26
|
-
"fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",
|
|
27
|
-
className
|
|
28
|
-
),
|
|
29
|
-
...props
|
|
30
|
-
}
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
function SheetContent({
|
|
34
|
-
className,
|
|
35
|
-
children,
|
|
36
|
-
side = "right",
|
|
37
|
-
showCloseButton = true,
|
|
38
|
-
...props
|
|
39
|
-
}) {
|
|
40
|
-
return /* @__PURE__ */ jsxs(SheetPortal, { children: [
|
|
41
|
-
/* @__PURE__ */ jsx(SheetOverlay, {}),
|
|
42
|
-
/* @__PURE__ */ jsxs(
|
|
43
|
-
Dialog.Popup,
|
|
44
|
-
{
|
|
45
|
-
"data-slot": "sheet-content",
|
|
46
|
-
"data-side": side,
|
|
47
|
-
className: cn(
|
|
48
|
-
"fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
|
|
49
|
-
className
|
|
50
|
-
),
|
|
51
|
-
...props,
|
|
52
|
-
children: [
|
|
53
|
-
children,
|
|
54
|
-
showCloseButton && /* @__PURE__ */ jsxs(
|
|
55
|
-
Dialog.Close,
|
|
56
|
-
{
|
|
57
|
-
"data-slot": "sheet-close",
|
|
58
|
-
render: /* @__PURE__ */ jsx(
|
|
59
|
-
Button,
|
|
60
|
-
{
|
|
61
|
-
variant: "ghost",
|
|
62
|
-
className: "absolute top-3 right-3",
|
|
63
|
-
size: "icon-sm"
|
|
64
|
-
}
|
|
65
|
-
),
|
|
66
|
-
children: [
|
|
67
|
-
/* @__PURE__ */ jsx(
|
|
68
|
-
XIcon,
|
|
69
|
-
{}
|
|
70
|
-
),
|
|
71
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
72
|
-
]
|
|
73
|
-
}
|
|
74
|
-
)
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
)
|
|
78
|
-
] });
|
|
79
|
-
}
|
|
80
|
-
function SheetHeader({ className, ...props }) {
|
|
81
|
-
return /* @__PURE__ */ jsx(
|
|
82
|
-
"div",
|
|
83
|
-
{
|
|
84
|
-
"data-slot": "sheet-header",
|
|
85
|
-
className: cn("flex flex-col gap-0.5 p-4", className),
|
|
86
|
-
...props
|
|
87
|
-
}
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
function SheetFooter({ className, ...props }) {
|
|
91
|
-
return /* @__PURE__ */ jsx(
|
|
92
|
-
"div",
|
|
93
|
-
{
|
|
94
|
-
"data-slot": "sheet-footer",
|
|
95
|
-
className: cn("mt-auto flex flex-col gap-2 p-4", className),
|
|
96
|
-
...props
|
|
97
|
-
}
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
function SheetTitle({ className, ...props }) {
|
|
101
|
-
return /* @__PURE__ */ jsx(
|
|
102
|
-
Dialog.Title,
|
|
103
|
-
{
|
|
104
|
-
"data-slot": "sheet-title",
|
|
105
|
-
className: cn(
|
|
106
|
-
"font-heading text-base font-medium text-foreground",
|
|
107
|
-
className
|
|
108
|
-
),
|
|
109
|
-
...props
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
function SheetDescription({
|
|
114
|
-
className,
|
|
115
|
-
...props
|
|
116
|
-
}) {
|
|
117
|
-
return /* @__PURE__ */ jsx(
|
|
118
|
-
Dialog.Description,
|
|
119
|
-
{
|
|
120
|
-
"data-slot": "sheet-description",
|
|
121
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
122
|
-
...props
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger };
|
|
2
|
+
export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from '../chunk-3YKVH4Y7.js';
|
|
3
|
+
import '../chunk-I4WDVYHX.js';
|
|
4
|
+
import '../chunk-77QBZC7J.js';
|
package/dist/ui-config.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { b as OvrConfig } from './schema-CdsFQxIg.js';
|
|
3
3
|
import { a as Formatters } from './format-C7MSwUHK.js';
|
|
4
|
-
import { D as Dictionary } from './types-
|
|
4
|
+
import { D as Dictionary } from './types-B8MopM4b.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import './types.js';
|
|
7
7
|
|
package/dist/ui-config.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { OvrConfigProvider, ThemeProvider, useCopy, useFormatters, useOvrConfig, useTheme } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
export { OvrConfigProvider, ThemeProvider, useCopy, useFormatters, useOvrConfig, useTheme } from './chunk-TJSNVTVB.js';
|
|
3
|
+
import './chunk-BI4EGLPG.js';
|
package/dist/ui-server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { b as OvrConfig } from './schema-CdsFQxIg.js';
|
|
2
2
|
import { a as Formatters } from './format-C7MSwUHK.js';
|
|
3
|
-
import { D as Dictionary, C as CopyOverrides } from './types-
|
|
3
|
+
import { D as Dictionary, C as CopyOverrides } from './types-B8MopM4b.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import './types.js';
|
|
6
6
|
|
package/dist/ui-server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gelabs/ovr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "The @gelabs/ovr SDK — one self-contained package over the OVR (Online Ordinance Violation Receipt) platform. A standalone per-LGU app installs ONLY this package and imports from @gelabs/ovr/{config,core,data,runtime,auth,ui,...}; the seven @gelabs/ovr-* implementation packages are bundled in at build time.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -158,14 +158,14 @@
|
|
|
158
158
|
"react-dom": "19.2.4",
|
|
159
159
|
"tsup": "^8.4.0",
|
|
160
160
|
"typescript": "^5",
|
|
161
|
-
"@gelabs/ovr-types": "0.0.0",
|
|
162
161
|
"@gelabs/ovr-config": "0.0.0",
|
|
163
|
-
"@gelabs/ovr-data": "0.0.0",
|
|
164
|
-
"@gelabs/ovr-ui": "0.0.0",
|
|
165
162
|
"@gelabs/ovr-offline": "0.0.0",
|
|
166
163
|
"@gelabs/ovr-core": "0.0.0",
|
|
167
|
-
"@gelabs/ovr-
|
|
168
|
-
"@gelabs/ovr-
|
|
164
|
+
"@gelabs/ovr-ui": "0.0.0",
|
|
165
|
+
"@gelabs/ovr-types": "0.0.0",
|
|
166
|
+
"@gelabs/ovr-data": "0.0.0",
|
|
167
|
+
"@gelabs/ovr-runtime": "0.0.0",
|
|
168
|
+
"@gelabs/ovr-auth": "0.0.0"
|
|
169
169
|
},
|
|
170
170
|
"scripts": {
|
|
171
171
|
"build": "tsup && node scripts/copy-assets.mjs",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- GE-013 (custom roles): roles + permissions become editable DATA.
|
|
2
|
+
|
|
3
|
+
-- CreateTable
|
|
4
|
+
CREATE TABLE "Role" (
|
|
5
|
+
"name" TEXT NOT NULL,
|
|
6
|
+
"label" TEXT NOT NULL,
|
|
7
|
+
"isSystem" BOOLEAN NOT NULL DEFAULT false,
|
|
8
|
+
"permissions" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[],
|
|
9
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
10
|
+
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
CONSTRAINT "Role_pkey" PRIMARY KEY ("name")
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
-- Seed the system roles up-front (they must exist before the FK below, and so
|
|
15
|
+
-- existing User.role values 'ENFORCER'/'ADMIN'/'SUPER_ADMIN' satisfy it).
|
|
16
|
+
INSERT INTO "Role" ("name", "label", "isSystem", "permissions", "updatedAt") VALUES
|
|
17
|
+
('SUPER_ADMIN', 'Super Admin', true, ARRAY['dashboard:view','tickets:view','tickets:create','accounts:manage','roles:manage'], CURRENT_TIMESTAMP),
|
|
18
|
+
('ADMIN', 'Administrator', true, ARRAY['dashboard:view','tickets:view','tickets:create'], CURRENT_TIMESTAMP),
|
|
19
|
+
('ENFORCER', 'Enforcer', true, ARRAY['tickets:view','tickets:create'], CURRENT_TIMESTAMP);
|
|
20
|
+
|
|
21
|
+
-- Convert User.role from the UserRole enum to a TEXT foreign key into Role.name.
|
|
22
|
+
ALTER TABLE "User" ALTER COLUMN "role" DROP DEFAULT;
|
|
23
|
+
ALTER TABLE "User" ALTER COLUMN "role" TYPE TEXT USING "role"::text;
|
|
24
|
+
ALTER TABLE "User" ALTER COLUMN "role" SET DEFAULT 'ENFORCER';
|
|
25
|
+
|
|
26
|
+
-- AddForeignKey
|
|
27
|
+
ALTER TABLE "User" ADD CONSTRAINT "User_role_fkey" FOREIGN KEY ("role") REFERENCES "Role"("name") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
28
|
+
|
|
29
|
+
-- DropEnum (no longer referenced)
|
|
30
|
+
DROP TYPE "UserRole";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
-- GE-022: append-only audit trail of account actions.
|
|
3
|
+
CREATE TABLE "ActivityLog" (
|
|
4
|
+
"id" TEXT NOT NULL,
|
|
5
|
+
"actorId" TEXT,
|
|
6
|
+
"actorUsername" TEXT,
|
|
7
|
+
"action" TEXT NOT NULL,
|
|
8
|
+
"summary" TEXT NOT NULL,
|
|
9
|
+
"targetType" TEXT,
|
|
10
|
+
"targetId" TEXT,
|
|
11
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
CONSTRAINT "ActivityLog_pkey" PRIMARY KEY ("id")
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
-- CreateIndex
|
|
16
|
+
CREATE INDEX "ActivityLog_action_idx" ON "ActivityLog"("action");
|
|
17
|
+
CREATE INDEX "ActivityLog_actorId_idx" ON "ActivityLog"("actorId");
|
|
18
|
+
CREATE INDEX "ActivityLog_createdAt_idx" ON "ActivityLog"("createdAt");
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- GE-031 (violation catalog management): soft-delete + edit tracking.
|
|
2
|
+
-- `active` lets admins archive a violation (hidden from issuance) while keeping
|
|
3
|
+
-- it resolvable for already-issued tickets. Existing rows default to active.
|
|
4
|
+
ALTER TABLE "ViolationCatalog" ADD COLUMN "active" BOOLEAN NOT NULL DEFAULT true;
|
|
5
|
+
ALTER TABLE "ViolationCatalog" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
package/prisma/schema.prisma
CHANGED
|
@@ -42,11 +42,6 @@ enum PaymentStatus {
|
|
|
42
42
|
CONTESTED
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
enum UserRole {
|
|
46
|
-
ENFORCER
|
|
47
|
-
ADMIN
|
|
48
|
-
}
|
|
49
|
-
|
|
50
45
|
model Officer {
|
|
51
46
|
id String @id // slug, e.g. "off-novelo"
|
|
52
47
|
name String // "NOVELO, RAYMUNDO V."
|
|
@@ -66,8 +61,10 @@ model ViolationCatalog {
|
|
|
66
61
|
category ViolationCategory
|
|
67
62
|
basicFine Decimal @db.Decimal(12, 2)
|
|
68
63
|
legalText String?
|
|
64
|
+
active Boolean @default(true) // GE-031: false = archived (hidden from issuance)
|
|
69
65
|
|
|
70
66
|
createdAt DateTime @default(now())
|
|
67
|
+
updatedAt DateTime @default(now()) @updatedAt
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
model Ticket {
|
|
@@ -94,6 +91,12 @@ model Ticket {
|
|
|
94
91
|
remarks String?
|
|
95
92
|
issuedBy String?
|
|
96
93
|
|
|
94
|
+
// GE-011: the enforcer ACCOUNT who apprehended (+ snapshot name for display).
|
|
95
|
+
// Soft reference to User.id — intentionally NOT a hard FK so the attribution
|
|
96
|
+
// survives if the account is later renamed or removed.
|
|
97
|
+
apprehendingEnforcerId String?
|
|
98
|
+
apprehendingEnforcerName String?
|
|
99
|
+
|
|
97
100
|
officerId String
|
|
98
101
|
officer Officer @relation(fields: [officerId], references: [id])
|
|
99
102
|
|
|
@@ -141,12 +144,30 @@ model Payment {
|
|
|
141
144
|
paidAt DateTime
|
|
142
145
|
}
|
|
143
146
|
|
|
147
|
+
// A role + its permission set (GE-013, custom roles). Permission keys come from
|
|
148
|
+
// the SDK catalog (@gelabs/ovr-types PERMISSION_CATALOG); the mapping is data.
|
|
149
|
+
model Role {
|
|
150
|
+
name String @id // "SUPER_ADMIN" / "ENFORCER" / custom slug e.g. "cashier"
|
|
151
|
+
label String // display name shown in the UI
|
|
152
|
+
isSystem Boolean @default(false) // system roles can't be renamed or deleted
|
|
153
|
+
permissions String[] // granted Permission keys
|
|
154
|
+
|
|
155
|
+
users User[]
|
|
156
|
+
|
|
157
|
+
createdAt DateTime @default(now())
|
|
158
|
+
updatedAt DateTime @updatedAt
|
|
159
|
+
}
|
|
160
|
+
|
|
144
161
|
model User {
|
|
145
|
-
id String
|
|
146
|
-
username String
|
|
162
|
+
id String @id @default(cuid())
|
|
163
|
+
username String @unique
|
|
147
164
|
passwordHash String
|
|
148
|
-
|
|
149
|
-
|
|
165
|
+
|
|
166
|
+
// Role is DATA now (see model Role): a string FK so custom roles are allowed.
|
|
167
|
+
role String @default("ENFORCER")
|
|
168
|
+
roleRef Role @relation(fields: [role], references: [name])
|
|
169
|
+
|
|
170
|
+
active Boolean @default(true)
|
|
150
171
|
|
|
151
172
|
// Links a login to an enforcer (so issued tickets can attribute the officer).
|
|
152
173
|
officerId String? @unique
|
|
@@ -154,3 +175,21 @@ model User {
|
|
|
154
175
|
|
|
155
176
|
createdAt DateTime @default(now())
|
|
156
177
|
}
|
|
178
|
+
|
|
179
|
+
// Audit trail (GE-022): who did what, when. Append-only. Actor is a SOFT
|
|
180
|
+
// reference (snapshot username) so entries survive account deletion.
|
|
181
|
+
model ActivityLog {
|
|
182
|
+
id String @id @default(cuid())
|
|
183
|
+
actorId String?
|
|
184
|
+
actorUsername String?
|
|
185
|
+
action String // e.g. "auth.login", "account.create", "role.update"
|
|
186
|
+
summary String // human-readable one-liner
|
|
187
|
+
targetType String? // "account" | "role" | "ticket" | …
|
|
188
|
+
targetId String?
|
|
189
|
+
|
|
190
|
+
createdAt DateTime @default(now())
|
|
191
|
+
|
|
192
|
+
@@index([action])
|
|
193
|
+
@@index([actorId])
|
|
194
|
+
@@index([createdAt])
|
|
195
|
+
}
|