@duongthiu/onex-core 0.1.0 → 0.1.1
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 +44 -65
- package/THEME_API.md +36 -33
- package/dist/api.js +14 -0
- package/dist/api.js.map +1 -0
- package/dist/api.mjs +5 -0
- package/dist/api.mjs.map +1 -0
- package/dist/auth.js +23 -0
- package/dist/auth.js.map +1 -0
- package/dist/auth.mjs +6 -0
- package/dist/auth.mjs.map +1 -0
- package/dist/blog.js +22 -0
- package/dist/blog.js.map +1 -0
- package/dist/blog.mjs +5 -0
- package/dist/blog.mjs.map +1 -0
- package/dist/cart.js +27 -0
- package/dist/cart.js.map +1 -0
- package/dist/cart.mjs +6 -0
- package/dist/cart.mjs.map +1 -0
- package/dist/chunk-2CSWHI3L.js +210 -0
- package/dist/chunk-2CSWHI3L.js.map +1 -0
- package/dist/chunk-2FGHIDUV.js +99 -0
- package/dist/chunk-2FGHIDUV.js.map +1 -0
- package/dist/chunk-2NMEKWO5.js +40 -0
- package/dist/chunk-2NMEKWO5.js.map +1 -0
- package/dist/chunk-43BVHGDT.mjs +131 -0
- package/dist/chunk-43BVHGDT.mjs.map +1 -0
- package/dist/chunk-4JVQJI3I.mjs +290 -0
- package/dist/chunk-4JVQJI3I.mjs.map +1 -0
- package/dist/chunk-5N2EKK5O.js +9550 -0
- package/dist/chunk-5N2EKK5O.js.map +1 -0
- package/dist/chunk-5T6NDVSN.js +76 -0
- package/dist/chunk-5T6NDVSN.js.map +1 -0
- package/dist/chunk-73AINNCI.mjs +201 -0
- package/dist/chunk-73AINNCI.mjs.map +1 -0
- package/dist/chunk-AIXBDAVP.mjs +61 -0
- package/dist/chunk-AIXBDAVP.mjs.map +1 -0
- package/dist/chunk-ALYN5HAC.js +210 -0
- package/dist/chunk-ALYN5HAC.js.map +1 -0
- package/dist/chunk-AREMJR3Q.js +36 -0
- package/dist/chunk-AREMJR3Q.js.map +1 -0
- package/dist/chunk-DXAI6XOI.mjs +33 -0
- package/dist/chunk-DXAI6XOI.mjs.map +1 -0
- package/dist/chunk-F5TFNWFJ.mjs +257 -0
- package/dist/chunk-F5TFNWFJ.mjs.map +1 -0
- package/dist/chunk-FQ7FWUZN.js +265 -0
- package/dist/chunk-FQ7FWUZN.js.map +1 -0
- package/dist/{chunk-3SZX6LHT.js → chunk-J27VGXJH.js} +2 -24
- package/dist/chunk-J27VGXJH.js.map +1 -0
- package/dist/chunk-JZ46LLTZ.js +121 -0
- package/dist/chunk-JZ46LLTZ.js.map +1 -0
- package/dist/chunk-K24UHN6G.mjs +76 -0
- package/dist/chunk-K24UHN6G.mjs.map +1 -0
- package/dist/chunk-KCQGGU5R.mjs +344 -0
- package/dist/chunk-KCQGGU5R.mjs.map +1 -0
- package/dist/chunk-MT22NYKT.mjs +117 -0
- package/dist/chunk-MT22NYKT.mjs.map +1 -0
- package/dist/chunk-NDD472IZ.js +85 -0
- package/dist/chunk-NDD472IZ.js.map +1 -0
- package/dist/chunk-NHOIGGYU.mjs +833 -0
- package/dist/chunk-NHOIGGYU.mjs.map +1 -0
- package/dist/chunk-O3XR7TW3.mjs +12 -0
- package/dist/chunk-O3XR7TW3.mjs.map +1 -0
- package/dist/chunk-OAPYSC2X.mjs +206 -0
- package/dist/chunk-OAPYSC2X.mjs.map +1 -0
- package/dist/{chunk-XE4EOKS4.mjs → chunk-ONJREDYY.mjs} +3 -23
- package/dist/chunk-ONJREDYY.mjs.map +1 -0
- package/dist/chunk-OVT2LUAM.js +197 -0
- package/dist/chunk-OVT2LUAM.js.map +1 -0
- package/dist/chunk-OWNGNGKL.js +331 -0
- package/dist/chunk-OWNGNGKL.js.map +1 -0
- package/dist/chunk-P7SXNZSV.js +298 -0
- package/dist/chunk-P7SXNZSV.js.map +1 -0
- package/dist/chunk-PFJOL3HI.mjs +71 -0
- package/dist/chunk-PFJOL3HI.mjs.map +1 -0
- package/dist/chunk-PPULMWJ6.js +295 -0
- package/dist/chunk-PPULMWJ6.js.map +1 -0
- package/dist/chunk-RGIVKACG.js +359 -0
- package/dist/chunk-RGIVKACG.js.map +1 -0
- package/dist/chunk-RPP5K2LP.js +870 -0
- package/dist/chunk-RPP5K2LP.js.map +1 -0
- package/dist/{chunk-7EON6Q4L.mjs → chunk-RUCHWUD7.mjs} +7651 -6370
- package/dist/chunk-RUCHWUD7.mjs.map +1 -0
- package/dist/chunk-SEVUIX4H.js +137 -0
- package/dist/chunk-SEVUIX4H.js.map +1 -0
- package/dist/chunk-SK2FSHFM.mjs +208 -0
- package/dist/chunk-SK2FSHFM.mjs.map +1 -0
- package/dist/chunk-T6EJ2GAV.mjs +294 -0
- package/dist/chunk-T6EJ2GAV.mjs.map +1 -0
- package/dist/chunk-ULBDOFZI.mjs +302 -0
- package/dist/chunk-ULBDOFZI.mjs.map +1 -0
- package/dist/chunk-V3JIELNV.js +241 -0
- package/dist/chunk-V3JIELNV.js.map +1 -0
- package/dist/chunk-V5E2KWMA.mjs +238 -0
- package/dist/chunk-V5E2KWMA.mjs.map +1 -0
- package/dist/chunk-VJA3ER6A.js +14 -0
- package/dist/chunk-VJA3ER6A.js.map +1 -0
- package/dist/chunk-VLI7ULX5.js +66 -0
- package/dist/chunk-VLI7ULX5.js.map +1 -0
- package/dist/chunk-WFGS5OFH.mjs +189 -0
- package/dist/chunk-WFGS5OFH.mjs.map +1 -0
- package/dist/chunk-WVC5GP24.mjs +96 -0
- package/dist/chunk-WVC5GP24.mjs.map +1 -0
- package/dist/chunk-YOSPWY5K.mjs +36 -0
- package/dist/chunk-YOSPWY5K.mjs.map +1 -0
- package/dist/chunk-ZFFXXLX7.js +205 -0
- package/dist/chunk-ZFFXXLX7.js.map +1 -0
- package/dist/client.js +512 -249
- package/dist/client.mjs +21 -2
- package/dist/components.js +393 -0
- package/dist/components.js.map +1 -0
- package/dist/components.mjs +8 -0
- package/dist/components.mjs.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/config.mjs +4 -0
- package/dist/config.mjs.map +1 -0
- package/dist/contact.js +22 -0
- package/dist/contact.js.map +1 -0
- package/dist/contact.mjs +5 -0
- package/dist/contact.mjs.map +1 -0
- package/dist/contexts.js +51 -0
- package/dist/contexts.js.map +1 -0
- package/dist/contexts.mjs +6 -0
- package/dist/contexts.mjs.map +1 -0
- package/dist/finance.js +26 -0
- package/dist/finance.js.map +1 -0
- package/dist/finance.mjs +5 -0
- package/dist/finance.mjs.map +1 -0
- package/dist/icons.js +15 -0
- package/dist/icons.js.map +1 -0
- package/dist/icons.mjs +4 -0
- package/dist/icons.mjs.map +1 -0
- package/dist/index.js +512 -249
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -2
- package/dist/index.mjs.map +1 -1
- package/dist/internal.js +1437 -0
- package/dist/internal.js.map +1 -0
- package/dist/internal.mjs +1404 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/motion.js +51 -0
- package/dist/motion.js.map +1 -0
- package/dist/motion.mjs +38 -0
- package/dist/motion.mjs.map +1 -0
- package/dist/orders.js +22 -0
- package/dist/orders.js.map +1 -0
- package/dist/orders.mjs +5 -0
- package/dist/orders.mjs.map +1 -0
- package/dist/products.js +27 -0
- package/dist/products.js.map +1 -0
- package/dist/products.mjs +6 -0
- package/dist/products.mjs.map +1 -0
- package/dist/registry.js +44 -0
- package/dist/registry.js.map +1 -0
- package/dist/registry.mjs +7 -0
- package/dist/registry.mjs.map +1 -0
- package/dist/renderers.js +51 -0
- package/dist/renderers.js.map +1 -0
- package/dist/renderers.mjs +6 -0
- package/dist/renderers.mjs.map +1 -0
- package/dist/server.js +11 -189
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +3 -186
- package/dist/server.mjs.map +1 -1
- package/dist/types.js +37 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +4 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils.js +160 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +7 -0
- package/dist/utils.mjs.map +1 -0
- package/dist/wrappers.js +104 -0
- package/dist/wrappers.js.map +1 -0
- package/dist/wrappers.mjs +96 -0
- package/dist/wrappers.mjs.map +1 -0
- package/package.json +112 -9
- package/dist/api-vuL1Eg5L.d.mts +0 -2961
- package/dist/api-vuL1Eg5L.d.ts +0 -2961
- package/dist/chunk-3SZX6LHT.js.map +0 -1
- package/dist/chunk-7EON6Q4L.mjs.map +0 -1
- package/dist/chunk-WDY773GJ.js +0 -8308
- package/dist/chunk-WDY773GJ.js.map +0 -1
- package/dist/chunk-XE4EOKS4.mjs.map +0 -1
- package/dist/client.d.mts +0 -1461
- package/dist/client.d.ts +0 -1461
- package/dist/index.d.mts +0 -125
- package/dist/index.d.ts +0 -125
- package/dist/server.d.mts +0 -70
- package/dist/server.d.ts +0 -70
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var zustand = require('zustand');
|
|
5
|
+
|
|
6
|
+
// src/features/finance/use-finance.ts
|
|
7
|
+
var financeService = null;
|
|
8
|
+
var useFinance = zustand.create((set) => ({
|
|
9
|
+
// Initial state
|
|
10
|
+
qrCode: null,
|
|
11
|
+
isLoading: false,
|
|
12
|
+
error: null,
|
|
13
|
+
/**
|
|
14
|
+
* Create QR code for bank transfer
|
|
15
|
+
*/
|
|
16
|
+
createQrCode: async (payload) => {
|
|
17
|
+
if (!financeService) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"Finance service not initialized. Call initializeOnex() first."
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
set({ isLoading: true, error: null });
|
|
23
|
+
try {
|
|
24
|
+
const qrCode = await financeService.createQrCode(payload);
|
|
25
|
+
set({ qrCode, isLoading: false });
|
|
26
|
+
return qrCode;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
set({ error: error.message, isLoading: false });
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* Clear QR code
|
|
34
|
+
*/
|
|
35
|
+
clearQrCode: () => {
|
|
36
|
+
set({ qrCode: null });
|
|
37
|
+
},
|
|
38
|
+
/**
|
|
39
|
+
* Clear error
|
|
40
|
+
*/
|
|
41
|
+
clearError: () => {
|
|
42
|
+
set({ error: null });
|
|
43
|
+
}
|
|
44
|
+
}));
|
|
45
|
+
function initializeFinanceService(service) {
|
|
46
|
+
financeService = service;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/features/finance/finance-service.ts
|
|
50
|
+
var FinanceService = class {
|
|
51
|
+
constructor(api) {
|
|
52
|
+
this.api = api;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Create QR code for bank transfer
|
|
56
|
+
*/
|
|
57
|
+
async createQrCode(payload) {
|
|
58
|
+
return await this.api.post("/finance/public/qr", payload);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// src/features/finance/constants.ts
|
|
63
|
+
var BANK_TRANSFER_DATA = {
|
|
64
|
+
account_number: "999914287",
|
|
65
|
+
account_name: "CONG TY TNHH TIN AN",
|
|
66
|
+
bank_id: "970422",
|
|
67
|
+
// MB Bank
|
|
68
|
+
bank_name: "Ng\xE2n h\xE0ng Qu\xE2n \u0111\u1ED9i (MB Bank)"
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
exports.BANK_TRANSFER_DATA = BANK_TRANSFER_DATA;
|
|
72
|
+
exports.FinanceService = FinanceService;
|
|
73
|
+
exports.initializeFinanceService = initializeFinanceService;
|
|
74
|
+
exports.useFinance = useFinance;
|
|
75
|
+
//# sourceMappingURL=chunk-5T6NDVSN.js.map
|
|
76
|
+
//# sourceMappingURL=chunk-5T6NDVSN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/finance/use-finance.ts","../src/features/finance/finance-service.ts","../src/features/finance/constants.ts"],"names":["create"],"mappings":";;;;;AAqBA,IAAI,cAAA,GAAwC,IAAA;AAErC,IAAM,UAAA,GAAaA,cAAA,CAAqB,CAAC,GAAA,MAAS;AAAA;AAAA,EAEvD,MAAA,EAAQ,IAAA;AAAA,EACR,SAAA,EAAW,KAAA;AAAA,EACX,KAAA,EAAO,IAAA;AAAA;AAAA;AAAA;AAAA,EAKP,YAAA,EAAc,OAAO,OAAA,KAAY;AAC/B,IAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,GAAA,CAAI,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AACpC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,YAAA,CAAa,OAAO,CAAA;AACxD,MAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,CAAA;AAChC,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,GAAA,CAAI,EAAE,KAAA,EAAQ,KAAA,CAAgB,OAAA,EAAS,SAAA,EAAW,OAAO,CAAA;AACzD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,MAAM;AACjB,IAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,EACtB,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,MAAM;AAChB,IAAA,GAAA,CAAI,EAAE,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,EACrB;AACF,CAAA,CAAE;AAMK,SAAS,yBAAyB,OAAA,EAA+B;AACtE,EAAA,cAAA,GAAiB,OAAA;AACnB;;;AC/DO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAAoB,GAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAiB;AAAA;AAAA;AAAA;AAAA,EAKrC,MAAM,aAAa,OAAA,EAA+C;AAChE,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAiB,sBAAsB,OAAO,CAAA;AAAA,EACtE;AACF;;;ACZO,IAAM,kBAAA,GAAqB;AAAA,EAChC,cAAA,EAAgB,WAAA;AAAA,EAChB,YAAA,EAAc,qBAAA;AAAA,EACd,OAAA,EAAS,QAAA;AAAA;AAAA,EACT,SAAA,EAAW;AACb","file":"chunk-5T6NDVSN.js","sourcesContent":["/**\n * Finance Hook\n * Zustand store for finance operations (QR code generation)\n */\n\nimport { create } from \"zustand\";\nimport { FinanceService } from \"./finance-service\";\nimport type { CreateQrPayload, QrResponse } from \"./types\";\n\ninterface FinanceState {\n // State\n qrCode: QrResponse | null;\n isLoading: boolean;\n error: string | null;\n\n // Actions\n createQrCode: (payload: CreateQrPayload) => Promise<QrResponse>;\n clearQrCode: () => void;\n clearError: () => void;\n}\n\nlet financeService: FinanceService | null = null;\n\nexport const useFinance = create<FinanceState>((set) => ({\n // Initial state\n qrCode: null,\n isLoading: false,\n error: null,\n\n /**\n * Create QR code for bank transfer\n */\n createQrCode: async (payload) => {\n if (!financeService) {\n throw new Error(\n \"Finance service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const qrCode = await financeService.createQrCode(payload);\n set({ qrCode, isLoading: false });\n return qrCode;\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Clear QR code\n */\n clearQrCode: () => {\n set({ qrCode: null });\n },\n\n /**\n * Clear error\n */\n clearError: () => {\n set({ error: null });\n },\n}));\n\n/**\n * Initialize finance service\n * @internal Called by initializeOnex()\n */\nexport function initializeFinanceService(service: FinanceService): void {\n financeService = service;\n}\n","/**\n * Finance Service\n * Handles QR code generation for bank transfers\n */\n\nimport { ApiClient } from \"../../api/client\";\nimport type { CreateQrPayload, QrResponse } from \"./types\";\n\nexport class FinanceService {\n constructor(private api: ApiClient) {}\n\n /**\n * Create QR code for bank transfer\n */\n async createQrCode(payload: CreateQrPayload): Promise<QrResponse> {\n return await this.api.post<QrResponse>(\"/finance/public/qr\", payload);\n }\n}\n","/**\n * Finance Constants\n * Bank transfer configuration\n */\n\nexport const BANK_TRANSFER_DATA = {\n account_number: \"999914287\",\n account_name: \"CONG TY TNHH TIN AN\",\n bank_id: \"970422\", // MB Bank\n bank_name: \"Ngân hàng Quân đội (MB Bank)\",\n} as const;\n"]}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { create } from 'zustand';
|
|
3
|
+
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
4
|
+
|
|
5
|
+
// src/features/cart/cart-service.ts
|
|
6
|
+
var CartService = class {
|
|
7
|
+
constructor(api) {
|
|
8
|
+
this.api = api;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Get current cart
|
|
12
|
+
*/
|
|
13
|
+
async getCart() {
|
|
14
|
+
return await this.api.get("/cart");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Add item to cart
|
|
18
|
+
*/
|
|
19
|
+
async addItem(data) {
|
|
20
|
+
return await this.api.post("/cart/items", data);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Update cart item quantity
|
|
24
|
+
*/
|
|
25
|
+
async updateQuantity(data) {
|
|
26
|
+
return await this.api.put(`/cart/items/${data.itemId}`, {
|
|
27
|
+
quantity: data.quantity
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Remove item from cart
|
|
32
|
+
*/
|
|
33
|
+
async removeItem(itemId) {
|
|
34
|
+
await this.api.delete(`/cart/items/${itemId}`);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Clear entire cart
|
|
38
|
+
*/
|
|
39
|
+
async clearCart() {
|
|
40
|
+
await this.api.delete("/cart");
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var cartService = null;
|
|
44
|
+
var useCart = create()(
|
|
45
|
+
persist(
|
|
46
|
+
(set, get) => ({
|
|
47
|
+
// Initial state
|
|
48
|
+
items: [],
|
|
49
|
+
isLoading: false,
|
|
50
|
+
error: null,
|
|
51
|
+
// Computed properties (getters)
|
|
52
|
+
get total() {
|
|
53
|
+
return get().items.reduce(
|
|
54
|
+
(sum, item) => sum + item.price * item.quantity,
|
|
55
|
+
0
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
get itemCount() {
|
|
59
|
+
return get().items.reduce((sum, item) => sum + item.quantity, 0);
|
|
60
|
+
},
|
|
61
|
+
get subtotal() {
|
|
62
|
+
return get().total;
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* Fetch cart from server
|
|
66
|
+
*/
|
|
67
|
+
fetchCart: async () => {
|
|
68
|
+
if (!cartService) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
"Cart service not initialized. Call initializeOnex() first."
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
set({ isLoading: true, error: null });
|
|
74
|
+
try {
|
|
75
|
+
const cart = await cartService.getCart();
|
|
76
|
+
set({ items: cart.items, isLoading: false });
|
|
77
|
+
} catch (error) {
|
|
78
|
+
set({ error: error.message, isLoading: false });
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Add item to cart
|
|
83
|
+
*/
|
|
84
|
+
addItem: async (data) => {
|
|
85
|
+
if (!cartService) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
"Cart service not initialized. Call initializeOnex() first."
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
set({ isLoading: true, error: null });
|
|
91
|
+
try {
|
|
92
|
+
const item = await cartService.addItem(data);
|
|
93
|
+
set((state) => {
|
|
94
|
+
const existingItemIndex = state.items.findIndex(
|
|
95
|
+
(i) => i.productId === data.productId && i.variant === data.variant
|
|
96
|
+
);
|
|
97
|
+
if (existingItemIndex >= 0) {
|
|
98
|
+
const updatedItems = [...state.items];
|
|
99
|
+
updatedItems[existingItemIndex] = item;
|
|
100
|
+
return { items: updatedItems, isLoading: false };
|
|
101
|
+
} else {
|
|
102
|
+
return {
|
|
103
|
+
items: [...state.items, item],
|
|
104
|
+
isLoading: false
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
} catch (error) {
|
|
109
|
+
set({ error: error.message, isLoading: false });
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* Update cart item quantity
|
|
115
|
+
* Supports both: updateQuantity({itemId, quantity}) and updateQuantity(itemId, quantity)
|
|
116
|
+
*/
|
|
117
|
+
updateQuantity: async (dataOrItemId, quantity) => {
|
|
118
|
+
if (!cartService) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
"Cart service not initialized. Call initializeOnex() first."
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
const data = typeof dataOrItemId === "string" ? { itemId: dataOrItemId, quantity } : dataOrItemId;
|
|
124
|
+
set({ isLoading: true, error: null });
|
|
125
|
+
try {
|
|
126
|
+
const updatedItem = await cartService.updateQuantity(data);
|
|
127
|
+
set((state) => ({
|
|
128
|
+
items: state.items.map(
|
|
129
|
+
(item) => item.id === data.itemId ? updatedItem : item
|
|
130
|
+
),
|
|
131
|
+
isLoading: false
|
|
132
|
+
}));
|
|
133
|
+
} catch (error) {
|
|
134
|
+
set({ error: error.message, isLoading: false });
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* Remove item from cart
|
|
140
|
+
*/
|
|
141
|
+
removeItem: async (itemId) => {
|
|
142
|
+
if (!cartService) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
"Cart service not initialized. Call initializeOnex() first."
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
set({ isLoading: true, error: null });
|
|
148
|
+
try {
|
|
149
|
+
await cartService.removeItem(itemId);
|
|
150
|
+
set((state) => ({
|
|
151
|
+
items: state.items.filter((item) => item.id !== itemId),
|
|
152
|
+
isLoading: false
|
|
153
|
+
}));
|
|
154
|
+
} catch (error) {
|
|
155
|
+
set({ error: error.message, isLoading: false });
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
/**
|
|
160
|
+
* Clear entire cart
|
|
161
|
+
*/
|
|
162
|
+
clearCart: async () => {
|
|
163
|
+
if (!cartService) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
"Cart service not initialized. Call initializeOnex() first."
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
set({ isLoading: true, error: null });
|
|
169
|
+
try {
|
|
170
|
+
await cartService.clearCart();
|
|
171
|
+
set({ items: [], isLoading: false });
|
|
172
|
+
} catch (error) {
|
|
173
|
+
set({ error: error.message, isLoading: false });
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
/**
|
|
178
|
+
* Clear error
|
|
179
|
+
*/
|
|
180
|
+
clearError: () => {
|
|
181
|
+
set({ error: null });
|
|
182
|
+
}
|
|
183
|
+
}),
|
|
184
|
+
{
|
|
185
|
+
name: "onex-cart-storage",
|
|
186
|
+
// localStorage key
|
|
187
|
+
storage: createJSONStorage(
|
|
188
|
+
() => typeof window !== "undefined" ? localStorage : {}
|
|
189
|
+
),
|
|
190
|
+
partialize: (state) => ({ items: state.items })
|
|
191
|
+
// Only persist items
|
|
192
|
+
}
|
|
193
|
+
)
|
|
194
|
+
);
|
|
195
|
+
function initializeCartService(service) {
|
|
196
|
+
cartService = service;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export { CartService, initializeCartService, useCart };
|
|
200
|
+
//# sourceMappingURL=chunk-73AINNCI.mjs.map
|
|
201
|
+
//# sourceMappingURL=chunk-73AINNCI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/cart/cart-service.ts","../src/features/cart/use-cart.ts"],"names":[],"mappings":"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","file":"chunk-73AINNCI.mjs","sourcesContent":["/**\n * Cart Service\n * Handles all cart-related API calls\n */\n\nimport { ApiClient } from \"../../api/client\";\nimport type {\n Cart,\n CartItem,\n AddToCartData,\n UpdateCartItemData,\n} from \"./types\";\n\nexport class CartService {\n constructor(private api: ApiClient) {}\n\n /**\n * Get current cart\n */\n async getCart(): Promise<Cart> {\n return await this.api.get<Cart>(\"/cart\");\n }\n\n /**\n * Add item to cart\n */\n async addItem(data: AddToCartData): Promise<CartItem> {\n return await this.api.post<CartItem>(\"/cart/items\", data);\n }\n\n /**\n * Update cart item quantity\n */\n async updateQuantity(data: UpdateCartItemData): Promise<CartItem> {\n return await this.api.put<CartItem>(`/cart/items/${data.itemId}`, {\n quantity: data.quantity,\n });\n }\n\n /**\n * Remove item from cart\n */\n async removeItem(itemId: string): Promise<void> {\n await this.api.delete(`/cart/items/${itemId}`);\n }\n\n /**\n * Clear entire cart\n */\n async clearCart(): Promise<void> {\n await this.api.delete(\"/cart\");\n }\n}\n","/**\n * Cart Hook\n * Zustand store for cart state and actions with persistence\n */\n\nimport { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport { CartService } from \"./cart-service\";\nimport type { CartItem, AddToCartData, UpdateCartItemData } from \"./types\";\n\ninterface CartState {\n // State\n items: CartItem[];\n isLoading: boolean;\n error: string | null;\n\n // Computed properties\n total: number;\n itemCount: number;\n subtotal: number;\n\n // Actions\n fetchCart: () => Promise<void>;\n addItem: (data: AddToCartData) => Promise<void>;\n updateQuantity: (\n dataOrItemId: UpdateCartItemData | string,\n quantity?: number\n ) => Promise<void>;\n removeItem: (itemId: string) => Promise<void>;\n clearCart: () => Promise<void>;\n clearError: () => void;\n}\n\nlet cartService: CartService | null = null;\n\nexport const useCart = create<CartState>()(\n persist(\n (set, get) => ({\n // Initial state\n items: [],\n isLoading: false,\n error: null,\n\n // Computed properties (getters)\n get total() {\n return get().items.reduce(\n (sum, item) => sum + item.price * item.quantity,\n 0\n );\n },\n\n get itemCount() {\n return get().items.reduce((sum, item) => sum + item.quantity, 0);\n },\n\n get subtotal() {\n return get().total; // Can add tax/shipping logic here\n },\n\n /**\n * Fetch cart from server\n */\n fetchCart: async () => {\n if (!cartService) {\n throw new Error(\n \"Cart service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const cart = await cartService.getCart();\n set({ items: cart.items, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Add item to cart\n */\n addItem: async (data) => {\n if (!cartService) {\n throw new Error(\n \"Cart service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const item = await cartService.addItem(data);\n\n set((state) => {\n // Check if item already exists in cart\n const existingItemIndex = state.items.findIndex(\n (i) =>\n i.productId === data.productId && i.variant === data.variant\n );\n\n if (existingItemIndex >= 0) {\n // Update quantity if exists\n const updatedItems = [...state.items];\n updatedItems[existingItemIndex] = item;\n return { items: updatedItems, isLoading: false };\n } else {\n // Add new item\n return {\n items: [...state.items, item],\n isLoading: false,\n };\n }\n });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Update cart item quantity\n * Supports both: updateQuantity({itemId, quantity}) and updateQuantity(itemId, quantity)\n */\n updateQuantity: async (dataOrItemId, quantity?) => {\n if (!cartService) {\n throw new Error(\n \"Cart service not initialized. Call initializeOnex() first.\"\n );\n }\n\n // Normalize to UpdateCartItemData format\n const data: UpdateCartItemData =\n typeof dataOrItemId === \"string\"\n ? { itemId: dataOrItemId, quantity: quantity! }\n : dataOrItemId;\n\n set({ isLoading: true, error: null });\n try {\n const updatedItem = await cartService.updateQuantity(data);\n\n set((state) => ({\n items: state.items.map((item) =>\n item.id === data.itemId ? updatedItem : item\n ),\n isLoading: false,\n }));\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Remove item from cart\n */\n removeItem: async (itemId) => {\n if (!cartService) {\n throw new Error(\n \"Cart service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await cartService.removeItem(itemId);\n\n set((state) => ({\n items: state.items.filter((item) => item.id !== itemId),\n isLoading: false,\n }));\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Clear entire cart\n */\n clearCart: async () => {\n if (!cartService) {\n throw new Error(\n \"Cart service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await cartService.clearCart();\n set({ items: [], isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Clear error\n */\n clearError: () => {\n set({ error: null });\n },\n }),\n {\n name: \"onex-cart-storage\", // localStorage key\n storage: createJSONStorage(() =>\n typeof window !== \"undefined\" ? localStorage : ({} as Storage)\n ),\n partialize: (state) => ({ items: state.items }), // Only persist items\n }\n )\n);\n\n/**\n * Initialize cart service\n * @internal Called by initializeOnex()\n */\nexport function initializeCartService(service: CartService): void {\n cartService = service;\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { CartService, initializeCartService } from './chunk-73AINNCI.mjs';
|
|
3
|
+
import { ProductsService, initializeProductsService } from './chunk-ULBDOFZI.mjs';
|
|
4
|
+
import { OrdersService, initializeOrdersService } from './chunk-T6EJ2GAV.mjs';
|
|
5
|
+
import { validateConfig } from './chunk-DXAI6XOI.mjs';
|
|
6
|
+
import { ApiClient } from './chunk-43BVHGDT.mjs';
|
|
7
|
+
import { AuthService } from './chunk-SK2FSHFM.mjs';
|
|
8
|
+
import { FinanceService, initializeFinanceService } from './chunk-PFJOL3HI.mjs';
|
|
9
|
+
import { ContactService, initializeContactService } from './chunk-MT22NYKT.mjs';
|
|
10
|
+
import { BlogService, initializeBlogService } from './chunk-OAPYSC2X.mjs';
|
|
11
|
+
import { initializeAuthService } from './chunk-V5E2KWMA.mjs';
|
|
12
|
+
|
|
13
|
+
// src/init.ts
|
|
14
|
+
var isInitialized = false;
|
|
15
|
+
function initializeOnex(config) {
|
|
16
|
+
validateConfig(config);
|
|
17
|
+
if (isInitialized) {
|
|
18
|
+
console.warn("[OneX] Already initialized. Skipping re-initialization.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const apiClient = new ApiClient({
|
|
22
|
+
baseURL: config.apiUrl,
|
|
23
|
+
tokenStorage: config.tokenStorage || "localStorage",
|
|
24
|
+
onUnauthorized: config.onUnauthorized,
|
|
25
|
+
headers: config.headers
|
|
26
|
+
});
|
|
27
|
+
const authService = new AuthService(apiClient);
|
|
28
|
+
const cartService = new CartService(apiClient);
|
|
29
|
+
const productsService = new ProductsService(apiClient);
|
|
30
|
+
const ordersService = new OrdersService(apiClient);
|
|
31
|
+
const financeService = new FinanceService(apiClient);
|
|
32
|
+
const contactService = new ContactService(apiClient, config.companyId);
|
|
33
|
+
const blogService = new BlogService(apiClient, config.companyId);
|
|
34
|
+
initializeAuthService(authService);
|
|
35
|
+
initializeCartService(cartService);
|
|
36
|
+
initializeProductsService(productsService);
|
|
37
|
+
initializeOrdersService(ordersService);
|
|
38
|
+
initializeFinanceService(financeService);
|
|
39
|
+
initializeContactService(contactService);
|
|
40
|
+
initializeBlogService(blogService);
|
|
41
|
+
isInitialized = true;
|
|
42
|
+
if (typeof window !== "undefined") {
|
|
43
|
+
console.log("[OneX] Initialized successfully", {
|
|
44
|
+
apiUrl: config.apiUrl,
|
|
45
|
+
companyId: config.companyId
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function isOnexInitialized() {
|
|
50
|
+
return isInitialized;
|
|
51
|
+
}
|
|
52
|
+
function resetOnexInitialization() {
|
|
53
|
+
isInitialized = false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/client.ts
|
|
57
|
+
var version = "0.1.0";
|
|
58
|
+
|
|
59
|
+
export { initializeOnex, isOnexInitialized, resetOnexInitialization, version };
|
|
60
|
+
//# sourceMappingURL=chunk-AIXBDAVP.mjs.map
|
|
61
|
+
//# sourceMappingURL=chunk-AIXBDAVP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/init.ts","../src/client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAmBA,IAAI,aAAA,GAAgB,KAAA;AAoBb,SAAS,eAAe,MAAA,EAA0B;AAEvD,EAAA,cAAA,CAAe,MAAM,CAAA;AAErB,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,OAAA,CAAQ,KAAK,yDAAyD,CAAA;AACtE,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,GAAY,IAAI,SAAA,CAAU;AAAA,IAC9B,SAAS,MAAA,CAAO,MAAA;AAAA,IAChB,YAAA,EAAc,OAAO,YAAA,IAAgB,cAAA;AAAA,IACrC,gBAAgB,MAAA,CAAO,cAAA;AAAA,IACvB,SAAS,MAAA,CAAO;AAAA,GACjB,CAAA;AAGD,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY,SAAS,CAAA;AAC7C,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY,SAAS,CAAA;AAC7C,EAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,CAAgB,SAAS,CAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,IAAI,aAAA,CAAc,SAAS,CAAA;AACjD,EAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,SAAS,CAAA;AACnD,EAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,SAAA,EAAW,OAAO,SAAS,CAAA;AACrE,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY,SAAA,EAAW,OAAO,SAAS,CAAA;AAG/D,EAAA,qBAAA,CAAsB,WAAW,CAAA;AACjC,EAAA,qBAAA,CAAsB,WAAW,CAAA;AACjC,EAAA,yBAAA,CAA0B,eAAe,CAAA;AACzC,EAAA,uBAAA,CAAwB,aAAa,CAAA;AACrC,EAAA,wBAAA,CAAyB,cAAc,CAAA;AACvC,EAAA,wBAAA,CAAyB,cAAc,CAAA;AACvC,EAAA,qBAAA,CAAsB,WAAW,CAAA;AAEjC,EAAA,aAAA,GAAgB,IAAA;AAEhB,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAA,CAAQ,IAAI,iCAAA,EAAmC;AAAA,MAC7C,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,WAAW,MAAA,CAAO;AAAA,KACnB,CAAA;AAAA,EACH;AACF;AAKO,SAAS,iBAAA,GAA6B;AAC3C,EAAA,OAAO,aAAA;AACT;AAMO,SAAS,uBAAA,GAAgC;AAC9C,EAAA,aAAA,GAAgB,KAAA;AAClB;;;ACnFO,IAAM,OAAA,GAAU","file":"chunk-AIXBDAVP.mjs","sourcesContent":["/**\n * OneX Initialization\n * Call this once at app startup to initialize all services\n */\n\nimport { ApiClient } from \"./api/client\";\nimport { AuthService, initializeAuthService } from \"./features/auth\";\nimport { CartService, initializeCartService } from \"./features/cart\";\nimport {\n ProductsService,\n initializeProductsService,\n} from \"./features/products\";\nimport { OrdersService, initializeOrdersService } from \"./features/orders\";\nimport { FinanceService, initializeFinanceService } from \"./features/finance\";\nimport { ContactService, initializeContactService } from \"./features/contact\";\nimport { BlogService, initializeBlogService } from \"./features/blog\";\nimport type { OnexConfig } from \"./config\";\nimport { validateConfig } from \"./config\";\n\nlet isInitialized = false;\n\n/**\n * Initialize OneX SDK with configuration\n * Must be called before using any hooks (useAuth, useCart, etc.)\n *\n * @example\n * ```tsx\n * // In your app's root component or layout\n * import { initializeOnex } from '@duongthiu/onex-core';\n *\n * initializeOnex({\n * apiUrl: 'https://api-dev.onexeos.com',\n * companyId: '9e61d187-426a-45ec-914d-7aea8ca7d42d',\n * onUnauthorized: () => {\n * window.location.href = '/login';\n * }\n * });\n * ```\n */\nexport function initializeOnex(config: OnexConfig): void {\n // Validate config first\n validateConfig(config);\n\n if (isInitialized) {\n console.warn(\"[OneX] Already initialized. Skipping re-initialization.\");\n return;\n }\n\n // Create API client\n const apiClient = new ApiClient({\n baseURL: config.apiUrl,\n tokenStorage: config.tokenStorage || \"localStorage\",\n onUnauthorized: config.onUnauthorized,\n headers: config.headers,\n });\n\n // Initialize all services\n const authService = new AuthService(apiClient);\n const cartService = new CartService(apiClient);\n const productsService = new ProductsService(apiClient);\n const ordersService = new OrdersService(apiClient);\n const financeService = new FinanceService(apiClient);\n const contactService = new ContactService(apiClient, config.companyId);\n const blogService = new BlogService(apiClient, config.companyId);\n\n // Register services with hooks\n initializeAuthService(authService);\n initializeCartService(cartService);\n initializeProductsService(productsService);\n initializeOrdersService(ordersService);\n initializeFinanceService(financeService);\n initializeContactService(contactService);\n initializeBlogService(blogService);\n\n isInitialized = true;\n\n if (typeof window !== \"undefined\") {\n console.log(\"[OneX] Initialized successfully\", {\n apiUrl: config.apiUrl,\n companyId: config.companyId,\n });\n }\n}\n\n/**\n * Check if OneX is initialized\n */\nexport function isOnexInitialized(): boolean {\n return isInitialized;\n}\n\n/**\n * Reset initialization state (useful for testing)\n * @internal\n */\nexport function resetOnexInitialization(): void {\n isInitialized = false;\n}\n","\"use client\";\n\n/**\n * @onex/core/client - Client-Safe Exports\n *\n * This entry point exports only client-safe code that can be used in:\n * - Client Components (\"use client\")\n * - Server Components\n * - Shared utilities\n *\n * Does NOT include:\n * - ThemeRegistryManager (server-only, uses fs/promises)\n */\n\nexport const version = \"0.1.0\";\n\n// Type Definitions (all safe)\nexport * from \"./types\";\n\n// Registry Factories (client-safe - no fs operations)\nexport * from \"./registry/section-registry\";\nexport * from \"./registry/block-registry\";\nexport * from \"./registry/component-registry\";\n// NOTE: theme-registry-manager is NOT exported here (server-only)\n\n// Utility Functions (all pure functions, client-safe)\nexport * from \"./utils\";\n\n// Rendering Engine (all client components)\nexport * from \"./renderers\";\n\n// React Contexts (all client-safe)\nexport * from \"./contexts\";\n\n// Layout Components (all client-safe)\nexport * from \"./components\";\n\n// API Client\nexport { ApiClient } from \"./api/client\";\nexport type { ApiConfig, ApiResponse } from \"./api/client\";\n\n// Features (Auth, Cart, Products)\n// Re-export specific items to avoid conflicts with existing domain types\nexport { useAuth, initializeAuthService, AuthService } from \"./features/auth\";\nexport type {\n User,\n LoginCredentials,\n SignupData,\n ForgotPasswordData,\n ResetPasswordData,\n VerifyCodeData,\n ResendCodeData,\n ChangePasswordData,\n TokenData,\n UserAttribute,\n UserInfoResponse,\n AuthResponse,\n} from \"./features/auth\";\n\nexport { useCart, initializeCartService, CartService } from \"./features/cart\";\nexport type {\n CartItem as CartItemFeature,\n Cart as CartFeature,\n AddToCartData,\n UpdateCartItemData,\n} from \"./features/cart\";\n\nexport {\n useProducts,\n initializeProductsService,\n ProductsService,\n} from \"./features/products\";\nexport type {\n ProductsListResponse,\n ProductsListParams,\n} from \"./features/products\";\n\n// ProductCard Component\nexport { ProductCard } from \"./components/product-card\";\nexport type { ProductCardProps } from \"./components/product-card\";\n\n// Orders Feature\nexport {\n useOrders,\n initializeOrdersService,\n OrdersService,\n} from \"./features/orders\";\nexport type {\n Address,\n OrderItem,\n Order,\n CreateOrderData,\n OrdersListResponse,\n OrdersListParams,\n} from \"./features/orders\";\n\n// Finance Feature\nexport {\n useFinance,\n initializeFinanceService,\n FinanceService,\n BANK_TRANSFER_DATA,\n} from \"./features/finance\";\nexport type { CreateQrPayload, QrResponse } from \"./features/finance\";\n\n// Contact Feature\nexport {\n useContact,\n initializeContactService,\n ContactService,\n} from \"./features/contact\";\nexport type {\n ContactSubmitPayload,\n ContactSubmitResponse,\n ContactInfo,\n ContactFormField,\n} from \"./features/contact\";\n\n// Blog Feature\nexport { useBlog, initializeBlogService, BlogService } from \"./features/blog\";\nexport type {\n Blog,\n BlogCategory,\n BlogAuthor,\n BlogListResponse,\n BlogListParams,\n} from \"./features/blog\";\n\n// Configuration\nexport { validateConfig, createConfigFromEnv } from \"./config\";\nexport type { OnexConfig } from \"./config\";\n\n// Initialization\nexport {\n initializeOnex,\n isOnexInitialized,\n resetOnexInitialization,\n} from \"./init\";\n"]}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// src/features/auth/auth-service.ts
|
|
5
|
+
var AuthService = class {
|
|
6
|
+
constructor(api) {
|
|
7
|
+
this.api = api;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Transform Cognito UserAttributes to User object
|
|
11
|
+
*/
|
|
12
|
+
transformUserInfo(userInfo, tokens) {
|
|
13
|
+
const getAttribute = (name) => {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
return (_b = (_a = userInfo.UserAttributes) == null ? void 0 : _a.find((attr) => attr.Name === name)) == null ? void 0 : _b.Value;
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
id: getAttribute("sub") || "",
|
|
19
|
+
email: getAttribute("email") || "",
|
|
20
|
+
name: getAttribute("name") || "",
|
|
21
|
+
phone_number: getAttribute("phone_number"),
|
|
22
|
+
avatar: getAttribute("picture"),
|
|
23
|
+
address: getAttribute("address"),
|
|
24
|
+
ward: getAttribute("custom:ward"),
|
|
25
|
+
district: getAttribute("custom:district"),
|
|
26
|
+
city: getAttribute("custom:city"),
|
|
27
|
+
province_code: getAttribute("custom:province_code"),
|
|
28
|
+
district_code: getAttribute("custom:district_code"),
|
|
29
|
+
ward_code: getAttribute("custom:ward_code")
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Login with username and password
|
|
34
|
+
*/
|
|
35
|
+
async login(credentials) {
|
|
36
|
+
const tokenResponse = await this.api.post(
|
|
37
|
+
"/auth/login",
|
|
38
|
+
credentials
|
|
39
|
+
);
|
|
40
|
+
this.api.setToken(tokenResponse.AccessToken);
|
|
41
|
+
this.storeTokens(tokenResponse);
|
|
42
|
+
const userInfo = await this.api.get("/auth/user_info");
|
|
43
|
+
const user = this.transformUserInfo(userInfo, tokenResponse);
|
|
44
|
+
if (typeof window !== "undefined") {
|
|
45
|
+
localStorage.setItem("customer_id", user.id);
|
|
46
|
+
}
|
|
47
|
+
return user;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Signup with username, email, password, and name
|
|
51
|
+
*/
|
|
52
|
+
async signup(data) {
|
|
53
|
+
return await this.api.post("/auth/register", data);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Logout current user
|
|
57
|
+
*/
|
|
58
|
+
async logout() {
|
|
59
|
+
try {
|
|
60
|
+
this.api.clearToken();
|
|
61
|
+
this.clearTokens();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
this.api.clearToken();
|
|
64
|
+
this.clearTokens();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Send forgot password email
|
|
69
|
+
*/
|
|
70
|
+
async forgotPassword(data) {
|
|
71
|
+
return await this.api.post("/auth/forgot", data);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Reset password with code
|
|
75
|
+
*/
|
|
76
|
+
async resetPassword(data) {
|
|
77
|
+
return await this.api.post("/auth/new_password", data);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Verify code (email verification, 2FA, etc.)
|
|
81
|
+
*/
|
|
82
|
+
async verifyCode(data) {
|
|
83
|
+
return await this.api.post("/auth/confirm", data);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Verify code for password reset
|
|
87
|
+
*/
|
|
88
|
+
async verifyCodeReset(data) {
|
|
89
|
+
return await this.api.post(
|
|
90
|
+
"/auth/confirm_reset_password_code",
|
|
91
|
+
data
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Resend verification code
|
|
96
|
+
*/
|
|
97
|
+
async resendCode(data) {
|
|
98
|
+
return await this.api.post("/auth/resend_code", data);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get current user
|
|
102
|
+
*/
|
|
103
|
+
async getCurrentUser() {
|
|
104
|
+
try {
|
|
105
|
+
const accessToken = this.getAccessToken();
|
|
106
|
+
if (!accessToken) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const userInfo = await this.api.get("/auth/user_info");
|
|
110
|
+
const tokens = this.getTokens();
|
|
111
|
+
if (!tokens) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
return this.transformUserInfo(userInfo, tokens);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Update user profile
|
|
121
|
+
*/
|
|
122
|
+
async updateProfile(data) {
|
|
123
|
+
const payload = {};
|
|
124
|
+
if (data.name) payload.name = data.name;
|
|
125
|
+
if (data.phone_number) payload.phone_number = data.phone_number;
|
|
126
|
+
if (data.address) payload.address = data.address;
|
|
127
|
+
if (data.avatar) payload.picture = data.avatar;
|
|
128
|
+
if (data.ward) payload["custom:ward"] = data.ward;
|
|
129
|
+
if (data.district) payload["custom:district"] = data.district;
|
|
130
|
+
if (data.city) payload["custom:city"] = data.city;
|
|
131
|
+
if (data.province_code)
|
|
132
|
+
payload["custom:province_code"] = data.province_code;
|
|
133
|
+
if (data.district_code)
|
|
134
|
+
payload["custom:district_code"] = data.district_code;
|
|
135
|
+
if (data.ward_code) payload["custom:ward_code"] = data.ward_code;
|
|
136
|
+
return await this.api.post("/auth/user_info", payload);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Change password
|
|
140
|
+
*/
|
|
141
|
+
async changePassword(data) {
|
|
142
|
+
return await this.api.post(
|
|
143
|
+
"/auth/change_password",
|
|
144
|
+
data
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Refresh access token
|
|
149
|
+
*/
|
|
150
|
+
async refreshToken() {
|
|
151
|
+
const tokens = this.getTokens();
|
|
152
|
+
if (!(tokens == null ? void 0 : tokens.RefreshToken)) {
|
|
153
|
+
throw new Error("No refresh token available");
|
|
154
|
+
}
|
|
155
|
+
const newTokens = await this.api.post("/auth/refresh", {
|
|
156
|
+
refresh_token: tokens.RefreshToken
|
|
157
|
+
});
|
|
158
|
+
this.storeTokens(newTokens);
|
|
159
|
+
this.api.setToken(newTokens.AccessToken);
|
|
160
|
+
return newTokens;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Store tokens in localStorage
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
166
|
+
storeTokens(tokens) {
|
|
167
|
+
if (typeof window !== "undefined") {
|
|
168
|
+
localStorage.setItem("auth_tokens", JSON.stringify(tokens));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get tokens from localStorage
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
getTokens() {
|
|
176
|
+
if (typeof window !== "undefined") {
|
|
177
|
+
const stored = localStorage.getItem("auth_tokens");
|
|
178
|
+
if (stored) {
|
|
179
|
+
try {
|
|
180
|
+
return JSON.parse(stored);
|
|
181
|
+
} catch (e) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get access token
|
|
190
|
+
* @private
|
|
191
|
+
*/
|
|
192
|
+
getAccessToken() {
|
|
193
|
+
const tokens = this.getTokens();
|
|
194
|
+
return (tokens == null ? void 0 : tokens.AccessToken) || null;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Clear all tokens
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
clearTokens() {
|
|
201
|
+
if (typeof window !== "undefined") {
|
|
202
|
+
localStorage.removeItem("auth_tokens");
|
|
203
|
+
localStorage.removeItem("customer_id");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
exports.AuthService = AuthService;
|
|
209
|
+
//# sourceMappingURL=chunk-ALYN5HAC.js.map
|
|
210
|
+
//# sourceMappingURL=chunk-ALYN5HAC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/auth/auth-service.ts"],"names":[],"mappings":"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","file":"chunk-ALYN5HAC.js","sourcesContent":["/**\n * Auth Service\n * Handles all authentication-related API calls\n * Compatible with AWS Cognito-based backend\n */\n\nimport { ApiClient } from \"../../api/client\";\nimport type {\n User,\n LoginCredentials,\n SignupData,\n TokenData,\n UserInfoResponse,\n UserAttribute,\n ForgotPasswordData,\n ResetPasswordData,\n VerifyCodeData,\n ResendCodeData,\n ChangePasswordData,\n} from \"./types\";\n\nexport class AuthService {\n constructor(private api: ApiClient) {}\n\n /**\n * Transform Cognito UserAttributes to User object\n */\n private transformUserInfo(\n userInfo: UserInfoResponse,\n tokens: TokenData\n ): User {\n const getAttribute = (name: string): string | undefined => {\n return userInfo.UserAttributes?.find((attr) => attr.Name === name)?.Value;\n };\n\n return {\n id: getAttribute(\"sub\") || \"\",\n email: getAttribute(\"email\") || \"\",\n name: getAttribute(\"name\") || \"\",\n phone_number: getAttribute(\"phone_number\"),\n avatar: getAttribute(\"picture\"),\n address: getAttribute(\"address\"),\n ward: getAttribute(\"custom:ward\"),\n district: getAttribute(\"custom:district\"),\n city: getAttribute(\"custom:city\"),\n province_code: getAttribute(\"custom:province_code\"),\n district_code: getAttribute(\"custom:district_code\"),\n ward_code: getAttribute(\"custom:ward_code\"),\n };\n }\n\n /**\n * Login with username and password\n */\n async login(credentials: LoginCredentials): Promise<User> {\n // Call login endpoint\n const tokenResponse = await this.api.post<TokenData>(\n \"/auth/login\",\n credentials\n );\n\n // Store tokens\n this.api.setToken(tokenResponse.AccessToken);\n this.storeTokens(tokenResponse);\n\n // Get user info\n const userInfo = await this.api.get<UserInfoResponse>(\"/auth/user_info\");\n\n // Transform and return user\n const user = this.transformUserInfo(userInfo, tokenResponse);\n\n // Store customer_id for order history\n if (typeof window !== \"undefined\") {\n localStorage.setItem(\"customer_id\", user.id);\n }\n\n return user;\n }\n\n /**\n * Signup with username, email, password, and name\n */\n async signup(data: SignupData): Promise<{ message: string }> {\n return await this.api.post<{ message: string }>(\"/auth/register\", data);\n }\n\n /**\n * Logout current user\n */\n async logout(): Promise<void> {\n try {\n // No logout endpoint in current API, just clear tokens\n this.api.clearToken();\n this.clearTokens();\n } catch (error) {\n // Always clear tokens even if API call fails\n this.api.clearToken();\n this.clearTokens();\n }\n }\n\n /**\n * Send forgot password email\n */\n async forgotPassword(data: ForgotPasswordData): Promise<{ message: string }> {\n return await this.api.post<{ message: string }>(\"/auth/forgot\", data);\n }\n\n /**\n * Reset password with code\n */\n async resetPassword(data: ResetPasswordData): Promise<{ message: string }> {\n return await this.api.post<{ message: string }>(\"/auth/new_password\", data);\n }\n\n /**\n * Verify code (email verification, 2FA, etc.)\n */\n async verifyCode(data: VerifyCodeData): Promise<{ message: string }> {\n return await this.api.post<{ message: string }>(\"/auth/confirm\", data);\n }\n\n /**\n * Verify code for password reset\n */\n async verifyCodeReset(\n data: VerifyCodeData\n ): Promise<{ session: string; message?: string }> {\n return await this.api.post<{ session: string; message?: string }>(\n \"/auth/confirm_reset_password_code\",\n data\n );\n }\n\n /**\n * Resend verification code\n */\n async resendCode(data: ResendCodeData): Promise<{ message: string }> {\n return await this.api.post<{ message: string }>(\"/auth/resend_code\", data);\n }\n\n /**\n * Get current user\n */\n async getCurrentUser(): Promise<User | null> {\n try {\n // Check if we have tokens\n const accessToken = this.getAccessToken();\n if (!accessToken) {\n return null;\n }\n\n // Get user info from API\n const userInfo = await this.api.get<UserInfoResponse>(\"/auth/user_info\");\n\n // Get tokens from storage\n const tokens = this.getTokens();\n if (!tokens) {\n return null;\n }\n\n return this.transformUserInfo(userInfo, tokens);\n } catch {\n return null;\n }\n }\n\n /**\n * Update user profile\n */\n async updateProfile(data: Partial<User>): Promise<{ message: string }> {\n // Transform User fields to Cognito attributes format\n const payload: Record<string, string> = {};\n\n if (data.name) payload.name = data.name;\n if (data.phone_number) payload.phone_number = data.phone_number;\n if (data.address) payload.address = data.address;\n if (data.avatar) payload.picture = data.avatar;\n if (data.ward) payload[\"custom:ward\"] = data.ward;\n if (data.district) payload[\"custom:district\"] = data.district;\n if (data.city) payload[\"custom:city\"] = data.city;\n if (data.province_code)\n payload[\"custom:province_code\"] = data.province_code;\n if (data.district_code)\n payload[\"custom:district_code\"] = data.district_code;\n if (data.ward_code) payload[\"custom:ward_code\"] = data.ward_code;\n\n return await this.api.post<{ message: string }>(\"/auth/user_info\", payload);\n }\n\n /**\n * Change password\n */\n async changePassword(data: ChangePasswordData): Promise<{ message: string }> {\n return await this.api.post<{ message: string }>(\n \"/auth/change_password\",\n data\n );\n }\n\n /**\n * Refresh access token\n */\n async refreshToken(): Promise<TokenData> {\n const tokens = this.getTokens();\n if (!tokens?.RefreshToken) {\n throw new Error(\"No refresh token available\");\n }\n\n const newTokens = await this.api.post<TokenData>(\"/auth/refresh\", {\n refresh_token: tokens.RefreshToken,\n });\n\n this.storeTokens(newTokens);\n this.api.setToken(newTokens.AccessToken);\n\n return newTokens;\n }\n\n /**\n * Store tokens in localStorage\n * @private\n */\n private storeTokens(tokens: TokenData): void {\n if (typeof window !== \"undefined\") {\n localStorage.setItem(\"auth_tokens\", JSON.stringify(tokens));\n }\n }\n\n /**\n * Get tokens from localStorage\n * @private\n */\n private getTokens(): TokenData | null {\n if (typeof window !== \"undefined\") {\n const stored = localStorage.getItem(\"auth_tokens\");\n if (stored) {\n try {\n return JSON.parse(stored);\n } catch {\n return null;\n }\n }\n }\n return null;\n }\n\n /**\n * Get access token\n * @private\n */\n private getAccessToken(): string | null {\n const tokens = this.getTokens();\n return tokens?.AccessToken || null;\n }\n\n /**\n * Clear all tokens\n * @private\n */\n private clearTokens(): void {\n if (typeof window !== \"undefined\") {\n localStorage.removeItem(\"auth_tokens\");\n localStorage.removeItem(\"customer_id\");\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// src/config/app-config.ts
|
|
5
|
+
function validateConfig(config) {
|
|
6
|
+
if (!config.apiUrl) {
|
|
7
|
+
throw new Error("[OneX] apiUrl is required in config");
|
|
8
|
+
}
|
|
9
|
+
if (!config.companyId) {
|
|
10
|
+
throw new Error("[OneX] companyId is required in config");
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
new URL(config.apiUrl);
|
|
14
|
+
} catch (e) {
|
|
15
|
+
throw new Error(`[OneX] Invalid apiUrl: ${config.apiUrl}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function createConfigFromEnv(overrides) {
|
|
19
|
+
var _a, _b, _c, _d;
|
|
20
|
+
const config = {
|
|
21
|
+
apiUrl: (overrides == null ? void 0 : overrides.apiUrl) || (typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a.NEXT_PUBLIC_API_URL : void 0) || "",
|
|
22
|
+
companyId: (overrides == null ? void 0 : overrides.companyId) || (typeof process !== "undefined" ? (_b = process.env) == null ? void 0 : _b.NEXT_PUBLIC_API_COMPANY_ID : void 0) || "",
|
|
23
|
+
themeCompanyId: (overrides == null ? void 0 : overrides.themeCompanyId) || (typeof process !== "undefined" ? (_c = process.env) == null ? void 0 : _c.NEXT_PUBLIC_THEME_COMPANY_ID : void 0),
|
|
24
|
+
domain: (overrides == null ? void 0 : overrides.domain) || (typeof process !== "undefined" ? (_d = process.env) == null ? void 0 : _d.NEXT_PUBLIC_DOMAIN : void 0),
|
|
25
|
+
tokenStorage: overrides == null ? void 0 : overrides.tokenStorage,
|
|
26
|
+
onUnauthorized: overrides == null ? void 0 : overrides.onUnauthorized,
|
|
27
|
+
headers: overrides == null ? void 0 : overrides.headers
|
|
28
|
+
};
|
|
29
|
+
validateConfig(config);
|
|
30
|
+
return config;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.createConfigFromEnv = createConfigFromEnv;
|
|
34
|
+
exports.validateConfig = validateConfig;
|
|
35
|
+
//# sourceMappingURL=chunk-AREMJR3Q.js.map
|
|
36
|
+
//# sourceMappingURL=chunk-AREMJR3Q.js.map
|