@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 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/orders/use-orders.ts","../src/features/orders/orders-service.ts"],"names":[],"mappings":"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","file":"chunk-T6EJ2GAV.mjs","sourcesContent":["/**\n * Orders Hook\n * Zustand store for orders state and actions\n */\n\nimport { create } from \"zustand\";\nimport { OrdersService } from \"./orders-service\";\nimport type { Order, CreateOrderData, OrdersListParams } from \"./types\";\n\ninterface OrdersState {\n // State\n orders: Order[];\n currentOrder: Order | null;\n isLoading: boolean;\n error: string | null;\n total: number;\n totalPages: number;\n currentPage: number;\n\n // Actions\n createOrder: (data: CreateOrderData) => Promise<Order>;\n createPrivateOrder: (data: CreateOrderData) => Promise<Order>;\n fetchOrders: (params?: OrdersListParams) => Promise<void>;\n fetchOrderHistory: (params?: OrdersListParams) => Promise<void>;\n fetchOrderById: (orderId: string) => Promise<void>;\n fetchOrderByNumber: (orderNumber: string) => Promise<void>;\n updateOrderStatus: (orderId: string, status: string) => Promise<void>;\n cancelOrder: (orderId: string) => Promise<void>;\n payOrder: (\n orderId: string,\n paymentData?: Record<string, unknown>\n ) => Promise<void>;\n clearError: () => void;\n clearCurrentOrder: () => void;\n}\n\nlet ordersService: OrdersService | null = null;\n\nexport const useOrders = create<OrdersState>((set) => ({\n // Initial state\n orders: [],\n currentOrder: null,\n isLoading: false,\n error: null,\n total: 0,\n totalPages: 0,\n currentPage: 1,\n\n /**\n * Create a new order (public)\n */\n createOrder: async (data) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const order = await ordersService.createOrder(data);\n set({ currentOrder: order, isLoading: false });\n return order;\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Create a private order (authenticated)\n */\n createPrivateOrder: async (data) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const order = await ordersService.createPrivateOrder(data);\n set({ currentOrder: order, isLoading: false });\n return order;\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Fetch orders list\n */\n fetchOrders: async (params) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const response = await ordersService.getOrders(params);\n set({\n orders: response.items,\n total: response.total,\n totalPages: response.totalPages,\n currentPage: response.page,\n isLoading: false,\n });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Fetch order history for authenticated user\n */\n fetchOrderHistory: async (params) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const response = await ordersService.getOrderHistory(params);\n set({\n orders: response.items,\n total: response.total,\n totalPages: response.totalPages,\n currentPage: response.page,\n isLoading: false,\n });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Fetch order by ID\n */\n fetchOrderById: async (orderId) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const order = await ordersService.getOrderById(orderId);\n set({ currentOrder: order, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Fetch order by order number\n */\n fetchOrderByNumber: async (orderNumber) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const order = await ordersService.getOrderByNumber(orderNumber);\n set({ currentOrder: order, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Update order status\n */\n updateOrderStatus: async (orderId, status) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const order = await ordersService.updateOrderStatus(orderId, status);\n set((state) => ({\n currentOrder:\n state.currentOrder?.id === orderId ? order : state.currentOrder,\n orders: state.orders.map((o) => (o.id === orderId ? order : o)),\n isLoading: false,\n }));\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Cancel order\n */\n cancelOrder: async (orderId) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const order = await ordersService.cancelOrder(orderId);\n set((state) => ({\n currentOrder:\n state.currentOrder?.id === orderId ? order : state.currentOrder,\n orders: state.orders.map((o) => (o.id === orderId ? order : o)),\n isLoading: false,\n }));\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Pay for order\n */\n payOrder: async (orderId, paymentData) => {\n if (!ordersService) {\n throw new Error(\n \"Orders service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const order = await ordersService.payOrder(orderId, paymentData);\n set((state) => ({\n currentOrder:\n state.currentOrder?.id === orderId ? order : state.currentOrder,\n orders: state.orders.map((o) => (o.id === orderId ? order : o)),\n isLoading: false,\n }));\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Clear error\n */\n clearError: () => {\n set({ error: null });\n },\n\n /**\n * Clear current order\n */\n clearCurrentOrder: () => {\n set({ currentOrder: null });\n },\n}));\n\n/**\n * Initialize orders service\n * @internal Called by initializeOnex()\n */\nexport function initializeOrdersService(service: OrdersService): void {\n ordersService = service;\n}\n","/**\n * Orders Service\n * Handles all order-related API calls\n */\n\nimport { ApiClient } from \"../../api/client\";\nimport type {\n Order,\n CreateOrderData,\n OrdersListResponse,\n OrdersListParams,\n} from \"./types\";\n\nexport class OrdersService {\n constructor(private api: ApiClient) {}\n\n /**\n * Create a new order (public - no auth required)\n */\n async createOrder(data: CreateOrderData): Promise<Order> {\n return await this.api.post<Order>(\"/orders\", data);\n }\n\n /**\n * Create a private order (requires authentication)\n */\n async createPrivateOrder(data: CreateOrderData): Promise<Order> {\n return await this.api.post<Order>(\"/orders/private\", data);\n }\n\n /**\n * Get order by ID\n */\n async getOrderById(orderId: string): Promise<Order> {\n return await this.api.get<Order>(`/orders/${orderId}`);\n }\n\n /**\n * Get order by order number\n */\n async getOrderByNumber(orderNumber: string): Promise<Order> {\n return await this.api.get<Order>(`/orders/number/${orderNumber}`);\n }\n\n /**\n * Get order history for authenticated user\n */\n async getOrderHistory(\n params?: OrdersListParams\n ): Promise<OrdersListResponse> {\n return await this.api.get<OrdersListResponse>(\n \"/orders/history\",\n params as Record<string, unknown>\n );\n }\n\n /**\n * Get all orders (with pagination)\n */\n async getOrders(params?: OrdersListParams): Promise<OrdersListResponse> {\n return await this.api.get<OrdersListResponse>(\n \"/orders\",\n params as Record<string, unknown>\n );\n }\n\n /**\n * Update order status\n */\n async updateOrderStatus(orderId: string, status: string): Promise<Order> {\n return await this.api.put<Order>(`/orders/${orderId}/status`, { status });\n }\n\n /**\n * Cancel order\n */\n async cancelOrder(orderId: string): Promise<Order> {\n return await this.api.put<Order>(`/orders/${orderId}/cancel`, {});\n }\n\n /**\n * Pay for order\n */\n async payOrder(\n orderId: string,\n paymentData?: Record<string, unknown>\n ): Promise<Order> {\n return await this.api.post<Order>(\n `/orders/${orderId}/pay`,\n paymentData || {}\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from './chunk-O3XR7TW3.mjs';
|
|
3
|
+
import { create } from 'zustand';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import Image from 'next/image';
|
|
6
|
+
import Link from 'next/link';
|
|
7
|
+
import { ShoppingCart } from 'lucide-react';
|
|
8
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
// src/features/products/products-service.ts
|
|
11
|
+
var ProductsService = class {
|
|
12
|
+
constructor(api) {
|
|
13
|
+
this.api = api;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get products list
|
|
17
|
+
*/
|
|
18
|
+
async getProducts(params) {
|
|
19
|
+
const response = await this.api.get(
|
|
20
|
+
"/products",
|
|
21
|
+
params
|
|
22
|
+
);
|
|
23
|
+
return response;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get product by ID
|
|
27
|
+
*/
|
|
28
|
+
async getProductById(productId) {
|
|
29
|
+
return await this.api.get(`/products/${productId}`);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get product by slug
|
|
33
|
+
*/
|
|
34
|
+
async getProductBySlug(productSlug) {
|
|
35
|
+
return await this.api.get(`/products/slug/${productSlug}`);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get best sellers
|
|
39
|
+
*/
|
|
40
|
+
async getBestSellers(limit) {
|
|
41
|
+
const response = await this.api.get("/products", {
|
|
42
|
+
filter: "best-sellers",
|
|
43
|
+
limit: limit || 8
|
|
44
|
+
});
|
|
45
|
+
return response.items;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get featured products
|
|
49
|
+
*/
|
|
50
|
+
async getFeaturedProducts(limit) {
|
|
51
|
+
const response = await this.api.get("/products", {
|
|
52
|
+
filter: "featured",
|
|
53
|
+
limit: limit || 8
|
|
54
|
+
});
|
|
55
|
+
return response.items;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Search products
|
|
59
|
+
*/
|
|
60
|
+
async searchProducts(query, limit) {
|
|
61
|
+
const response = await this.api.get("/products", {
|
|
62
|
+
search: query,
|
|
63
|
+
limit: limit || 20
|
|
64
|
+
});
|
|
65
|
+
return response.items;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var productsService = null;
|
|
69
|
+
var useProducts = create((set) => ({
|
|
70
|
+
// Initial state
|
|
71
|
+
products: [],
|
|
72
|
+
currentProduct: null,
|
|
73
|
+
isLoading: false,
|
|
74
|
+
error: null,
|
|
75
|
+
total: 0,
|
|
76
|
+
totalPages: 0,
|
|
77
|
+
currentPage: 1,
|
|
78
|
+
/**
|
|
79
|
+
* Fetch products list
|
|
80
|
+
*/
|
|
81
|
+
fetchProducts: async (params) => {
|
|
82
|
+
if (!productsService) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
"Products service not initialized. Call initializeOnex() first."
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
set({ isLoading: true, error: null });
|
|
88
|
+
try {
|
|
89
|
+
const response = await productsService.getProducts(params);
|
|
90
|
+
set({
|
|
91
|
+
products: response.items,
|
|
92
|
+
total: response.total,
|
|
93
|
+
totalPages: response.totalPages,
|
|
94
|
+
currentPage: (params == null ? void 0 : params.page) || 1,
|
|
95
|
+
isLoading: false
|
|
96
|
+
});
|
|
97
|
+
} catch (error) {
|
|
98
|
+
set({ error: error.message, isLoading: false });
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* Fetch product by ID
|
|
103
|
+
*/
|
|
104
|
+
fetchProductById: async (productId) => {
|
|
105
|
+
if (!productsService) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
"Products service not initialized. Call initializeOnex() first."
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
set({ isLoading: true, error: null });
|
|
111
|
+
try {
|
|
112
|
+
const product = await productsService.getProductById(productId);
|
|
113
|
+
set({ currentProduct: product, isLoading: false });
|
|
114
|
+
} catch (error) {
|
|
115
|
+
set({ error: error.message, isLoading: false });
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
/**
|
|
119
|
+
* Fetch product by slug
|
|
120
|
+
*/
|
|
121
|
+
fetchProductBySlug: async (productSlug) => {
|
|
122
|
+
if (!productsService) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
"Products service not initialized. Call initializeOnex() first."
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
set({ isLoading: true, error: null });
|
|
128
|
+
try {
|
|
129
|
+
const product = await productsService.getProductBySlug(productSlug);
|
|
130
|
+
set({ currentProduct: product, isLoading: false });
|
|
131
|
+
} catch (error) {
|
|
132
|
+
set({ error: error.message, isLoading: false });
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Fetch best sellers
|
|
137
|
+
*/
|
|
138
|
+
fetchBestSellers: async (limit) => {
|
|
139
|
+
if (!productsService) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
"Products service not initialized. Call initializeOnex() first."
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
set({ isLoading: true, error: null });
|
|
145
|
+
try {
|
|
146
|
+
const products = await productsService.getBestSellers(limit);
|
|
147
|
+
set({ products, isLoading: false });
|
|
148
|
+
} catch (error) {
|
|
149
|
+
set({ error: error.message, isLoading: false });
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
/**
|
|
153
|
+
* Fetch featured products
|
|
154
|
+
*/
|
|
155
|
+
fetchFeaturedProducts: async (limit) => {
|
|
156
|
+
if (!productsService) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
"Products service not initialized. Call initializeOnex() first."
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
set({ isLoading: true, error: null });
|
|
162
|
+
try {
|
|
163
|
+
const products = await productsService.getFeaturedProducts(limit);
|
|
164
|
+
set({ products, isLoading: false });
|
|
165
|
+
} catch (error) {
|
|
166
|
+
set({ error: error.message, isLoading: false });
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
/**
|
|
170
|
+
* Search products
|
|
171
|
+
*/
|
|
172
|
+
searchProducts: async (query, limit) => {
|
|
173
|
+
if (!productsService) {
|
|
174
|
+
throw new Error(
|
|
175
|
+
"Products service not initialized. Call initializeOnex() first."
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
set({ isLoading: true, error: null });
|
|
179
|
+
try {
|
|
180
|
+
const products = await productsService.searchProducts(query, limit);
|
|
181
|
+
set({ products, isLoading: false });
|
|
182
|
+
} catch (error) {
|
|
183
|
+
set({ error: error.message, isLoading: false });
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
/**
|
|
187
|
+
* Clear error
|
|
188
|
+
*/
|
|
189
|
+
clearError: () => {
|
|
190
|
+
set({ error: null });
|
|
191
|
+
},
|
|
192
|
+
/**
|
|
193
|
+
* Clear current product
|
|
194
|
+
*/
|
|
195
|
+
clearCurrentProduct: () => {
|
|
196
|
+
set({ currentProduct: null });
|
|
197
|
+
}
|
|
198
|
+
}));
|
|
199
|
+
function initializeProductsService(service) {
|
|
200
|
+
productsService = service;
|
|
201
|
+
}
|
|
202
|
+
function formatPrice(price) {
|
|
203
|
+
return new Intl.NumberFormat("vi-VN").format(price) + " \u0111";
|
|
204
|
+
}
|
|
205
|
+
function ProductCard(props) {
|
|
206
|
+
const [imageError, setImageError] = React.useState(false);
|
|
207
|
+
const {
|
|
208
|
+
product: productObj,
|
|
209
|
+
slug: slugProp,
|
|
210
|
+
name: nameProp,
|
|
211
|
+
description: descriptionProp,
|
|
212
|
+
price: priceProp,
|
|
213
|
+
originalPrice: originalPriceProp,
|
|
214
|
+
discount: discountProp,
|
|
215
|
+
image: imageProp,
|
|
216
|
+
href,
|
|
217
|
+
className,
|
|
218
|
+
showAddToCart = true,
|
|
219
|
+
onAddToCart,
|
|
220
|
+
onClick
|
|
221
|
+
} = props;
|
|
222
|
+
const product = productObj || {
|
|
223
|
+
slug: slugProp,
|
|
224
|
+
title: nameProp || "",
|
|
225
|
+
description: descriptionProp,
|
|
226
|
+
salePrice: priceProp || 0,
|
|
227
|
+
originalPrice: originalPriceProp,
|
|
228
|
+
discount: discountProp,
|
|
229
|
+
image: imageProp,
|
|
230
|
+
id: slugProp || ""
|
|
231
|
+
};
|
|
232
|
+
const link = href || (product.slug ? `/products/${product.slug}` : `/products/${product.id}`);
|
|
233
|
+
const handleAddToCart = (e) => {
|
|
234
|
+
if (e) {
|
|
235
|
+
e.preventDefault();
|
|
236
|
+
e.stopPropagation();
|
|
237
|
+
}
|
|
238
|
+
onAddToCart == null ? void 0 : onAddToCart(product, e);
|
|
239
|
+
};
|
|
240
|
+
const handleClick = () => {
|
|
241
|
+
onClick == null ? void 0 : onClick();
|
|
242
|
+
};
|
|
243
|
+
const placeholderSvg = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400' viewBox='0 0 400 400'%3E%3Crect fill='%232A2A2A' width='400' height='400'/%3E%3Cpath fill='%23444' d='M150 170h100v60H150z'/%3E%3Ccircle fill='%23444' cx='175' cy='145' r='20'/%3E%3Cpath fill='%23444' d='M140 250l50-40 30 25 40-60 50 75H140z'/%3E%3C/svg%3E";
|
|
244
|
+
const displayImage = product.image && !imageError ? product.image : placeholderSvg;
|
|
245
|
+
const isOutOfStock = product.inStock === false;
|
|
246
|
+
const discount = typeof product.discount === "number" ? product.discount : typeof product.discount === "string" ? parseInt(product.discount) : 0;
|
|
247
|
+
return /* @__PURE__ */ jsx(
|
|
248
|
+
Link,
|
|
249
|
+
{
|
|
250
|
+
href: link,
|
|
251
|
+
className: cn("group block", className),
|
|
252
|
+
onClick: handleClick,
|
|
253
|
+
children: /* @__PURE__ */ jsxs("div", { className: "bg-card rounded-lg overflow-hidden hover:shadow-xl hover:shadow-black/20 transition-shadow h-full flex flex-col", children: [
|
|
254
|
+
/* @__PURE__ */ jsxs("div", { className: "relative aspect-square", children: [
|
|
255
|
+
/* @__PURE__ */ jsx(
|
|
256
|
+
Image,
|
|
257
|
+
{
|
|
258
|
+
src: displayImage,
|
|
259
|
+
alt: product.title,
|
|
260
|
+
fill: true,
|
|
261
|
+
className: cn(
|
|
262
|
+
"object-cover group-hover:scale-105 transition-transform duration-300",
|
|
263
|
+
isOutOfStock && "opacity-60 grayscale"
|
|
264
|
+
),
|
|
265
|
+
sizes: "(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw",
|
|
266
|
+
onError: () => setImageError(true)
|
|
267
|
+
}
|
|
268
|
+
),
|
|
269
|
+
isOutOfStock && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "bg-white/90 rounded-md px-3 py-1.5 text-xs font-semibold", children: "H\u1EBFt h\xE0ng" }) }),
|
|
270
|
+
discount > 0 && !isOutOfStock && /* @__PURE__ */ jsxs("div", { className: "absolute top-2 right-2 bg-[#C41E3A] text-white text-xs font-semibold px-2 py-1 rounded", children: [
|
|
271
|
+
"-",
|
|
272
|
+
discount,
|
|
273
|
+
"%"
|
|
274
|
+
] })
|
|
275
|
+
] }),
|
|
276
|
+
/* @__PURE__ */ jsxs("div", { className: "p-3 md:p-4 flex flex-col flex-1", children: [
|
|
277
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold text-sm md:text-base mb-1 line-clamp-2 transition-colors", children: product.title }),
|
|
278
|
+
product.description && /* @__PURE__ */ jsx("p", { className: "text-gray-400 text-xs md:text-sm mb-2 line-clamp-2 flex-1", children: product.description }),
|
|
279
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-auto", children: [
|
|
280
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
281
|
+
/* @__PURE__ */ jsx("span", { className: "text-[#C41E3A] font-bold text-sm md:text-base", children: formatPrice(product.salePrice) }),
|
|
282
|
+
product.originalPrice && product.originalPrice > product.salePrice && /* @__PURE__ */ jsx("span", { className: "text-gray-500 text-xs md:text-sm line-through", children: formatPrice(product.originalPrice) })
|
|
283
|
+
] }),
|
|
284
|
+
showAddToCart && onAddToCart && !isOutOfStock && /* @__PURE__ */ jsx(
|
|
285
|
+
"button",
|
|
286
|
+
{
|
|
287
|
+
onClick: handleAddToCart,
|
|
288
|
+
className: "w-8 h-8 md:w-9 md:h-9 bg-[#2A2A2A] hover:bg-[#3A3A3A] text-white rounded-lg flex items-center justify-center transition-colors shrink-0",
|
|
289
|
+
"aria-label": "Th\xEAm v\xE0o gi\u1ECF h\xE0ng",
|
|
290
|
+
children: /* @__PURE__ */ jsx(ShoppingCart, { className: "w-4 h-4" })
|
|
291
|
+
}
|
|
292
|
+
)
|
|
293
|
+
] })
|
|
294
|
+
] })
|
|
295
|
+
] })
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export { ProductCard, ProductsService, initializeProductsService, useProducts };
|
|
301
|
+
//# sourceMappingURL=chunk-ULBDOFZI.mjs.map
|
|
302
|
+
//# sourceMappingURL=chunk-ULBDOFZI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/products/products-service.ts","../src/features/products/use-products.ts","../src/components/product-card/product-card.tsx"],"names":[],"mappings":"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","file":"chunk-ULBDOFZI.mjs","sourcesContent":["/**\n * Products Service\n * Handles all product-related API calls\n */\n\nimport { ApiClient } from \"../../api/client\";\nimport type { Product } from \"../../types/product\";\n\nexport interface ProductsListResponse {\n items: Product[];\n total: number;\n totalPages: number;\n}\n\nexport interface ProductsListParams {\n page?: number;\n limit?: number;\n category?: string;\n search?: string;\n filter?: string;\n}\n\nexport class ProductsService {\n constructor(private api: ApiClient) {}\n\n /**\n * Get products list\n */\n async getProducts(\n params?: ProductsListParams\n ): Promise<ProductsListResponse> {\n const response = await this.api.get<ProductsListResponse>(\n \"/products\",\n params as Record<string, unknown>\n );\n return response;\n }\n\n /**\n * Get product by ID\n */\n async getProductById(productId: string): Promise<Product> {\n return await this.api.get<Product>(`/products/${productId}`);\n }\n\n /**\n * Get product by slug\n */\n async getProductBySlug(productSlug: string): Promise<Product> {\n return await this.api.get<Product>(`/products/slug/${productSlug}`);\n }\n\n /**\n * Get best sellers\n */\n async getBestSellers(limit?: number): Promise<Product[]> {\n const response = await this.api.get<ProductsListResponse>(\"/products\", {\n filter: \"best-sellers\",\n limit: limit || 8,\n });\n return response.items;\n }\n\n /**\n * Get featured products\n */\n async getFeaturedProducts(limit?: number): Promise<Product[]> {\n const response = await this.api.get<ProductsListResponse>(\"/products\", {\n filter: \"featured\",\n limit: limit || 8,\n });\n return response.items;\n }\n\n /**\n * Search products\n */\n async searchProducts(query: string, limit?: number): Promise<Product[]> {\n const response = await this.api.get<ProductsListResponse>(\"/products\", {\n search: query,\n limit: limit || 20,\n });\n return response.items;\n }\n}\n","/**\n * Products Hook\n * Zustand store for products state and actions\n */\n\nimport { create } from \"zustand\";\nimport { ProductsService } from \"./products-service\";\nimport type { Product } from \"../../types/product\";\nimport type { ProductsListParams } from \"./products-service\";\n\ninterface ProductsState {\n // State\n products: Product[];\n currentProduct: Product | null;\n isLoading: boolean;\n error: string | null;\n total: number;\n totalPages: number;\n currentPage: number;\n\n // Actions\n fetchProducts: (params?: ProductsListParams) => Promise<void>;\n fetchProductById: (productId: string) => Promise<void>;\n fetchProductBySlug: (productSlug: string) => Promise<void>;\n fetchBestSellers: (limit?: number) => Promise<void>;\n fetchFeaturedProducts: (limit?: number) => Promise<void>;\n searchProducts: (query: string, limit?: number) => Promise<void>;\n clearError: () => void;\n clearCurrentProduct: () => void;\n}\n\nlet productsService: ProductsService | null = null;\n\nexport const useProducts = create<ProductsState>((set) => ({\n // Initial state\n products: [],\n currentProduct: null,\n isLoading: false,\n error: null,\n total: 0,\n totalPages: 0,\n currentPage: 1,\n\n /**\n * Fetch products list\n */\n fetchProducts: async (params) => {\n if (!productsService) {\n throw new Error(\n \"Products service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const response = await productsService.getProducts(params);\n set({\n products: response.items,\n total: response.total,\n totalPages: response.totalPages,\n currentPage: params?.page || 1,\n isLoading: false,\n });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Fetch product by ID\n */\n fetchProductById: async (productId) => {\n if (!productsService) {\n throw new Error(\n \"Products service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const product = await productsService.getProductById(productId);\n set({ currentProduct: product, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Fetch product by slug\n */\n fetchProductBySlug: async (productSlug) => {\n if (!productsService) {\n throw new Error(\n \"Products service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const product = await productsService.getProductBySlug(productSlug);\n set({ currentProduct: product, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Fetch best sellers\n */\n fetchBestSellers: async (limit) => {\n if (!productsService) {\n throw new Error(\n \"Products service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const products = await productsService.getBestSellers(limit);\n set({ products, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Fetch featured products\n */\n fetchFeaturedProducts: async (limit) => {\n if (!productsService) {\n throw new Error(\n \"Products service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const products = await productsService.getFeaturedProducts(limit);\n set({ products, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Search products\n */\n searchProducts: async (query, limit) => {\n if (!productsService) {\n throw new Error(\n \"Products service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const products = await productsService.searchProducts(query, limit);\n set({ products, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n }\n },\n\n /**\n * Clear error\n */\n clearError: () => {\n set({ error: null });\n },\n\n /**\n * Clear current product\n */\n clearCurrentProduct: () => {\n set({ currentProduct: null });\n },\n}));\n\n/**\n * Initialize products service\n * @internal Called by initializeOnex()\n */\nexport function initializeProductsService(service: ProductsService): void {\n productsService = service;\n}\n","/**\n * ProductCard Component\n * Generic product card for displaying products in themes\n */\n\n\"use client\";\n\nimport * as React from \"react\";\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ShoppingCart } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport type { Product } from \"../../types/product\";\n\nexport interface ProductCardProps {\n /** Product data (full object) */\n product?: Product;\n\n // Alternative: Individual props\n slug?: string;\n name?: string;\n description?: string;\n price?: number;\n originalPrice?: number;\n discount?: number;\n image?: string;\n\n /** Custom href (overrides default /products/[slug]) */\n href?: string;\n\n /** Custom class name */\n className?: string;\n\n /** Show add to cart button */\n showAddToCart?: boolean;\n\n /** Add to cart handler */\n onAddToCart?: (product: Product, e?: React.MouseEvent) => void;\n\n /** Click handler for entire card */\n onClick?: () => void;\n}\n\n/**\n * Format price in Vietnamese dong\n */\nfunction formatPrice(price: number): string {\n return new Intl.NumberFormat(\"vi-VN\").format(price) + \" đ\";\n}\n\n/**\n * ProductCard Component\n */\nexport function ProductCard(props: ProductCardProps) {\n const [imageError, setImageError] = React.useState(false);\n\n // Normalize props - support both product object and individual props\n const {\n product: productObj,\n slug: slugProp,\n name: nameProp,\n description: descriptionProp,\n price: priceProp,\n originalPrice: originalPriceProp,\n discount: discountProp,\n image: imageProp,\n href,\n className,\n showAddToCart = true,\n onAddToCart,\n onClick,\n } = props;\n\n // Use product object if provided, otherwise use individual props\n const product =\n productObj ||\n ({\n slug: slugProp,\n title: nameProp || \"\",\n description: descriptionProp,\n salePrice: priceProp || 0,\n originalPrice: originalPriceProp,\n discount: discountProp,\n image: imageProp,\n id: slugProp || \"\",\n } as Product);\n\n // Generate slug-based URL\n const link =\n href ||\n (product.slug ? `/products/${product.slug}` : `/products/${product.id}`);\n\n const handleAddToCart = (e?: React.MouseEvent) => {\n if (e) {\n e.preventDefault();\n e.stopPropagation();\n }\n onAddToCart?.(product, e);\n };\n\n const handleClick = () => {\n onClick?.();\n };\n\n // Placeholder SVG for missing images\n const placeholderSvg =\n \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400' viewBox='0 0 400 400'%3E%3Crect fill='%232A2A2A' width='400' height='400'/%3E%3Cpath fill='%23444' d='M150 170h100v60H150z'/%3E%3Ccircle fill='%23444' cx='175' cy='145' r='20'/%3E%3Cpath fill='%23444' d='M140 250l50-40 30 25 40-60 50 75H140z'/%3E%3C/svg%3E\";\n\n const displayImage =\n product.image && !imageError ? product.image : placeholderSvg;\n\n const isOutOfStock = product.inStock === false;\n const discount =\n typeof product.discount === \"number\"\n ? product.discount\n : typeof product.discount === \"string\"\n ? parseInt(product.discount)\n : 0;\n\n return (\n <Link\n href={link}\n className={cn(\"group block\", className)}\n onClick={handleClick}\n >\n <div className=\"bg-card rounded-lg overflow-hidden hover:shadow-xl hover:shadow-black/20 transition-shadow h-full flex flex-col\">\n {/* Image Container */}\n <div className=\"relative aspect-square\">\n <Image\n src={displayImage}\n alt={product.title}\n fill\n className={cn(\n \"object-cover group-hover:scale-105 transition-transform duration-300\",\n isOutOfStock && \"opacity-60 grayscale\"\n )}\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n onError={() => setImageError(true)}\n />\n\n {/* Out of Stock Overlay */}\n {isOutOfStock && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"bg-white/90 rounded-md px-3 py-1.5 text-xs font-semibold\">\n Hết hàng\n </div>\n </div>\n )}\n\n {/* Discount Badge */}\n {discount > 0 && !isOutOfStock && (\n <div className=\"absolute top-2 right-2 bg-[#C41E3A] text-white text-xs font-semibold px-2 py-1 rounded\">\n -{discount}%\n </div>\n )}\n </div>\n\n {/* Product Info */}\n <div className=\"p-3 md:p-4 flex flex-col flex-1\">\n {/* Title */}\n <h3 className=\"font-semibold text-sm md:text-base mb-1 line-clamp-2 transition-colors\">\n {product.title}\n </h3>\n\n {/* Description */}\n {product.description && (\n <p className=\"text-gray-400 text-xs md:text-sm mb-2 line-clamp-2 flex-1\">\n {product.description}\n </p>\n )}\n\n {/* Price Row */}\n <div className=\"flex items-center justify-between mt-auto\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"text-[#C41E3A] font-bold text-sm md:text-base\">\n {formatPrice(product.salePrice)}\n </span>\n {product.originalPrice &&\n product.originalPrice > product.salePrice && (\n <span className=\"text-gray-500 text-xs md:text-sm line-through\">\n {formatPrice(product.originalPrice)}\n </span>\n )}\n </div>\n\n {/* Add to Cart Button */}\n {showAddToCart && onAddToCart && !isOutOfStock && (\n <button\n onClick={handleAddToCart}\n className=\"w-8 h-8 md:w-9 md:h-9 bg-[#2A2A2A] hover:bg-[#3A3A3A] text-white rounded-lg flex items-center justify-center transition-colors shrink-0\"\n aria-label=\"Thêm vào giỏ hàng\"\n >\n <ShoppingCart className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n </div>\n </Link>\n );\n}\n"]}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var zustand = require('zustand');
|
|
5
|
+
|
|
6
|
+
// src/features/auth/use-auth.ts
|
|
7
|
+
var authService = null;
|
|
8
|
+
var useAuth = zustand.create((set, get) => ({
|
|
9
|
+
// Initial state
|
|
10
|
+
user: null,
|
|
11
|
+
isLoading: false,
|
|
12
|
+
isAuthenticated: false,
|
|
13
|
+
error: null,
|
|
14
|
+
isInitialized: false,
|
|
15
|
+
/**
|
|
16
|
+
* Initialize auth state - fetch current user
|
|
17
|
+
*/
|
|
18
|
+
initialize: async () => {
|
|
19
|
+
if (!authService) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
if (get().isInitialized) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
set({ isLoading: true });
|
|
28
|
+
try {
|
|
29
|
+
const user = await authService.getCurrentUser();
|
|
30
|
+
set({
|
|
31
|
+
user,
|
|
32
|
+
isAuthenticated: !!user,
|
|
33
|
+
isLoading: false,
|
|
34
|
+
isInitialized: true
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
set({
|
|
38
|
+
error: error.message,
|
|
39
|
+
isLoading: false,
|
|
40
|
+
isInitialized: true
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
/**
|
|
45
|
+
* Login with email and password
|
|
46
|
+
*/
|
|
47
|
+
login: async (credentials) => {
|
|
48
|
+
if (!authService) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
set({ isLoading: true, error: null });
|
|
54
|
+
try {
|
|
55
|
+
const user = await authService.login(credentials);
|
|
56
|
+
set({ user, isAuthenticated: true, isLoading: false });
|
|
57
|
+
} catch (error) {
|
|
58
|
+
set({ error: error.message, isLoading: false });
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* Signup with email, password, and name
|
|
64
|
+
* Note: Signup returns a message, user must verify email before login
|
|
65
|
+
*/
|
|
66
|
+
signup: async (data) => {
|
|
67
|
+
if (!authService) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
set({ isLoading: true, error: null });
|
|
73
|
+
try {
|
|
74
|
+
await authService.signup(data);
|
|
75
|
+
set({ isLoading: false });
|
|
76
|
+
} catch (error) {
|
|
77
|
+
set({ error: error.message, isLoading: false });
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Logout current user
|
|
83
|
+
*/
|
|
84
|
+
logout: async () => {
|
|
85
|
+
if (!authService) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
set({ isLoading: true });
|
|
91
|
+
try {
|
|
92
|
+
await authService.logout();
|
|
93
|
+
set({ user: null, isAuthenticated: false, isLoading: false });
|
|
94
|
+
} catch (error) {
|
|
95
|
+
set({ error: error.message, isLoading: false });
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* Send forgot password email
|
|
101
|
+
*/
|
|
102
|
+
forgotPassword: async (data) => {
|
|
103
|
+
if (!authService) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
set({ isLoading: true, error: null });
|
|
109
|
+
try {
|
|
110
|
+
await authService.forgotPassword(data);
|
|
111
|
+
set({ isLoading: false });
|
|
112
|
+
} catch (error) {
|
|
113
|
+
set({ error: error.message, isLoading: false });
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
/**
|
|
118
|
+
* Reset password with token
|
|
119
|
+
*/
|
|
120
|
+
resetPassword: async (data) => {
|
|
121
|
+
if (!authService) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
set({ isLoading: true, error: null });
|
|
127
|
+
try {
|
|
128
|
+
await authService.resetPassword(data);
|
|
129
|
+
set({ isLoading: false });
|
|
130
|
+
} catch (error) {
|
|
131
|
+
set({ error: error.message, isLoading: false });
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Verify code (email verification, 2FA, etc.)
|
|
137
|
+
*/
|
|
138
|
+
verifyCode: async (data) => {
|
|
139
|
+
if (!authService) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
set({ isLoading: true, error: null });
|
|
145
|
+
try {
|
|
146
|
+
await authService.verifyCode(data);
|
|
147
|
+
set({ isLoading: false });
|
|
148
|
+
} catch (error) {
|
|
149
|
+
set({ error: error.message, isLoading: false });
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
/**
|
|
154
|
+
* Verify code for password reset
|
|
155
|
+
*/
|
|
156
|
+
verifyCodeReset: async (data) => {
|
|
157
|
+
if (!authService) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
set({ isLoading: true, error: null });
|
|
163
|
+
try {
|
|
164
|
+
const result = await authService.verifyCodeReset(data);
|
|
165
|
+
set({ isLoading: false });
|
|
166
|
+
return result;
|
|
167
|
+
} catch (error) {
|
|
168
|
+
set({ error: error.message, isLoading: false });
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
/**
|
|
173
|
+
* Resend verification code
|
|
174
|
+
*/
|
|
175
|
+
resendCode: async (data) => {
|
|
176
|
+
if (!authService) {
|
|
177
|
+
throw new Error(
|
|
178
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
set({ isLoading: true, error: null });
|
|
182
|
+
try {
|
|
183
|
+
await authService.resendCode(data);
|
|
184
|
+
set({ isLoading: false });
|
|
185
|
+
} catch (error) {
|
|
186
|
+
set({ error: error.message, isLoading: false });
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
/**
|
|
191
|
+
* Update user profile
|
|
192
|
+
*/
|
|
193
|
+
updateProfile: async (data) => {
|
|
194
|
+
if (!authService) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
set({ isLoading: true, error: null });
|
|
200
|
+
try {
|
|
201
|
+
await authService.updateProfile(data);
|
|
202
|
+
const user = await authService.getCurrentUser();
|
|
203
|
+
set({ user, isLoading: false });
|
|
204
|
+
} catch (error) {
|
|
205
|
+
set({ error: error.message, isLoading: false });
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
/**
|
|
210
|
+
* Change password
|
|
211
|
+
*/
|
|
212
|
+
changePassword: async (data) => {
|
|
213
|
+
if (!authService) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
"Auth service not initialized. Call initializeOnex() first."
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
set({ isLoading: true, error: null });
|
|
219
|
+
try {
|
|
220
|
+
await authService.changePassword(data);
|
|
221
|
+
set({ isLoading: false });
|
|
222
|
+
} catch (error) {
|
|
223
|
+
set({ error: error.message, isLoading: false });
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
/**
|
|
228
|
+
* Clear error
|
|
229
|
+
*/
|
|
230
|
+
clearError: () => {
|
|
231
|
+
set({ error: null });
|
|
232
|
+
}
|
|
233
|
+
}));
|
|
234
|
+
function initializeAuthService(service) {
|
|
235
|
+
authService = service;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
exports.initializeAuthService = initializeAuthService;
|
|
239
|
+
exports.useAuth = useAuth;
|
|
240
|
+
//# sourceMappingURL=chunk-V3JIELNV.js.map
|
|
241
|
+
//# sourceMappingURL=chunk-V3JIELNV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/auth/use-auth.ts"],"names":["create"],"mappings":"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","file":"chunk-V3JIELNV.js","sourcesContent":["/**\n * Auth Hook\n * Zustand store for authentication state and actions\n */\n\nimport { create } from \"zustand\";\nimport { AuthService } from \"./auth-service\";\nimport type {\n User,\n LoginCredentials,\n SignupData,\n ForgotPasswordData,\n ResetPasswordData,\n VerifyCodeData,\n ResendCodeData,\n ChangePasswordData,\n} from \"./types\";\n\ninterface AuthState {\n // State\n user: User | null;\n isLoading: boolean;\n isAuthenticated: boolean;\n error: string | null;\n isInitialized: boolean;\n\n // Actions\n initialize: () => Promise<void>;\n login: (credentials: LoginCredentials) => Promise<void>;\n signup: (data: SignupData) => Promise<void>;\n logout: () => Promise<void>;\n forgotPassword: (data: ForgotPasswordData) => Promise<void>;\n resetPassword: (data: ResetPasswordData) => Promise<void>;\n verifyCode: (data: VerifyCodeData) => Promise<void>;\n verifyCodeReset: (data: VerifyCodeData) => Promise<{ session: string }>;\n resendCode: (data: ResendCodeData) => Promise<void>;\n updateProfile: (data: Partial<User>) => Promise<void>;\n changePassword: (data: ChangePasswordData) => Promise<void>;\n clearError: () => void;\n}\n\nlet authService: AuthService | null = null;\n\nexport const useAuth = create<AuthState>((set, get) => ({\n // Initial state\n user: null,\n isLoading: false,\n isAuthenticated: false,\n error: null,\n isInitialized: false,\n\n /**\n * Initialize auth state - fetch current user\n */\n initialize: async () => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n if (get().isInitialized) {\n return;\n }\n\n set({ isLoading: true });\n try {\n const user = await authService.getCurrentUser();\n set({\n user,\n isAuthenticated: !!user,\n isLoading: false,\n isInitialized: true,\n });\n } catch (error) {\n set({\n error: (error as Error).message,\n isLoading: false,\n isInitialized: true,\n });\n }\n },\n\n /**\n * Login with email and password\n */\n login: async (credentials) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const user = await authService.login(credentials);\n set({ user, isAuthenticated: true, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Signup with email, password, and name\n * Note: Signup returns a message, user must verify email before login\n */\n signup: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await authService.signup(data);\n // Signup successful but user is not logged in yet\n // They need to verify their email first\n set({ isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Logout current user\n */\n logout: async () => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true });\n try {\n await authService.logout();\n set({ user: null, isAuthenticated: false, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Send forgot password email\n */\n forgotPassword: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await authService.forgotPassword(data);\n set({ isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Reset password with token\n */\n resetPassword: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await authService.resetPassword(data);\n set({ isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Verify code (email verification, 2FA, etc.)\n */\n verifyCode: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await authService.verifyCode(data);\n set({ isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Verify code for password reset\n */\n verifyCodeReset: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n const result = await authService.verifyCodeReset(data);\n set({ isLoading: false });\n return result;\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Resend verification code\n */\n resendCode: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await authService.resendCode(data);\n set({ isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Update user profile\n */\n updateProfile: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await authService.updateProfile(data);\n // Re-fetch user info to get updated data\n const user = await authService.getCurrentUser();\n set({ user, isLoading: false });\n } catch (error) {\n set({ error: (error as Error).message, isLoading: false });\n throw error;\n }\n },\n\n /**\n * Change password\n */\n changePassword: async (data) => {\n if (!authService) {\n throw new Error(\n \"Auth service not initialized. Call initializeOnex() first.\"\n );\n }\n\n set({ isLoading: true, error: null });\n try {\n await authService.changePassword(data);\n set({ 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/**\n * Initialize auth service\n * @internal Called by initializeOnex()\n */\nexport function initializeAuthService(service: AuthService): void {\n authService = service;\n}\n"]}
|