@htlkg/data 0.0.21 → 0.0.22
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/hooks/index.d.ts +601 -94
- package/dist/hooks/index.js +682 -73
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +691 -82
- package/dist/index.js.map +1 -1
- package/dist/mutations/index.js +4 -4
- package/dist/mutations/index.js.map +1 -1
- package/dist/queries/index.js +5 -5
- package/dist/queries/index.js.map +1 -1
- package/package.json +11 -12
- package/src/hooks/accounts/index.ts +2 -0
- package/src/hooks/{useAccounts.ts → accounts/useAccounts.ts} +48 -5
- package/src/hooks/accounts/usePaginatedAccounts.ts +166 -0
- package/src/hooks/brands/index.ts +2 -0
- package/src/hooks/{useBrands.ts → brands/useBrands.ts} +1 -1
- package/src/hooks/brands/usePaginatedBrands.ts +206 -0
- package/src/hooks/createPaginatedDataHook.ts +359 -0
- package/src/hooks/data-hook-errors.property.test.ts +4 -4
- package/src/hooks/data-hook-filters.property.test.ts +4 -4
- package/src/hooks/data-hooks.property.test.ts +4 -4
- package/src/hooks/index.ts +96 -8
- package/src/hooks/productInstances/index.ts +1 -0
- package/src/hooks/{useProductInstances.ts → productInstances/useProductInstances.ts} +9 -6
- package/src/hooks/products/index.ts +1 -0
- package/src/hooks/{useProducts.ts → products/useProducts.ts} +4 -5
- package/src/hooks/reservations/index.ts +2 -0
- package/src/hooks/reservations/usePaginatedReservations.ts +258 -0
- package/src/hooks/{useReservations.ts → reservations/useReservations.ts} +65 -10
- package/src/hooks/users/index.ts +2 -0
- package/src/hooks/users/usePaginatedUsers.ts +213 -0
- package/src/hooks/{useUsers.ts → users/useUsers.ts} +1 -1
- package/src/mutations/accounts/accounts.test.ts +287 -0
- package/src/mutations/{accounts.ts → accounts/accounts.ts} +2 -2
- package/src/mutations/accounts/index.ts +1 -0
- package/src/mutations/brands/brands.test.ts +292 -0
- package/src/mutations/{brands.ts → brands/brands.ts} +2 -2
- package/src/mutations/brands/index.ts +1 -0
- package/src/mutations/reservations/index.ts +1 -0
- package/src/mutations/{reservations.test.ts → reservations/reservations.test.ts} +1 -1
- package/src/mutations/{reservations.ts → reservations/reservations.ts} +2 -2
- package/src/mutations/users/index.ts +1 -0
- package/src/mutations/users/users.test.ts +289 -0
- package/src/mutations/{users.ts → users/users.ts} +2 -2
- package/src/queries/accounts/accounts.test.ts +228 -0
- package/src/queries/accounts/index.ts +1 -0
- package/src/queries/brands/brands.test.ts +288 -0
- package/src/queries/brands/index.ts +1 -0
- package/src/queries/products/index.ts +1 -0
- package/src/queries/products/products.test.ts +347 -0
- package/src/queries/reservations/index.ts +1 -0
- package/src/queries/users/index.ts +1 -0
- package/src/queries/users/users.test.ts +301 -0
- /package/src/queries/{accounts.ts → accounts/accounts.ts} +0 -0
- /package/src/queries/{brands.ts → brands/brands.ts} +0 -0
- /package/src/queries/{products.ts → products/products.ts} +0 -0
- /package/src/queries/{reservations.test.ts → reservations/reservations.test.ts} +0 -0
- /package/src/queries/{reservations.ts → reservations/reservations.ts} +0 -0
- /package/src/queries/{users.ts → users/users.ts} +0 -0
package/src/hooks/index.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Data Hooks for @htlkg/data
|
|
3
3
|
*
|
|
4
4
|
* Vue composables for fetching and managing data with reactive state.
|
|
5
|
+
* Organized by entity type in subfolders for better maintainability.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
// Hook factory for creating custom data hooks
|
|
@@ -14,11 +15,98 @@ export {
|
|
|
14
15
|
type InferHookReturn,
|
|
15
16
|
} from "./createDataHook";
|
|
16
17
|
|
|
17
|
-
//
|
|
18
|
-
export {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
// Paginated hook factory for large datasets
|
|
19
|
+
export {
|
|
20
|
+
createPaginatedDataHook,
|
|
21
|
+
ACTIVE_FILTER,
|
|
22
|
+
DELETED_FILTER,
|
|
23
|
+
type CreatePaginatedDataHookOptions,
|
|
24
|
+
type PaginatedHookOptions,
|
|
25
|
+
type PaginationState,
|
|
26
|
+
type PaginatedDataHookReturn,
|
|
27
|
+
type InferPaginatedHookReturn,
|
|
28
|
+
} from "./createPaginatedDataHook";
|
|
29
|
+
|
|
30
|
+
// ============================================
|
|
31
|
+
// BRAND HOOKS
|
|
32
|
+
// ============================================
|
|
33
|
+
export {
|
|
34
|
+
useBrands,
|
|
35
|
+
useActiveBrands,
|
|
36
|
+
useDeletedBrands,
|
|
37
|
+
type UseBrandsOptions,
|
|
38
|
+
type UseBrandsReturn,
|
|
39
|
+
type BrandWithCounts,
|
|
40
|
+
type UsePaginatedBrandsOptions,
|
|
41
|
+
type UsePaginatedBrandsReturn,
|
|
42
|
+
} from "./brands";
|
|
43
|
+
|
|
44
|
+
// ============================================
|
|
45
|
+
// USER HOOKS
|
|
46
|
+
// ============================================
|
|
47
|
+
export {
|
|
48
|
+
useUsers,
|
|
49
|
+
useActiveUsers,
|
|
50
|
+
useDeletedUsers,
|
|
51
|
+
type UseUsersOptions,
|
|
52
|
+
type UseUsersReturn,
|
|
53
|
+
type UserWithRelations,
|
|
54
|
+
type UsePaginatedUsersOptions,
|
|
55
|
+
type UsePaginatedUsersReturn,
|
|
56
|
+
} from "./users";
|
|
57
|
+
|
|
58
|
+
// ============================================
|
|
59
|
+
// ACCOUNT HOOKS
|
|
60
|
+
// ============================================
|
|
61
|
+
export {
|
|
62
|
+
useAccounts,
|
|
63
|
+
useActiveAccounts,
|
|
64
|
+
useDeletedAccounts,
|
|
65
|
+
type UseAccountsOptions,
|
|
66
|
+
type UseAccountsReturn,
|
|
67
|
+
type AccountWithBrands,
|
|
68
|
+
type AccountWithBrands as PaginatedAccountWithBrands,
|
|
69
|
+
type UsePaginatedAccountsOptions,
|
|
70
|
+
type UsePaginatedAccountsReturn,
|
|
71
|
+
} from "./accounts";
|
|
72
|
+
|
|
73
|
+
// ============================================
|
|
74
|
+
// RESERVATION HOOKS
|
|
75
|
+
// ============================================
|
|
76
|
+
export {
|
|
77
|
+
useReservations,
|
|
78
|
+
useActiveReservations,
|
|
79
|
+
useDeletedReservations,
|
|
80
|
+
type UseReservationsOptions,
|
|
81
|
+
type UseReservationsReturn,
|
|
82
|
+
type ReservationWithRelations,
|
|
83
|
+
type UsePaginatedReservationsOptions,
|
|
84
|
+
type UsePaginatedReservationsReturn,
|
|
85
|
+
} from "./reservations";
|
|
86
|
+
|
|
87
|
+
// ============================================
|
|
88
|
+
// PRODUCT HOOKS
|
|
89
|
+
// ============================================
|
|
90
|
+
export {
|
|
91
|
+
useProducts,
|
|
92
|
+
type UseProductsOptions,
|
|
93
|
+
type UseProductsReturn,
|
|
94
|
+
} from "./products";
|
|
95
|
+
|
|
96
|
+
// ============================================
|
|
97
|
+
// PRODUCT INSTANCE HOOKS
|
|
98
|
+
// ============================================
|
|
99
|
+
export {
|
|
100
|
+
useProductInstances,
|
|
101
|
+
type UseProductInstancesOptions,
|
|
102
|
+
type UseProductInstancesReturn,
|
|
103
|
+
} from "./productInstances";
|
|
104
|
+
|
|
105
|
+
// ============================================
|
|
106
|
+
// CONTACT HOOKS
|
|
107
|
+
// ============================================
|
|
108
|
+
export {
|
|
109
|
+
useContacts,
|
|
110
|
+
type UseContactsOptions,
|
|
111
|
+
type UseContactsReturn,
|
|
112
|
+
} from "./useContacts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useProductInstances";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ProductInstance Hooks
|
|
3
3
|
*
|
|
4
|
-
* Vue
|
|
4
|
+
* Vue composables for fetching and managing product instance data with reactive state.
|
|
5
5
|
* Provides loading states, error handling, refetch capabilities, and CRUD operations.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Ref, ComputedRef } from "vue";
|
|
9
9
|
import type { ProductInstance } from "@htlkg/core/types";
|
|
10
|
-
import { createDataHook, type BaseHookOptions } from "
|
|
11
|
-
import { getSharedClient } from "
|
|
10
|
+
import { createDataHook, type BaseHookOptions } from "../createDataHook";
|
|
11
|
+
import { getSharedClient } from "../../client";
|
|
12
12
|
import {
|
|
13
13
|
createProductInstance,
|
|
14
14
|
updateProductInstance,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
toggleProductInstanceEnabled,
|
|
17
17
|
type CreateProductInstanceInput,
|
|
18
18
|
type UpdateProductInstanceInput,
|
|
19
|
-
} from "
|
|
19
|
+
} from "../../mutations/productInstances";
|
|
20
20
|
|
|
21
21
|
export interface UseProductInstancesOptions extends BaseHookOptions {
|
|
22
22
|
/** Filter criteria for product instances */
|
|
@@ -102,7 +102,7 @@ const useProductInstancesInternal = createDataHook<
|
|
|
102
102
|
*
|
|
103
103
|
* @example
|
|
104
104
|
* ```typescript
|
|
105
|
-
* import { useProductInstances } from '@htlkg/data/hooks';
|
|
105
|
+
* import { useProductInstances } from '@htlkg/data/hooks/productInstances';
|
|
106
106
|
*
|
|
107
107
|
* const { instances, loading, error, refetch } = useProductInstances();
|
|
108
108
|
* ```
|
|
@@ -172,3 +172,6 @@ export function useProductInstances(options: UseProductInstancesOptions = {}): U
|
|
|
172
172
|
toggleEnabled,
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
|
+
|
|
176
|
+
// Re-export types for convenience
|
|
177
|
+
export type { CreateProductInstanceInput, UpdateProductInstanceInput };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useProducts";
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Product Hooks
|
|
3
3
|
*
|
|
4
|
-
* Vue
|
|
5
|
-
* Provides loading states, error handling, and refetch capabilities.
|
|
4
|
+
* Vue composables for fetching and managing product data with reactive state.
|
|
6
5
|
*/
|
|
7
6
|
|
|
8
7
|
import type { Ref, ComputedRef } from "vue";
|
|
9
8
|
import type { Product } from "@htlkg/core/types";
|
|
10
|
-
import { createDataHook, type BaseHookOptions } from "
|
|
9
|
+
import { createDataHook, type BaseHookOptions } from "../createDataHook";
|
|
11
10
|
|
|
12
11
|
export interface UseProductsOptions extends BaseHookOptions {
|
|
13
12
|
/** Filter criteria for products */
|
|
@@ -63,7 +62,7 @@ const useProductsInternal = createDataHook<Product, UseProductsOptions, { active
|
|
|
63
62
|
*
|
|
64
63
|
* @example
|
|
65
64
|
* ```typescript
|
|
66
|
-
* import { useProducts } from '@htlkg/data/hooks';
|
|
65
|
+
* import { useProducts } from '@htlkg/data/hooks/products';
|
|
67
66
|
*
|
|
68
67
|
* const { products, loading, error, refetch } = useProducts();
|
|
69
68
|
* ```
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paginated Reservations Hooks
|
|
3
|
+
*
|
|
4
|
+
* Vue composables for fetching reservations with server-side pagination.
|
|
5
|
+
* Provides separate hooks for active and deleted reservations to enable
|
|
6
|
+
* efficient tab-based filtering in large datasets.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Ref, ComputedRef } from "vue";
|
|
10
|
+
import type { Reservation } from "../../queries/reservations";
|
|
11
|
+
import {
|
|
12
|
+
createPaginatedDataHook,
|
|
13
|
+
ACTIVE_FILTER,
|
|
14
|
+
DELETED_FILTER,
|
|
15
|
+
type PaginatedHookOptions,
|
|
16
|
+
type PaginationState,
|
|
17
|
+
} from "../createPaginatedDataHook";
|
|
18
|
+
import type { ReservationWithRelations } from "./useReservations";
|
|
19
|
+
|
|
20
|
+
export interface UsePaginatedReservationsOptions extends PaginatedHookOptions {
|
|
21
|
+
/** Filter by brand ID */
|
|
22
|
+
brandId?: string;
|
|
23
|
+
/** Filter by start date (check-in date >= startDate) */
|
|
24
|
+
startDate?: string;
|
|
25
|
+
/** Filter by end date (check-in date <= endDate) */
|
|
26
|
+
endDate?: string;
|
|
27
|
+
/** Filter by reservation status */
|
|
28
|
+
status?: Reservation["status"];
|
|
29
|
+
/** Filter by contact/visit ID */
|
|
30
|
+
contactId?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface UsePaginatedReservationsReturn {
|
|
34
|
+
/** Reactive array of reservations with brand and guest info */
|
|
35
|
+
reservations: Ref<ReservationWithRelations[]>;
|
|
36
|
+
/** Loading state (true during any fetch) */
|
|
37
|
+
loading: Ref<boolean>;
|
|
38
|
+
/** Loading state for initial fetch */
|
|
39
|
+
initialLoading: Ref<boolean>;
|
|
40
|
+
/** Loading state for loadMore */
|
|
41
|
+
loadingMore: Ref<boolean>;
|
|
42
|
+
/** Error state */
|
|
43
|
+
error: Ref<Error | null>;
|
|
44
|
+
/** Pagination state */
|
|
45
|
+
pagination: Ref<PaginationState>;
|
|
46
|
+
/** Whether there are more items to load */
|
|
47
|
+
hasMore: ComputedRef<boolean>;
|
|
48
|
+
/** Load next page of data */
|
|
49
|
+
loadMore: () => Promise<void>;
|
|
50
|
+
/** Refetch data (resets to first page) */
|
|
51
|
+
refetch: () => Promise<void>;
|
|
52
|
+
/** Reset data and pagination state */
|
|
53
|
+
reset: () => void;
|
|
54
|
+
/** Update search filter and refetch from server (searches ALL data) */
|
|
55
|
+
setSearchFilter: (filter: any) => Promise<void>;
|
|
56
|
+
/** Current search filter */
|
|
57
|
+
searchFilter: Ref<any>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Build additional filter from hook options
|
|
62
|
+
*/
|
|
63
|
+
function buildFilter(options: UsePaginatedReservationsOptions): any {
|
|
64
|
+
const conditions: any[] = [];
|
|
65
|
+
|
|
66
|
+
if (options.brandId) {
|
|
67
|
+
conditions.push({ brandId: { eq: options.brandId } });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (options.status) {
|
|
71
|
+
conditions.push({ status: { eq: options.status } });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (options.contactId) {
|
|
75
|
+
conditions.push({ visitId: { eq: options.contactId } });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (options.startDate) {
|
|
79
|
+
conditions.push({ checkIn: { ge: options.startDate } });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (options.endDate) {
|
|
83
|
+
conditions.push({ checkIn: { le: options.endDate } });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (options.filter && Object.keys(options.filter).length > 0) {
|
|
87
|
+
conditions.push(options.filter);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (conditions.length === 0) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
if (conditions.length === 1) {
|
|
94
|
+
return conditions[0];
|
|
95
|
+
}
|
|
96
|
+
return { and: conditions };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Transform reservation data to include brandName and guest info from visit.snapshot
|
|
101
|
+
*/
|
|
102
|
+
function transformReservation(r: any): ReservationWithRelations {
|
|
103
|
+
// Parse snapshot if it's a string (handles double-stringification from import)
|
|
104
|
+
let snapshot = r.visit?.snapshot;
|
|
105
|
+
if (typeof snapshot === "string") {
|
|
106
|
+
try {
|
|
107
|
+
snapshot = JSON.parse(snapshot);
|
|
108
|
+
} catch {
|
|
109
|
+
snapshot = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
...r,
|
|
115
|
+
brandName: r.brand?.name || "Unknown Brand",
|
|
116
|
+
guestName: snapshot
|
|
117
|
+
? `${snapshot.firstName || ""} ${snapshot.lastName || ""}`.trim() || "Unknown Guest"
|
|
118
|
+
: "Unknown Guest",
|
|
119
|
+
guestEmail: snapshot?.email || "",
|
|
120
|
+
guestPhone: snapshot?.phone || "",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Selection set for reservation queries
|
|
126
|
+
*/
|
|
127
|
+
const RESERVATION_SELECTION_SET = [
|
|
128
|
+
"id",
|
|
129
|
+
"brandId",
|
|
130
|
+
"visitId",
|
|
131
|
+
"checkIn",
|
|
132
|
+
"checkOut",
|
|
133
|
+
"room",
|
|
134
|
+
"roomType",
|
|
135
|
+
"status",
|
|
136
|
+
"source",
|
|
137
|
+
"channel",
|
|
138
|
+
"confirmationCode",
|
|
139
|
+
"totalAmount",
|
|
140
|
+
"currency",
|
|
141
|
+
"nights",
|
|
142
|
+
"deletedAt",
|
|
143
|
+
"deletedBy",
|
|
144
|
+
"brand.name",
|
|
145
|
+
"visit.snapshot",
|
|
146
|
+
];
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Internal hook for active reservations
|
|
150
|
+
*/
|
|
151
|
+
const useActiveReservationsInternal = createPaginatedDataHook<
|
|
152
|
+
ReservationWithRelations,
|
|
153
|
+
UsePaginatedReservationsOptions
|
|
154
|
+
>({
|
|
155
|
+
model: "Reservation",
|
|
156
|
+
dataPropertyName: "reservations",
|
|
157
|
+
defaultPageSize: 25,
|
|
158
|
+
selectionSet: RESERVATION_SELECTION_SET,
|
|
159
|
+
transform: transformReservation,
|
|
160
|
+
buildFilter,
|
|
161
|
+
baseFilter: ACTIVE_FILTER,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Internal hook for deleted reservations
|
|
166
|
+
*/
|
|
167
|
+
const useDeletedReservationsInternal = createPaginatedDataHook<
|
|
168
|
+
ReservationWithRelations,
|
|
169
|
+
UsePaginatedReservationsOptions
|
|
170
|
+
>({
|
|
171
|
+
model: "Reservation",
|
|
172
|
+
dataPropertyName: "reservations",
|
|
173
|
+
defaultPageSize: 25,
|
|
174
|
+
selectionSet: RESERVATION_SELECTION_SET,
|
|
175
|
+
transform: transformReservation,
|
|
176
|
+
buildFilter,
|
|
177
|
+
baseFilter: DELETED_FILTER,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Composable for fetching active (non-deleted) reservations with pagination
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* import { useActiveReservations } from '@htlkg/data/hooks';
|
|
186
|
+
*
|
|
187
|
+
* const { reservations, loading, hasMore, loadMore, refetch } = useActiveReservations({
|
|
188
|
+
* pageSize: 25,
|
|
189
|
+
* brandId: 'brand-123',
|
|
190
|
+
* });
|
|
191
|
+
*
|
|
192
|
+
* // Load more when user scrolls or clicks "Load More"
|
|
193
|
+
* async function onLoadMore() {
|
|
194
|
+
* await loadMore();
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* @example With date filters
|
|
199
|
+
* ```typescript
|
|
200
|
+
* const { reservations, loading } = useActiveReservations({
|
|
201
|
+
* brandId: 'brand-123',
|
|
202
|
+
* startDate: '2026-01-01',
|
|
203
|
+
* endDate: '2026-01-31',
|
|
204
|
+
* status: 'confirmed'
|
|
205
|
+
* });
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
export function useActiveReservations(
|
|
209
|
+
options: UsePaginatedReservationsOptions = {},
|
|
210
|
+
): UsePaginatedReservationsReturn {
|
|
211
|
+
const result = useActiveReservationsInternal(options);
|
|
212
|
+
return {
|
|
213
|
+
reservations: result.reservations as Ref<ReservationWithRelations[]>,
|
|
214
|
+
loading: result.loading,
|
|
215
|
+
initialLoading: result.initialLoading,
|
|
216
|
+
loadingMore: result.loadingMore,
|
|
217
|
+
error: result.error,
|
|
218
|
+
pagination: result.pagination,
|
|
219
|
+
hasMore: result.hasMore,
|
|
220
|
+
loadMore: result.loadMore,
|
|
221
|
+
refetch: result.refetch,
|
|
222
|
+
reset: result.reset,
|
|
223
|
+
setSearchFilter: result.setSearchFilter,
|
|
224
|
+
searchFilter: result.searchFilter,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Composable for fetching deleted reservations with pagination
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* import { useDeletedReservations } from '@htlkg/data/hooks';
|
|
234
|
+
*
|
|
235
|
+
* const { reservations, loading, hasMore, loadMore, refetch } = useDeletedReservations({
|
|
236
|
+
* pageSize: 25,
|
|
237
|
+
* });
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
export function useDeletedReservations(
|
|
241
|
+
options: UsePaginatedReservationsOptions = {},
|
|
242
|
+
): UsePaginatedReservationsReturn {
|
|
243
|
+
const result = useDeletedReservationsInternal(options);
|
|
244
|
+
return {
|
|
245
|
+
reservations: result.reservations as Ref<ReservationWithRelations[]>,
|
|
246
|
+
loading: result.loading,
|
|
247
|
+
initialLoading: result.initialLoading,
|
|
248
|
+
loadingMore: result.loadingMore,
|
|
249
|
+
error: result.error,
|
|
250
|
+
pagination: result.pagination,
|
|
251
|
+
hasMore: result.hasMore,
|
|
252
|
+
loadMore: result.loadMore,
|
|
253
|
+
refetch: result.refetch,
|
|
254
|
+
reset: result.reset,
|
|
255
|
+
setSearchFilter: result.setSearchFilter,
|
|
256
|
+
searchFilter: result.searchFilter,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Ref, ComputedRef } from "vue";
|
|
9
|
-
import type { Reservation } from "
|
|
10
|
-
import { createDataHook, type BaseHookOptions } from "
|
|
9
|
+
import type { Reservation } from "../../queries/reservations";
|
|
10
|
+
import { createDataHook, type BaseHookOptions } from "../createDataHook";
|
|
11
11
|
|
|
12
12
|
export interface UseReservationsOptions extends BaseHookOptions {
|
|
13
13
|
/** Filter by brand ID */
|
|
@@ -24,13 +24,21 @@ export interface UseReservationsOptions extends BaseHookOptions {
|
|
|
24
24
|
nextToken?: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/** Extended reservation type with related data */
|
|
28
|
+
export type ReservationWithRelations = Reservation & {
|
|
29
|
+
brandName: string;
|
|
30
|
+
guestName: string;
|
|
31
|
+
guestEmail: string;
|
|
32
|
+
guestPhone: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
27
35
|
export interface UseReservationsReturn {
|
|
28
|
-
/** Reactive array of reservations */
|
|
29
|
-
reservations: Ref<
|
|
36
|
+
/** Reactive array of reservations with brand and guest info */
|
|
37
|
+
reservations: Ref<ReservationWithRelations[]>;
|
|
30
38
|
/** Computed array of confirmed reservations */
|
|
31
|
-
confirmedReservations: ComputedRef<
|
|
39
|
+
confirmedReservations: ComputedRef<ReservationWithRelations[]>;
|
|
32
40
|
/** Computed array of active reservations (confirmed or checked_in) */
|
|
33
|
-
activeReservations: ComputedRef<
|
|
41
|
+
activeReservations: ComputedRef<ReservationWithRelations[]>;
|
|
34
42
|
/** Loading state */
|
|
35
43
|
loading: Ref<boolean>;
|
|
36
44
|
/** Error state */
|
|
@@ -80,17 +88,64 @@ function buildFilter(options: UseReservationsOptions): any {
|
|
|
80
88
|
return { and: conditions };
|
|
81
89
|
}
|
|
82
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Transform reservation data to include brandName and guest info from visit.snapshot
|
|
93
|
+
*/
|
|
94
|
+
function transformReservation(r: any): Reservation & { brandName: string; guestName: string; guestEmail: string; guestPhone: string } {
|
|
95
|
+
// Parse snapshot if it's a string (handles double-stringification from import)
|
|
96
|
+
let snapshot = r.visit?.snapshot;
|
|
97
|
+
if (typeof snapshot === "string") {
|
|
98
|
+
try {
|
|
99
|
+
snapshot = JSON.parse(snapshot);
|
|
100
|
+
} catch {
|
|
101
|
+
snapshot = null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
...r,
|
|
107
|
+
brandName: r.brand?.name || "Unknown Brand",
|
|
108
|
+
guestName: snapshot
|
|
109
|
+
? `${snapshot.firstName || ""} ${snapshot.lastName || ""}`.trim() || "Unknown Guest"
|
|
110
|
+
: "Unknown Guest",
|
|
111
|
+
guestEmail: snapshot?.email || "",
|
|
112
|
+
guestPhone: snapshot?.phone || "",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
83
116
|
/**
|
|
84
117
|
* Internal hook created by factory
|
|
85
118
|
*/
|
|
86
119
|
const useReservationsInternal = createDataHook<
|
|
87
|
-
Reservation,
|
|
120
|
+
Reservation & { brandName: string; guestName: string; guestEmail: string; guestPhone: string },
|
|
88
121
|
UseReservationsOptions,
|
|
89
122
|
{ confirmedReservations: Reservation[]; activeReservations: Reservation[] }
|
|
90
123
|
>({
|
|
91
124
|
model: "Reservation",
|
|
92
125
|
dataPropertyName: "reservations",
|
|
93
126
|
buildFilter,
|
|
127
|
+
// Include related data for brand name and guest info
|
|
128
|
+
selectionSet: [
|
|
129
|
+
"id",
|
|
130
|
+
"brandId",
|
|
131
|
+
"visitId",
|
|
132
|
+
"checkIn",
|
|
133
|
+
"checkOut",
|
|
134
|
+
"room",
|
|
135
|
+
"roomType",
|
|
136
|
+
"status",
|
|
137
|
+
"source",
|
|
138
|
+
"channel",
|
|
139
|
+
"confirmationCode",
|
|
140
|
+
"totalAmount",
|
|
141
|
+
"currency",
|
|
142
|
+
"nights",
|
|
143
|
+
"deletedAt",
|
|
144
|
+
"deletedBy",
|
|
145
|
+
"brand.name",
|
|
146
|
+
"visit.snapshot",
|
|
147
|
+
],
|
|
148
|
+
transform: transformReservation,
|
|
94
149
|
computedProperties: {
|
|
95
150
|
confirmedReservations: (reservations) =>
|
|
96
151
|
reservations.filter((r) => r.status === "confirmed"),
|
|
@@ -135,9 +190,9 @@ const useReservationsInternal = createDataHook<
|
|
|
135
190
|
export function useReservations(options: UseReservationsOptions = {}): UseReservationsReturn {
|
|
136
191
|
const result = useReservationsInternal(options);
|
|
137
192
|
return {
|
|
138
|
-
reservations: result.reservations as Ref<
|
|
139
|
-
confirmedReservations: result.confirmedReservations as ComputedRef<
|
|
140
|
-
activeReservations: result.activeReservations as ComputedRef<
|
|
193
|
+
reservations: result.reservations as Ref<ReservationWithRelations[]>,
|
|
194
|
+
confirmedReservations: result.confirmedReservations as ComputedRef<ReservationWithRelations[]>,
|
|
195
|
+
activeReservations: result.activeReservations as ComputedRef<ReservationWithRelations[]>,
|
|
141
196
|
loading: result.loading,
|
|
142
197
|
error: result.error,
|
|
143
198
|
refetch: result.refetch,
|