hey-pharmacist-ecommerce 1.0.5 → 1.0.6
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 +107 -1
- package/dist/index.d.mts +3636 -316
- package/dist/index.d.ts +3636 -316
- package/dist/index.js +6802 -3866
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6756 -3818
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -14
- package/src/components/AddressFormModal.tsx +171 -0
- package/src/components/CartItem.tsx +17 -12
- package/src/components/FilterChips.tsx +195 -0
- package/src/components/Header.tsx +121 -71
- package/src/components/OrderCard.tsx +18 -25
- package/src/components/ProductCard.tsx +209 -72
- package/src/components/ui/Button.tsx +13 -5
- package/src/components/ui/Card.tsx +46 -0
- package/src/hooks/useAddresses.ts +83 -0
- package/src/hooks/useOrders.ts +37 -19
- package/src/hooks/useProducts.ts +55 -63
- package/src/hooks/useWishlistProducts.ts +75 -0
- package/src/index.ts +3 -19
- package/src/lib/Apis/api.ts +1 -0
- package/src/lib/Apis/apis/cart-api.ts +3 -3
- package/src/lib/Apis/apis/inventory-api.ts +0 -108
- package/src/lib/Apis/apis/stores-api.ts +70 -0
- package/src/lib/Apis/apis/wishlist-api.ts +447 -0
- package/src/lib/Apis/models/cart-item-populated.ts +0 -1
- package/src/lib/Apis/models/create-single-variant-product-dto.ts +3 -10
- package/src/lib/Apis/models/create-variant-dto.ts +26 -33
- package/src/lib/Apis/models/extended-product-dto.ts +20 -24
- package/src/lib/Apis/models/index.ts +2 -1
- package/src/lib/Apis/models/order-time-line-dto.ts +49 -0
- package/src/lib/Apis/models/order.ts +3 -8
- package/src/lib/Apis/models/populated-order.ts +3 -8
- package/src/lib/Apis/models/product-variant.ts +29 -0
- package/src/lib/Apis/models/update-product-variant-dto.ts +16 -23
- package/src/lib/Apis/models/wishlist.ts +51 -0
- package/src/lib/Apis/wrapper.ts +18 -7
- package/src/lib/api-adapter/index.ts +0 -12
- package/src/lib/types/index.ts +16 -61
- package/src/lib/utils/colors.ts +7 -4
- package/src/lib/utils/format.ts +1 -1
- package/src/lib/validations/address.ts +14 -0
- package/src/providers/AuthProvider.tsx +61 -31
- package/src/providers/CartProvider.tsx +18 -28
- package/src/providers/EcommerceProvider.tsx +7 -0
- package/src/providers/FavoritesProvider.tsx +86 -0
- package/src/providers/ThemeProvider.tsx +16 -1
- package/src/providers/WishlistProvider.tsx +174 -0
- package/src/screens/AddressesScreen.tsx +484 -0
- package/src/screens/CartScreen.tsx +120 -84
- package/src/screens/CategoriesScreen.tsx +120 -0
- package/src/screens/CheckoutScreen.tsx +919 -241
- package/src/screens/CurrentOrdersScreen.tsx +125 -61
- package/src/screens/HomeScreen.tsx +209 -0
- package/src/screens/LoginScreen.tsx +133 -88
- package/src/screens/NewAddressScreen.tsx +187 -0
- package/src/screens/OrdersScreen.tsx +162 -50
- package/src/screens/ProductDetailScreen.tsx +641 -190
- package/src/screens/ProfileScreen.tsx +192 -116
- package/src/screens/RegisterScreen.tsx +193 -144
- package/src/screens/SearchResultsScreen.tsx +165 -0
- package/src/screens/ShopScreen.tsx +1110 -146
- package/src/screens/WishlistScreen.tsx +428 -0
- package/src/lib/Apis/models/inventory-paginated-response.ts +0 -75
- package/src/lib/api/auth.ts +0 -81
- package/src/lib/api/cart.ts +0 -42
- package/src/lib/api/orders.ts +0 -53
- package/src/lib/api/products.ts +0 -51
- package/src/lib/api-adapter/auth-adapter.ts +0 -196
- package/src/lib/api-adapter/cart-adapter.ts +0 -193
- package/src/lib/api-adapter/mappers.ts +0 -152
- package/src/lib/api-adapter/orders-adapter.ts +0 -195
- package/src/lib/api-adapter/products-adapter.ts +0 -194
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Orders API Adapter
|
|
3
|
-
* Connects frontend orders to real backend orders APIs
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { OrdersApi } from '../Apis/apis/orders-api';
|
|
7
|
-
import { ManualOrderDTO } from '../Apis/models';
|
|
8
|
-
import { getApiConfiguration } from './config';
|
|
9
|
-
import { mapOrder } from './mappers';
|
|
10
|
-
import { Order, ApiResponse, PaginatedResponse, Address } from '../types';
|
|
11
|
-
|
|
12
|
-
export interface CreateOrderData {
|
|
13
|
-
shippingAddress: Address;
|
|
14
|
-
billingAddress: Address;
|
|
15
|
-
sameAsShipping?: boolean;
|
|
16
|
-
paymentMethod?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const ordersAdapter = {
|
|
20
|
-
/**
|
|
21
|
-
* Get user's orders with pagination
|
|
22
|
-
*/
|
|
23
|
-
async getOrders(page: number = 1, limit: number = 10): Promise<PaginatedResponse<Order>> {
|
|
24
|
-
try {
|
|
25
|
-
const ordersApi = new OrdersApi(getApiConfiguration());
|
|
26
|
-
const response = await ordersApi.getAllOrders(
|
|
27
|
-
undefined, // paymentStatus
|
|
28
|
-
undefined, // orderStatus
|
|
29
|
-
page,
|
|
30
|
-
limit,
|
|
31
|
-
undefined, // search
|
|
32
|
-
undefined, // createdAfter
|
|
33
|
-
undefined, // createdBefore
|
|
34
|
-
undefined // userId
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
const orders = response.data.data?.map(mapOrder) || [];
|
|
38
|
-
|
|
39
|
-
return {
|
|
40
|
-
data: orders,
|
|
41
|
-
pagination: {
|
|
42
|
-
page: response.data.page || page,
|
|
43
|
-
limit: response.data.limit || limit,
|
|
44
|
-
total: response.data.total || orders.length,
|
|
45
|
-
totalPages: response.data.totalPages || 1,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
} catch (error: any) {
|
|
49
|
-
console.error('Failed to get orders:', error);
|
|
50
|
-
return {
|
|
51
|
-
data: [],
|
|
52
|
-
pagination: { page, limit, total: 0, totalPages: 0 },
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Get current/active orders
|
|
59
|
-
* Orders that are not delivered or cancelled
|
|
60
|
-
*/
|
|
61
|
-
async getCurrentOrders(): Promise<ApiResponse<Order[]>> {
|
|
62
|
-
try {
|
|
63
|
-
const ordersApi = new OrdersApi(getApiConfiguration());
|
|
64
|
-
const response = await ordersApi.getUserOrders();
|
|
65
|
-
|
|
66
|
-
const orders = (response.data || [])
|
|
67
|
-
.map((order: any) => mapOrder(order))
|
|
68
|
-
.filter((order: Order) =>
|
|
69
|
-
order.status !== 'delivered' &&
|
|
70
|
-
order.status !== 'cancelled'
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
success: true,
|
|
75
|
-
data: orders,
|
|
76
|
-
};
|
|
77
|
-
} catch (error: any) {
|
|
78
|
-
return {
|
|
79
|
-
success: false,
|
|
80
|
-
message: error.response?.data?.message || 'Failed to get current orders',
|
|
81
|
-
data: [],
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Get a single order by ID
|
|
88
|
-
*/
|
|
89
|
-
async getOrder(id: string): Promise<ApiResponse<Order>> {
|
|
90
|
-
try {
|
|
91
|
-
const ordersApi = new OrdersApi(getApiConfiguration());
|
|
92
|
-
const response = await ordersApi.getSingleOrder(id);
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
success: true,
|
|
96
|
-
data: mapOrder(response.data),
|
|
97
|
-
};
|
|
98
|
-
} catch (error: any) {
|
|
99
|
-
return {
|
|
100
|
-
success: false,
|
|
101
|
-
message: error.response?.data?.message || 'Failed to get order',
|
|
102
|
-
data: {} as Order,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Create a new order
|
|
109
|
-
*/
|
|
110
|
-
async createOrder(data: CreateOrderData): Promise<ApiResponse<Order>> {
|
|
111
|
-
try {
|
|
112
|
-
const ordersApi = new OrdersApi(getApiConfiguration());
|
|
113
|
-
|
|
114
|
-
// Build the order DTO
|
|
115
|
-
// Note: Cart items are handled automatically by backend
|
|
116
|
-
const orderDTO: ManualOrderDTO = {
|
|
117
|
-
items: [], // Will be populated from user's cart by backend
|
|
118
|
-
paymentMethod: 'Card' as any, // Card for Stripe, Cash for COD
|
|
119
|
-
orderStatus: 'Pending' as any,
|
|
120
|
-
manualDiscount: {} as any,
|
|
121
|
-
discountId: '',
|
|
122
|
-
manualShipping: {} as any,
|
|
123
|
-
paymentDueDate: new Date(),
|
|
124
|
-
chargeTax: true,
|
|
125
|
-
orderRemindingDates: [],
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const response = await ordersApi.createCheckout(
|
|
129
|
-
orderDTO,
|
|
130
|
-
true, // isDelivery
|
|
131
|
-
undefined, // userId (from token)
|
|
132
|
-
undefined, // rateId
|
|
133
|
-
undefined // billingAddressId
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
success: true,
|
|
138
|
-
data: mapOrder(response.data),
|
|
139
|
-
};
|
|
140
|
-
} catch (error: any) {
|
|
141
|
-
return {
|
|
142
|
-
success: false,
|
|
143
|
-
message: error.response?.data?.message || 'Failed to create order',
|
|
144
|
-
data: {} as Order,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Cancel an order
|
|
151
|
-
*/
|
|
152
|
-
async cancelOrder(id: string): Promise<ApiResponse<Order>> {
|
|
153
|
-
try {
|
|
154
|
-
const ordersApi = new OrdersApi(getApiConfiguration());
|
|
155
|
-
const response = await ordersApi.cancelOrder(id);
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
success: true,
|
|
159
|
-
data: mapOrder(response.data),
|
|
160
|
-
};
|
|
161
|
-
} catch (error: any) {
|
|
162
|
-
return {
|
|
163
|
-
success: false,
|
|
164
|
-
message: error.response?.data?.message || 'Failed to cancel order',
|
|
165
|
-
data: {} as Order,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Get order tracking information
|
|
172
|
-
*/
|
|
173
|
-
async getOrderTracking(id: string): Promise<ApiResponse<any>> {
|
|
174
|
-
try {
|
|
175
|
-
const ordersApi = new OrdersApi(getApiConfiguration());
|
|
176
|
-
const response = await ordersApi.getSingleOrder(id);
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
success: true,
|
|
180
|
-
data: {
|
|
181
|
-
orderStatus: response.data.orderStatus,
|
|
182
|
-
orderTimeLine: response.data.orderTimeLine,
|
|
183
|
-
shippingInfo: response.data.shippingInfo,
|
|
184
|
-
},
|
|
185
|
-
};
|
|
186
|
-
} catch (error: any) {
|
|
187
|
-
return {
|
|
188
|
-
success: false,
|
|
189
|
-
message: error.response?.data?.message || 'Failed to get tracking',
|
|
190
|
-
data: {},
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Products API Adapter
|
|
3
|
-
* Connects frontend products to real backend products APIs
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ProductsApi } from '../Apis/apis/products-api';
|
|
7
|
-
import { CategoriesApi } from '../Apis/apis/categories-api';
|
|
8
|
-
import { getApiConfiguration } from './config';
|
|
9
|
-
import { mapProduct } from './mappers';
|
|
10
|
-
import { Product, ApiResponse, PaginatedResponse, ProductFilters, Category } from '../types';
|
|
11
|
-
|
|
12
|
-
export const productsAdapter = {
|
|
13
|
-
/**
|
|
14
|
-
* Get all products with optional filters and pagination
|
|
15
|
-
*/
|
|
16
|
-
async getProducts(
|
|
17
|
-
filters?: ProductFilters,
|
|
18
|
-
page: number = 1,
|
|
19
|
-
limit: number = 20
|
|
20
|
-
): Promise<PaginatedResponse<Product>> {
|
|
21
|
-
try {
|
|
22
|
-
const productsApi = new ProductsApi(getApiConfiguration());
|
|
23
|
-
|
|
24
|
-
const response = await productsApi.getAllProductsForStore(
|
|
25
|
-
filters?.search,
|
|
26
|
-
undefined, // productType
|
|
27
|
-
filters?.category,
|
|
28
|
-
filters?.maxPrice,
|
|
29
|
-
filters?.minPrice,
|
|
30
|
-
undefined, // brandFilter
|
|
31
|
-
filters?.inStock !== undefined ? (filters.inStock ? 'in-stock' : 'out-of-stock') : undefined,
|
|
32
|
-
undefined, // sort
|
|
33
|
-
true, // includeNoVariantProducts
|
|
34
|
-
true, // isActive
|
|
35
|
-
limit,
|
|
36
|
-
page
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const products = response.data.data?.map(mapProduct) || [];
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
data: products,
|
|
43
|
-
pagination: {
|
|
44
|
-
page: response.data.currentPage || page,
|
|
45
|
-
limit: response.data.limit || limit,
|
|
46
|
-
total: response.data.totalItems || products.length,
|
|
47
|
-
totalPages: response.data.totalPages || 1,
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
} catch (error: any) {
|
|
51
|
-
console.error('Failed to get products:', error);
|
|
52
|
-
return {
|
|
53
|
-
data: [],
|
|
54
|
-
pagination: { page, limit, total: 0, totalPages: 0 },
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get a single product by ID
|
|
61
|
-
*/
|
|
62
|
-
async getProduct(id: string): Promise<ApiResponse<Product>> {
|
|
63
|
-
try {
|
|
64
|
-
const productsApi = new ProductsApi(getApiConfiguration());
|
|
65
|
-
const response = await productsApi.getSingleProduct(id);
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
success: true,
|
|
69
|
-
data: mapProduct(response.data),
|
|
70
|
-
};
|
|
71
|
-
} catch (error: any) {
|
|
72
|
-
return {
|
|
73
|
-
success: false,
|
|
74
|
-
message: error.response?.data?.message || 'Failed to get product',
|
|
75
|
-
data: {} as Product,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Get featured/top selling products
|
|
82
|
-
*/
|
|
83
|
-
async getFeaturedProducts(limit: number = 8): Promise<ApiResponse<Product[]>> {
|
|
84
|
-
try {
|
|
85
|
-
const productsApi = new ProductsApi(getApiConfiguration());
|
|
86
|
-
const response = await productsApi.getTopSellingProducts(limit, 1, true, true);
|
|
87
|
-
|
|
88
|
-
const products = response.data.data?.map(mapProduct) || [];
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
success: true,
|
|
92
|
-
data: products,
|
|
93
|
-
};
|
|
94
|
-
} catch (error: any) {
|
|
95
|
-
return {
|
|
96
|
-
success: false,
|
|
97
|
-
message: error.response?.data?.message || 'Failed to get featured products',
|
|
98
|
-
data: [],
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Get related products
|
|
105
|
-
*/
|
|
106
|
-
async getRelatedProducts(productId: string, limit: number = 4): Promise<ApiResponse<Product[]>> {
|
|
107
|
-
try {
|
|
108
|
-
const productsApi = new ProductsApi(getApiConfiguration());
|
|
109
|
-
const response = await productsApi.getRelatedProducts(productId);
|
|
110
|
-
|
|
111
|
-
const products = (response.data || [])
|
|
112
|
-
.map(mapProduct)
|
|
113
|
-
.slice(0, limit);
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
success: true,
|
|
117
|
-
data: products,
|
|
118
|
-
};
|
|
119
|
-
} catch (error: any) {
|
|
120
|
-
return {
|
|
121
|
-
success: false,
|
|
122
|
-
message: error.response?.data?.message || 'Failed to get related products',
|
|
123
|
-
data: [],
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Get all categories
|
|
130
|
-
*/
|
|
131
|
-
async getCategories(): Promise<ApiResponse<Category[]>> {
|
|
132
|
-
try {
|
|
133
|
-
const categoriesApi = new CategoriesApi(getApiConfiguration());
|
|
134
|
-
const response = await categoriesApi.getAllCategories();
|
|
135
|
-
|
|
136
|
-
const categories: Category[] = (response.data.data || []).map((cat: any) => ({
|
|
137
|
-
id: cat.id || cat._id || '',
|
|
138
|
-
name: cat.name || '',
|
|
139
|
-
slug: cat.slug || cat.name?.toLowerCase().replace(/\s+/g, '-') || '',
|
|
140
|
-
description: cat.description,
|
|
141
|
-
image: cat.image,
|
|
142
|
-
productCount: cat.productCount || 0,
|
|
143
|
-
}));
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
success: true,
|
|
147
|
-
data: categories,
|
|
148
|
-
};
|
|
149
|
-
} catch (error: any) {
|
|
150
|
-
return {
|
|
151
|
-
success: false,
|
|
152
|
-
message: error.response?.data?.message || 'Failed to get categories',
|
|
153
|
-
data: [],
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Search products
|
|
160
|
-
*/
|
|
161
|
-
async searchProducts(query: string, limit: number = 10): Promise<ApiResponse<Product[]>> {
|
|
162
|
-
try {
|
|
163
|
-
const productsApi = new ProductsApi(getApiConfiguration());
|
|
164
|
-
const response = await productsApi.getAllProductsForStore(
|
|
165
|
-
query, // searchTerm
|
|
166
|
-
undefined,
|
|
167
|
-
undefined,
|
|
168
|
-
undefined,
|
|
169
|
-
undefined,
|
|
170
|
-
undefined,
|
|
171
|
-
undefined,
|
|
172
|
-
undefined,
|
|
173
|
-
true,
|
|
174
|
-
true,
|
|
175
|
-
limit,
|
|
176
|
-
1
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
const products = response.data.data?.map(mapProduct) || [];
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
success: true,
|
|
183
|
-
data: products,
|
|
184
|
-
};
|
|
185
|
-
} catch (error: any) {
|
|
186
|
-
return {
|
|
187
|
-
success: false,
|
|
188
|
-
message: error.response?.data?.message || 'Failed to search products',
|
|
189
|
-
data: [],
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
};
|
|
194
|
-
|