@gelabs/ovr 0.2.2 → 0.3.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-BIQ2J75Y.js → chunk-GLIK5BHP.js} +2 -2
- package/dist/{chunk-5YYR37CF.js → chunk-HGWPA7FU.js} +119 -0
- package/dist/{chunk-JEYT63LE.js → chunk-IBZVIUNI.js} +1 -1
- package/dist/chunk-IS3THKTE.js +89 -0
- 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-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 +263 -9
- package/dist/data-prisma-store.js +251 -1
- package/dist/data-seed-runner.js +18 -15
- package/dist/data.d.ts +53 -3
- package/dist/generated/client/edge.js +28 -9
- package/dist/generated/client/index-browser.js +25 -6
- package/dist/generated/client/index.d.ts +3500 -552
- package/dist/generated/client/index.js +28 -9
- package/dist/generated/client/package.json +1 -1
- package/dist/generated/client/schema.prisma +46 -9
- package/dist/generated/client/wasm.js +28 -9
- 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-CtBC5-TW.d.ts → types-BOgdk0Jw.d.ts} +119 -0
- package/dist/types.d.ts +93 -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 +386 -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-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 +4 -4
- 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/schema.prisma +46 -9
- package/dist/chunk-B634JHKZ.js +0 -181
package/dist/auth-auth.js
CHANGED
package/dist/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ADMIN_COOKIE, createAuth } from './chunk-
|
|
1
|
+
export { ADMIN_COOKIE, createAuth } from './chunk-AJ2RZTVX.js';
|
|
2
2
|
export { rateLimit } from './chunk-77ULDXQX.js';
|
|
3
3
|
export { SESSION_COOKIE, cookieSecure, createSession, destroySession, getSession } from './chunk-KIKDXRM5.js';
|
|
4
4
|
export { getRedis } from './chunk-ASFB24ZY.js';
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Button } from './chunk-I4WDVYHX.js';
|
|
2
|
+
import { cn } from './chunk-77QBZC7J.js';
|
|
3
|
+
import { Dialog } from '@base-ui/react/dialog';
|
|
4
|
+
import { XIcon } from 'lucide-react';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function Sheet({ ...props }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { "data-slot": "sheet", ...props });
|
|
9
|
+
}
|
|
10
|
+
function SheetTrigger({ ...props }) {
|
|
11
|
+
return /* @__PURE__ */ jsx(Dialog.Trigger, { "data-slot": "sheet-trigger", ...props });
|
|
12
|
+
}
|
|
13
|
+
function SheetClose({ ...props }) {
|
|
14
|
+
return /* @__PURE__ */ jsx(Dialog.Close, { "data-slot": "sheet-close", ...props });
|
|
15
|
+
}
|
|
16
|
+
function SheetPortal({ ...props }) {
|
|
17
|
+
return /* @__PURE__ */ jsx(Dialog.Portal, { "data-slot": "sheet-portal", ...props });
|
|
18
|
+
}
|
|
19
|
+
function SheetOverlay({ className, ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsx(
|
|
21
|
+
Dialog.Backdrop,
|
|
22
|
+
{
|
|
23
|
+
"data-slot": "sheet-overlay",
|
|
24
|
+
className: cn(
|
|
25
|
+
"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",
|
|
26
|
+
className
|
|
27
|
+
),
|
|
28
|
+
...props
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
function SheetContent({
|
|
33
|
+
className,
|
|
34
|
+
children,
|
|
35
|
+
side = "right",
|
|
36
|
+
showCloseButton = true,
|
|
37
|
+
...props
|
|
38
|
+
}) {
|
|
39
|
+
return /* @__PURE__ */ jsxs(SheetPortal, { children: [
|
|
40
|
+
/* @__PURE__ */ jsx(SheetOverlay, {}),
|
|
41
|
+
/* @__PURE__ */ jsxs(
|
|
42
|
+
Dialog.Popup,
|
|
43
|
+
{
|
|
44
|
+
"data-slot": "sheet-content",
|
|
45
|
+
"data-side": side,
|
|
46
|
+
className: cn(
|
|
47
|
+
"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",
|
|
48
|
+
className
|
|
49
|
+
),
|
|
50
|
+
...props,
|
|
51
|
+
children: [
|
|
52
|
+
children,
|
|
53
|
+
showCloseButton && /* @__PURE__ */ jsxs(
|
|
54
|
+
Dialog.Close,
|
|
55
|
+
{
|
|
56
|
+
"data-slot": "sheet-close",
|
|
57
|
+
render: /* @__PURE__ */ jsx(
|
|
58
|
+
Button,
|
|
59
|
+
{
|
|
60
|
+
variant: "ghost",
|
|
61
|
+
className: "absolute top-3 right-3",
|
|
62
|
+
size: "icon-sm"
|
|
63
|
+
}
|
|
64
|
+
),
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
XIcon,
|
|
68
|
+
{}
|
|
69
|
+
),
|
|
70
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
] });
|
|
78
|
+
}
|
|
79
|
+
function SheetHeader({ className, ...props }) {
|
|
80
|
+
return /* @__PURE__ */ jsx(
|
|
81
|
+
"div",
|
|
82
|
+
{
|
|
83
|
+
"data-slot": "sheet-header",
|
|
84
|
+
className: cn("flex flex-col gap-0.5 p-4", className),
|
|
85
|
+
...props
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
function SheetFooter({ className, ...props }) {
|
|
90
|
+
return /* @__PURE__ */ jsx(
|
|
91
|
+
"div",
|
|
92
|
+
{
|
|
93
|
+
"data-slot": "sheet-footer",
|
|
94
|
+
className: cn("mt-auto flex flex-col gap-2 p-4", className),
|
|
95
|
+
...props
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
function SheetTitle({ className, ...props }) {
|
|
100
|
+
return /* @__PURE__ */ jsx(
|
|
101
|
+
Dialog.Title,
|
|
102
|
+
{
|
|
103
|
+
"data-slot": "sheet-title",
|
|
104
|
+
className: cn(
|
|
105
|
+
"font-heading text-base font-medium text-foreground",
|
|
106
|
+
className
|
|
107
|
+
),
|
|
108
|
+
...props
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
function SheetDescription({
|
|
113
|
+
className,
|
|
114
|
+
...props
|
|
115
|
+
}) {
|
|
116
|
+
return /* @__PURE__ */ jsx(
|
|
117
|
+
Dialog.Description,
|
|
118
|
+
{
|
|
119
|
+
"data-slot": "sheet-description",
|
|
120
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
121
|
+
...props
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Button } from './chunk-I4WDVYHX.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function usePagination(items, pageSize = 15, resetKey) {
|
|
7
|
+
const [page, setPage] = React.useState(1);
|
|
8
|
+
const total = items.length;
|
|
9
|
+
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
10
|
+
const current = Math.min(page, totalPages);
|
|
11
|
+
const start = (current - 1) * pageSize;
|
|
12
|
+
const pageItems = items.slice(start, start + pageSize);
|
|
13
|
+
React.useEffect(() => {
|
|
14
|
+
setPage(1);
|
|
15
|
+
}, [resetKey]);
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
if (page > totalPages) setPage(totalPages);
|
|
18
|
+
}, [page, totalPages]);
|
|
19
|
+
return {
|
|
20
|
+
page: current,
|
|
21
|
+
setPage,
|
|
22
|
+
totalPages,
|
|
23
|
+
pageItems,
|
|
24
|
+
total,
|
|
25
|
+
from: total ? start + 1 : 0,
|
|
26
|
+
to: Math.min(start + pageSize, total)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function Pagination({
|
|
30
|
+
page,
|
|
31
|
+
totalPages,
|
|
32
|
+
from,
|
|
33
|
+
to,
|
|
34
|
+
total,
|
|
35
|
+
onPage
|
|
36
|
+
}) {
|
|
37
|
+
if (totalPages <= 1) return null;
|
|
38
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t px-4 py-3 text-sm text-muted-foreground", children: [
|
|
39
|
+
/* @__PURE__ */ jsxs("span", { className: "tabular-nums", children: [
|
|
40
|
+
from,
|
|
41
|
+
"\u2013",
|
|
42
|
+
to,
|
|
43
|
+
" of ",
|
|
44
|
+
total
|
|
45
|
+
] }),
|
|
46
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
47
|
+
/* @__PURE__ */ jsxs(
|
|
48
|
+
Button,
|
|
49
|
+
{
|
|
50
|
+
variant: "outline",
|
|
51
|
+
size: "sm",
|
|
52
|
+
className: "gap-1",
|
|
53
|
+
disabled: page <= 1,
|
|
54
|
+
onClick: () => onPage(page - 1),
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" }),
|
|
57
|
+
"Prev"
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsxs("span", { className: "px-1 tabular-nums", children: [
|
|
62
|
+
page,
|
|
63
|
+
" / ",
|
|
64
|
+
totalPages
|
|
65
|
+
] }),
|
|
66
|
+
/* @__PURE__ */ jsxs(
|
|
67
|
+
Button,
|
|
68
|
+
{
|
|
69
|
+
variant: "outline",
|
|
70
|
+
size: "sm",
|
|
71
|
+
className: "gap-1",
|
|
72
|
+
disabled: page >= totalPages,
|
|
73
|
+
onClick: () => onPage(page + 1),
|
|
74
|
+
children: [
|
|
75
|
+
"Next",
|
|
76
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
] })
|
|
81
|
+
] });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { Pagination, usePagination };
|
|
@@ -13,10 +13,17 @@ function createAuth(deps) {
|
|
|
13
13
|
if (deps.useDbBackend) return !!await getSession();
|
|
14
14
|
return isMockAuthed();
|
|
15
15
|
},
|
|
16
|
-
/** The signed-in admin, or null. Mock mode
|
|
16
|
+
/** The signed-in admin, or null. Mock mode's single demo login is the local
|
|
17
|
+
* superuser (SUPER_ADMIN) so every view — incl. account management — is
|
|
18
|
+
* reachable with zero infrastructure. LOCAL-DEV-ONLY. */
|
|
17
19
|
async currentUser() {
|
|
18
20
|
if (deps.useDbBackend) return getSession();
|
|
19
|
-
return await isMockAuthed() ? {
|
|
21
|
+
return await isMockAuthed() ? {
|
|
22
|
+
userId: "mock",
|
|
23
|
+
username: deps.demoAdmin.username,
|
|
24
|
+
role: "SUPER_ADMIN",
|
|
25
|
+
officerId: null
|
|
26
|
+
} : null;
|
|
20
27
|
}
|
|
21
28
|
};
|
|
22
29
|
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
// ../ovr-core/src/penalty.ts
|
|
2
|
+
var MS_PER_DAY = 864e5;
|
|
3
|
+
function startedMonthsSince(from, to) {
|
|
4
|
+
const days = Math.max(0, (to.getTime() - from.getTime()) / MS_PER_DAY);
|
|
5
|
+
return Math.ceil(days / 30);
|
|
6
|
+
}
|
|
7
|
+
function computeCharges({
|
|
8
|
+
basicFines,
|
|
9
|
+
apprehendedAt,
|
|
10
|
+
asOf,
|
|
11
|
+
dueDate,
|
|
12
|
+
ratePerMonth
|
|
13
|
+
}) {
|
|
14
|
+
if (asOf.getTime() <= dueDate.getTime()) {
|
|
15
|
+
return { basicFines, penalty: 0, total: basicFines, monthsOverdue: 0 };
|
|
16
|
+
}
|
|
17
|
+
const months = Math.max(1, startedMonthsSince(apprehendedAt, asOf));
|
|
18
|
+
const penalty = Math.round(basicFines * ratePerMonth * months * 100) / 100;
|
|
19
|
+
return {
|
|
20
|
+
basicFines,
|
|
21
|
+
penalty,
|
|
22
|
+
total: Math.round((basicFines + penalty) * 100) / 100,
|
|
23
|
+
monthsOverdue: months
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ../ovr-core/src/ids.ts
|
|
28
|
+
var pad = (n, len) => String(n).padStart(len, "0");
|
|
29
|
+
var two = (n) => pad(n, 2);
|
|
30
|
+
function makeOvrTicketNo(idPrefix, year, seq) {
|
|
31
|
+
return `${idPrefix}-${year}-${pad(seq, 6)}`;
|
|
32
|
+
}
|
|
33
|
+
function makeOrderOfPaymentNo(ovrTicketNo) {
|
|
34
|
+
return `${ovrTicketNo}-01`;
|
|
35
|
+
}
|
|
36
|
+
function makeBillNo(date, officeAbbr, officerCode, seq) {
|
|
37
|
+
const ymd = `${date.getFullYear()}-${two(date.getMonth() + 1)}-${two(date.getDate())}`;
|
|
38
|
+
return `M-${ymd}-${officeAbbr}-${officerCode}-${pad(seq, 6)}`;
|
|
39
|
+
}
|
|
40
|
+
function makePaymentRef(method, at) {
|
|
41
|
+
const prefix = method.slice(0, 3);
|
|
42
|
+
const ymd = `${at.getFullYear()}${two(at.getMonth() + 1)}${two(at.getDate())}`;
|
|
43
|
+
const hms = `${two(at.getHours())}${two(at.getMinutes())}${two(at.getSeconds())}`;
|
|
44
|
+
return `${prefix}-${ymd}-${hms}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ../ovr-core/src/format.ts
|
|
48
|
+
function createFormatters(rules) {
|
|
49
|
+
const pesoFmt = new Intl.NumberFormat(rules.locale, {
|
|
50
|
+
style: "currency",
|
|
51
|
+
currency: rules.currency
|
|
52
|
+
});
|
|
53
|
+
const dateFmt = new Intl.DateTimeFormat(rules.locale, {
|
|
54
|
+
year: "numeric",
|
|
55
|
+
month: "short",
|
|
56
|
+
day: "2-digit",
|
|
57
|
+
timeZone: rules.timeZone
|
|
58
|
+
});
|
|
59
|
+
const dateTimeFmt = new Intl.DateTimeFormat(rules.locale, {
|
|
60
|
+
year: "numeric",
|
|
61
|
+
month: "short",
|
|
62
|
+
day: "2-digit",
|
|
63
|
+
hour: "numeric",
|
|
64
|
+
minute: "2-digit",
|
|
65
|
+
timeZone: rules.timeZone
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
formatPeso: (amount) => pesoFmt.format(amount),
|
|
69
|
+
formatDate: (iso) => dateFmt.format(new Date(iso)),
|
|
70
|
+
formatDateTime: (iso) => dateTimeFmt.format(new Date(iso)),
|
|
71
|
+
nowManilaLocalInput: () => {
|
|
72
|
+
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
73
|
+
timeZone: rules.timeZone,
|
|
74
|
+
year: "numeric",
|
|
75
|
+
month: "2-digit",
|
|
76
|
+
day: "2-digit",
|
|
77
|
+
hour: "2-digit",
|
|
78
|
+
minute: "2-digit",
|
|
79
|
+
hour12: false
|
|
80
|
+
}).formatToParts(/* @__PURE__ */ new Date());
|
|
81
|
+
const get = (t) => parts.find((p) => p.type === t)?.value ?? "00";
|
|
82
|
+
return `${get("year")}-${get("month")}-${get("day")}T${get("hour")}:${get("minute")}`;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function fullName(v) {
|
|
87
|
+
return [v.firstName, v.middleName, v.lastName].filter(Boolean).join(" ");
|
|
88
|
+
}
|
|
89
|
+
function formalName(v) {
|
|
90
|
+
const given = [v.firstName, v.middleName].filter(Boolean).join(" ");
|
|
91
|
+
return `${v.lastName}, ${given}`;
|
|
92
|
+
}
|
|
93
|
+
function formatAddress(v) {
|
|
94
|
+
return [v.street, v.barangay, v.cityMunicipality, v.province].map((p) => p?.trim()).filter(Boolean).join(", ");
|
|
95
|
+
}
|
|
96
|
+
function addDays(date, days) {
|
|
97
|
+
const d = new Date(date);
|
|
98
|
+
d.setDate(d.getDate() + days);
|
|
99
|
+
return d;
|
|
100
|
+
}
|
|
101
|
+
function localToManilaISO(local) {
|
|
102
|
+
if (!local) return (/* @__PURE__ */ new Date()).toISOString();
|
|
103
|
+
const withSeconds = local.length === 16 ? `${local}:00` : local;
|
|
104
|
+
return (/* @__PURE__ */ new Date(`${withSeconds}+08:00`)).toISOString();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ../ovr-core/src/enrich.ts
|
|
108
|
+
var round2 = (n) => Math.round(n * 100) / 100;
|
|
109
|
+
function enrich(rec, asOf, ratePerMonth) {
|
|
110
|
+
if (rec.paymentStatus === "PAID") {
|
|
111
|
+
const paid = rec.payment?.amount ?? rec.basicFinesTotal;
|
|
112
|
+
return {
|
|
113
|
+
...rec,
|
|
114
|
+
status: "PAID",
|
|
115
|
+
penaltyAmount: Math.max(0, round2(paid - rec.basicFinesTotal)),
|
|
116
|
+
totalAmountDue: 0
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const { penalty, total } = computeCharges({
|
|
120
|
+
basicFines: rec.basicFinesTotal,
|
|
121
|
+
apprehendedAt: new Date(rec.apprehendedAt),
|
|
122
|
+
asOf,
|
|
123
|
+
dueDate: new Date(rec.dueDate),
|
|
124
|
+
ratePerMonth
|
|
125
|
+
});
|
|
126
|
+
if (rec.paymentStatus === "CONTESTED") {
|
|
127
|
+
return { ...rec, status: "CONTESTED", penaltyAmount: penalty, totalAmountDue: total };
|
|
128
|
+
}
|
|
129
|
+
const overdue = asOf.getTime() > new Date(rec.dueDate).getTime();
|
|
130
|
+
return {
|
|
131
|
+
...rec,
|
|
132
|
+
status: overdue ? "OVERDUE" : "OUTSTANDING",
|
|
133
|
+
penaltyAmount: penalty,
|
|
134
|
+
totalAmountDue: total
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ../ovr-core/src/preview.ts
|
|
139
|
+
var PREVIEW_PLACEHOLDER = "\u2014 assigned on confirm \u2014";
|
|
140
|
+
function toPreviewTicket(draft, now, rules) {
|
|
141
|
+
const basicFinesTotal = draft.violations.reduce(
|
|
142
|
+
(s, v) => s + v.item.basicFine,
|
|
143
|
+
0
|
|
144
|
+
);
|
|
145
|
+
const apprehendedAt = draft.apprehendedAtISO || now.toISOString();
|
|
146
|
+
const dueDate = addDays(now, rules.dueWindowDays);
|
|
147
|
+
const { penalty, total } = computeCharges({
|
|
148
|
+
basicFines: basicFinesTotal,
|
|
149
|
+
apprehendedAt: new Date(apprehendedAt),
|
|
150
|
+
asOf: now,
|
|
151
|
+
dueDate,
|
|
152
|
+
ratePerMonth: rules.surchargeRatePerMonth
|
|
153
|
+
});
|
|
154
|
+
const officer = draft.officer ?? { id: "", name: PREVIEW_PLACEHOLDER, office: "" };
|
|
155
|
+
return {
|
|
156
|
+
ovrTicketNo: PREVIEW_PLACEHOLDER,
|
|
157
|
+
orderOfPaymentNo: PREVIEW_PLACEHOLDER,
|
|
158
|
+
billNo: PREVIEW_PLACEHOLDER,
|
|
159
|
+
violator: draft.violator,
|
|
160
|
+
apprehendedAt,
|
|
161
|
+
placeOfViolation: draft.placeOfViolation,
|
|
162
|
+
officer,
|
|
163
|
+
violations: draft.violations.map((v) => ({
|
|
164
|
+
catalogCode: v.item.code,
|
|
165
|
+
title: v.item.title,
|
|
166
|
+
basicFine: v.item.basicFine,
|
|
167
|
+
details: v.details?.trim() || void 0
|
|
168
|
+
})),
|
|
169
|
+
remarks: draft.remarks,
|
|
170
|
+
assessedAt: now.toISOString(),
|
|
171
|
+
dueDate: dueDate.toISOString(),
|
|
172
|
+
basicFinesTotal,
|
|
173
|
+
paymentStatus: "UNPAID",
|
|
174
|
+
status: "OUTSTANDING",
|
|
175
|
+
penaltyAmount: penalty,
|
|
176
|
+
totalAmountDue: total,
|
|
177
|
+
createdAt: now.toISOString()
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ../ovr-core/src/dashboard.ts
|
|
182
|
+
var DASHBOARD_PRESETS = [
|
|
183
|
+
{ key: "1d", label: "Today" },
|
|
184
|
+
{ key: "7d", label: "7 days" },
|
|
185
|
+
{ key: "mtd", label: "Month" },
|
|
186
|
+
{ key: "prev-mtd", label: "Prev month" },
|
|
187
|
+
{ key: "all", label: "All time" }
|
|
188
|
+
];
|
|
189
|
+
function tzOffsetMinutes(date, timeZone) {
|
|
190
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
191
|
+
timeZone,
|
|
192
|
+
hour12: false,
|
|
193
|
+
year: "numeric",
|
|
194
|
+
month: "2-digit",
|
|
195
|
+
day: "2-digit",
|
|
196
|
+
hour: "2-digit",
|
|
197
|
+
minute: "2-digit",
|
|
198
|
+
second: "2-digit"
|
|
199
|
+
}).formatToParts(date);
|
|
200
|
+
const map = {};
|
|
201
|
+
for (const p of parts) if (p.type !== "literal") map[p.type] = Number(p.value);
|
|
202
|
+
const hour = map.hour === 24 ? 0 : map.hour;
|
|
203
|
+
const asUTC = Date.UTC(map.year, map.month - 1, map.day, hour, map.minute, map.second);
|
|
204
|
+
return Math.round((asUTC - date.getTime()) / 6e4);
|
|
205
|
+
}
|
|
206
|
+
function zonedYMD(date, timeZone) {
|
|
207
|
+
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
208
|
+
timeZone,
|
|
209
|
+
year: "numeric",
|
|
210
|
+
month: "2-digit",
|
|
211
|
+
day: "2-digit"
|
|
212
|
+
}).formatToParts(date);
|
|
213
|
+
const get = (t) => Number(parts.find((p) => p.type === t)?.value);
|
|
214
|
+
return { y: get("year"), m: get("month"), d: get("day") };
|
|
215
|
+
}
|
|
216
|
+
function zonedInstant(y, m, d, h, min, s, timeZone, ref) {
|
|
217
|
+
const off = tzOffsetMinutes(ref, timeZone);
|
|
218
|
+
return new Date(Date.UTC(y, m - 1, d, h, min, s) - off * 6e4);
|
|
219
|
+
}
|
|
220
|
+
function dashboardDateRange(preset, now, timeZone) {
|
|
221
|
+
const toISO = now.toISOString();
|
|
222
|
+
if (preset === "all") return { fromISO: null, toISO };
|
|
223
|
+
const { y, m, d } = zonedYMD(now, timeZone);
|
|
224
|
+
if (preset === "1d") {
|
|
225
|
+
const from2 = zonedInstant(y, m, d, 0, 0, 0, timeZone, now);
|
|
226
|
+
return { fromISO: from2.toISOString(), toISO };
|
|
227
|
+
}
|
|
228
|
+
if (preset === "7d") {
|
|
229
|
+
const base = new Date(Date.UTC(y, m - 1, d) - 6 * 864e5);
|
|
230
|
+
const from2 = zonedInstant(
|
|
231
|
+
base.getUTCFullYear(),
|
|
232
|
+
base.getUTCMonth() + 1,
|
|
233
|
+
base.getUTCDate(),
|
|
234
|
+
0,
|
|
235
|
+
0,
|
|
236
|
+
0,
|
|
237
|
+
timeZone,
|
|
238
|
+
now
|
|
239
|
+
);
|
|
240
|
+
return { fromISO: from2.toISOString(), toISO };
|
|
241
|
+
}
|
|
242
|
+
if (preset === "mtd") {
|
|
243
|
+
const from2 = zonedInstant(y, m, 1, 0, 0, 0, timeZone, now);
|
|
244
|
+
return { fromISO: from2.toISOString(), toISO };
|
|
245
|
+
}
|
|
246
|
+
const prevM = m === 1 ? 12 : m - 1;
|
|
247
|
+
const prevY = m === 1 ? y - 1 : y;
|
|
248
|
+
const daysInPrev = new Date(Date.UTC(prevY, prevM, 0)).getUTCDate();
|
|
249
|
+
const upperDay = Math.min(d, daysInPrev);
|
|
250
|
+
const from = zonedInstant(prevY, prevM, 1, 0, 0, 0, timeZone, now);
|
|
251
|
+
const to = zonedInstant(prevY, prevM, upperDay, 23, 59, 59, timeZone, now);
|
|
252
|
+
return { fromISO: from.toISOString(), toISO: to.toISOString() };
|
|
253
|
+
}
|
|
254
|
+
function customDateRange(fromYMD, toYMD, now, timeZone) {
|
|
255
|
+
const start = (ymd) => {
|
|
256
|
+
const [y, m, d] = ymd.split("-").map(Number);
|
|
257
|
+
return zonedInstant(y, m, d, 0, 0, 0, timeZone, now);
|
|
258
|
+
};
|
|
259
|
+
const end = (ymd) => {
|
|
260
|
+
const [y, m, d] = ymd.split("-").map(Number);
|
|
261
|
+
return zonedInstant(y, m, d, 23, 59, 59, timeZone, now);
|
|
262
|
+
};
|
|
263
|
+
let from = fromYMD ? start(fromYMD) : null;
|
|
264
|
+
let to = toYMD ? end(toYMD) : now;
|
|
265
|
+
if (from && to && from.getTime() > to.getTime()) {
|
|
266
|
+
[from, to] = [start(toYMD), end(fromYMD)];
|
|
267
|
+
}
|
|
268
|
+
return { fromISO: from ? from.toISOString() : null, toISO: to.toISOString() };
|
|
269
|
+
}
|
|
270
|
+
function computeDashboardStats(tickets, range) {
|
|
271
|
+
const from = range.fromISO ? Date.parse(range.fromISO) : -Infinity;
|
|
272
|
+
const to = Date.parse(range.toISO);
|
|
273
|
+
const inRange = tickets.filter((t) => {
|
|
274
|
+
const c = Date.parse(t.createdAt);
|
|
275
|
+
return c >= from && c <= to;
|
|
276
|
+
});
|
|
277
|
+
const collected = inRange.filter((t) => t.status === "PAID").reduce((s, t) => s + (t.payment?.amount ?? 0), 0);
|
|
278
|
+
return {
|
|
279
|
+
issued: inRange.length,
|
|
280
|
+
outstanding: inRange.filter((t) => t.status === "OUTSTANDING").length,
|
|
281
|
+
overdue: inRange.filter((t) => t.status === "OVERDUE").length,
|
|
282
|
+
paid: inRange.filter((t) => t.status === "PAID").length,
|
|
283
|
+
collected: round2(collected)
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ../ovr-core/src/ph-locations.ts
|
|
288
|
+
var PH_PROVINCES = [{ "province": "Abra", "cities": ["Bangued", "Boliney", "Bucay", "Bucloc", "Daguioman", "Danglas", "Dolores", "La Paz", "Lacub", "Lagangilang", "Lagayan", "Langiden", "Licuan-Baay (Licuan)", "Luba", "Malibcong", "Manabo", "Pe\xF1arrubia", "Pidigan", "Pilar", "Sallapadan", "San Isidro", "San Juan", "San Quintin", "Tayum", "Tineg", "Tubo", "Villaviciosa"] }, { "province": "Agusan Del Norte", "cities": ["Buenavista", "Butuan City", "Cabadbaran City", "Carmen", "Jabonga", "Kitcharao", "Las Nieves", "Magallanes", "Nasipit", "Remedios T. Romualdez", "Santiago", "Tubay"] }, { "province": "Agusan Del Sur", "cities": ["Bayugan City", "Bunawan", "Esperanza", "La Paz", "Loreto", "Prosperidad", "Rosario", "San Francisco", "San Luis", "Santa Josefa", "Sibagat", "Talacogon", "Trento", "Veruela"] }, { "province": "Aklan", "cities": ["Altavas", "Balete", "Banga", "Batan", "Buruanga", "Ibajay", "Kalibo", "Lezo", "Libacao", "Madalag", "Makato", "Malay", "Malinao", "Nabas", "New Washington", "Numancia", "Tangalan"] }, { "province": "Albay", "cities": ["Bacacay", "Camalig", "City Of Ligao", "Daraga (Locsin)", "Guinobatan", "Jovellar", "Legazpi City", "Libon", "Malilipot", "Malinao", "Manito", "Oas", "Pio Duran", "Polangui", "Rapu-Rapu", "Santo Domingo (Libog)", "Tabaco City", "Tiwi"] }, { "province": "Antique", "cities": ["Anini-Y", "Barbaza", "Belison", "Bugasong", "Caluya", "Culasi", "Hamtic", "Laua-An", "Libertad", "Pandan", "Patnongon", "San Jose", "San Remigio", "Sebaste", "Sibalom", "Tibiao", "Tobias Fornier (Dao)", "Valderrama"] }, { "province": "Apayao", "cities": ["Calanasan (Bayag)", "Conner", "Flora", "Kabugao", "Luna", "Pudtol", "Santa Marcela"] }, { "province": "Aurora", "cities": ["Baler", "Casiguran", "Dilasag", "Dinalungan", "Dingalan", "Dipaculao", "Maria Aurora", "San Luis"] }, { "province": "Basilan", "cities": ["Akbar", "Al-Barka", "Hadji Mohammad Ajul", "Hadji Muhtamad", "Isabela City", "Lamitan City", "Lantawan", "Maluso", "Sumisip", "Tabuan-Lasa", "Tipo-Tipo", "Tuburan", "Ungkaya Pukan"] }, { "province": "Bataan", "cities": ["Abucay", "Bagac", "Balanga City", "Dinalupihan", "Hermosa", "Limay", "Mariveles", "Morong", "Orani", "Orion", "Pilar", "Samal"] }, { "province": "Batanes", "cities": ["Basco", "Itbayat", "Ivana", "Mahatao", "Sabtang", "Uyugan"] }, { "province": "Batangas", "cities": ["Agoncillo", "Alitagtag", "Balayan", "Balete", "Batangas City", "Bauan", "Calaca", "Calatagan", "Cuenca", "Ibaan", "Laurel", "Lemery", "Lian", "Lipa City", "Lobo", "Mabini", "Malvar", "Mataas Na Kahoy", "Nasugbu", "Padre Garcia", "Rosario", "San Jose", "San Juan", "San Luis", "San Nicolas", "San Pascual", "Santa Teresita", "Santo Tomas", "Taal", "Talisay", "Tanauan City", "Taysan", "Tingloy", "Tuy"] }, { "province": "Benguet", "cities": ["Atok", "Baguio City", "Bakun", "Bokod", "Buguias", "Itogon", "Kabayan", "Kapangan", "Kibungan", "La Trinidad", "Mankayan", "Sablan", "Tuba", "Tublay"] }, { "province": "Biliran", "cities": ["Almeria", "Biliran", "Cabucgayan", "Caibiran", "Culaba", "Kawayan", "Maripipi", "Naval"] }, { "province": "Bohol", "cities": ["Alburquerque", "Alicia", "Anda", "Antequera", "Baclayon", "Balilihan", "Batuan", "Bien Unido", "Bilar", "Buenavista", "Calape", "Candijay", "Carmen", "Catigbian", "Clarin", "Corella", "Cortes", "Dagohoy", "Danao", "Dauis", "Dimiao", "Duero", "Garcia Hernandez", "Guindulman", "Inabanga", "Jagna", "Jetafe", "Lila", "Loay", "Loboc", "Loon", "Mabini", "Maribojoc", "Panglao", "Pilar", "Pres. Carlos P. Garcia (Pitogo)", "Sagbayan (Borja)", "San Isidro", "San Miguel", "Sevilla", "Sierra Bullones", "Sikatuna", "Tagbilaran City", "Talibon", "Trinidad", "Tubigon", "Ubay", "Valencia"] }, { "province": "Bukidnon", "cities": ["Baungon", "Cabanglasan", "City Of Malaybalay", "Damulog", "Dangcagan", "Don Carlos", "Impasug-Ong", "Kadingilan", "Kalilangan", "Kibawe", "Kitaotao", "Lantapan", "Libona", "Malitbog", "Manolo Fortich", "Maramag", "Pangantucan", "Quezon", "San Fernando", "Sumilao", "Talakag", "Valencia City"] }, { "province": "Bulacan", "cities": ["Angat", "Balagtas (Bigaa)", "Baliuag", "Bocaue", "Bulacan", "Bustos", "Calumpit", "Do\xF1a Remedios Trinidad", "Guiguinto", "Hagonoy", "Malolos City", "Marilao", "Meycauayan City", "Norzagaray", "Obando", "Pandi", "Paombong", "Plaridel", "Pulilan", "San Ildefonso", "San Jose Del Monte City", "San Miguel", "San Rafael", "Santa Maria"] }, { "province": "Cagayan", "cities": ["Abulug", "Alcala", "Allacapan", "Amulung", "Aparri", "Baggao", "Ballesteros", "Buguey", "Calayan", "Camalaniugan", "Claveria", "Enrile", "Gattaran", "Gonzaga", "Iguig", "Lal-Lo", "Lasam", "Pamplona", "Pe\xF1ablanca", "Piat", "Rizal", "Sanchez-Mira", "Santa Ana", "Santa Praxedes", "Santa Teresita", "Santo Ni\xF1o (Faire)", "Solana", "Tuao", "Tuguegarao City"] }, { "province": "Camarines Norte", "cities": ["Basud", "Capalonga", "Daet", "Jose Panganiban", "Labo", "Mercedes", "Paracale", "San Lorenzo Ruiz (Imelda)", "San Vicente", "Santa Elena", "Talisay", "Vinzons"] }, { "province": "Camarines Sur", "cities": ["Baao", "Balatan", "Bato", "Bombon", "Buhi", "Bula", "Cabusao", "Calabanga", "Camaligan", "Canaman", "Caramoan", "Del Gallego", "Gainza", "Garchitorena", "Goa", "Iriga City", "Lagonoy", "Libmanan", "Lupi", "Magarao", "Milaor", "Minalabac", "Nabua", "Naga City", "Ocampo", "Pamplona", "Pasacao", "Pili", "Presentacion (Parubcan)", "Ragay", "Sag\xF1ay", "San Fernando", "San Jose", "Sipocot", "Siruma", "Tigaon", "Tinambac"] }, { "province": "Camiguin", "cities": ["Catarman", "Guinsiliban", "Mahinog", "Mambajao", "Sagay"] }, { "province": "Capiz", "cities": ["Cuartero", "Dao", "Dumalag", "Dumarao", "Ivisan", "Jamindan", "Ma-Ayon", "Mambusao", "Panay", "Panitan", "Pilar", "Pontevedra", "President Roxas", "Roxas City", "Sapi-An", "Sigma", "Tapaz"] }, { "province": "Catanduanes", "cities": ["Bagamanoc", "Baras", "Bato", "Caramoran", "Gigmoto", "Pandan", "Panganiban (Payo)", "San Andres (Calolbon)", "San Miguel", "Viga", "Virac"] }, { "province": "Cavite", "cities": ["Alfonso", "Amadeo", "Bacoor City", "Carmona", "Cavite City", "Dasmari\xF1as City", "Gen. Mariano Alvarez", "General Emilio Aguinaldo", "General Trias City", "Imus City", "Indang", "Kawit", "Magallanes", "Maragondon", "Mendez (Mendez-Nu\xF1ez)", "Naic", "Noveleta", "Rosario", "Silang", "Tagaytay City", "Tanza", "Ternate", "Trece Martires City"] }, { "province": "Cebu", "cities": ["Alcantara", "Alcoy", "Alegria", "Aloguinsan", "Argao", "Asturias", "Badian", "Balamban", "Bantayan", "Barili", "Bogo City", "Boljoon", "Borbon", "Carcar City", "Carmen", "Catmon", "Cebu City", "Compostela", "Consolacion", "Cordoba", "Daanbantayan", "Dalaguete", "Danao City", "Dumanjug", "Ginatilan", "Lapu-Lapu City (Opon)", "Liloan", "Madridejos", "Malabuyoc", "Mandaue City", "Medellin", "Minglanilla", "Moalboal", "Naga City", "Oslob", "Pilar", "Pinamungahan", "Poro", "Ronda", "Samboan", "San Fernando", "San Francisco", "San Remigio", "Santa Fe", "Santander", "Sibonga", "Sogod", "Tabogon", "Tabuelan", "Talisay City", "Toledo City", "Tuburan", "Tudela"] }, { "province": "Compostela Valley", "cities": ["Compostela", "Laak (San Vicente)", "Mabini (Do\xF1a Alicia)", "Maco", "Maragusan (San Mariano)", "Mawab", "Monkayo", "Montevista", "Nabunturan", "New Bataan", "Pantukan"] }, { "province": "Cotabato (North Cot.)", "cities": ["Alamada", "Aleosan", "Antipas", "Arakan", "Banisilan", "Carmen", "City Of Kidapawan", "Kabacan", "Libungan", "M'Lang", "Magpet", "Makilala", "Matalam", "Midsayap", "Pigkawayan", "Pikit", "President Roxas", "Tulunan"] }, { "province": "Davao (Davao Del Norte)", "cities": ["Asuncion (Saug)", "Braulio E. Dujali", "Carmen", "City Of Tagum", "Island Garden City Of Samal", "Kapalong", "New Corella", "Panabo City", "San Isidro", "Santo Tomas", "Talaingod"] }, { "province": "Davao Del Sur", "cities": ["Bansalan", "Davao City", "Digos City", "Hagonoy", "Kiblawan", "Magsaysay", "Malalag", "Matanao", "Padada", "Santa Cruz", "Sulop"] }, { "province": "Davao Occidental", "cities": ["Don Marcelino", "Jose Abad Santos (Trinidad)", "Malita", "Santa Maria", "Sarangani"] }, { "province": "Davao Oriental", "cities": ["Baganga", "Banaybanay", "Boston", "Caraga", "Cateel", "Governor Generoso", "Lupon", "Manay", "Mati City", "San Isidro", "Tarragona"] }, { "province": "Dinagat Islands", "cities": ["Basilisa (Rizal)", "Cagdianao", "Dinagat", "Libjo (Albor)", "Loreto", "San Jose", "Tubajon"] }, { "province": "Eastern Samar", "cities": ["Arteche", "Balangiga", "Balangkayan", "Borongan City", "Can-Avid", "Dolores", "General Macarthur", "Giporlos", "Guiuan", "Hernani", "Jipapad", "Lawaan", "Llorente", "Maslog", "Maydolong", "Mercedes", "Oras", "Quinapondan", "Salcedo", "San Julian", "San Policarpo", "Sulat", "Taft"] }, { "province": "Guimaras", "cities": ["Buenavista", "Jordan", "Nueva Valencia", "San Lorenzo", "Sibunag"] }, { "province": "Ifugao", "cities": ["Aguinaldo", "Alfonso Lista (Potia)", "Asipulo", "Banaue", "Hingyon", "Hungduan", "Kiangan", "Lagawe", "Lamut", "Mayoyao", "Tinoc"] }, { "province": "Ilocos Norte", "cities": ["Adams", "Bacarra", "Badoc", "Bangui", "Banna (Espiritu)", "Batac City", "Burgos", "Carasi", "Currimao", "Dingras", "Dumalneg", "Laoag City", "Marcos", "Nueva Era", "Pagudpud", "Paoay", "Pasuquin", "Piddig", "Pinili", "San Nicolas", "Sarrat", "Solsona", "Vintar"] }, { "province": "Ilocos Sur", "cities": ["Alilem", "Banayoyo", "Bantay", "Burgos", "Cabugao", "Candon City", "Caoayan", "Cervantes", "Galimuyod", "Gregorio Del Pilar (Concepcion)", "Lidlidda", "Magsingal", "Nagbukel", "Narvacan", "Quirino (Angkaki)", "Salcedo (Baugen)", "San Emilio", "San Esteban", "San Ildefonso", "San Juan (Lapog)", "San Vicente", "Santa", "Santa Catalina", "Santa Cruz", "Santa Lucia", "Santa Maria", "Santiago", "Santo Domingo", "Sigay", "Sinait", "Sugpon", "Suyo", "Tagudin", "Vigan City"] }, { "province": "Iloilo", "cities": ["Ajuy", "Alimodian", "Anilao", "Badiangan", "Balasan", "Banate", "Barotac Nuevo", "Barotac Viejo", "Batad", "Bingawan", "Cabatuan", "Calinog", "Carles", "City Of Passi", "Concepcion", "Dingle", "Due\xF1as", "Dumangas", "Estancia", "Guimbal", "Igbaras", "Iloilo City", "Janiuay", "Lambunao", "Leganes", "Lemery", "Leon", "Maasin", "Miagao", "Mina", "New Lucena", "Oton", "Pavia", "Pototan", "San Dionisio", "San Enrique", "San Joaquin", "San Miguel", "San Rafael", "Santa Barbara", "Sara", "Tigbauan", "Tubungan", "Zarraga"] }, { "province": "Isabela", "cities": ["Alicia", "Angadanan", "Aurora", "Benito Soliven", "Burgos", "Cabagan", "Cabatuan", "Cauayan City", "City Of Santiago", "Cordon", "Delfin Albano (Magsaysay)", "Dinapigue", "Divilacan", "Echague", "Gamu", "Ilagan City", "Jones", "Luna", "Maconacon", "Mallig", "Naguilian", "Palanan", "Quezon", "Quirino", "Ramon", "Reina Mercedes", "Roxas", "San Agustin", "San Guillermo", "San Isidro", "San Manuel", "San Mariano", "San Mateo", "San Pablo", "Santa Maria", "Santo Tomas", "Tumauini"] }, { "province": "Kalinga", "cities": ["Balbalan", "Lubuagan", "Pasil", "Pinukpuk", "Rizal (Liwan)", "Tabuk City", "Tanudan", "Tinglayan"] }, { "province": "La Union", "cities": ["Agoo", "Aringay", "Bacnotan", "Bagulin", "Balaoan", "Bangar", "Bauang", "Burgos", "Caba", "City Of San Fernando", "Luna", "Naguilian", "Pugo", "Rosario", "San Gabriel", "San Juan", "Santo Tomas", "Santol", "Sudipen", "Tubao"] }, { "province": "Laguna", "cities": ["Alaminos", "Bay", "Cabuyao City", "Calamba City", "Calauan", "Cavinti", "City Of Bi\xF1an", "Famy", "Kalayaan", "Liliw", "Los Ba\xF1os", "Luisiana", "Lumban", "Mabitac", "Magdalena", "Majayjay", "Nagcarlan", "Paete", "Pagsanjan", "Pakil", "Pangil", "Pila", "Rizal", "San Pablo City", "San Pedro City", "Santa Cruz", "Santa Maria", "Santa Rosa City", "Siniloan", "Victoria"] }, { "province": "Lanao Del Norte", "cities": ["Bacolod", "Baloi", "Baroy", "Iligan City", "Kapatagan", "Kauswagan", "Kolambugan", "Lala", "Linamon", "Magsaysay", "Maigo", "Matungao", "Munai", "Nunungan", "Pantao Ragat", "Pantar", "Poona Piagapo", "Salvador", "Sapad", "Sultan Naga Dimaporo (Karomatan)", "Tagoloan", "Tangcal", "Tubod"] }, { "province": "Lanao Del Sur", "cities": ["Amai Manabilang (Bumbaran)", "Bacolod-Kalawi (Bacolod Grande)", "Balabagan", "Balindong (Watu)", "Bayang", "Binidayan", "Buadiposo-Buntong", "Bubong", "Butig", "Calanogas", "Ditsaan-Ramain", "Ganassi", "Kapai", "Kapatagan", "Lumba-Bayabao (Maguing)", "Lumbaca-Unayan", "Lumbatan", "Lumbayanague", "Madalum", "Madamba", "Maguing", "Malabang", "Marantao", "Marawi City", "Marogong", "Masiu", "Mulondo", "Pagayawan (Tatarikan)", "Piagapo", "Picong (Sultan Gumander)", "Poona Bayabao (Gata)", "Pualas", "Saguiaran", "Sultan Dumalondong", "Tagoloan", "Tamparan", "Taraka", "Tubaran", "Tugaya", "Wao"] }, { "province": "Leyte", "cities": ["Abuyog", "Alangalang", "Albuera", "Babatngon", "Barugo", "Bato", "Baybay City", "Burauen", "Calubian", "Capoocan", "Carigara", "Dagami", "Dulag", "Hilongos", "Hindang", "Inopacan", "Isabel", "Jaro", "Javier (Bugho)", "Julita", "Kananga", "La Paz", "Leyte", "Macarthur", "Mahaplag", "Matag-Ob", "Matalom", "Mayorga", "Merida", "Ormoc City", "Palo", "Palompon", "Pastrana", "San Isidro", "San Miguel", "Santa Fe", "Tabango", "Tabontabon", "Tacloban City", "Tanauan", "Tolosa", "Tunga", "Villaba"] }, { "province": "Maguindanao", "cities": ["Ampatuan", "Barira", "Buldon", "Buluan", "Cotabato City", "Datu Abdullah Sangki", "Datu Anggal Midtimbang", "Datu Blah T. Sinsuat", "Datu Hoffer Ampatuan", "Datu Odin Sinsuat (Dinaig)", "Datu Paglas", "Datu Piang", "Datu Salibo", "Datu Saudi Ampatuan", "Datu Unsay", "Gen. S. K. Pendatun", "Guindulungan", "Kabuntalan (Tumbao)", "Mamasapano", "Mangudadatu", "Matanog", "Northern Kabuntalan", "Pagagawan", "Pagalungan", "Paglat", "Pandag", "Parang", "Rajah Buayan", "Shariff Aguak (Maganoy)", "Shariff Saydona Mustapha", "South Upi", "Sultan Kudarat (Nuling)", "Sultan Mastura", "Sultan Sa Barongis (Lambayong)", "Talayan", "Talitay", "Upi"] }, { "province": "Marinduque", "cities": ["Boac", "Buenavista", "Gasan", "Mogpog", "Santa Cruz", "Torrijos"] }, { "province": "Masbate", "cities": ["Aroroy", "Baleno", "Balud", "Batuan", "Cataingan", "Cawayan", "Claveria", "Dimasalang", "Esperanza", "Mandaon", "Masbate City", "Milagros", "Mobo", "Monreal", "Palanas", "Pio V. Corpuz (Limbuhan)", "Placer", "San Fernando", "San Jacinto", "San Pascual", "Uson"] }, { "province": "Metro Manila", "cities": ["Binondo", "Caloocan City", "City Of Las Pi\xF1as", "City Of Makati", "City Of Mandaluyong", "City Of Marikina", "City Of Muntinlupa", "City Of Para\xF1aque", "City Of Pasig", "City Of Valenzuela", "Ermita", "Intramuros", "Malabon City", "Malate", "Navotas City", "Paco", "Pandacan", "Pasay City", "Pateros", "Port Area", "Quezon City", "Quiapo", "Sampaloc", "San Juan City", "San Miguel", "San Nicolas", "Santa Ana", "Santa Cruz", "Taguig", "Tondo"] }, { "province": "Misamis Occidental", "cities": ["Aloran", "Baliangao", "Bonifacio", "Calamba", "Clarin", "Concepcion", "Don Victoriano Chiongbian (Don Mariano Marcos)", "Jimenez", "Lopez Jaena", "Oroquieta City", "Ozamis City", "Panaon", "Plaridel", "Sapang Dalaga", "Sinacaban", "Tangub City", "Tudela"] }, { "province": "Misamis Oriental", "cities": ["Alubijid", "Balingasag", "Balingoan", "Binuangan", "Cagayan De Oro City", "Claveria", "El Salvador City", "Gingoog City", "Gitagum", "Initao", "Jasaan", "Kinoguitan", "Lagonglong", "Laguindingan", "Libertad", "Lugait", "Magsaysay (Linugos)", "Manticao", "Medina", "Naawan", "Opol", "Salay", "Sugbongcogon", "Tagoloan", "Talisayan", "Villanueva"] }, { "province": "Mountain Province", "cities": ["Barlig", "Bauko", "Besao", "Bontoc", "Natonin", "Paracelis", "Sabangan", "Sadanga", "Sagada", "Tadian"] }, { "province": "Negros Occidental", "cities": ["Bacolod City", "Bago City", "Binalbagan", "Cadiz City", "Calatrava", "Candoni", "Cauayan", "Enrique B. Magalona (Saravia)", "Escalante City", "Himamaylan City", "Hinigaran", "Hinoba-An (Asia)", "Ilog", "Isabela", "Kabankalan City", "La Carlota City", "La Castellana", "Manapla", "Moises Padilla (Magallon)", "Murcia", "Pontevedra", "Pulupandan", "Sagay City", "Salvador Benedicto", "San Carlos City", "San Enrique", "Silay City", "Sipalay City", "Talisay City", "Toboso", "Valladolid", "Victorias City"] }, { "province": "Negros Oriental", "cities": ["Amlan (Ayuquitan)", "Ayungon", "Bacong", "Bais City", "Basay", "Bayawan City (Tulong)", "Bindoy (Payabon)", "Canlaon City", "Dauin", "Dumaguete City", "Guihulngan City", "Jimalalud", "La Libertad", "Mabinay", "Manjuyod", "Pamplona", "San Jose", "Santa Catalina", "Siaton", "Sibulan", "Tanjay City", "Tayasan", "Valencia (Luzurriaga)", "Vallehermoso", "Zamboanguita"] }, { "province": "Northern Samar", "cities": ["Allen", "Biri", "Bobon", "Capul", "Catarman", "Catubig", "Gamay", "Laoang", "Lapinig", "Las Navas", "Lavezares", "Lope De Vega", "Mapanas", "Mondragon", "Palapag", "Pambujan", "Rosario", "San Antonio", "San Isidro", "San Jose", "San Roque", "San Vicente", "Silvino Lobos", "Victoria"] }, { "province": "Nueva Ecija", "cities": ["Aliaga", "Bongabon", "Cabanatuan City", "Cabiao", "Carranglan", "Cuyapo", "Gabaldon (Bitulok And Sabani)", "Gapan City", "General Mamerto Natividad", "General Tinio (Papaya)", "Guimba", "Jaen", "Laur", "Licab", "Llanera", "Lupao", "Nampicuan", "Palayan City", "Pantabangan", "Pe\xF1aranda", "Quezon", "Rizal", "San Antonio", "San Isidro", "San Jose City", "San Leonardo", "Santa Rosa", "Santo Domingo", "Science City Of Mu\xF1oz", "Talavera", "Talugtug", "Zaragoza"] }, { "province": "Nueva Vizcaya", "cities": ["Alfonso Castaneda", "Ambaguio", "Aritao", "Bagabag", "Bambang", "Bayombong", "Diadi", "Dupax Del Norte", "Dupax Del Sur", "Kasibu", "Kayapa", "Quezon", "Santa Fe", "Solano", "Villaverde"] }, { "province": "Occidental Mindoro", "cities": ["Abra De Ilog", "Calintaan", "Looc", "Lubang", "Magsaysay", "Mamburao", "Paluan", "Rizal", "Sablayan", "San Jose", "Santa Cruz"] }, { "province": "Oriental Mindoro", "cities": ["Baco", "Bansud", "Bongabong", "Bulalacao (San Pedro)", "City Of Calapan", "Gloria", "Mansalay", "Naujan", "Pinamalayan", "Pola", "Puerto Galera", "Roxas", "San Teodoro", "Socorro", "Victoria"] }, { "province": "Palawan", "cities": ["Aborlan", "Agutaya", "Araceli", "Balabac", "Bataraza", "Brooke'S Point", "Busuanga", "Cagayancillo", "Coron", "Culion", "Cuyo", "Dumaran", "El Nido (Bacuit)", "Kalayaan", "Linapacan", "Magsaysay", "Narra", "Puerto Princesa City", "Quezon", "Rizal (Marcos)", "Roxas", "San Vicente", "Sofronio Espa\xF1ola", "Taytay"] }, { "province": "Pampanga", "cities": ["Angeles City", "Apalit", "Arayat", "Bacolor", "Candaba", "Floridablanca", "Guagua", "Lubao", "Mabalacat City", "Macabebe", "Magalang", "Masantol", "Mexico", "Minalin", "Porac", "San Fernando City", "San Luis", "San Simon", "Santa Ana", "Santa Rita", "Santo Tomas", "Sasmuan (Sexmoan)"] }, { "province": "Pangasinan", "cities": ["Agno", "Aguilar", "Alaminos City", "Alcala", "Anda", "Asingan", "Balungao", "Bani", "Basista", "Bautista", "Bayambang", "Binalonan", "Binmaley", "Bolinao", "Bugallon", "Burgos", "Calasiao", "Dagupan City", "Dasol", "Infanta", "Labrador", "Laoac", "Lingayen", "Mabini", "Malasiqui", "Manaoag", "Mangaldan", "Mangatarem", "Mapandan", "Natividad", "Pozorrubio", "Rosales", "San Carlos City", "San Fabian", "San Jacinto", "San Manuel", "San Nicolas", "San Quintin", "Santa Barbara", "Santa Maria", "Santo Tomas", "Sison", "Sual", "Tayug", "Umingan", "Urbiztondo", "Urdaneta City", "Villasis"] }, { "province": "Quezon", "cities": ["Agdangan", "Alabat", "Atimonan", "Buenavista", "Burdeos", "Calauag", "Candelaria", "Catanauan", "Dolores", "General Luna", "General Nakar", "Guinayangan", "Gumaca", "Infanta", "Jomalig", "Lopez", "Lucban", "Lucena City", "Macalelon", "Mauban", "Mulanay", "Padre Burgos", "Pagbilao", "Panukulan", "Patnanungan", "Perez", "Pitogo", "Plaridel", "Polillo", "Quezon", "Real", "Sampaloc", "San Andres", "San Antonio", "San Francisco (Aurora)", "San Narciso", "Sariaya", "Tagkawayan", "Tayabas City", "Tiaong", "Unisan"] }, { "province": "Quirino", "cities": ["Aglipay", "Cabarroguis", "Diffun", "Maddela", "Nagtipunan", "Saguday"] }, { "province": "Rizal", "cities": ["Angono", "Baras", "Binangonan", "Cainta", "Cardona", "City Of Antipolo", "Jala-Jala", "Morong", "Pililla", "Rodriguez (Montalban)", "San Mateo", "Tanay", "Taytay", "Teresa"] }, { "province": "Romblon", "cities": ["Alcantara", "Banton", "Cajidiocan", "Calatrava", "Concepcion", "Corcuera", "Ferrol", "Looc", "Magdiwang", "Odiongan", "Romblon", "San Agustin", "San Andres", "San Fernando", "San Jose", "Santa Fe", "Santa Maria (Imelda)"] }, { "province": "Samar (Western Samar)", "cities": ["Almagro", "Basey", "Calbayog City", "Calbiga", "Catbalogan City", "Daram", "Gandara", "Hinabangan", "Jiabong", "Marabut", "Matuguinao", "Motiong", "Pagsanghan", "Paranas (Wright)", "Pinabacdao", "San Jorge", "San Jose De Buan", "San Sebastian", "Santa Margarita", "Santa Rita", "Santo Ni\xF1o", "Tagapul-An", "Talalora", "Tarangnan", "Villareal", "Zumarraga"] }, { "province": "Sarangani", "cities": ["Alabel", "Glan", "Kiamba", "Maasim", "Maitum", "Malapatan", "Malungon"] }, { "province": "Siquijor", "cities": ["Enrique Villanueva", "Larena", "Lazi", "Maria", "San Juan", "Siquijor"] }, { "province": "Sorsogon", "cities": ["Barcelona", "Bulan", "Bulusan", "Casiguran", "Castilla", "Donsol", "Gubat", "Irosin", "Juban", "Magallanes", "Matnog", "Pilar", "Prieto Diaz", "Santa Magdalena", "Sorsogon City"] }, { "province": "South Cotabato", "cities": ["Banga", "General Santos City (Dadiangas)", "Koronadal City", "Lake Sebu", "Norala", "Polomolok", "Santo Ni\xF1o", "Surallah", "T`Boli", "Tampakan", "Tantangan", "Tupi"] }, { "province": "Southern Leyte", "cities": ["Anahawan", "Bontoc", "Hinunangan", "Hinundayan", "Libagon", "Liloan", "Limasawa", "Maasin City", "Macrohon", "Malitbog", "Padre Burgos", "Pintuyan", "Saint Bernard", "San Francisco", "San Juan (Cabalian)", "San Ricardo", "Silago", "Sogod", "Tomas Oppus"] }, { "province": "Sultan Kudarat", "cities": ["Bagumbayan", "Columbio", "Esperanza", "Isulan", "Kalamansig", "Lambayong (Mariano Marcos)", "Lebak", "Lutayan", "Palimbang", "President Quirino", "Sen. Ninoy Aquino", "Tacurong City"] }, { "province": "Sulu", "cities": ["Hadji Panglima Tahil (Marunggas)", "Indanan", "Jolo", "Kalingalan Caluang", "Lugus", "Luuk", "Maimbung", "Old Panamao", "Omar", "Pandami", "Panglima Estino (New Panamao)", "Pangutaran", "Parang", "Pata", "Patikul", "Siasi", "Talipao", "Tapul", "Tongkil"] }, { "province": "Surigao Del Norte", "cities": ["Alegria", "Bacuag", "Burgos", "Claver", "Dapa", "Del Carmen", "General Luna", "Gigaquit", "Mainit", "Malimono", "Pilar", "Placer", "San Benito", "San Francisco (Anao-Aon)", "San Isidro", "Santa Monica (Sapao)", "Sison", "Socorro", "Surigao City", "Tagana-An", "Tubod"] }, { "province": "Surigao Del Sur", "cities": ["Barobo", "Bayabas", "Bislig City", "Cagwait", "Cantilan", "Carmen", "Carrascal", "Cortes", "Hinatuan", "Lanuza", "Lianga", "Lingig", "Madrid", "Marihatag", "San Agustin", "San Miguel", "Tagbina", "Tago", "Tandag City"] }, { "province": "Tarlac", "cities": ["Anao", "Bamban", "Camiling", "Capas", "City Of Tarlac", "Concepcion", "Gerona", "La Paz", "Mayantoc", "Moncada", "Paniqui", "Pura", "Ramos", "San Clemente", "San Jose", "San Manuel", "Santa Ignacia", "Victoria"] }, { "province": "Tawi-Tawi", "cities": ["Bongao", "Languyan", "Mapun (Cagayan De Tawi-Tawi)", "Panglima Sugala (Balimbing)", "Sapa-Sapa", "Sibutu", "Simunul", "Sitangkai", "South Ubian", "Tandubas", "Turtle Islands"] }, { "province": "Zambales", "cities": ["Botolan", "Cabangan", "Candelaria", "Castillejos", "Iba", "Masinloc", "Olongapo City", "Palauig", "San Antonio", "San Felipe", "San Marcelino", "San Narciso", "Santa Cruz", "Subic"] }, { "province": "Zamboanga Del Norte", "cities": ["Bacungan (Leon T. Postigo)", "Baliguian", "Dapitan City", "Dipolog City", "Godod", "Gutalac", "Jose Dalman (Ponot)", "Kalawit", "Katipunan", "La Libertad", "Labason", "Liloy", "Manukan", "Mutia", "Pi\xF1an (New Pi\xF1an)", "Polanco", "Pres. Manuel A. Roxas", "Rizal", "Salug", "Sergio Osme\xF1a Sr.", "Siayan", "Sibuco", "Sibutad", "Sindangan", "Siocon", "Sirawai", "Tampilisan"] }, { "province": "Zamboanga Del Sur", "cities": ["Aurora", "Bayog", "Dimataling", "Dinas", "Dumalinao", "Dumingag", "Guipos", "Josefina", "Kumalarang", "Labangan", "Lakewood", "Lapuyan", "Mahayag", "Margosatubig", "Midsalip", "Molave", "Pagadian City", "Pitogo", "Ramon Magsaysay (Liargo)", "San Miguel", "San Pablo", "Sominot (Don Mariano Marcos)", "Tabina", "Tambulig", "Tigbao", "Tukuran", "Vincenzo A. Sagun", "Zamboanga City"] }, { "province": "Zamboanga Sibugay", "cities": ["Alicia", "Buug", "Diplahan", "Imelda", "Ipil", "Kabasalan", "Mabuhay", "Malangas", "Naga", "Olutanga", "Payao", "Roseller Lim", "Siay", "Talusan", "Titay", "Tungawan"] }];
|
|
289
|
+
function listProvinces() {
|
|
290
|
+
return PH_PROVINCES.map((p) => p.province);
|
|
291
|
+
}
|
|
292
|
+
function citiesOfProvince(province) {
|
|
293
|
+
if (!province) return [];
|
|
294
|
+
const key = province.trim().toLowerCase();
|
|
295
|
+
return PH_PROVINCES.find((p) => p.province.toLowerCase() === key)?.cities ?? [];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export { DASHBOARD_PRESETS, PH_PROVINCES, PREVIEW_PLACEHOLDER, addDays, citiesOfProvince, computeCharges, computeDashboardStats, createFormatters, customDateRange, dashboardDateRange, enrich, formalName, formatAddress, fullName, listProvinces, localToManilaISO, makeBillNo, makeOrderOfPaymentNo, makeOvrTicketNo, makePaymentRef, round2, startedMonthsSince, toPreviewTicket };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Separator } from './chunk-NSCIBSCW.js';
|
|
2
|
-
import { Money } from './chunk-
|
|
3
|
-
import { useFormatters, useOvrConfig } from './chunk-
|
|
2
|
+
import { Money } from './chunk-BVI5XDDA.js';
|
|
3
|
+
import { useFormatters, useOvrConfig } from './chunk-TJSNVTVB.js';
|
|
4
4
|
import { cn } from './chunk-77QBZC7J.js';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
6
|
|