@teincfood/core 0.7.8 → 0.8.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/README.md +26 -21
- package/dist/adapters/auth.d.ts +10 -0
- package/dist/adapters/auth.js +43 -0
- package/dist/adapters/devices.d.ts +3 -1
- package/dist/adapters/devices.js +187 -3
- package/dist/adapters/filesystem.d.ts +4 -0
- package/dist/adapters/kv.d.ts +10 -0
- package/dist/adapters/kv.js +23 -7
- package/dist/adapters/local-node.d.ts +4 -6
- package/dist/adapters/local-node.js +9 -32
- package/dist/adapters/notify.d.ts +12 -0
- package/dist/adapters/notify.js +33 -0
- package/dist/adapters/query-keys.d.ts +4 -0
- package/dist/adapters/query-keys.js +4 -0
- package/dist/adapters/services.d.ts +99 -15
- package/dist/adapters/services.js +244 -4
- package/dist/auth/session.d.ts +66 -0
- package/dist/auth/session.js +172 -0
- package/dist/catalog/hooks.d.ts +10 -0
- package/dist/catalog/hooks.js +82 -11
- package/dist/db/migrations.js +274 -0
- package/dist/db/operations.d.ts +53 -2
- package/dist/db/operations.js +177 -8
- package/dist/domain/business/index.d.ts +5 -0
- package/dist/domain/business/index.js +5 -0
- package/dist/domain/orders/lifecycle.d.ts +6 -0
- package/dist/domain/orders/lifecycle.js +6 -0
- package/dist/domain/orders/service.d.ts +24 -0
- package/dist/domain/orders/service.js +242 -0
- package/dist/domain/payments/index.d.ts +6 -0
- package/dist/domain/payments/index.js +5 -0
- package/dist/domain/reference/index.d.ts +8 -0
- package/dist/domain/reference/index.js +8 -0
- package/dist/e2e/harness.d.ts +1 -0
- package/dist/e2e/harness.js +61 -0
- package/dist/hooks/analytics.hooks.d.ts +25 -0
- package/dist/hooks/analytics.hooks.js +214 -0
- package/dist/hooks/business-hours.hooks.d.ts +8 -0
- package/dist/hooks/business-hours.hooks.js +45 -0
- package/dist/hooks/dashboard.hooks.d.ts +30 -0
- package/dist/hooks/dashboard.hooks.js +132 -0
- package/dist/hooks/delivery.hooks.d.ts +225 -0
- package/dist/hooks/delivery.hooks.js +80 -0
- package/dist/hooks/fleet.hooks.d.ts +37 -0
- package/dist/hooks/fleet.hooks.js +229 -0
- package/dist/hooks/image.hooks.d.ts +20 -0
- package/dist/hooks/image.hooks.js +62 -0
- package/dist/hooks/kiosk.hooks.d.ts +22 -5
- package/dist/hooks/kiosk.hooks.js +74 -5
- package/dist/hooks/members.hooks.d.ts +48 -0
- package/dist/hooks/members.hooks.js +302 -0
- package/dist/hooks/offline-orders.hooks.d.ts +9 -0
- package/dist/hooks/offline-orders.hooks.js +51 -0
- package/dist/hooks/orders.hooks.d.ts +19 -39
- package/dist/hooks/orders.hooks.js +126 -321
- package/dist/hooks/places.hooks.d.ts +21 -0
- package/dist/hooks/places.hooks.js +112 -0
- package/dist/hooks/realtime-stubs.d.ts +28 -0
- package/dist/hooks/realtime-stubs.js +85 -0
- package/dist/hooks/rider.hooks.d.ts +470 -0
- package/dist/hooks/rider.hooks.js +373 -0
- package/dist/hooks/use-infinite-list.d.ts +243 -0
- package/dist/hooks/use-infinite-list.js +58 -0
- package/dist/hooks/wallet.hooks.d.ts +219 -0
- package/dist/hooks/wallet.hooks.js +56 -0
- package/dist/image-cache/service.d.ts +8 -0
- package/dist/image-cache/service.js +15 -3
- package/dist/index.d.ts +60 -5
- package/dist/index.js +78 -5
- package/dist/local-node/adapters.d.ts +87 -0
- package/dist/local-node/adapters.js +4 -0
- package/dist/local-node/index.d.ts +5 -0
- package/dist/local-node/index.js +5 -0
- package/dist/local-node/security.d.ts +25 -0
- package/dist/local-node/security.js +149 -0
- package/dist/local-node/service.d.ts +83 -0
- package/dist/local-node/service.js +706 -0
- package/dist/local-node/store.d.ts +50 -0
- package/dist/local-node/store.js +284 -0
- package/dist/local-node/types.d.ts +92 -0
- package/dist/local-node/types.js +4 -0
- package/dist/printer/receipt.d.ts +4 -0
- package/dist/printer/receipt.js +75 -0
- package/dist/printer/service.js +1 -1
- package/dist/providers/query-client.d.ts +13 -0
- package/dist/providers/query-client.js +58 -0
- package/dist/realtime/events.service.d.ts +18 -0
- package/dist/realtime/events.service.js +76 -0
- package/dist/realtime/order-events.service.d.ts +6 -0
- package/dist/realtime/order-events.service.js +17 -0
- package/dist/realtime/phoenix-socket.d.ts +55 -0
- package/dist/realtime/phoenix-socket.js +269 -0
- package/dist/realtime/useEventsConnection.d.ts +1 -0
- package/dist/realtime/useEventsConnection.js +50 -0
- package/dist/reference/api.d.ts +2 -0
- package/dist/reference/api.js +2 -0
- package/dist/reference/capabilities.d.ts +12 -7
- package/dist/reference/capabilities.js +28 -13
- package/dist/reference/hooks.d.ts +34 -0
- package/dist/reference/hooks.js +124 -0
- package/dist/reference/menu-apply.d.ts +29 -0
- package/dist/reference/menu-apply.js +289 -0
- package/dist/reference/menu-record.d.ts +69 -0
- package/dist/reference/menu-record.js +163 -0
- package/dist/reference/operations.d.ts +3 -0
- package/dist/reference/operations.js +35 -1
- package/dist/reference/service.js +36 -9
- package/dist/reference/types.d.ts +1 -1
- package/dist/repositories/order.repository.d.ts +8 -0
- package/dist/repositories/order.repository.js +24 -2
- package/dist/repositories/pos.repository.d.ts +4 -0
- package/dist/repositories/pos.repository.js +4 -0
- package/dist/sync/backoff.d.ts +21 -0
- package/dist/sync/backoff.js +42 -0
- package/dist/sync/command-builder.js +10 -2
- package/dist/sync/command-queue.service.d.ts +12 -0
- package/dist/sync/command-queue.service.js +115 -18
- package/dist/sync/device-lease.service.d.ts +3 -3
- package/dist/sync/device-lease.service.js +80 -20
- package/dist/sync/engine.d.ts +3 -1
- package/dist/sync/engine.js +44 -4
- package/dist/sync/full-sync.d.ts +6 -0
- package/dist/sync/full-sync.js +72 -0
- package/dist/sync/health-probe.d.ts +24 -0
- package/dist/sync/health-probe.js +138 -0
- package/dist/sync/offline-capable.js +25 -0
- package/dist/sync/online-gates.d.ts +17 -0
- package/dist/sync/online-gates.js +55 -0
- package/dist/sync/order-number.d.ts +4 -4
- package/dist/sync/order-number.js +33 -13
- package/dist/sync/order-snapshots.service.d.ts +1 -0
- package/dist/sync/order-snapshots.service.js +47 -2
- package/dist/sync/pending-orders.service.d.ts +18 -0
- package/dist/sync/pending-orders.service.js +148 -3
- package/dist/sync/reconciliation/index.d.ts +5 -0
- package/dist/sync/reconciliation/index.js +5 -0
- package/dist/sync/snapshots/entity.d.ts +6 -0
- package/dist/sync/snapshots/entity.js +6 -0
- package/dist/sync/sync-jobs.service.d.ts +18 -0
- package/dist/sync/sync-jobs.service.js +539 -0
- package/dist/sync/transition-endpoints.d.ts +11 -0
- package/dist/sync/transition-endpoints.js +30 -0
- package/dist/sync/transport-local-node.js +3 -2
- package/dist/sync/transport-rest.d.ts +7 -0
- package/dist/sync/transport-rest.js +90 -25
- package/dist/sync/use-sync-reconciliation.js +58 -16
- package/dist/test-helpers/memory-driver.js +182 -4
- package/dist/test-helpers/seed-hours.d.ts +1 -0
- package/dist/test-helpers/seed-hours.js +23 -0
- package/dist/types/api/business.api.d.ts +42 -0
- package/dist/types/api/menu.api.d.ts +15 -0
- package/dist/types/api/seller.api.d.ts +20 -0
- package/dist/types/places.d.ts +19 -0
- package/dist/types/places.js +2 -0
- package/dist/types/rider.d.ts +67 -0
- package/dist/types/rider.js +2 -0
- package/dist/utils/attempt-stats.d.ts +23 -0
- package/dist/utils/attempt-stats.js +61 -0
- package/dist/utils/business-hours.d.ts +37 -0
- package/dist/utils/business-hours.js +96 -0
- package/dist/utils/debug-log.d.ts +23 -0
- package/dist/utils/debug-log.js +153 -0
- package/dist/utils/order-filter.d.ts +1 -1
- package/dist/utils/order-filter.js +1 -1
- package/dist/utils/order-transitions.d.ts +30 -0
- package/dist/utils/order-transitions.js +185 -0
- package/dist/utils/sync-logger.js +5 -4
- package/dist/validation/offline.d.ts +46 -0
- package/dist/validation/offline.js +79 -0
- package/package.json +6 -1
- package/dist/pricing/engine.test.d.ts +0 -1
- package/dist/pricing/engine.test.js +0 -142
- package/dist/reference/lww.test.d.ts +0 -1
- package/dist/reference/lww.test.js +0 -23
- package/dist/reference/operations.test.d.ts +0 -1
- package/dist/reference/operations.test.js +0 -66
- package/dist/standalone.integration.test.d.ts +0 -1
- package/dist/standalone.integration.test.js +0 -235
- package/dist/sync/device-lease.test.d.ts +0 -1
- package/dist/sync/device-lease.test.js +0 -38
- package/dist/sync/offline-integration.test.d.ts +0 -1
- package/dist/sync/offline-integration.test.js +0 -52
- package/dist/sync/order-number.test.d.ts +0 -1
- package/dist/sync/order-number.test.js +0 -51
- package/dist/sync/perms.test.d.ts +0 -1
- package/dist/sync/perms.test.js +0 -15
- package/dist/utils/currency.test.d.ts +0 -1
- package/dist/utils/currency.test.js +0 -17
- package/dist/utils/hlc.test.d.ts +0 -1
- package/dist/utils/hlc.test.js +0 -29
- package/dist/utils/phone.test.d.ts +0 -1
- package/dist/utils/phone.test.js +0 -19
- package/dist/utils/responsive.d.ts +0 -13
- package/dist/utils/responsive.js +0 -18
- package/dist/utils/uuid.test.d.ts +0 -1
- package/dist/utils/uuid.test.js +0 -13
- package/dist/utils/validation.test.d.ts +0 -1
- package/dist/utils/validation.test.js +0 -23
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seller analytics hooks — single source for both apps.
|
|
3
|
+
* Offline-first: local SQLite aggregates serve instantly; the network
|
|
4
|
+
* refreshes silently when online.
|
|
5
|
+
*/
|
|
6
|
+
import { useQuery } from "@tanstack/react-query";
|
|
7
|
+
import { useSyncExternalStore } from "react";
|
|
8
|
+
import { getActiveBusiness, subscribeBusiness } from "../adapters/business";
|
|
9
|
+
import { analyticsService } from "../adapters/services";
|
|
10
|
+
import { listLocalOrders } from "../domain/orders/service";
|
|
11
|
+
import { useIsEffectivelyOnline } from "./use-infinite-list";
|
|
12
|
+
export const SELLER_ANALYTICS_KEYS = {
|
|
13
|
+
all: ["seller-analytics"],
|
|
14
|
+
analytics: (businessId, period) => [...SELLER_ANALYTICS_KEYS.all, businessId, period],
|
|
15
|
+
};
|
|
16
|
+
export const REVENUE_KEYS = {
|
|
17
|
+
all: ["revenue-summary"],
|
|
18
|
+
summary: (businessId, period) => [...REVENUE_KEYS.all, businessId, period],
|
|
19
|
+
};
|
|
20
|
+
function useBusinessId() {
|
|
21
|
+
const id = useSyncExternalStore(subscribeBusiness, () => getActiveBusiness()?.id ?? null, () => null);
|
|
22
|
+
return id ?? undefined;
|
|
23
|
+
}
|
|
24
|
+
const OFFLINE_FIRST = { retry: false, networkMode: "offlineFirst" };
|
|
25
|
+
/**
|
|
26
|
+
* Backend-shaped aggregates computed from local SQLite rows (offline).
|
|
27
|
+
* Field names mirror orders.ex get_seller_analytics / get_revenue_summary
|
|
28
|
+
* exactly so screens render identically online and offline.
|
|
29
|
+
*/
|
|
30
|
+
function filterByPeriod(orders, period) {
|
|
31
|
+
const now = new Date();
|
|
32
|
+
const todayStr = now.toISOString().slice(0, 10);
|
|
33
|
+
if (period === "today") {
|
|
34
|
+
return orders.filter((o) => (o.inserted_at ?? "").slice(0, 10) === todayStr);
|
|
35
|
+
}
|
|
36
|
+
if (period === "this_week") {
|
|
37
|
+
const startOfWeek = new Date(now);
|
|
38
|
+
startOfWeek.setDate(now.getDate() - now.getDay()); // Sunday
|
|
39
|
+
const startStr = startOfWeek.toISOString().slice(0, 10);
|
|
40
|
+
return orders.filter((o) => {
|
|
41
|
+
const d = (o.inserted_at ?? "").slice(0, 10);
|
|
42
|
+
return d >= startStr && d <= todayStr;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// this_month
|
|
46
|
+
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
47
|
+
const startStr = startOfMonth.toISOString().slice(0, 10);
|
|
48
|
+
return orders.filter((o) => {
|
|
49
|
+
const d = (o.inserted_at ?? "").slice(0, 10);
|
|
50
|
+
return d >= startStr && d <= todayStr;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function aggregateLocal(orders, period, opts) {
|
|
54
|
+
const filtered = filterByPeriod(orders, period);
|
|
55
|
+
const total_revenue_minor = filtered.reduce((s, o) => s + (o.total_minor ?? 0), 0);
|
|
56
|
+
const total_orders = filtered.length;
|
|
57
|
+
const average_order_value_minor = total_orders ? Math.round(total_revenue_minor / total_orders) : 0;
|
|
58
|
+
const byMethod = new Map();
|
|
59
|
+
const byType = new Map();
|
|
60
|
+
const byDay = new Map();
|
|
61
|
+
const byStatus = {};
|
|
62
|
+
const itemQty = new Map();
|
|
63
|
+
const itemRev = new Map();
|
|
64
|
+
for (const o of filtered) {
|
|
65
|
+
const method = o.pos_payment_method ?? o.payment_mode ?? "cash";
|
|
66
|
+
const m = byMethod.get(method) ?? { revenue_minor: 0, count: 0 };
|
|
67
|
+
m.revenue_minor += o.total_minor ?? 0;
|
|
68
|
+
m.count += 1;
|
|
69
|
+
byMethod.set(method, m);
|
|
70
|
+
const t = o.order_type ?? "takeout";
|
|
71
|
+
const ty = byType.get(t) ?? { revenue_minor: 0, count: 0 };
|
|
72
|
+
ty.revenue_minor += o.total_minor ?? 0;
|
|
73
|
+
ty.count += 1;
|
|
74
|
+
byType.set(t, ty);
|
|
75
|
+
const day = (o.inserted_at ?? "").slice(0, 10);
|
|
76
|
+
const d = byDay.get(day) ?? { revenue_minor: 0, count: 0 };
|
|
77
|
+
d.revenue_minor += o.total_minor ?? 0;
|
|
78
|
+
d.count += 1;
|
|
79
|
+
byDay.set(day, d);
|
|
80
|
+
byStatus[o.status] = (byStatus[o.status] ?? 0) + 1;
|
|
81
|
+
for (const it of o.items ?? []) {
|
|
82
|
+
const name = it.menu_item?.name ?? "Unknown";
|
|
83
|
+
const qty = it.quantity ?? 0;
|
|
84
|
+
const rev = it.subtotal ?? it.total_price_minor ?? 0;
|
|
85
|
+
itemQty.set(name, (itemQty.get(name) ?? 0) + qty);
|
|
86
|
+
itemRev.set(name, (itemRev.get(name) ?? 0) + rev);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const pct = (v) => (total_revenue_minor > 0 ? Math.round((v / total_revenue_minor) * 1000) / 10 : 0);
|
|
90
|
+
if (opts.forRevenueSummary) {
|
|
91
|
+
return {
|
|
92
|
+
period,
|
|
93
|
+
total_revenue_minor,
|
|
94
|
+
total_orders,
|
|
95
|
+
average_order_value_minor,
|
|
96
|
+
by_payment_method: [...byMethod.entries()]
|
|
97
|
+
.map(([method, v]) => ({ method, ...v, percentage: pct(v.revenue_minor) }))
|
|
98
|
+
.sort((a, b) => b.revenue_minor - a.revenue_minor),
|
|
99
|
+
by_order_type: [...byType.entries()]
|
|
100
|
+
.map(([type, v]) => ({ type, ...v }))
|
|
101
|
+
.sort((a, b) => b.revenue_minor - a.revenue_minor),
|
|
102
|
+
by_day: [...byDay.entries()]
|
|
103
|
+
.map(([date, v]) => ({ date, ...v }))
|
|
104
|
+
.sort((a, b) => a.date.localeCompare(b.date)),
|
|
105
|
+
offline: true,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
period,
|
|
110
|
+
total_revenue_minor,
|
|
111
|
+
total_orders,
|
|
112
|
+
average_order_value_minor,
|
|
113
|
+
total_refunds_minor: 0,
|
|
114
|
+
top_items: [...itemQty.entries()]
|
|
115
|
+
.map(([name, quantity]) => ({ name, quantity, revenue_minor: itemRev.get(name) ?? 0 }))
|
|
116
|
+
.sort((a, b) => b.revenue_minor - a.revenue_minor)
|
|
117
|
+
.slice(0, 10),
|
|
118
|
+
orders_by_status: byStatus,
|
|
119
|
+
revenue_by_day: [...byDay.entries()]
|
|
120
|
+
.map(([date, v]) => ({ date, revenue_minor: v.revenue_minor }))
|
|
121
|
+
.sort((a, b) => a.date.localeCompare(b.date)),
|
|
122
|
+
offline: true,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async function localOrders(businessId) {
|
|
126
|
+
const { data } = await listLocalOrders(businessId, {}, 1, 500);
|
|
127
|
+
return (data ?? []);
|
|
128
|
+
}
|
|
129
|
+
export function useSellerAnalyticsQuery(period = "today", enabled = true) {
|
|
130
|
+
const businessId = useBusinessId();
|
|
131
|
+
const online = useIsEffectivelyOnline();
|
|
132
|
+
return useQuery({
|
|
133
|
+
queryKey: SELLER_ANALYTICS_KEYS.analytics(businessId ?? "", period),
|
|
134
|
+
queryFn: async () => {
|
|
135
|
+
if (!online) {
|
|
136
|
+
try {
|
|
137
|
+
return { data: aggregateLocal(await localOrders(businessId), period, { forRevenueSummary: false }) };
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return { data: aggregateLocal([], period, { forRevenueSummary: false }) };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const backendRes = await analyticsService.fetchSellerAnalytics(businessId, period);
|
|
145
|
+
// Safety net: if backend doesn't filter by period (returns all days regardless), filter locally
|
|
146
|
+
const backendData = backendRes.data;
|
|
147
|
+
const byDay = backendData?.revenue_by_day;
|
|
148
|
+
const shouldFilterLocally = !byDay?.length ||
|
|
149
|
+
(period === "today" && byDay.length > 1) ||
|
|
150
|
+
(period === "this_week" && byDay.some(d => {
|
|
151
|
+
const day = new Date(d.date ?? "");
|
|
152
|
+
const now = new Date();
|
|
153
|
+
const startOfWeek = new Date(now);
|
|
154
|
+
startOfWeek.setDate(now.getDate() - now.getDay());
|
|
155
|
+
return day < startOfWeek || day > now;
|
|
156
|
+
}));
|
|
157
|
+
if (shouldFilterLocally) {
|
|
158
|
+
const localOrdersData = await localOrders(businessId);
|
|
159
|
+
return { data: aggregateLocal(localOrdersData, period, { forRevenueSummary: false }) };
|
|
160
|
+
}
|
|
161
|
+
return backendRes;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return { data: aggregateLocal(await localOrders(businessId), period, { forRevenueSummary: false }) };
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
enabled: enabled && Boolean(businessId),
|
|
168
|
+
staleTime: 30000,
|
|
169
|
+
...OFFLINE_FIRST,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
export function useRevenueSummaryQuery(period = "today", enabled = true) {
|
|
173
|
+
const businessId = useBusinessId();
|
|
174
|
+
const online = useIsEffectivelyOnline();
|
|
175
|
+
return useQuery({
|
|
176
|
+
queryKey: REVENUE_KEYS.summary(businessId ?? "", period),
|
|
177
|
+
queryFn: async () => {
|
|
178
|
+
if (!online) {
|
|
179
|
+
try {
|
|
180
|
+
return { data: aggregateLocal(await localOrders(businessId), period, { forRevenueSummary: true }) };
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return { data: aggregateLocal([], period, { forRevenueSummary: true }) };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const backendRes = await analyticsService.fetchRevenueSummary(businessId, period);
|
|
188
|
+
// Safety net: if backend doesn't filter by period (returns all days regardless), filter locally
|
|
189
|
+
const backendData = backendRes.data;
|
|
190
|
+
const byDay = backendData?.by_day;
|
|
191
|
+
const shouldFilterLocally = !byDay?.length ||
|
|
192
|
+
(period === "today" && byDay.length > 1) ||
|
|
193
|
+
(period === "this_week" && byDay.some(d => {
|
|
194
|
+
const day = new Date(d.date ?? "");
|
|
195
|
+
const now = new Date();
|
|
196
|
+
const startOfWeek = new Date(now);
|
|
197
|
+
startOfWeek.setDate(now.getDate() - now.getDay());
|
|
198
|
+
return day < startOfWeek || day > now;
|
|
199
|
+
}));
|
|
200
|
+
if (shouldFilterLocally) {
|
|
201
|
+
const localOrdersData = await localOrders(businessId);
|
|
202
|
+
return { data: aggregateLocal(localOrdersData, period, { forRevenueSummary: true }) };
|
|
203
|
+
}
|
|
204
|
+
return backendRes;
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
return { data: aggregateLocal(await localOrders(businessId), period, { forRevenueSummary: true }) };
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
enabled: enabled && Boolean(businessId),
|
|
211
|
+
staleTime: 30000,
|
|
212
|
+
...OFFLINE_FIRST,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type BusinessOpenState } from "../utils/business-hours";
|
|
2
|
+
import type { OperatingHoursEntry } from "../types/api/business.api";
|
|
3
|
+
export declare const BUSINESS_HOURS_KEYS: {
|
|
4
|
+
all: readonly ["business-hours"];
|
|
5
|
+
open: (bid?: string) => readonly ["business-hours", "open", string | undefined];
|
|
6
|
+
};
|
|
7
|
+
export declare function useBusinessOpenNow(businessId?: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<BusinessOpenState, Error>;
|
|
8
|
+
export declare function useOperatingHours(businessId?: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<OperatingHoursEntry[], Error>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Business open/closed hook — reads the offline-first SQLite reference cache.
|
|
3
|
+
* Refetches on a minute cadence so the flag flips at hour boundaries, and on
|
|
4
|
+
* any reference-change invalidation (hours edited locally or background-synced).
|
|
5
|
+
*/
|
|
6
|
+
import { useQuery } from "@tanstack/react-query";
|
|
7
|
+
import { isBusinessOpenNow } from "../utils/business-hours";
|
|
8
|
+
import { getReferenceData } from "../reference/operations";
|
|
9
|
+
import { openSyncDatabase } from "../db/connection";
|
|
10
|
+
export const BUSINESS_HOURS_KEYS = {
|
|
11
|
+
all: ["business-hours"],
|
|
12
|
+
open: (bid) => [...BUSINESS_HOURS_KEYS.all, "open", bid],
|
|
13
|
+
};
|
|
14
|
+
export function useBusinessOpenNow(businessId, enabled = true) {
|
|
15
|
+
return useQuery({
|
|
16
|
+
queryKey: BUSINESS_HOURS_KEYS.open(businessId),
|
|
17
|
+
queryFn: async () => {
|
|
18
|
+
if (!businessId)
|
|
19
|
+
throw new Error("No business");
|
|
20
|
+
return isBusinessOpenNow(businessId);
|
|
21
|
+
},
|
|
22
|
+
enabled: enabled && !!businessId,
|
|
23
|
+
staleTime: 30 * 1000,
|
|
24
|
+
refetchInterval: 60 * 1000,
|
|
25
|
+
networkMode: "offlineFirst",
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function useOperatingHours(businessId, enabled = true) {
|
|
29
|
+
return useQuery({
|
|
30
|
+
queryKey: BUSINESS_HOURS_KEYS.open(businessId).concat(["entries"]),
|
|
31
|
+
queryFn: async () => {
|
|
32
|
+
if (!businessId)
|
|
33
|
+
throw new Error("No business");
|
|
34
|
+
const db = await openSyncDatabase();
|
|
35
|
+
const rec = await getReferenceData(db, businessId, "operating-hours");
|
|
36
|
+
if (!rec)
|
|
37
|
+
return [];
|
|
38
|
+
const payload = rec.payload;
|
|
39
|
+
return Array.isArray(payload) ? payload : (payload.data ?? []);
|
|
40
|
+
},
|
|
41
|
+
enabled: enabled && !!businessId,
|
|
42
|
+
staleTime: 30 * 1000,
|
|
43
|
+
networkMode: "offlineFirst",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seller dashboard hooks — single source for both apps.
|
|
3
|
+
* Offline-first: local SQLite aggregates serve instantly; the network
|
|
4
|
+
* refreshes silently when online.
|
|
5
|
+
*/
|
|
6
|
+
import type { SellerDashboardMetrics } from "../types/api/seller.api";
|
|
7
|
+
export declare const SELLER_DASHBOARD_KEYS: {
|
|
8
|
+
all: readonly ["seller-dashboard"];
|
|
9
|
+
metrics: (businessId?: string) => readonly ["seller-dashboard", "metrics", string | undefined];
|
|
10
|
+
recentOrders: (businessId?: string) => readonly ["seller-dashboard", "recent-orders", string | undefined];
|
|
11
|
+
full: (businessId?: string) => readonly ["seller-dashboard", "full", string | undefined];
|
|
12
|
+
};
|
|
13
|
+
export declare function useSellerDashboardMetricsQuery(businessId: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<SellerDashboardMetrics, Error>;
|
|
14
|
+
export declare function useSellerDashboardRecentOrdersQuery(businessId: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<{
|
|
15
|
+
id: string;
|
|
16
|
+
order_number: string;
|
|
17
|
+
status: string;
|
|
18
|
+
total_minor: number;
|
|
19
|
+
item_count: number;
|
|
20
|
+
}[], Error>;
|
|
21
|
+
export declare function useSellerDashboardQuery(businessId: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<{
|
|
22
|
+
metrics: SellerDashboardMetrics;
|
|
23
|
+
recent_orders: {
|
|
24
|
+
id: string;
|
|
25
|
+
order_number: string;
|
|
26
|
+
status: string;
|
|
27
|
+
total_minor: number;
|
|
28
|
+
item_count: number;
|
|
29
|
+
}[];
|
|
30
|
+
}, Error>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seller dashboard hooks — single source for both apps.
|
|
3
|
+
* Offline-first: local SQLite aggregates serve instantly; the network
|
|
4
|
+
* refreshes silently when online.
|
|
5
|
+
*/
|
|
6
|
+
import { useQuery } from "@tanstack/react-query";
|
|
7
|
+
import { dashboardService } from "../adapters/services";
|
|
8
|
+
import { listLocalOrders } from "../domain/orders/service";
|
|
9
|
+
import { useIsEffectivelyOnline } from "./use-infinite-list";
|
|
10
|
+
export const SELLER_DASHBOARD_KEYS = {
|
|
11
|
+
all: ["seller-dashboard"],
|
|
12
|
+
metrics: (businessId) => [...SELLER_DASHBOARD_KEYS.all, "metrics", businessId],
|
|
13
|
+
recentOrders: (businessId) => [...SELLER_DASHBOARD_KEYS.all, "recent-orders", businessId],
|
|
14
|
+
full: (businessId) => [...SELLER_DASHBOARD_KEYS.all, "full", businessId],
|
|
15
|
+
};
|
|
16
|
+
const EMPTY_METRICS = {
|
|
17
|
+
today_orders: 0,
|
|
18
|
+
today_revenue_minor: 0,
|
|
19
|
+
pending_orders: 0,
|
|
20
|
+
active_orders: 0,
|
|
21
|
+
average_rating: 0,
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Local SQLite aggregates — instant, even online. Single source for all
|
|
25
|
+
* three dashboard queries so metrics/recent/full never diverge.
|
|
26
|
+
*/
|
|
27
|
+
async function computeLocalDashboard(businessId) {
|
|
28
|
+
const { data } = await listLocalOrders(businessId, {}, 1, 200);
|
|
29
|
+
const orders = (data ?? []);
|
|
30
|
+
const todayStr = new Date().toISOString().slice(0, 10);
|
|
31
|
+
const todayOrders = orders.filter((o) => (o.inserted_at ?? "").slice(0, 10) === todayStr);
|
|
32
|
+
const todayRevenue = todayOrders.reduce((sum, o) => sum + (o.total_minor ?? 0), 0);
|
|
33
|
+
const pending = orders.filter((o) => ["pending", "awaiting_payment", "accepted"].includes(o.status)).length;
|
|
34
|
+
const active = orders.filter((o) => !["delivered", "cancelled", "rejected"].includes(o.status)).length;
|
|
35
|
+
const recent = [...orders]
|
|
36
|
+
.sort((a, b) => (b.inserted_at ?? "").localeCompare(a.inserted_at ?? ""))
|
|
37
|
+
.slice(0, 5)
|
|
38
|
+
.map((o) => ({ id: o.id, order_number: o.order_number, status: o.status, total_minor: o.total_minor, item_count: 1 }));
|
|
39
|
+
return {
|
|
40
|
+
metrics: { today_orders: todayOrders.length, today_revenue_minor: todayRevenue, pending_orders: pending, active_orders: active, average_rating: 0 },
|
|
41
|
+
recent_orders: recent,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function useSellerDashboardMetricsQuery(businessId, enabled = true) {
|
|
45
|
+
const online = useIsEffectivelyOnline();
|
|
46
|
+
return useQuery({
|
|
47
|
+
queryKey: SELLER_DASHBOARD_KEYS.metrics(businessId),
|
|
48
|
+
queryFn: async () => {
|
|
49
|
+
// DB first — instant, even online.
|
|
50
|
+
let local = null;
|
|
51
|
+
try {
|
|
52
|
+
local = (await computeLocalDashboard(businessId)).metrics;
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
55
|
+
if (!online)
|
|
56
|
+
return local ?? EMPTY_METRICS;
|
|
57
|
+
try {
|
|
58
|
+
const res = (await dashboardService.fetchSellerDashboard(businessId));
|
|
59
|
+
return res.data.metrics ?? local ?? EMPTY_METRICS;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return local ?? EMPTY_METRICS;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
enabled: enabled && Boolean(businessId),
|
|
66
|
+
staleTime: 1000 * 60 * 2,
|
|
67
|
+
retry: false,
|
|
68
|
+
networkMode: "offlineFirst",
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export function useSellerDashboardRecentOrdersQuery(businessId, enabled = true) {
|
|
72
|
+
const online = useIsEffectivelyOnline();
|
|
73
|
+
return useQuery({
|
|
74
|
+
queryKey: SELLER_DASHBOARD_KEYS.recentOrders(businessId),
|
|
75
|
+
queryFn: async () => {
|
|
76
|
+
// DB first — instant, even online.
|
|
77
|
+
let local = [];
|
|
78
|
+
try {
|
|
79
|
+
local = (await computeLocalDashboard(businessId)).recent_orders;
|
|
80
|
+
}
|
|
81
|
+
catch { }
|
|
82
|
+
if (!online)
|
|
83
|
+
return local;
|
|
84
|
+
try {
|
|
85
|
+
const res = (await dashboardService.fetchSellerDashboard(businessId));
|
|
86
|
+
return local.length > 0 ? local : res.data.recent_orders;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return local;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
enabled: enabled && Boolean(businessId),
|
|
93
|
+
staleTime: 1000 * 60 * 2,
|
|
94
|
+
retry: false,
|
|
95
|
+
networkMode: "offlineFirst",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
export function useSellerDashboardQuery(businessId, enabled = true) {
|
|
99
|
+
const online = useIsEffectivelyOnline();
|
|
100
|
+
return useQuery({
|
|
101
|
+
queryKey: SELLER_DASHBOARD_KEYS.full(businessId),
|
|
102
|
+
queryFn: async () => {
|
|
103
|
+
// Local SQLite aggregates first — instant, even online.
|
|
104
|
+
let localRecent = [];
|
|
105
|
+
let localMetrics = null;
|
|
106
|
+
try {
|
|
107
|
+
const local = await computeLocalDashboard(businessId);
|
|
108
|
+
localRecent = local.recent_orders;
|
|
109
|
+
localMetrics = local.metrics;
|
|
110
|
+
}
|
|
111
|
+
catch { }
|
|
112
|
+
if (!online) {
|
|
113
|
+
return { metrics: localMetrics ?? EMPTY_METRICS, recent_orders: localRecent };
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const res = (await dashboardService.fetchSellerDashboard(businessId));
|
|
117
|
+
const backend = res.data;
|
|
118
|
+
return {
|
|
119
|
+
metrics: backend.metrics ?? localMetrics,
|
|
120
|
+
recent_orders: localRecent.length > 0 ? localRecent : backend.recent_orders,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return { metrics: localMetrics ?? EMPTY_METRICS, recent_orders: localRecent };
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
enabled: enabled && Boolean(businessId),
|
|
128
|
+
staleTime: 30 * 1000,
|
|
129
|
+
retry: false,
|
|
130
|
+
networkMode: "offlineFirst",
|
|
131
|
+
});
|
|
132
|
+
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Business deliveries hooks — single source for both apps.
|
|
3
|
+
* Offline-first: local orders with delivery_id serve instantly; the network
|
|
4
|
+
* refreshes silently when online.
|
|
5
|
+
*/
|
|
6
|
+
import type { BusinessDelivery } from "../types/api/seller.api";
|
|
7
|
+
import { type ListPage } from "./use-infinite-list";
|
|
8
|
+
export declare const DELIVERY_KEYS: {
|
|
9
|
+
all: readonly ["business-deliveries"];
|
|
10
|
+
list: (businessId?: string, filters?: Record<string, unknown>) => readonly ["business-deliveries", string | undefined, Record<string, unknown> | undefined];
|
|
11
|
+
};
|
|
12
|
+
export declare const DELIVERY_DETAIL_KEYS: {
|
|
13
|
+
all: readonly ["delivery"];
|
|
14
|
+
detail: (id: string) => readonly ["delivery", "detail", string];
|
|
15
|
+
};
|
|
16
|
+
export declare function useDeliveryDetailQuery(deliveryId: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<unknown, Error>;
|
|
17
|
+
export interface DeliveryFilters {
|
|
18
|
+
status?: string;
|
|
19
|
+
search?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function useBusinessDeliveriesQuery(enabled?: boolean, filters?: DeliveryFilters): {
|
|
22
|
+
dataUpdatedAt: number;
|
|
23
|
+
errorUpdatedAt: number;
|
|
24
|
+
failureCount: number;
|
|
25
|
+
failureReason: Error | null;
|
|
26
|
+
errorUpdateCount: number;
|
|
27
|
+
isFetched: boolean;
|
|
28
|
+
isFetchedAfterMount: boolean;
|
|
29
|
+
isFetching: boolean;
|
|
30
|
+
isInitialLoading: boolean;
|
|
31
|
+
isPaused: boolean;
|
|
32
|
+
isRefetching: boolean;
|
|
33
|
+
isStale: boolean;
|
|
34
|
+
isEnabled: boolean;
|
|
35
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
36
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
37
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
38
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
39
|
+
hasNextPage: boolean;
|
|
40
|
+
hasPreviousPage: boolean;
|
|
41
|
+
isFetchingNextPage: boolean;
|
|
42
|
+
isFetchingPreviousPage: boolean;
|
|
43
|
+
error: Error;
|
|
44
|
+
isError: true;
|
|
45
|
+
isPending: false;
|
|
46
|
+
isLoading: false;
|
|
47
|
+
isLoadingError: true;
|
|
48
|
+
isRefetchError: false;
|
|
49
|
+
isFetchNextPageError: false;
|
|
50
|
+
isFetchPreviousPageError: false;
|
|
51
|
+
isSuccess: false;
|
|
52
|
+
isPlaceholderData: false;
|
|
53
|
+
status: 'error';
|
|
54
|
+
data: BusinessDelivery[] | undefined;
|
|
55
|
+
} | {
|
|
56
|
+
dataUpdatedAt: number;
|
|
57
|
+
errorUpdatedAt: number;
|
|
58
|
+
failureCount: number;
|
|
59
|
+
failureReason: Error | null;
|
|
60
|
+
errorUpdateCount: number;
|
|
61
|
+
isFetched: boolean;
|
|
62
|
+
isFetchedAfterMount: boolean;
|
|
63
|
+
isFetching: boolean;
|
|
64
|
+
isInitialLoading: boolean;
|
|
65
|
+
isPaused: boolean;
|
|
66
|
+
isRefetching: boolean;
|
|
67
|
+
isStale: boolean;
|
|
68
|
+
isEnabled: boolean;
|
|
69
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
70
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
71
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
72
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
73
|
+
hasNextPage: boolean;
|
|
74
|
+
hasPreviousPage: boolean;
|
|
75
|
+
isFetchingNextPage: boolean;
|
|
76
|
+
isFetchingPreviousPage: boolean;
|
|
77
|
+
error: null;
|
|
78
|
+
isError: false;
|
|
79
|
+
isPending: true;
|
|
80
|
+
isLoading: true;
|
|
81
|
+
isLoadingError: false;
|
|
82
|
+
isRefetchError: false;
|
|
83
|
+
isFetchNextPageError: false;
|
|
84
|
+
isFetchPreviousPageError: false;
|
|
85
|
+
isSuccess: false;
|
|
86
|
+
isPlaceholderData: false;
|
|
87
|
+
status: 'pending';
|
|
88
|
+
data: BusinessDelivery[] | undefined;
|
|
89
|
+
} | {
|
|
90
|
+
dataUpdatedAt: number;
|
|
91
|
+
errorUpdatedAt: number;
|
|
92
|
+
failureCount: number;
|
|
93
|
+
failureReason: Error | null;
|
|
94
|
+
errorUpdateCount: number;
|
|
95
|
+
isFetched: boolean;
|
|
96
|
+
isFetchedAfterMount: boolean;
|
|
97
|
+
isFetching: boolean;
|
|
98
|
+
isLoading: boolean;
|
|
99
|
+
isInitialLoading: boolean;
|
|
100
|
+
isPaused: boolean;
|
|
101
|
+
isRefetching: boolean;
|
|
102
|
+
isStale: boolean;
|
|
103
|
+
isEnabled: boolean;
|
|
104
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
105
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
106
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
107
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
108
|
+
hasNextPage: boolean;
|
|
109
|
+
hasPreviousPage: boolean;
|
|
110
|
+
isFetchingNextPage: boolean;
|
|
111
|
+
isFetchingPreviousPage: boolean;
|
|
112
|
+
error: null;
|
|
113
|
+
isError: false;
|
|
114
|
+
isPending: true;
|
|
115
|
+
isLoadingError: false;
|
|
116
|
+
isRefetchError: false;
|
|
117
|
+
isFetchNextPageError: false;
|
|
118
|
+
isFetchPreviousPageError: false;
|
|
119
|
+
isSuccess: false;
|
|
120
|
+
isPlaceholderData: false;
|
|
121
|
+
status: 'pending';
|
|
122
|
+
data: BusinessDelivery[] | undefined;
|
|
123
|
+
} | {
|
|
124
|
+
dataUpdatedAt: number;
|
|
125
|
+
errorUpdatedAt: number;
|
|
126
|
+
failureCount: number;
|
|
127
|
+
failureReason: Error | null;
|
|
128
|
+
errorUpdateCount: number;
|
|
129
|
+
isFetched: boolean;
|
|
130
|
+
isFetchedAfterMount: boolean;
|
|
131
|
+
isFetching: boolean;
|
|
132
|
+
isInitialLoading: boolean;
|
|
133
|
+
isPaused: boolean;
|
|
134
|
+
isRefetching: boolean;
|
|
135
|
+
isStale: boolean;
|
|
136
|
+
isEnabled: boolean;
|
|
137
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
138
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
139
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
140
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
141
|
+
hasNextPage: boolean;
|
|
142
|
+
hasPreviousPage: boolean;
|
|
143
|
+
isFetchingNextPage: boolean;
|
|
144
|
+
isFetchingPreviousPage: boolean;
|
|
145
|
+
isError: false;
|
|
146
|
+
error: null;
|
|
147
|
+
isPending: false;
|
|
148
|
+
isLoading: false;
|
|
149
|
+
isLoadingError: false;
|
|
150
|
+
isRefetchError: false;
|
|
151
|
+
isSuccess: true;
|
|
152
|
+
isPlaceholderData: true;
|
|
153
|
+
isFetchNextPageError: false;
|
|
154
|
+
isFetchPreviousPageError: false;
|
|
155
|
+
status: 'success';
|
|
156
|
+
data: BusinessDelivery[] | undefined;
|
|
157
|
+
} | {
|
|
158
|
+
dataUpdatedAt: number;
|
|
159
|
+
errorUpdatedAt: number;
|
|
160
|
+
failureCount: number;
|
|
161
|
+
failureReason: Error | null;
|
|
162
|
+
errorUpdateCount: number;
|
|
163
|
+
isFetched: boolean;
|
|
164
|
+
isFetchedAfterMount: boolean;
|
|
165
|
+
isFetching: boolean;
|
|
166
|
+
isInitialLoading: boolean;
|
|
167
|
+
isPaused: boolean;
|
|
168
|
+
isRefetching: boolean;
|
|
169
|
+
isStale: boolean;
|
|
170
|
+
isEnabled: boolean;
|
|
171
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
172
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
173
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
174
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
175
|
+
hasNextPage: boolean;
|
|
176
|
+
hasPreviousPage: boolean;
|
|
177
|
+
isFetchNextPageError: boolean;
|
|
178
|
+
isFetchingNextPage: boolean;
|
|
179
|
+
isFetchPreviousPageError: boolean;
|
|
180
|
+
isFetchingPreviousPage: boolean;
|
|
181
|
+
error: Error;
|
|
182
|
+
isError: true;
|
|
183
|
+
isPending: false;
|
|
184
|
+
isLoading: false;
|
|
185
|
+
isLoadingError: false;
|
|
186
|
+
isRefetchError: true;
|
|
187
|
+
isSuccess: false;
|
|
188
|
+
isPlaceholderData: false;
|
|
189
|
+
status: 'error';
|
|
190
|
+
data: BusinessDelivery[] | undefined;
|
|
191
|
+
} | {
|
|
192
|
+
dataUpdatedAt: number;
|
|
193
|
+
errorUpdatedAt: number;
|
|
194
|
+
failureCount: number;
|
|
195
|
+
failureReason: Error | null;
|
|
196
|
+
errorUpdateCount: number;
|
|
197
|
+
isFetched: boolean;
|
|
198
|
+
isFetchedAfterMount: boolean;
|
|
199
|
+
isFetching: boolean;
|
|
200
|
+
isInitialLoading: boolean;
|
|
201
|
+
isPaused: boolean;
|
|
202
|
+
isRefetching: boolean;
|
|
203
|
+
isStale: boolean;
|
|
204
|
+
isEnabled: boolean;
|
|
205
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
206
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
207
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
208
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<ListPage<BusinessDelivery>, unknown>, Error>>;
|
|
209
|
+
hasNextPage: boolean;
|
|
210
|
+
hasPreviousPage: boolean;
|
|
211
|
+
isFetchingNextPage: boolean;
|
|
212
|
+
isFetchingPreviousPage: boolean;
|
|
213
|
+
error: null;
|
|
214
|
+
isError: false;
|
|
215
|
+
isPending: false;
|
|
216
|
+
isLoading: false;
|
|
217
|
+
isLoadingError: false;
|
|
218
|
+
isRefetchError: false;
|
|
219
|
+
isFetchNextPageError: false;
|
|
220
|
+
isFetchPreviousPageError: false;
|
|
221
|
+
isSuccess: true;
|
|
222
|
+
isPlaceholderData: false;
|
|
223
|
+
status: 'success';
|
|
224
|
+
data: BusinessDelivery[] | undefined;
|
|
225
|
+
};
|