hey-pharmacist-ecommerce 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +810 -703
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +616 -510
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Footer.tsx +17 -15
- package/src/components/Header.tsx +14 -12
- package/src/components/OrderCard.tsx +3 -1
- package/src/components/ProductCard.tsx +3 -1
- package/src/index.ts +1 -0
- package/src/lib/api-adapter/config.ts +8 -5
- package/src/providers/AuthProvider.tsx +19 -5
- package/src/providers/BasePathProvider.tsx +36 -0
- package/src/providers/EcommerceProvider.tsx +13 -9
- package/src/providers/FavoritesProvider.tsx +12 -2
- package/src/screens/CartScreen.tsx +5 -3
- package/src/screens/CategoriesScreen.tsx +4 -2
- package/src/screens/CheckoutScreen.tsx +6 -4
- package/src/screens/CurrentOrdersScreen.tsx +4 -2
- package/src/screens/HomeScreen.tsx +8 -6
- package/src/screens/LoginScreen.tsx +3 -1
- package/src/screens/OrdersScreen.tsx +3 -1
- package/src/screens/ProductDetailScreen.tsx +5 -3
- package/src/screens/ProfileScreen.tsx +10 -8
- package/src/screens/RegisterScreen.tsx +3 -1
- package/src/screens/SearchResultsScreen.tsx +4 -2
- package/src/screens/ShopScreen.tsx +7 -5
- package/src/screens/WishlistScreen.tsx +7 -5
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var React20 = require('react');
|
|
5
5
|
var globalAxios4 = require('axios');
|
|
6
6
|
var sonner = require('sonner');
|
|
7
7
|
var reactQuery = require('@tanstack/react-query');
|
|
@@ -17,13 +17,117 @@ var zod = require('zod');
|
|
|
17
17
|
|
|
18
18
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
19
|
|
|
20
|
-
var
|
|
20
|
+
var React20__default = /*#__PURE__*/_interopDefault(React20);
|
|
21
21
|
var globalAxios4__default = /*#__PURE__*/_interopDefault(globalAxios4);
|
|
22
22
|
var Image3__default = /*#__PURE__*/_interopDefault(Image3);
|
|
23
23
|
var dynamic__default = /*#__PURE__*/_interopDefault(dynamic);
|
|
24
24
|
var Link8__default = /*#__PURE__*/_interopDefault(Link8);
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
var __defProp = Object.defineProperty;
|
|
27
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
28
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
29
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
30
|
+
var __esm = (fn, res) => function __init() {
|
|
31
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
32
|
+
};
|
|
33
|
+
var __export = (target, all) => {
|
|
34
|
+
for (var name in all)
|
|
35
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
36
|
+
};
|
|
37
|
+
var __copyProps = (to, from, except, desc) => {
|
|
38
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
39
|
+
for (let key of __getOwnPropNames(from))
|
|
40
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
41
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
42
|
+
}
|
|
43
|
+
return to;
|
|
44
|
+
};
|
|
45
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
46
|
+
|
|
47
|
+
// src/lib/Apis/configuration.ts
|
|
48
|
+
var Configuration;
|
|
49
|
+
var init_configuration = __esm({
|
|
50
|
+
"src/lib/Apis/configuration.ts"() {
|
|
51
|
+
Configuration = class {
|
|
52
|
+
constructor(param = {}) {
|
|
53
|
+
this.apiKey = param.apiKey;
|
|
54
|
+
this.username = param.username;
|
|
55
|
+
this.password = param.password;
|
|
56
|
+
this.accessToken = param.accessToken;
|
|
57
|
+
this.basePath = param.basePath;
|
|
58
|
+
this.baseOptions = param.baseOptions;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// src/lib/api-adapter/config.ts
|
|
65
|
+
var config_exports = {};
|
|
66
|
+
__export(config_exports, {
|
|
67
|
+
clearAuthToken: () => clearAuthToken,
|
|
68
|
+
getApiConfiguration: () => getApiConfiguration,
|
|
69
|
+
getAuthToken: () => getAuthToken,
|
|
70
|
+
getCurrentConfig: () => getCurrentConfig,
|
|
71
|
+
initializeApiAdapter: () => initializeApiAdapter,
|
|
72
|
+
setAuthToken: () => setAuthToken
|
|
73
|
+
});
|
|
74
|
+
function initializeApiAdapter(config) {
|
|
75
|
+
currentConfig = config;
|
|
76
|
+
apiConfiguration = new Configuration({
|
|
77
|
+
basePath: config.apiBaseUrl,
|
|
78
|
+
apiKey: () => config.storeId,
|
|
79
|
+
// x-store-key header
|
|
80
|
+
accessToken: () => getAuthToken() || ""
|
|
81
|
+
// Bearer token
|
|
82
|
+
});
|
|
83
|
+
return apiConfiguration;
|
|
84
|
+
}
|
|
85
|
+
function getApiConfiguration() {
|
|
86
|
+
if (!apiConfiguration) {
|
|
87
|
+
throw new Error("API adapter not initialized. Call initializeApiAdapter first.");
|
|
88
|
+
}
|
|
89
|
+
return apiConfiguration;
|
|
90
|
+
}
|
|
91
|
+
function getCurrentConfig() {
|
|
92
|
+
if (!currentConfig) {
|
|
93
|
+
throw new Error("API adapter not initialized.");
|
|
94
|
+
}
|
|
95
|
+
return currentConfig;
|
|
96
|
+
}
|
|
97
|
+
function getTokenKey() {
|
|
98
|
+
const storeId = currentConfig?.storeId || "default";
|
|
99
|
+
return `ecommerce_access_token_${storeId}`;
|
|
100
|
+
}
|
|
101
|
+
function setAuthToken(token) {
|
|
102
|
+
if (typeof window !== "undefined") {
|
|
103
|
+
localStorage.setItem(getTokenKey(), token);
|
|
104
|
+
if (apiConfiguration) {
|
|
105
|
+
apiConfiguration.accessToken = () => token;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function getAuthToken() {
|
|
110
|
+
if (typeof window !== "undefined") {
|
|
111
|
+
return localStorage.getItem(getTokenKey());
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
function clearAuthToken() {
|
|
116
|
+
if (typeof window !== "undefined") {
|
|
117
|
+
localStorage.removeItem(getTokenKey());
|
|
118
|
+
if (apiConfiguration) {
|
|
119
|
+
apiConfiguration.accessToken = () => "";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
var apiConfiguration, currentConfig;
|
|
124
|
+
var init_config = __esm({
|
|
125
|
+
"src/lib/api-adapter/config.ts"() {
|
|
126
|
+
init_configuration();
|
|
127
|
+
apiConfiguration = null;
|
|
128
|
+
currentConfig = null;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
27
131
|
|
|
28
132
|
// src/lib/utils/colors.ts
|
|
29
133
|
function hexToRgb(hex) {
|
|
@@ -68,16 +172,16 @@ function darken(r, g, b, amount) {
|
|
|
68
172
|
}
|
|
69
173
|
|
|
70
174
|
// src/providers/ThemeProvider.tsx
|
|
71
|
-
var ThemeContext =
|
|
175
|
+
var ThemeContext = React20.createContext(void 0);
|
|
72
176
|
function useTheme() {
|
|
73
|
-
const context =
|
|
177
|
+
const context = React20.useContext(ThemeContext);
|
|
74
178
|
if (!context) {
|
|
75
179
|
throw new Error("useTheme must be used within ThemeProvider");
|
|
76
180
|
}
|
|
77
181
|
return context;
|
|
78
182
|
}
|
|
79
183
|
function ThemeProvider({ config, children }) {
|
|
80
|
-
|
|
184
|
+
React20.useEffect(() => {
|
|
81
185
|
const primaryShades = generateColorShades(config.colors.primary);
|
|
82
186
|
const secondaryShades = generateColorShades(config.colors.secondary);
|
|
83
187
|
const accentShades = generateColorShades(config.colors.accent);
|
|
@@ -104,70 +208,11 @@ function ThemeProvider({ config, children }) {
|
|
|
104
208
|
root.style.setProperty(`--header-to`, secondaryShades[600]);
|
|
105
209
|
}
|
|
106
210
|
}, [config]);
|
|
107
|
-
return /* @__PURE__ */
|
|
211
|
+
return /* @__PURE__ */ React20__default.default.createElement(ThemeContext.Provider, { value: { config } }, children);
|
|
108
212
|
}
|
|
109
213
|
|
|
110
|
-
// src/
|
|
111
|
-
|
|
112
|
-
constructor(param = {}) {
|
|
113
|
-
this.apiKey = param.apiKey;
|
|
114
|
-
this.username = param.username;
|
|
115
|
-
this.password = param.password;
|
|
116
|
-
this.accessToken = param.accessToken;
|
|
117
|
-
this.basePath = param.basePath;
|
|
118
|
-
this.baseOptions = param.baseOptions;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
// src/lib/api-adapter/config.ts
|
|
123
|
-
var apiConfiguration = null;
|
|
124
|
-
var currentConfig = null;
|
|
125
|
-
function initializeApiAdapter(config) {
|
|
126
|
-
currentConfig = config;
|
|
127
|
-
apiConfiguration = new Configuration({
|
|
128
|
-
basePath: config.apiBaseUrl,
|
|
129
|
-
apiKey: () => config.storeId,
|
|
130
|
-
// x-store-key header
|
|
131
|
-
accessToken: () => getAuthToken() || ""
|
|
132
|
-
// Bearer token
|
|
133
|
-
});
|
|
134
|
-
return apiConfiguration;
|
|
135
|
-
}
|
|
136
|
-
function getApiConfiguration() {
|
|
137
|
-
if (!apiConfiguration) {
|
|
138
|
-
throw new Error("API adapter not initialized. Call initializeApiAdapter first.");
|
|
139
|
-
}
|
|
140
|
-
return apiConfiguration;
|
|
141
|
-
}
|
|
142
|
-
function getCurrentConfig() {
|
|
143
|
-
if (!currentConfig) {
|
|
144
|
-
throw new Error("API adapter not initialized.");
|
|
145
|
-
}
|
|
146
|
-
return currentConfig;
|
|
147
|
-
}
|
|
148
|
-
var TOKEN_KEY = "ecommerce_access_token";
|
|
149
|
-
function setAuthToken(token) {
|
|
150
|
-
if (typeof window !== "undefined") {
|
|
151
|
-
localStorage.setItem(TOKEN_KEY, token);
|
|
152
|
-
if (apiConfiguration) {
|
|
153
|
-
apiConfiguration.accessToken = () => token;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function getAuthToken() {
|
|
158
|
-
if (typeof window !== "undefined") {
|
|
159
|
-
return localStorage.getItem(TOKEN_KEY);
|
|
160
|
-
}
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
function clearAuthToken() {
|
|
164
|
-
if (typeof window !== "undefined") {
|
|
165
|
-
localStorage.removeItem(TOKEN_KEY);
|
|
166
|
-
if (apiConfiguration) {
|
|
167
|
-
apiConfiguration.accessToken = () => "";
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
214
|
+
// src/providers/AuthProvider.tsx
|
|
215
|
+
init_config();
|
|
171
216
|
var BASE_PATH = "/".replace(/\/+$/, "");
|
|
172
217
|
var BaseAPI = class {
|
|
173
218
|
constructor(configuration, basePath = BASE_PATH, axios = globalAxios4__default.default) {
|
|
@@ -1895,19 +1940,29 @@ var AuthApi = class extends BaseAPI {
|
|
|
1895
1940
|
};
|
|
1896
1941
|
|
|
1897
1942
|
// src/providers/AuthProvider.tsx
|
|
1898
|
-
var AuthContext =
|
|
1943
|
+
var AuthContext = React20.createContext(void 0);
|
|
1899
1944
|
function useAuth() {
|
|
1900
|
-
const context =
|
|
1945
|
+
const context = React20.useContext(AuthContext);
|
|
1901
1946
|
if (!context) {
|
|
1902
1947
|
throw new Error("useAuth must be used within AuthProvider");
|
|
1903
1948
|
}
|
|
1904
1949
|
return context;
|
|
1905
1950
|
}
|
|
1906
1951
|
function AuthProvider({ children }) {
|
|
1907
|
-
const [user, setUser] =
|
|
1908
|
-
const [isLoading, setIsLoading] =
|
|
1909
|
-
const
|
|
1910
|
-
|
|
1952
|
+
const [user, setUser] = React20.useState(null);
|
|
1953
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
1954
|
+
const getUserKey = () => {
|
|
1955
|
+
if (typeof window === "undefined") return "ecommerce_user";
|
|
1956
|
+
const token = getAuthToken();
|
|
1957
|
+
if (!token) return "ecommerce_user";
|
|
1958
|
+
try {
|
|
1959
|
+
const config = (init_config(), __toCommonJS(config_exports)).getCurrentConfig();
|
|
1960
|
+
return `ecommerce_user_${config?.storeId || "default"}`;
|
|
1961
|
+
} catch {
|
|
1962
|
+
return "ecommerce_user";
|
|
1963
|
+
}
|
|
1964
|
+
};
|
|
1965
|
+
const refreshUser = React20.useCallback(async () => {
|
|
1911
1966
|
try {
|
|
1912
1967
|
const token = getAuthToken();
|
|
1913
1968
|
if (token) {
|
|
@@ -1921,10 +1976,11 @@ function AuthProvider({ children }) {
|
|
|
1921
1976
|
setIsLoading(false);
|
|
1922
1977
|
}
|
|
1923
1978
|
}, []);
|
|
1924
|
-
|
|
1979
|
+
React20.useEffect(() => {
|
|
1925
1980
|
if (typeof window !== "undefined") {
|
|
1926
1981
|
try {
|
|
1927
|
-
const
|
|
1982
|
+
const userKey = getUserKey();
|
|
1983
|
+
const cached = localStorage.getItem(userKey);
|
|
1928
1984
|
if (cached) {
|
|
1929
1985
|
const parsed = JSON.parse(cached);
|
|
1930
1986
|
setUser(parsed);
|
|
@@ -1944,7 +2000,7 @@ function AuthProvider({ children }) {
|
|
|
1944
2000
|
}
|
|
1945
2001
|
setUser(response.data.userData);
|
|
1946
2002
|
if (typeof window !== "undefined") {
|
|
1947
|
-
localStorage.setItem(
|
|
2003
|
+
localStorage.setItem(getUserKey(), JSON.stringify(response.data.userData));
|
|
1948
2004
|
}
|
|
1949
2005
|
return response.data;
|
|
1950
2006
|
} finally {
|
|
@@ -1960,7 +2016,7 @@ function AuthProvider({ children }) {
|
|
|
1960
2016
|
}
|
|
1961
2017
|
setUser(response.data.userData);
|
|
1962
2018
|
if (typeof window !== "undefined") {
|
|
1963
|
-
localStorage.setItem(
|
|
2019
|
+
localStorage.setItem(getUserKey(), JSON.stringify(response.data.userData));
|
|
1964
2020
|
}
|
|
1965
2021
|
return response.data;
|
|
1966
2022
|
} finally {
|
|
@@ -1973,7 +2029,7 @@ function AuthProvider({ children }) {
|
|
|
1973
2029
|
clearAuthToken();
|
|
1974
2030
|
setUser(null);
|
|
1975
2031
|
if (typeof window !== "undefined") {
|
|
1976
|
-
localStorage.removeItem(
|
|
2032
|
+
localStorage.removeItem(getUserKey());
|
|
1977
2033
|
}
|
|
1978
2034
|
} finally {
|
|
1979
2035
|
setIsLoading(false);
|
|
@@ -2002,7 +2058,7 @@ function AuthProvider({ children }) {
|
|
|
2002
2058
|
updateUser,
|
|
2003
2059
|
refreshUser
|
|
2004
2060
|
};
|
|
2005
|
-
return /* @__PURE__ */
|
|
2061
|
+
return /* @__PURE__ */ React20__default.default.createElement(AuthContext.Provider, { value }, children);
|
|
2006
2062
|
}
|
|
2007
2063
|
var AddressesApiAxiosParamCreator = function(configuration) {
|
|
2008
2064
|
return {
|
|
@@ -6670,6 +6726,9 @@ var WishlistApi = class extends BaseAPI {
|
|
|
6670
6726
|
}
|
|
6671
6727
|
};
|
|
6672
6728
|
|
|
6729
|
+
// src/lib/Apis/index.ts
|
|
6730
|
+
init_configuration();
|
|
6731
|
+
|
|
6673
6732
|
// src/lib/Apis/models/manual-order-dto.ts
|
|
6674
6733
|
var ManualOrderDTOOrderStatusEnum = /* @__PURE__ */ ((ManualOrderDTOOrderStatusEnum2) => {
|
|
6675
6734
|
ManualOrderDTOOrderStatusEnum2["Pending"] = "Pending";
|
|
@@ -6706,20 +6765,23 @@ var PaymentPaymentStatusEnum = /* @__PURE__ */ ((PaymentPaymentStatusEnum2) => {
|
|
|
6706
6765
|
return PaymentPaymentStatusEnum2;
|
|
6707
6766
|
})(PaymentPaymentStatusEnum || {});
|
|
6708
6767
|
|
|
6768
|
+
// src/lib/api-adapter/index.ts
|
|
6769
|
+
init_config();
|
|
6770
|
+
|
|
6709
6771
|
// src/providers/CartProvider.tsx
|
|
6710
|
-
var CartContext =
|
|
6772
|
+
var CartContext = React20.createContext(void 0);
|
|
6711
6773
|
function useCart() {
|
|
6712
|
-
const context =
|
|
6774
|
+
const context = React20.useContext(CartContext);
|
|
6713
6775
|
if (!context) {
|
|
6714
6776
|
throw new Error("useCart must be used within CartProvider");
|
|
6715
6777
|
}
|
|
6716
6778
|
return context;
|
|
6717
6779
|
}
|
|
6718
6780
|
function CartProvider({ children }) {
|
|
6719
|
-
const [cart, setCart] =
|
|
6720
|
-
const [isLoading, setIsLoading] =
|
|
6781
|
+
const [cart, setCart] = React20.useState(null);
|
|
6782
|
+
const [isLoading, setIsLoading] = React20.useState(false);
|
|
6721
6783
|
const { isAuthenticated } = useAuth();
|
|
6722
|
-
const refreshCart =
|
|
6784
|
+
const refreshCart = React20.useCallback(async () => {
|
|
6723
6785
|
if (!isAuthenticated) {
|
|
6724
6786
|
setCart(null);
|
|
6725
6787
|
return;
|
|
@@ -6731,7 +6793,7 @@ function CartProvider({ children }) {
|
|
|
6731
6793
|
console.error("Failed to fetch cart:", error);
|
|
6732
6794
|
}
|
|
6733
6795
|
}, [isAuthenticated]);
|
|
6734
|
-
|
|
6796
|
+
React20.useEffect(() => {
|
|
6735
6797
|
refreshCart();
|
|
6736
6798
|
}, [refreshCart]);
|
|
6737
6799
|
const addToCart = async (productId, quantity = 1, variantId) => {
|
|
@@ -6792,8 +6854,13 @@ function CartProvider({ children }) {
|
|
|
6792
6854
|
clearCart,
|
|
6793
6855
|
refreshCart
|
|
6794
6856
|
};
|
|
6795
|
-
return /* @__PURE__ */
|
|
6857
|
+
return /* @__PURE__ */ React20__default.default.createElement(CartContext.Provider, { value }, children);
|
|
6796
6858
|
}
|
|
6859
|
+
|
|
6860
|
+
// src/lib/Apis/wrapper.ts
|
|
6861
|
+
init_configuration();
|
|
6862
|
+
init_config();
|
|
6863
|
+
init_config();
|
|
6797
6864
|
var BaseUrl = "https://api.heypharmacist.com";
|
|
6798
6865
|
globalAxios4__default.default.interceptors.request.use(async (config) => {
|
|
6799
6866
|
if (!config?.headers) {
|
|
@@ -6825,9 +6892,9 @@ var AXIOS_CONFIG = new Configuration({
|
|
|
6825
6892
|
timeout: 2e4
|
|
6826
6893
|
}
|
|
6827
6894
|
});
|
|
6828
|
-
var WishlistContext =
|
|
6895
|
+
var WishlistContext = React20.createContext(void 0);
|
|
6829
6896
|
function WishlistProvider({ children }) {
|
|
6830
|
-
const [state, setState] =
|
|
6897
|
+
const [state, setState] = React20.useState({
|
|
6831
6898
|
_id: "",
|
|
6832
6899
|
createdAt: /* @__PURE__ */ new Date(),
|
|
6833
6900
|
updatedAt: /* @__PURE__ */ new Date(),
|
|
@@ -6835,8 +6902,8 @@ function WishlistProvider({ children }) {
|
|
|
6835
6902
|
products: []
|
|
6836
6903
|
});
|
|
6837
6904
|
const { isAuthenticated } = useAuth() || {};
|
|
6838
|
-
const wishlistApi =
|
|
6839
|
-
const fetchWishlist =
|
|
6905
|
+
const wishlistApi = React20.useMemo(() => new WishlistApi(AXIOS_CONFIG), []);
|
|
6906
|
+
const fetchWishlist = React20.useCallback(async () => {
|
|
6840
6907
|
if (!isAuthenticated) {
|
|
6841
6908
|
setState((prev) => ({
|
|
6842
6909
|
...prev,
|
|
@@ -6865,7 +6932,7 @@ function WishlistProvider({ children }) {
|
|
|
6865
6932
|
}));
|
|
6866
6933
|
}
|
|
6867
6934
|
}, [isAuthenticated]);
|
|
6868
|
-
|
|
6935
|
+
React20.useEffect(() => {
|
|
6869
6936
|
fetchWishlist();
|
|
6870
6937
|
}, [fetchWishlist]);
|
|
6871
6938
|
const addToWishlist = async (product) => {
|
|
@@ -6927,7 +6994,7 @@ function WishlistProvider({ children }) {
|
|
|
6927
6994
|
const refreshWishlist = async () => {
|
|
6928
6995
|
await fetchWishlist();
|
|
6929
6996
|
};
|
|
6930
|
-
return /* @__PURE__ */
|
|
6997
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
6931
6998
|
WishlistContext.Provider,
|
|
6932
6999
|
{
|
|
6933
7000
|
value: {
|
|
@@ -6944,20 +7011,37 @@ function WishlistProvider({ children }) {
|
|
|
6944
7011
|
);
|
|
6945
7012
|
}
|
|
6946
7013
|
var useWishlist = () => {
|
|
6947
|
-
const context =
|
|
7014
|
+
const context = React20.useContext(WishlistContext);
|
|
6948
7015
|
if (context === void 0) {
|
|
6949
7016
|
throw new Error("useWishlist must be used within a WishlistProvider");
|
|
6950
7017
|
}
|
|
6951
7018
|
return context;
|
|
6952
7019
|
};
|
|
6953
|
-
|
|
6954
|
-
|
|
7020
|
+
var BasePathContext = React20.createContext(void 0);
|
|
7021
|
+
function BasePathProvider({ basePath = "", children }) {
|
|
7022
|
+
const normalized = basePath ? basePath.startsWith("/") ? basePath : `/${basePath}` : "";
|
|
7023
|
+
const buildPath = (path) => {
|
|
7024
|
+
if (!normalized) return path;
|
|
7025
|
+
if (!path) return normalized;
|
|
7026
|
+
if (path.startsWith(normalized + "/")) return path;
|
|
7027
|
+
if (path.startsWith("/")) return `${normalized}${path}`;
|
|
7028
|
+
return `${normalized}/${path}`;
|
|
7029
|
+
};
|
|
7030
|
+
return /* @__PURE__ */ React20__default.default.createElement(BasePathContext.Provider, { value: { basePath: normalized, buildPath } }, children);
|
|
7031
|
+
}
|
|
7032
|
+
function useBasePath() {
|
|
7033
|
+
const ctx = React20.useContext(BasePathContext);
|
|
7034
|
+
if (!ctx) throw new Error("useBasePath must be used within BasePathProvider");
|
|
7035
|
+
return ctx;
|
|
7036
|
+
}
|
|
7037
|
+
function EcommerceProvider({ config, children, withToaster = true, basePath = "" }) {
|
|
7038
|
+
React20.useEffect(() => {
|
|
6955
7039
|
initializeApiAdapter(config);
|
|
6956
7040
|
}, [config]);
|
|
6957
|
-
const [client] =
|
|
7041
|
+
const [client] = React20__default.default.useState(
|
|
6958
7042
|
new reactQuery.QueryClient({ defaultOptions: { queries: { staleTime: 5e3 } } })
|
|
6959
7043
|
);
|
|
6960
|
-
return /* @__PURE__ */
|
|
7044
|
+
return /* @__PURE__ */ React20__default.default.createElement(reactQuery.QueryClientProvider, { client }, /* @__PURE__ */ React20__default.default.createElement(ThemeProvider, { config }, /* @__PURE__ */ React20__default.default.createElement(BasePathProvider, { basePath }, /* @__PURE__ */ React20__default.default.createElement(AuthProvider, null, /* @__PURE__ */ React20__default.default.createElement(CartProvider, null, /* @__PURE__ */ React20__default.default.createElement(WishlistProvider, null, children, withToaster && /* @__PURE__ */ React20__default.default.createElement(sonner.Toaster, { position: "top-right", richColors: true })))))));
|
|
6961
7045
|
}
|
|
6962
7046
|
|
|
6963
7047
|
// src/lib/utils/format.ts
|
|
@@ -7000,14 +7084,15 @@ function ProductCard({
|
|
|
7000
7084
|
className
|
|
7001
7085
|
}) {
|
|
7002
7086
|
const router = navigation.useRouter();
|
|
7003
|
-
const
|
|
7087
|
+
const { buildPath } = useBasePath();
|
|
7088
|
+
const [isFavorite, setIsFavorite] = React20.useState(isFavorited);
|
|
7004
7089
|
const { addToWishlist, removeFromWishlist, isInWishlist } = useWishlist();
|
|
7005
|
-
const [isHovered, setIsHovered] =
|
|
7006
|
-
const [isImageLoaded, setIsImageLoaded] =
|
|
7007
|
-
const handleImageLoad =
|
|
7090
|
+
const [isHovered, setIsHovered] = React20.useState(false);
|
|
7091
|
+
const [isImageLoaded, setIsImageLoaded] = React20.useState(false);
|
|
7092
|
+
const handleImageLoad = React20.useCallback(() => {
|
|
7008
7093
|
setIsImageLoaded(true);
|
|
7009
7094
|
}, []);
|
|
7010
|
-
const handleCardClick =
|
|
7095
|
+
const handleCardClick = React20.useCallback((e) => {
|
|
7011
7096
|
if (onClickProduct) {
|
|
7012
7097
|
e.preventDefault();
|
|
7013
7098
|
onClickProduct(product);
|
|
@@ -7031,7 +7116,7 @@ function ProductCard({
|
|
|
7031
7116
|
sonner.toast.error("Failed to update wishlist");
|
|
7032
7117
|
}
|
|
7033
7118
|
};
|
|
7034
|
-
|
|
7119
|
+
React20.useEffect(() => {
|
|
7035
7120
|
setIsFavorite(isInWishlist(product?._id || "") || isFavorited);
|
|
7036
7121
|
}, [isFavorited, isInWishlist, product?._id]);
|
|
7037
7122
|
const handleKeyDown = (e) => {
|
|
@@ -7040,13 +7125,13 @@ function ProductCard({
|
|
|
7040
7125
|
handleCardClick(e);
|
|
7041
7126
|
}
|
|
7042
7127
|
};
|
|
7043
|
-
|
|
7128
|
+
React20.useMemo(() => {
|
|
7044
7129
|
return {
|
|
7045
7130
|
src: product.productMedia?.[0]?.file || "/placeholder-product.jpg",
|
|
7046
7131
|
alt: product.name || "Product image"
|
|
7047
7132
|
};
|
|
7048
7133
|
}, [product.productMedia, product.name]);
|
|
7049
|
-
return /* @__PURE__ */
|
|
7134
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
7050
7135
|
framerMotion.motion.article,
|
|
7051
7136
|
{
|
|
7052
7137
|
className: "relative group bg-white rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-all duration-300 border border-gray-100 hover:border-gray-200 flex h-[420px] flex-col",
|
|
@@ -7059,7 +7144,7 @@ function ProductCard({
|
|
|
7059
7144
|
onClick: handleCardClick,
|
|
7060
7145
|
onKeyDown: handleKeyDown
|
|
7061
7146
|
},
|
|
7062
|
-
/* @__PURE__ */
|
|
7147
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative h-48 w-full overflow-hidden bg-gray-50" }, /* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, !isImageLoaded && /* @__PURE__ */ React20__default.default.createElement(
|
|
7063
7148
|
framerMotion.motion.div,
|
|
7064
7149
|
{
|
|
7065
7150
|
className: "absolute inset-0 bg-gray-200 animate-pulse",
|
|
@@ -7067,7 +7152,7 @@ function ProductCard({
|
|
|
7067
7152
|
exit: { opacity: 0 },
|
|
7068
7153
|
transition: { duration: 0.2 }
|
|
7069
7154
|
}
|
|
7070
|
-
)), product.productMedia?.[0]?.file && /* @__PURE__ */
|
|
7155
|
+
)), product.productMedia?.[0]?.file && /* @__PURE__ */ React20__default.default.createElement(
|
|
7071
7156
|
Image3__default.default,
|
|
7072
7157
|
{
|
|
7073
7158
|
src: product.productMedia?.[0]?.file || "/placeholder-product.jpg",
|
|
@@ -7078,7 +7163,7 @@ function ProductCard({
|
|
|
7078
7163
|
priority: false,
|
|
7079
7164
|
onLoad: handleImageLoad
|
|
7080
7165
|
}
|
|
7081
|
-
), /* @__PURE__ */
|
|
7166
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute top-3 left-3 flex flex-col gap-2 z-10" }, product.isDiscounted && /* @__PURE__ */ React20__default.default.createElement(
|
|
7082
7167
|
framerMotion.motion.span,
|
|
7083
7168
|
{
|
|
7084
7169
|
initial: { scale: 0.9, opacity: 0 },
|
|
@@ -7088,7 +7173,7 @@ function ProductCard({
|
|
|
7088
7173
|
"-",
|
|
7089
7174
|
product.discountAmount,
|
|
7090
7175
|
"%"
|
|
7091
|
-
), product.inventoryCount === 0 && /* @__PURE__ */
|
|
7176
|
+
), product.inventoryCount === 0 && /* @__PURE__ */ React20__default.default.createElement(
|
|
7092
7177
|
framerMotion.motion.span,
|
|
7093
7178
|
{
|
|
7094
7179
|
initial: { scale: 0.9, opacity: 0 },
|
|
@@ -7096,7 +7181,7 @@ function ProductCard({
|
|
|
7096
7181
|
className: "inline-flex items-center justify-center px-2.5 py-1 rounded-full text-xs font-bold text-white bg-red-600"
|
|
7097
7182
|
},
|
|
7098
7183
|
"Out of Stock"
|
|
7099
|
-
)), showFavoriteButton && /* @__PURE__ */
|
|
7184
|
+
)), showFavoriteButton && /* @__PURE__ */ React20__default.default.createElement(
|
|
7100
7185
|
framerMotion.motion.button,
|
|
7101
7186
|
{
|
|
7102
7187
|
type: "button",
|
|
@@ -7106,10 +7191,10 @@ function ProductCard({
|
|
|
7106
7191
|
whileTap: { scale: 0.95 },
|
|
7107
7192
|
"aria-label": isFavorite ? "Remove from wishlist" : "Add to wishlist"
|
|
7108
7193
|
},
|
|
7109
|
-
/* @__PURE__ */
|
|
7194
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Heart, { className: `w-5 h-5 ${isFavorite ? "fill-current" : ""}` })
|
|
7110
7195
|
)),
|
|
7111
|
-
/* @__PURE__ */
|
|
7112
|
-
showFavoriteButton && /* @__PURE__ */
|
|
7196
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute top-4 left-4 flex flex-col gap-2" }, product.inventoryCount === 0 && /* @__PURE__ */ React20__default.default.createElement("span", { className: "px-3 py-1 rounded-full text-sm font-bold bg-red-100 text-red-800" }, "Out of Stock")),
|
|
7197
|
+
showFavoriteButton && /* @__PURE__ */ React20__default.default.createElement(
|
|
7113
7198
|
"button",
|
|
7114
7199
|
{
|
|
7115
7200
|
type: "button",
|
|
@@ -7117,21 +7202,21 @@ function ProductCard({
|
|
|
7117
7202
|
className: `absolute top-2 right-2 p-2 rounded-full transition-colors ${isFavorite ? "text-red-500" : "text-gray-400 hover:text-red-500"}`,
|
|
7118
7203
|
"aria-label": isFavorite ? "Remove from wishlist" : "Add to wishlist"
|
|
7119
7204
|
},
|
|
7120
|
-
/* @__PURE__ */
|
|
7205
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Heart, { className: `w-5 h-5 ${isFavorite ? "fill-current" : ""}` })
|
|
7121
7206
|
),
|
|
7122
|
-
/* @__PURE__ */
|
|
7123
|
-
/* @__PURE__ */
|
|
7207
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "p-4" }, product.parentCategories && product.parentCategories?.length > 0 && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs text-gray-500 uppercase tracking-wider mb-2" }, product.parentCategories?.map((category) => category?.name).join(", ") || "No categories"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mb-2" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-900 line-clamp-1 group-hover:text-primary-600 transition-colors" }, product.name), product?.sku && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs text-gray-400 mt-1" }, "SKU: ", product.sku)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-baseline gap-2" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-2xl font-bold text-gray-900" }, formatPrice(product.finalPrice)), product.inventoryCount > 0 && /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-xs text-gray-500" }, product.inventoryCount > 0 ? "In Stock" : "Out of Stock")), product.priceBeforeDiscount && product.priceBeforeDiscount > product.finalPrice && /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm text-gray-500 line-through" }, formatPrice(product.priceBeforeDiscount)))),
|
|
7208
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-auto p-4 pt-0" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
7124
7209
|
"button",
|
|
7125
7210
|
{
|
|
7126
7211
|
type: "button",
|
|
7127
7212
|
onClick: (e) => {
|
|
7128
7213
|
e.stopPropagation();
|
|
7129
|
-
router.push(`/products/${product._id}`);
|
|
7214
|
+
router.push(buildPath(`/products/${product._id}`));
|
|
7130
7215
|
},
|
|
7131
7216
|
className: `w-full flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium bg-primary-600 hover:bg-primary-700 text-white`
|
|
7132
7217
|
},
|
|
7133
7218
|
"View Product"
|
|
7134
|
-
), showFavoriteButton && /* @__PURE__ */
|
|
7219
|
+
), showFavoriteButton && /* @__PURE__ */ React20__default.default.createElement(
|
|
7135
7220
|
"button",
|
|
7136
7221
|
{
|
|
7137
7222
|
type: "button",
|
|
@@ -7139,7 +7224,7 @@ function ProductCard({
|
|
|
7139
7224
|
className: "mt-2 w-full flex items-center justify-center rounded-md border border-gray-300 bg-white px-3 py-2 text-sm font-medium text-primary-600 hover:bg-gray-50",
|
|
7140
7225
|
"aria-label": isFavorite ? "Remove from wishlist" : "Add to wishlist"
|
|
7141
7226
|
},
|
|
7142
|
-
/* @__PURE__ */
|
|
7227
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
7143
7228
|
lucideReact.Heart,
|
|
7144
7229
|
{
|
|
7145
7230
|
className: `mr-2 h-4 w-4 ${isFavorite ? "fill-red-500 text-red-500" : "text-primary-600"}`
|
|
@@ -7150,13 +7235,13 @@ function ProductCard({
|
|
|
7150
7235
|
);
|
|
7151
7236
|
}
|
|
7152
7237
|
function Skeleton({ className = "" }) {
|
|
7153
|
-
return /* @__PURE__ */
|
|
7238
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: `animate-pulse bg-gradient-to-r from-gray-200 via-gray-300 to-gray-200 bg-[length:200%_100%] rounded ${className}` });
|
|
7154
7239
|
}
|
|
7155
7240
|
function ProductCardSkeleton() {
|
|
7156
|
-
return /* @__PURE__ */
|
|
7241
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "bg-white rounded-2xl overflow-hidden shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-64 w-full" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "p-4 space-y-3" }, /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-6 w-3/4" }), /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-4 w-1/2" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex justify-between items-center pt-2" }, /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-8 w-24" }), /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-10 w-10 rounded-full" }))));
|
|
7157
7242
|
}
|
|
7158
7243
|
function OrderCardSkeleton() {
|
|
7159
|
-
return /* @__PURE__ */
|
|
7244
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "bg-white rounded-2xl p-6 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex justify-between items-start mb-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-2 flex-1" }, /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-6 w-32" }), /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-4 w-48" })), /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-6 w-20 rounded-full" })), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-4 w-full" }), /* @__PURE__ */ React20__default.default.createElement(Skeleton, { className: "h-4 w-2/3" })));
|
|
7160
7245
|
}
|
|
7161
7246
|
var MotionDiv = dynamic__default.default(() => import('framer-motion').then((mod) => mod.motion.div), {
|
|
7162
7247
|
ssr: false
|
|
@@ -7182,14 +7267,14 @@ function Button({
|
|
|
7182
7267
|
md: "px-6 py-3 text-base",
|
|
7183
7268
|
lg: "px-8 py-4 text-lg"
|
|
7184
7269
|
};
|
|
7185
|
-
return /* @__PURE__ */
|
|
7270
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
7186
7271
|
MotionDiv,
|
|
7187
7272
|
{
|
|
7188
7273
|
whileHover: { scale: 1.02 },
|
|
7189
7274
|
whileTap: { scale: 0.98 },
|
|
7190
7275
|
className: "inline-block"
|
|
7191
7276
|
},
|
|
7192
|
-
/* @__PURE__ */
|
|
7277
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
7193
7278
|
"button",
|
|
7194
7279
|
{
|
|
7195
7280
|
className: `${baseStyles} ${variants[variant]} ${sizes[size]} ${className}`,
|
|
@@ -7198,18 +7283,18 @@ function Button({
|
|
|
7198
7283
|
"aria-busy": isLoading,
|
|
7199
7284
|
...props
|
|
7200
7285
|
},
|
|
7201
|
-
isLoading ? /* @__PURE__ */
|
|
7286
|
+
isLoading ? /* @__PURE__ */ React20__default.default.createElement(React20__default.default.Fragment, null, /* @__PURE__ */ React20__default.default.createElement("svg", { className: "animate-spin h-5 w-5", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "aria-hidden": "true" }, /* @__PURE__ */ React20__default.default.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React20__default.default.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })), "Loading...") : children
|
|
7202
7287
|
)
|
|
7203
7288
|
);
|
|
7204
7289
|
}
|
|
7205
7290
|
|
|
7206
7291
|
// src/components/EmptyState.tsx
|
|
7207
7292
|
function EmptyState({ icon: Icon, title, description, actionLabel, onAction }) {
|
|
7208
|
-
return /* @__PURE__ */
|
|
7293
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col items-center justify-center py-16 px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mb-6" }, /* @__PURE__ */ React20__default.default.createElement(Icon, { className: "w-12 h-12 text-gray-400" })), /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-2xl font-bold text-gray-900 mb-2" }, title), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-gray-600 text-center max-w-md mb-8" }, description), actionLabel && onAction && /* @__PURE__ */ React20__default.default.createElement(Button, { onClick: onAction }, actionLabel));
|
|
7209
7294
|
}
|
|
7210
|
-
var Input =
|
|
7295
|
+
var Input = React20.forwardRef(
|
|
7211
7296
|
({ label, error, helperText, className = "", ...props }, ref) => {
|
|
7212
|
-
return /* @__PURE__ */
|
|
7297
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "w-full" }, label && /* @__PURE__ */ React20__default.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, label), /* @__PURE__ */ React20__default.default.createElement(
|
|
7213
7298
|
"input",
|
|
7214
7299
|
{
|
|
7215
7300
|
ref,
|
|
@@ -7223,21 +7308,21 @@ var Input = React19.forwardRef(
|
|
|
7223
7308
|
`,
|
|
7224
7309
|
...props
|
|
7225
7310
|
}
|
|
7226
|
-
), error && /* @__PURE__ */
|
|
7311
|
+
), error && /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 text-sm text-red-600" }, error), helperText && !error && /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 text-sm text-gray-500" }, helperText));
|
|
7227
7312
|
}
|
|
7228
7313
|
);
|
|
7229
7314
|
Input.displayName = "Input";
|
|
7230
7315
|
function useProducts(filters, page = 1, limit = 20) {
|
|
7231
|
-
const [products, setProducts] =
|
|
7232
|
-
const [isLoading, setIsLoading] =
|
|
7233
|
-
const [error, setError] =
|
|
7234
|
-
const [pagination, setPagination] =
|
|
7316
|
+
const [products, setProducts] = React20.useState([]);
|
|
7317
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
7318
|
+
const [error, setError] = React20.useState(null);
|
|
7319
|
+
const [pagination, setPagination] = React20.useState({
|
|
7235
7320
|
page: 1,
|
|
7236
7321
|
limit: 20,
|
|
7237
7322
|
total: 0,
|
|
7238
7323
|
totalPages: 0
|
|
7239
7324
|
});
|
|
7240
|
-
const fetchProducts =
|
|
7325
|
+
const fetchProducts = React20.useCallback(async () => {
|
|
7241
7326
|
setIsLoading(true);
|
|
7242
7327
|
setError(null);
|
|
7243
7328
|
try {
|
|
@@ -7293,16 +7378,16 @@ function useProducts(filters, page = 1, limit = 20) {
|
|
|
7293
7378
|
}
|
|
7294
7379
|
setIsLoading(false);
|
|
7295
7380
|
}, [filters, page, limit]);
|
|
7296
|
-
|
|
7381
|
+
React20.useEffect(() => {
|
|
7297
7382
|
fetchProducts();
|
|
7298
7383
|
}, [fetchProducts]);
|
|
7299
7384
|
return { products, isLoading, error, pagination };
|
|
7300
7385
|
}
|
|
7301
7386
|
function useProduct(id) {
|
|
7302
|
-
const [product, setProduct] =
|
|
7303
|
-
const [isLoading, setIsLoading] =
|
|
7304
|
-
const [error, setError] =
|
|
7305
|
-
|
|
7387
|
+
const [product, setProduct] = React20.useState(null);
|
|
7388
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
7389
|
+
const [error, setError] = React20.useState(null);
|
|
7390
|
+
React20.useEffect(() => {
|
|
7306
7391
|
const fetchProduct = async () => {
|
|
7307
7392
|
setIsLoading(true);
|
|
7308
7393
|
setError(null);
|
|
@@ -7319,10 +7404,10 @@ function useProduct(id) {
|
|
|
7319
7404
|
return { product, isLoading, error };
|
|
7320
7405
|
}
|
|
7321
7406
|
function useCategories() {
|
|
7322
|
-
const [categories, setCategories] =
|
|
7323
|
-
const [isLoading, setIsLoading] =
|
|
7324
|
-
const [error, setError] =
|
|
7325
|
-
|
|
7407
|
+
const [categories, setCategories] = React20.useState([]);
|
|
7408
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
7409
|
+
const [error, setError] = React20.useState(null);
|
|
7410
|
+
React20.useEffect(() => {
|
|
7326
7411
|
const fetchCategories = async () => {
|
|
7327
7412
|
try {
|
|
7328
7413
|
setIsLoading(true);
|
|
@@ -7343,26 +7428,27 @@ function useCategories() {
|
|
|
7343
7428
|
// src/screens/ShopScreen.tsx
|
|
7344
7429
|
function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
7345
7430
|
const router = navigation.useRouter();
|
|
7346
|
-
const
|
|
7347
|
-
const [
|
|
7348
|
-
const [
|
|
7349
|
-
const [
|
|
7350
|
-
const [
|
|
7351
|
-
const [
|
|
7352
|
-
const [
|
|
7353
|
-
const [
|
|
7354
|
-
const [
|
|
7431
|
+
const { buildPath } = useBasePath();
|
|
7432
|
+
const [filters, setFilters] = React20.useState(initialFilters);
|
|
7433
|
+
const [page, setPage] = React20.useState(1);
|
|
7434
|
+
const [showFilters, setShowFilters] = React20.useState(false);
|
|
7435
|
+
const [searchQuery, setSearchQuery] = React20.useState("");
|
|
7436
|
+
const [isSearching, setIsSearching] = React20.useState(false);
|
|
7437
|
+
const [sortOption, setSortOption] = React20.useState("featured");
|
|
7438
|
+
const [viewMode, setViewMode] = React20.useState("grid");
|
|
7439
|
+
const [selectedPriceRange, setSelectedPriceRange] = React20.useState(null);
|
|
7440
|
+
const [customPrice, setCustomPrice] = React20.useState({
|
|
7355
7441
|
min: "",
|
|
7356
7442
|
max: ""
|
|
7357
7443
|
});
|
|
7358
|
-
const [expandedCategories, setExpandedCategories] =
|
|
7444
|
+
const [expandedCategories, setExpandedCategories] = React20.useState({});
|
|
7359
7445
|
const { products, isLoading, pagination } = useProducts(filters, page, 20);
|
|
7360
7446
|
const { categories } = useCategories();
|
|
7361
7447
|
const handleSearch = (e) => {
|
|
7362
7448
|
e.preventDefault();
|
|
7363
7449
|
if (searchQuery.trim()) {
|
|
7364
7450
|
setIsSearching(true);
|
|
7365
|
-
router.push(`/search?q=${encodeURIComponent(searchQuery.trim())}`);
|
|
7451
|
+
router.push(buildPath(`/search?q=${encodeURIComponent(searchQuery.trim())}`));
|
|
7366
7452
|
}
|
|
7367
7453
|
};
|
|
7368
7454
|
const handleInputChange = (e) => {
|
|
@@ -7372,10 +7458,10 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7372
7458
|
if (e.key === "Enter" && searchQuery.trim()) {
|
|
7373
7459
|
e.preventDefault();
|
|
7374
7460
|
setIsSearching(true);
|
|
7375
|
-
router.push(`/search?q=${encodeURIComponent(searchQuery.trim())}`);
|
|
7461
|
+
router.push(buildPath(`/search?q=${encodeURIComponent(searchQuery.trim())}`));
|
|
7376
7462
|
}
|
|
7377
7463
|
};
|
|
7378
|
-
const priceRanges =
|
|
7464
|
+
const priceRanges = React20.useMemo(
|
|
7379
7465
|
() => [
|
|
7380
7466
|
{ label: `Under ${formatPrice(25)}`, value: "under-25", min: void 0, max: 25 },
|
|
7381
7467
|
{ label: `${formatPrice(25)} - ${formatPrice(50)}`, value: "25-50", min: 25, max: 50 },
|
|
@@ -7384,13 +7470,13 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7384
7470
|
],
|
|
7385
7471
|
[]
|
|
7386
7472
|
);
|
|
7387
|
-
|
|
7473
|
+
React20.useEffect(() => {
|
|
7388
7474
|
setCustomPrice({
|
|
7389
7475
|
min: filters.minPrice !== void 0 ? String(filters.minPrice) : "",
|
|
7390
7476
|
max: filters.maxPrice !== void 0 ? String(filters.maxPrice) : ""
|
|
7391
7477
|
});
|
|
7392
7478
|
}, [filters.minPrice, filters.maxPrice]);
|
|
7393
|
-
|
|
7479
|
+
React20.useEffect(() => {
|
|
7394
7480
|
const updates = {};
|
|
7395
7481
|
if (filters.category) updates[filters.category] = true;
|
|
7396
7482
|
if (filters.subCategory) {
|
|
@@ -7403,18 +7489,18 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7403
7489
|
setExpandedCategories((prev) => ({ ...prev, ...updates }));
|
|
7404
7490
|
}
|
|
7405
7491
|
}, [filters.category, filters.subCategory, categories]);
|
|
7406
|
-
const toggleCategoryExpand =
|
|
7492
|
+
const toggleCategoryExpand = React20.useCallback((id) => {
|
|
7407
7493
|
setExpandedCategories((prev) => ({ ...prev, [id]: !prev[id] }));
|
|
7408
7494
|
}, []);
|
|
7409
|
-
const sortedCategories =
|
|
7495
|
+
const sortedCategories = React20.useMemo(
|
|
7410
7496
|
() => [...categories].sort((a, b) => a.name?.localeCompare(b.name ?? "") ?? 0),
|
|
7411
7497
|
[categories]
|
|
7412
7498
|
);
|
|
7413
|
-
const topCategories =
|
|
7499
|
+
const topCategories = React20.useMemo(
|
|
7414
7500
|
() => [...categories].sort((a, b) => (b.productCount ?? 0) - (a.productCount ?? 0)).slice(0, 6),
|
|
7415
7501
|
[categories]
|
|
7416
7502
|
);
|
|
7417
|
-
const productInsights =
|
|
7503
|
+
const productInsights = React20.useMemo(() => {
|
|
7418
7504
|
if (!products.length) {
|
|
7419
7505
|
return { newArrivals: 0, inStockCount: 0 };
|
|
7420
7506
|
}
|
|
@@ -7427,7 +7513,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7427
7513
|
});
|
|
7428
7514
|
return { newArrivals: newArrivals2, inStockCount };
|
|
7429
7515
|
}, [products]);
|
|
7430
|
-
const insightCards =
|
|
7516
|
+
const insightCards = React20.useMemo(
|
|
7431
7517
|
() => [
|
|
7432
7518
|
{
|
|
7433
7519
|
id: "new",
|
|
@@ -7460,7 +7546,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7460
7546
|
filters.newArrivals
|
|
7461
7547
|
]
|
|
7462
7548
|
);
|
|
7463
|
-
const filteredProducts =
|
|
7549
|
+
const filteredProducts = React20.useMemo(() => {
|
|
7464
7550
|
if (isLoading) return products;
|
|
7465
7551
|
let items = [...products];
|
|
7466
7552
|
if (filters.tags?.length) {
|
|
@@ -7472,7 +7558,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7472
7558
|
}
|
|
7473
7559
|
return items;
|
|
7474
7560
|
}, [isLoading, products, filters.tags, filters.newArrivals]);
|
|
7475
|
-
const sortedProducts =
|
|
7561
|
+
const sortedProducts = React20.useMemo(() => {
|
|
7476
7562
|
if (isLoading) {
|
|
7477
7563
|
return filteredProducts;
|
|
7478
7564
|
}
|
|
@@ -7491,14 +7577,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7491
7577
|
}
|
|
7492
7578
|
}, [isLoading, filteredProducts, sortOption]);
|
|
7493
7579
|
const displayedProducts = sortedProducts;
|
|
7494
|
-
const quickSearches =
|
|
7580
|
+
const quickSearches = React20.useMemo(() => {
|
|
7495
7581
|
const counts = /* @__PURE__ */ new Map();
|
|
7496
7582
|
products.forEach((p) => {
|
|
7497
7583
|
(p.tags || []).forEach((t) => counts.set(t, (counts.get(t) || 0) + 1));
|
|
7498
7584
|
});
|
|
7499
7585
|
return Array.from(counts.entries()).sort((a, b) => b[1] - a[1]).slice(0, 4).map(([tag]) => tag);
|
|
7500
7586
|
}, [products]);
|
|
7501
|
-
const handleQuickSearch =
|
|
7587
|
+
const handleQuickSearch = React20.useCallback((term) => {
|
|
7502
7588
|
setSearchQuery("");
|
|
7503
7589
|
setFilters((current) => ({
|
|
7504
7590
|
...current,
|
|
@@ -7507,7 +7593,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7507
7593
|
}));
|
|
7508
7594
|
setPage(1);
|
|
7509
7595
|
}, []);
|
|
7510
|
-
const handleCategoryChange =
|
|
7596
|
+
const handleCategoryChange = React20.useCallback(
|
|
7511
7597
|
(categorySlug) => {
|
|
7512
7598
|
setFilters((current) => {
|
|
7513
7599
|
if (current.category === categorySlug) {
|
|
@@ -7524,7 +7610,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7524
7610
|
},
|
|
7525
7611
|
[]
|
|
7526
7612
|
);
|
|
7527
|
-
const handleSubCategoryChange =
|
|
7613
|
+
const handleSubCategoryChange = React20.useCallback((parentCategoryId, subCategoryId) => {
|
|
7528
7614
|
setFilters((current) => {
|
|
7529
7615
|
if (current.subCategory === subCategoryId) {
|
|
7530
7616
|
const { subCategory, ...rest } = current;
|
|
@@ -7534,7 +7620,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7534
7620
|
});
|
|
7535
7621
|
setPage(1);
|
|
7536
7622
|
}, []);
|
|
7537
|
-
const handleToggleStock =
|
|
7623
|
+
const handleToggleStock = React20.useCallback(() => {
|
|
7538
7624
|
setFilters((current) => {
|
|
7539
7625
|
if (current.inStock) {
|
|
7540
7626
|
const { inStock, ...rest } = current;
|
|
@@ -7544,7 +7630,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7544
7630
|
});
|
|
7545
7631
|
setPage(1);
|
|
7546
7632
|
}, []);
|
|
7547
|
-
const handleToggleNewArrivals =
|
|
7633
|
+
const handleToggleNewArrivals = React20.useCallback(() => {
|
|
7548
7634
|
setFilters((current) => {
|
|
7549
7635
|
if (current.newArrivals) {
|
|
7550
7636
|
const { newArrivals: newArrivals2, ...rest } = current;
|
|
@@ -7554,21 +7640,21 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7554
7640
|
});
|
|
7555
7641
|
setPage(1);
|
|
7556
7642
|
}, []);
|
|
7557
|
-
const handleClearFilters =
|
|
7643
|
+
const handleClearFilters = React20.useCallback(() => {
|
|
7558
7644
|
setFilters({});
|
|
7559
7645
|
setSearchQuery("");
|
|
7560
7646
|
setSelectedPriceRange(null);
|
|
7561
7647
|
setCustomPrice({ min: "", max: "" });
|
|
7562
7648
|
setPage(1);
|
|
7563
7649
|
}, []);
|
|
7564
|
-
const handleRemoveCategory =
|
|
7650
|
+
const handleRemoveCategory = React20.useCallback(() => {
|
|
7565
7651
|
setFilters((current) => {
|
|
7566
7652
|
const { category, subCategory, ...rest } = current;
|
|
7567
7653
|
return rest;
|
|
7568
7654
|
});
|
|
7569
7655
|
setPage(1);
|
|
7570
7656
|
}, []);
|
|
7571
|
-
const handleRemoveSubCategory =
|
|
7657
|
+
const handleRemoveSubCategory = React20.useCallback(() => {
|
|
7572
7658
|
setFilters((current) => {
|
|
7573
7659
|
const next = { ...current };
|
|
7574
7660
|
delete next.subCategory;
|
|
@@ -7576,7 +7662,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7576
7662
|
});
|
|
7577
7663
|
setPage(1);
|
|
7578
7664
|
}, []);
|
|
7579
|
-
const handleRemoveSearch =
|
|
7665
|
+
const handleRemoveSearch = React20.useCallback(() => {
|
|
7580
7666
|
setFilters((current) => {
|
|
7581
7667
|
const { search, ...rest } = current;
|
|
7582
7668
|
return rest;
|
|
@@ -7584,14 +7670,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7584
7670
|
setSearchQuery("");
|
|
7585
7671
|
setPage(1);
|
|
7586
7672
|
}, []);
|
|
7587
|
-
const handleRemoveInStock =
|
|
7673
|
+
const handleRemoveInStock = React20.useCallback(() => {
|
|
7588
7674
|
setFilters((current) => {
|
|
7589
7675
|
const { inStock, ...rest } = current;
|
|
7590
7676
|
return rest;
|
|
7591
7677
|
});
|
|
7592
7678
|
setPage(1);
|
|
7593
7679
|
}, []);
|
|
7594
|
-
const handleRemovePrice =
|
|
7680
|
+
const handleRemovePrice = React20.useCallback(() => {
|
|
7595
7681
|
setFilters((current) => {
|
|
7596
7682
|
const next = { ...current };
|
|
7597
7683
|
delete next.minPrice;
|
|
@@ -7602,7 +7688,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7602
7688
|
setCustomPrice({ min: "", max: "" });
|
|
7603
7689
|
setPage(1);
|
|
7604
7690
|
}, []);
|
|
7605
|
-
const handleRemoveTag =
|
|
7691
|
+
const handleRemoveTag = React20.useCallback((tag) => {
|
|
7606
7692
|
setFilters((current) => {
|
|
7607
7693
|
if (!current.tags) return current;
|
|
7608
7694
|
const updated = current.tags.filter((item) => item !== tag);
|
|
@@ -7616,7 +7702,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7616
7702
|
});
|
|
7617
7703
|
setPage(1);
|
|
7618
7704
|
}, []);
|
|
7619
|
-
const handlePriceRangeSelect =
|
|
7705
|
+
const handlePriceRangeSelect = React20.useCallback(
|
|
7620
7706
|
(value) => {
|
|
7621
7707
|
const range = priceRanges.find((item) => item.value === value);
|
|
7622
7708
|
if (selectedPriceRange === value) {
|
|
@@ -7655,7 +7741,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7655
7741
|
},
|
|
7656
7742
|
[priceRanges, selectedPriceRange]
|
|
7657
7743
|
);
|
|
7658
|
-
const applyCustomPrice =
|
|
7744
|
+
const applyCustomPrice = React20.useCallback(() => {
|
|
7659
7745
|
const rawMin = customPrice.min.trim();
|
|
7660
7746
|
const rawMax = customPrice.max.trim();
|
|
7661
7747
|
const minValue = rawMin !== "" ? Number(rawMin) : void 0;
|
|
@@ -7692,7 +7778,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7692
7778
|
tags,
|
|
7693
7779
|
newArrivals
|
|
7694
7780
|
} = filters;
|
|
7695
|
-
const activeFilterChips =
|
|
7781
|
+
const activeFilterChips = React20.useMemo(() => {
|
|
7696
7782
|
const chips = [];
|
|
7697
7783
|
if (searchFilter) {
|
|
7698
7784
|
chips.push({
|
|
@@ -7784,7 +7870,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7784
7870
|
]);
|
|
7785
7871
|
const hasActiveFilters = activeFilterChips.length > 0;
|
|
7786
7872
|
const isCustomPriceDirty = customPrice.min.trim() !== "" || customPrice.max.trim() !== "";
|
|
7787
|
-
const renderFiltersPanel = () => /* @__PURE__ */
|
|
7873
|
+
const renderFiltersPanel = () => /* @__PURE__ */ React20__default.default.createElement(React20__default.default.Fragment, null, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-8" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-8" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start justify-between gap-3" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, "Refine results"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-1 text-sm text-gray-500" }, "Filter by category, price, and availability to find the perfect fit faster.")), hasActiveFilters && /* @__PURE__ */ React20__default.default.createElement(
|
|
7788
7874
|
"button",
|
|
7789
7875
|
{
|
|
7790
7876
|
type: "button",
|
|
@@ -7792,10 +7878,10 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7792
7878
|
className: "text-sm font-semibold text-primary-600 hover:text-primary-700"
|
|
7793
7879
|
},
|
|
7794
7880
|
"Clear all"
|
|
7795
|
-
)), /* @__PURE__ */
|
|
7881
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React20__default.default.createElement("h4", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-gray-500" }, "Categories"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-2" }, sortedCategories.length === 0 && /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm text-gray-500" }, "No categories available yet."), sortedCategories.map((category) => {
|
|
7796
7882
|
const isCategoryActive = categoryFilter === category.id;
|
|
7797
7883
|
const isExpanded = !!expandedCategories[category.id];
|
|
7798
|
-
return /* @__PURE__ */
|
|
7884
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { key: category.id, className: "rounded-xl border-gray-100 bg-white/50" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
7799
7885
|
"div",
|
|
7800
7886
|
{
|
|
7801
7887
|
role: "button",
|
|
@@ -7806,8 +7892,8 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7806
7892
|
},
|
|
7807
7893
|
className: `flex w-full items-center justify-between rounded-xl px-3 py-2 text-sm font-medium transition ${isCategoryActive ? "text-primary-700 bg-primary-50" : "text-gray-700 hover:text-primary-700 hover:bg-primary-50/50"}`
|
|
7808
7894
|
},
|
|
7809
|
-
/* @__PURE__ */
|
|
7810
|
-
/* @__PURE__ */
|
|
7895
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-medium" }, category.name), category.productCount > 0 && /* @__PURE__ */ React20__default.default.createElement("span", { className: `ml-1 rounded-full bg-gray-100 px-2 py-0.5 text-xs ${isCategoryActive ? "text-primary-700" : "text-gray-500"}` }, category.productCount)),
|
|
7896
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
7811
7897
|
"button",
|
|
7812
7898
|
{
|
|
7813
7899
|
type: "button",
|
|
@@ -7819,11 +7905,11 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7819
7905
|
className: "rounded-md p-1 hover:bg-gray-100",
|
|
7820
7906
|
"aria-label": isExpanded ? "Collapse" : "Expand"
|
|
7821
7907
|
},
|
|
7822
|
-
/* @__PURE__ */
|
|
7908
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ChevronDown, { className: `h-4 w-4 transition-transform ${isExpanded ? "rotate-180 text-primary-600" : "rotate-0 text-gray-400"}` })
|
|
7823
7909
|
)
|
|
7824
|
-
), isExpanded && Array.isArray(category.categorySubCategories) && category.categorySubCategories.length > 0 && /* @__PURE__ */
|
|
7910
|
+
), isExpanded && Array.isArray(category.categorySubCategories) && category.categorySubCategories.length > 0 && /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-1 border-gray-100 px-2 pb-2 pl-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "divide-y divide-gray-100" }, category.categorySubCategories.map((sub) => {
|
|
7825
7911
|
const isSubActive = subCategoryFilter === sub.id;
|
|
7826
|
-
return /* @__PURE__ */
|
|
7912
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
7827
7913
|
"button",
|
|
7828
7914
|
{
|
|
7829
7915
|
key: sub.id,
|
|
@@ -7834,9 +7920,9 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7834
7920
|
sub.name
|
|
7835
7921
|
);
|
|
7836
7922
|
}))));
|
|
7837
|
-
}))))), /* @__PURE__ */
|
|
7923
|
+
}))))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("h4", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-gray-500" }, "Price"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-2" }, priceRanges.map((range) => {
|
|
7838
7924
|
const isActive = selectedPriceRange === range.value;
|
|
7839
|
-
return /* @__PURE__ */
|
|
7925
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
7840
7926
|
"button",
|
|
7841
7927
|
{
|
|
7842
7928
|
type: "button",
|
|
@@ -7846,7 +7932,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7846
7932
|
},
|
|
7847
7933
|
range.label
|
|
7848
7934
|
);
|
|
7849
|
-
})), /* @__PURE__ */
|
|
7935
|
+
})), /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-2 gap-3" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
7850
7936
|
Input,
|
|
7851
7937
|
{
|
|
7852
7938
|
type: "number",
|
|
@@ -7855,7 +7941,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7855
7941
|
value: customPrice.min,
|
|
7856
7942
|
onChange: (event) => setCustomPrice((current) => ({ ...current, min: event.target.value }))
|
|
7857
7943
|
}
|
|
7858
|
-
), /* @__PURE__ */
|
|
7944
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
7859
7945
|
Input,
|
|
7860
7946
|
{
|
|
7861
7947
|
type: "number",
|
|
@@ -7864,7 +7950,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7864
7950
|
value: customPrice.max,
|
|
7865
7951
|
onChange: (event) => setCustomPrice((current) => ({ ...current, max: event.target.value }))
|
|
7866
7952
|
}
|
|
7867
|
-
)), /* @__PURE__ */
|
|
7953
|
+
)), /* @__PURE__ */ React20__default.default.createElement(
|
|
7868
7954
|
"button",
|
|
7869
7955
|
{
|
|
7870
7956
|
type: "button",
|
|
@@ -7873,48 +7959,48 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7873
7959
|
className: "w-full rounded-xl border border-primary-500 bg-primary-500/10 px-4 py-2.5 text-sm font-semibold text-primary-700 transition hover:bg-primary-500/20 disabled:cursor-not-allowed disabled:border-gray-200 disabled:text-gray-400"
|
|
7874
7960
|
},
|
|
7875
7961
|
"Apply price range"
|
|
7876
|
-
)), /* @__PURE__ */
|
|
7962
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React20__default.default.createElement("h4", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-gray-500" }, "Availability"), /* @__PURE__ */ React20__default.default.createElement(
|
|
7877
7963
|
"button",
|
|
7878
7964
|
{
|
|
7879
7965
|
type: "button",
|
|
7880
7966
|
onClick: handleToggleStock,
|
|
7881
7967
|
className: `flex w-full items-center justify-between rounded-xl border px-4 py-3 text-sm font-medium transition ${inStockOnly ? "border-primary-500 bg-primary-50 text-primary-700" : "border-gray-200 bg-white text-gray-600 hover:border-primary-300 hover:text-primary-600"}`
|
|
7882
7968
|
},
|
|
7883
|
-
/* @__PURE__ */
|
|
7884
|
-
/* @__PURE__ */
|
|
7885
|
-
), /* @__PURE__ */
|
|
7969
|
+
/* @__PURE__ */ React20__default.default.createElement("span", null, "In stock only"),
|
|
7970
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-4 w-4 text-primary-500" })
|
|
7971
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
7886
7972
|
"button",
|
|
7887
7973
|
{
|
|
7888
7974
|
type: "button",
|
|
7889
7975
|
onClick: handleToggleNewArrivals,
|
|
7890
7976
|
className: `mt-2 flex w-full items-center justify-between rounded-xl border px-4 py-3 text-sm font-medium transition ${newArrivals ? "border-secondary-500 bg-secondary-50 text-secondary-700" : "border-gray-200 bg-white text-gray-600 hover:border-secondary-300 hover:text-secondary-600"}`
|
|
7891
7977
|
},
|
|
7892
|
-
/* @__PURE__ */
|
|
7893
|
-
/* @__PURE__ */
|
|
7978
|
+
/* @__PURE__ */ React20__default.default.createElement("span", null, "New arrivals (last 30 days)"),
|
|
7979
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-4 w-4 text-secondary-500" })
|
|
7894
7980
|
))));
|
|
7895
|
-
return /* @__PURE__ */
|
|
7981
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
7896
7982
|
"div",
|
|
7897
7983
|
{
|
|
7898
7984
|
className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]",
|
|
7899
7985
|
"aria-hidden": "true"
|
|
7900
7986
|
}
|
|
7901
|
-
), /* @__PURE__ */
|
|
7987
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_bottom_right,_rgba(94,234,212,0.35),_transparent_55%)] opacity-60" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-24" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
7902
7988
|
framerMotion.motion.div,
|
|
7903
7989
|
{
|
|
7904
7990
|
initial: { opacity: 0, y: 24 },
|
|
7905
7991
|
animate: { opacity: 1, y: 0 },
|
|
7906
7992
|
className: "max-w-3xl space-y-8 text-center md:mx-auto md:text-left"
|
|
7907
7993
|
},
|
|
7908
|
-
/* @__PURE__ */
|
|
7909
|
-
/* @__PURE__ */
|
|
7910
|
-
/* @__PURE__ */
|
|
7911
|
-
/* @__PURE__ */
|
|
7994
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/10 px-4 py-2 text-sm font-semibold tracking-wide text-white/80 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-4 w-4" }), "Wellness products, curated for you"),
|
|
7995
|
+
/* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold leading-tight md:text-6xl" }, "Find pharmacy favorites crafted to keep your family thriving"),
|
|
7996
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "text-lg text-white/80 md:text-xl" }, "Explore a modern storefront with real-time inventory, smart filters, and rich product details designed to make healthier choices easier."),
|
|
7997
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
7912
7998
|
"form",
|
|
7913
7999
|
{
|
|
7914
8000
|
onSubmit: handleSearch,
|
|
7915
8001
|
className: "mx-auto max-w-2xl md:mx-0"
|
|
7916
8002
|
},
|
|
7917
|
-
/* @__PURE__ */
|
|
8003
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
7918
8004
|
"input",
|
|
7919
8005
|
{
|
|
7920
8006
|
type: "search",
|
|
@@ -7925,17 +8011,17 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7925
8011
|
className: "flex h-12 w-full rounded-xl border border-white/20 bg-white/10 px-4 py-2 pr-14 text-lg text-white placeholder-white/60 shadow-2xl shadow-primary-900/20 backdrop-blur focus:border-white/30 focus:outline-none focus:ring-2 focus:ring-white/20 disabled:opacity-50",
|
|
7926
8012
|
disabled: isSearching
|
|
7927
8013
|
}
|
|
7928
|
-
), /* @__PURE__ */
|
|
8014
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
7929
8015
|
"button",
|
|
7930
8016
|
{
|
|
7931
8017
|
type: "submit",
|
|
7932
8018
|
className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-xl bg-white/20 p-3 text-white transition hover:bg-white/30 disabled:opacity-50",
|
|
7933
8019
|
disabled: !searchQuery.trim() || isSearching
|
|
7934
8020
|
},
|
|
7935
|
-
isSearching ? /* @__PURE__ */
|
|
8021
|
+
isSearching ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-5 w-5 animate-spin rounded-full border-2 border-white border-t-transparent" }) : /* @__PURE__ */ React20__default.default.createElement(lucideReact.Search, { className: "h-5 w-5" })
|
|
7936
8022
|
))
|
|
7937
8023
|
)
|
|
7938
|
-
), /* @__PURE__ */
|
|
8024
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
7939
8025
|
framerMotion.motion.div,
|
|
7940
8026
|
{
|
|
7941
8027
|
initial: { opacity: 0, y: 24 },
|
|
@@ -7943,7 +8029,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7943
8029
|
transition: { delay: 0.15 },
|
|
7944
8030
|
className: "mt-12 flex flex-col gap-6 rounded-3xl border border-white/20 bg-white/10 p-6 backdrop-blur md:flex-row md:items-center md:justify-between"
|
|
7945
8031
|
},
|
|
7946
|
-
/* @__PURE__ */
|
|
8032
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.3em] text-white/60" }, "Explore popular searches"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-2" }, quickSearches.map((term) => /* @__PURE__ */ React20__default.default.createElement(
|
|
7947
8033
|
"button",
|
|
7948
8034
|
{
|
|
7949
8035
|
key: term,
|
|
@@ -7953,7 +8039,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7953
8039
|
},
|
|
7954
8040
|
term
|
|
7955
8041
|
)))),
|
|
7956
|
-
topCategories.length > 0 && /* @__PURE__ */
|
|
8042
|
+
topCategories.length > 0 && /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3 md:text-right" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.3em] text-white/60" }, "Trending categories"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap justify-start gap-2 md:justify-end" }, topCategories.map((category) => /* @__PURE__ */ React20__default.default.createElement(
|
|
7957
8043
|
"button",
|
|
7958
8044
|
{
|
|
7959
8045
|
key: category.id,
|
|
@@ -7963,9 +8049,9 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7963
8049
|
},
|
|
7964
8050
|
category.name
|
|
7965
8051
|
))))
|
|
7966
|
-
), /* @__PURE__ */
|
|
8052
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-10 grid gap-4 md:grid-cols-3" }, insightCards.map((card, index) => {
|
|
7967
8053
|
const Icon = card.icon;
|
|
7968
|
-
return /* @__PURE__ */
|
|
8054
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
7969
8055
|
framerMotion.motion.div,
|
|
7970
8056
|
{
|
|
7971
8057
|
key: card.id,
|
|
@@ -7978,10 +8064,10 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7978
8064
|
"aria-pressed": card.id === "new" ? newArrivals ? "true" : "false" : void 0,
|
|
7979
8065
|
title: card.id === "new" ? newArrivals ? "Filter active: showing products from the last 30 days" : "Click to filter products from the last 30 days" : void 0
|
|
7980
8066
|
},
|
|
7981
|
-
/* @__PURE__ */
|
|
7982
|
-
/* @__PURE__ */
|
|
8067
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.3em] text-white/60" }, card.label), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 text-3xl font-semibold text-white" }, card.value)), /* @__PURE__ */ React20__default.default.createElement("span", { className: "rounded-full bg-white/20 p-3 text-white" }, /* @__PURE__ */ React20__default.default.createElement(Icon, { className: "h-5 w-5" }))),
|
|
8068
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 text-sm text-white/70" }, card.helper)
|
|
7983
8069
|
);
|
|
7984
|
-
})))), /* @__PURE__ */
|
|
8070
|
+
})))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative z-10 -mt-12 pb-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-8 lg:flex-row" }, /* @__PURE__ */ React20__default.default.createElement("aside", { className: "hidden w-72 flex-shrink-0 lg:block" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "sticky top-24 rounded-3xl border border-gray-100 bg-white p-6 shadow-xl shadow-gray-200/40" }, renderFiltersPanel())), /* @__PURE__ */ React20__default.default.createElement("main", { className: "flex-1 space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-gray-100 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-6 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-2xl font-bold text-gray-900" }, "All products"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-1 text-sm text-gray-500" }, "Browse a pharmacy-grade catalogue with smart merchandising and modern UI.")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-3 md:flex-row md:items-center" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ArrowUpDown, { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), /* @__PURE__ */ React20__default.default.createElement(
|
|
7985
8071
|
"select",
|
|
7986
8072
|
{
|
|
7987
8073
|
value: sortOption,
|
|
@@ -7990,11 +8076,11 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7990
8076
|
},
|
|
7991
8077
|
className: "appearance-none rounded-xl border border-gray-200 bg-white py-2.5 pl-10 pr-9 text-sm font-medium text-gray-700 shadow-sm transition focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/30"
|
|
7992
8078
|
},
|
|
7993
|
-
/* @__PURE__ */
|
|
7994
|
-
/* @__PURE__ */
|
|
7995
|
-
/* @__PURE__ */
|
|
7996
|
-
/* @__PURE__ */
|
|
7997
|
-
), /* @__PURE__ */
|
|
8079
|
+
/* @__PURE__ */ React20__default.default.createElement("option", { value: "featured" }, "Featured products"),
|
|
8080
|
+
/* @__PURE__ */ React20__default.default.createElement("option", { value: "price-low-high" }, "Price: low to high"),
|
|
8081
|
+
/* @__PURE__ */ React20__default.default.createElement("option", { value: "price-high-low" }, "Price: high to low"),
|
|
8082
|
+
/* @__PURE__ */ React20__default.default.createElement("option", { value: "newest" }, "Newest arrivals")
|
|
8083
|
+
), /* @__PURE__ */ React20__default.default.createElement(lucideReact.ChevronDown, { className: "pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" })), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center rounded-xl border border-gray-200 bg-white shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
7998
8084
|
"button",
|
|
7999
8085
|
{
|
|
8000
8086
|
type: "button",
|
|
@@ -8002,9 +8088,9 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8002
8088
|
className: `flex items-center gap-2 rounded-l-xl px-4 py-2 text-sm font-medium transition ${viewMode === "grid" ? "bg-primary-50 text-primary-600" : "text-gray-500 hover:text-gray-700"}`,
|
|
8003
8089
|
"aria-pressed": viewMode === "grid"
|
|
8004
8090
|
},
|
|
8005
|
-
/* @__PURE__ */
|
|
8091
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.LayoutGrid, { className: "h-4 w-4" }),
|
|
8006
8092
|
"Grid"
|
|
8007
|
-
), /* @__PURE__ */
|
|
8093
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
8008
8094
|
"button",
|
|
8009
8095
|
{
|
|
8010
8096
|
type: "button",
|
|
@@ -8012,19 +8098,19 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8012
8098
|
className: `flex items-center gap-2 rounded-r-xl px-4 py-2 text-sm font-medium transition ${viewMode === "list" ? "bg-primary-50 text-primary-600" : "text-gray-500 hover:text-gray-700"}`,
|
|
8013
8099
|
"aria-pressed": viewMode === "list"
|
|
8014
8100
|
},
|
|
8015
|
-
/* @__PURE__ */
|
|
8101
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.LayoutList, { className: "h-4 w-4" }),
|
|
8016
8102
|
"List"
|
|
8017
|
-
)))), /* @__PURE__ */
|
|
8103
|
+
)))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-4 md:hidden" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8018
8104
|
Button,
|
|
8019
8105
|
{
|
|
8020
8106
|
variant: "outline",
|
|
8021
8107
|
className: "w-full",
|
|
8022
8108
|
onClick: () => setShowFilters(true)
|
|
8023
8109
|
},
|
|
8024
|
-
/* @__PURE__ */
|
|
8110
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.SlidersHorizontal, { className: "h-5 w-5" }),
|
|
8025
8111
|
"Filters",
|
|
8026
|
-
hasActiveFilters && /* @__PURE__ */
|
|
8027
|
-
)), hasActiveFilters && /* @__PURE__ */
|
|
8112
|
+
hasActiveFilters && /* @__PURE__ */ React20__default.default.createElement("span", { className: "ml-2 rounded-full bg-primary-600 px-2 py-0.5 text-xs font-semibold text-white" }, activeFilterChips.length)
|
|
8113
|
+
)), hasActiveFilters && /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 flex flex-wrap items-center gap-2 border-t border-gray-100 pt-4" }, activeFilterChips.map((chip) => /* @__PURE__ */ React20__default.default.createElement(
|
|
8028
8114
|
"button",
|
|
8029
8115
|
{
|
|
8030
8116
|
key: chip.key,
|
|
@@ -8033,8 +8119,8 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8033
8119
|
className: "group flex items-center gap-2 rounded-full bg-primary-50 px-3 py-1.5 text-sm font-medium text-primary-700 transition hover:bg-primary-100"
|
|
8034
8120
|
},
|
|
8035
8121
|
chip.label,
|
|
8036
|
-
/* @__PURE__ */
|
|
8037
|
-
)), /* @__PURE__ */
|
|
8122
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.X, { className: "h-4 w-4 text-primary-500 group-hover:text-primary-700" })
|
|
8123
|
+
)), /* @__PURE__ */ React20__default.default.createElement(
|
|
8038
8124
|
"button",
|
|
8039
8125
|
{
|
|
8040
8126
|
type: "button",
|
|
@@ -8042,28 +8128,28 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8042
8128
|
className: "text-sm font-semibold text-gray-500 hover:text-gray-700"
|
|
8043
8129
|
},
|
|
8044
8130
|
"Reset all"
|
|
8045
|
-
))), /* @__PURE__ */
|
|
8131
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-gray-100 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-3 text-sm text-gray-600 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React20__default.default.createElement("span", null, isLoading ? "Loading products..." : `Showing ${displayedProducts.length} of ${pagination.total || displayedProducts.length} products`), /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 text-gray-400" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Clock, { className: "h-4 w-4" }), "Updated a moment ago")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6" }, isLoading ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 xl:grid-cols-3" }, Array.from({ length: 6 }).map((_, index) => /* @__PURE__ */ React20__default.default.createElement(ProductCardSkeleton, { key: index }))) : displayedProducts.length > 0 ? viewMode === "grid" ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 xl:grid-cols-3" }, displayedProducts.map((product) => /* @__PURE__ */ React20__default.default.createElement("div", { key: product.id, className: "h-full" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8046
8132
|
ProductCard,
|
|
8047
8133
|
{
|
|
8048
8134
|
product,
|
|
8049
8135
|
onClickProduct: (item) => {
|
|
8050
8136
|
const productData = encodeURIComponent(JSON.stringify(item));
|
|
8051
|
-
router.push(`/products/${item.id}?product=${productData}`);
|
|
8137
|
+
router.push(buildPath(`/products/${item.id}?product=${productData}`));
|
|
8052
8138
|
}
|
|
8053
8139
|
}
|
|
8054
|
-
)))) : /* @__PURE__ */
|
|
8140
|
+
)))) : /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4" }, displayedProducts.map((product) => {
|
|
8055
8141
|
product.priceBeforeDiscount && product.priceBeforeDiscount > product.finalPrice ? Math.round(
|
|
8056
8142
|
(product.priceBeforeDiscount - product.finalPrice) / product.priceBeforeDiscount * 100
|
|
8057
8143
|
) : 0;
|
|
8058
|
-
return /* @__PURE__ */
|
|
8144
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
8059
8145
|
framerMotion.motion.div,
|
|
8060
8146
|
{
|
|
8061
8147
|
key: product.id,
|
|
8062
8148
|
whileHover: { y: -4 },
|
|
8063
8149
|
className: "group flex cursor-pointer flex-col gap-6 rounded-2xl border border-gray-100 bg-white p-5 shadow-sm transition hover:shadow-xl md:flex-row md:items-start",
|
|
8064
|
-
onClick: () => router.push(`/products/${product.id}`)
|
|
8150
|
+
onClick: () => router.push(buildPath(`/products/${product.id}`))
|
|
8065
8151
|
},
|
|
8066
|
-
/* @__PURE__ */
|
|
8152
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative h-48 w-full overflow-hidden rounded-2xl bg-gray-100 md:h-40 md:w-40" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8067
8153
|
Image3__default.default,
|
|
8068
8154
|
{
|
|
8069
8155
|
src: product.productMedia[0]?.file || "/placeholder-product.jpg",
|
|
@@ -8072,27 +8158,27 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8072
8158
|
className: "object-cover transition duration-500 group-hover:scale-105"
|
|
8073
8159
|
}
|
|
8074
8160
|
)),
|
|
8075
|
-
/* @__PURE__ */
|
|
8161
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-1 space-y-3" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-2 text-xs font-semibold uppercase tracking-wide text-primary-600" }, product.parentCategories.length > 0 && /* @__PURE__ */ React20__default.default.createElement("span", { className: "rounded-full bg-primary-50 px-3 py-1 text-primary-700" }, product.parentCategories.map((category) => category?.name).join(", ")), product.tags?.slice(0, 3).map((tag) => /* @__PURE__ */ React20__default.default.createElement(
|
|
8076
8162
|
"span",
|
|
8077
8163
|
{
|
|
8078
8164
|
key: tag,
|
|
8079
8165
|
className: "rounded-full bg-slate-100 px-3 py-1 text-gray-600"
|
|
8080
8166
|
},
|
|
8081
8167
|
tag
|
|
8082
|
-
))), /* @__PURE__ */
|
|
8083
|
-
/* @__PURE__ */
|
|
8168
|
+
))), /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-xl font-semibold text-gray-900" }, product.name), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-4 text-sm text-gray-500" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 font-medium text-primary-600" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "h-4 w-4" }), product.inventoryCount > 0 ? "In stock & ready to ship" : "Restocking soon"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Clock, { className: "h-4 w-4 text-primary-500" }), "Added ", new Date(product.createdAt).toLocaleDateString()))),
|
|
8169
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex w-full flex-col items-end gap-3 md:w-auto" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-right" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-3xl font-semibold text-gray-900" }, formatPrice(product.finalPrice)), product.priceBeforeDiscount && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-gray-400 line-through" }, formatPrice(product.priceBeforeDiscount))), /* @__PURE__ */ React20__default.default.createElement(
|
|
8084
8170
|
Button,
|
|
8085
8171
|
{
|
|
8086
8172
|
size: "sm",
|
|
8087
8173
|
onClick: (event) => {
|
|
8088
8174
|
event.stopPropagation();
|
|
8089
|
-
router.push(`/products/${product._id}`);
|
|
8175
|
+
router.push(buildPath(`/products/${product._id}`));
|
|
8090
8176
|
}
|
|
8091
8177
|
},
|
|
8092
8178
|
"View product"
|
|
8093
8179
|
))
|
|
8094
8180
|
);
|
|
8095
|
-
})) : /* @__PURE__ */
|
|
8181
|
+
})) : /* @__PURE__ */ React20__default.default.createElement(
|
|
8096
8182
|
EmptyState,
|
|
8097
8183
|
{
|
|
8098
8184
|
icon: lucideReact.Package,
|
|
@@ -8101,7 +8187,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8101
8187
|
actionLabel: hasActiveFilters ? "Clear filters" : void 0,
|
|
8102
8188
|
onAction: hasActiveFilters ? handleClearFilters : void 0
|
|
8103
8189
|
}
|
|
8104
|
-
)), pagination.totalPages > 1 && /* @__PURE__ */
|
|
8190
|
+
)), pagination.totalPages > 1 && /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-10 flex flex-wrap items-center justify-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8105
8191
|
Button,
|
|
8106
8192
|
{
|
|
8107
8193
|
variant: "outline",
|
|
@@ -8109,7 +8195,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8109
8195
|
disabled: page === 1
|
|
8110
8196
|
},
|
|
8111
8197
|
"Previous"
|
|
8112
|
-
), /* @__PURE__ */
|
|
8198
|
+
), /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm font-semibold text-gray-600" }, "Page ", page, " of ", pagination.totalPages), /* @__PURE__ */ React20__default.default.createElement(
|
|
8113
8199
|
Button,
|
|
8114
8200
|
{
|
|
8115
8201
|
variant: "outline",
|
|
@@ -8117,7 +8203,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8117
8203
|
disabled: page === pagination.totalPages
|
|
8118
8204
|
},
|
|
8119
8205
|
"Next"
|
|
8120
|
-
))))))), /* @__PURE__ */
|
|
8206
|
+
))))))), /* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, showFilters && /* @__PURE__ */ React20__default.default.createElement(
|
|
8121
8207
|
framerMotion.motion.div,
|
|
8122
8208
|
{
|
|
8123
8209
|
initial: { opacity: 0 },
|
|
@@ -8125,7 +8211,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8125
8211
|
exit: { opacity: 0 },
|
|
8126
8212
|
className: "fixed inset-0 z-50 bg-black/40 backdrop-blur-sm lg:hidden"
|
|
8127
8213
|
},
|
|
8128
|
-
/* @__PURE__ */
|
|
8214
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
8129
8215
|
framerMotion.motion.div,
|
|
8130
8216
|
{
|
|
8131
8217
|
initial: { y: "100%" },
|
|
@@ -8134,14 +8220,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8134
8220
|
transition: { type: "spring", stiffness: 260, damping: 26 },
|
|
8135
8221
|
className: "absolute inset-x-0 bottom-0 max-h-[85vh] overflow-y-auto rounded-t-3xl bg-white p-6 shadow-2xl"
|
|
8136
8222
|
},
|
|
8137
|
-
/* @__PURE__ */
|
|
8223
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "mb-6 flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, "Filters"), /* @__PURE__ */ React20__default.default.createElement(
|
|
8138
8224
|
"button",
|
|
8139
8225
|
{
|
|
8140
8226
|
type: "button",
|
|
8141
8227
|
onClick: () => setShowFilters(false),
|
|
8142
8228
|
className: "rounded-full border border-gray-200 p-2 text-gray-500 hover:text-gray-700"
|
|
8143
8229
|
},
|
|
8144
|
-
/* @__PURE__ */
|
|
8230
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.X, { className: "h-4 w-4" })
|
|
8145
8231
|
)),
|
|
8146
8232
|
renderFiltersPanel()
|
|
8147
8233
|
)
|
|
@@ -8160,7 +8246,7 @@ function Badge({ children, variant = "primary", size = "md", className = "" }) {
|
|
|
8160
8246
|
sm: "px-2 py-1 text-xs",
|
|
8161
8247
|
md: "px-3 py-1 text-sm"
|
|
8162
8248
|
};
|
|
8163
|
-
return /* @__PURE__ */
|
|
8249
|
+
return /* @__PURE__ */ React20__default.default.createElement("span", { className: `inline-flex items-center font-medium rounded-full border ${variants[variant]} ${sizes[size]} ${className}` }, children);
|
|
8164
8250
|
}
|
|
8165
8251
|
var safeFormatDate = (date, format = "long") => {
|
|
8166
8252
|
if (!date) return "N/A";
|
|
@@ -8174,19 +8260,20 @@ var safeFormatDate = (date, format = "long") => {
|
|
|
8174
8260
|
};
|
|
8175
8261
|
function ProductDetailScreen({ productId }) {
|
|
8176
8262
|
const router = navigation.useRouter();
|
|
8263
|
+
const { buildPath } = useBasePath();
|
|
8177
8264
|
const { product: productData, isLoading } = useProduct(productId);
|
|
8178
8265
|
const { addToCart } = useCart();
|
|
8179
|
-
const [selectedVariant, setSelectedVariant] =
|
|
8180
|
-
const [quantity, setQuantity] =
|
|
8181
|
-
const [isAddingToCart, setIsAddingToCart] =
|
|
8182
|
-
const [isFavorited, setIsFavorited] =
|
|
8183
|
-
const [relatedProducts, setRelatedProducts] =
|
|
8184
|
-
const [initialProductData, setInitialProductData] =
|
|
8185
|
-
const [activeImageIndex, setActiveImageIndex] =
|
|
8186
|
-
|
|
8266
|
+
const [selectedVariant, setSelectedVariant] = React20.useState(null);
|
|
8267
|
+
const [quantity, setQuantity] = React20.useState(1);
|
|
8268
|
+
const [isAddingToCart, setIsAddingToCart] = React20.useState(false);
|
|
8269
|
+
const [isFavorited, setIsFavorited] = React20.useState(false);
|
|
8270
|
+
const [relatedProducts, setRelatedProducts] = React20.useState([]);
|
|
8271
|
+
const [initialProductData, setInitialProductData] = React20.useState(null);
|
|
8272
|
+
const [activeImageIndex, setActiveImageIndex] = React20.useState(0);
|
|
8273
|
+
React20.useEffect(() => {
|
|
8187
8274
|
setActiveImageIndex(0);
|
|
8188
8275
|
}, [selectedVariant]);
|
|
8189
|
-
const product =
|
|
8276
|
+
const product = React20.useMemo(() => {
|
|
8190
8277
|
if (initialProductData && !productData) {
|
|
8191
8278
|
return initialProductData;
|
|
8192
8279
|
}
|
|
@@ -8237,7 +8324,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8237
8324
|
);
|
|
8238
8325
|
const variantSku = currentVariant?.sku || product?.sku || "N/A";
|
|
8239
8326
|
const variantInStock = currentVariant?.inventoryCount > 0;
|
|
8240
|
-
|
|
8327
|
+
React20.useEffect(() => {
|
|
8241
8328
|
if (typeof window === "undefined") return;
|
|
8242
8329
|
const searchParams = new URLSearchParams(window.location.search);
|
|
8243
8330
|
const productParam = searchParams.get("product");
|
|
@@ -8250,13 +8337,13 @@ function ProductDetailScreen({ productId }) {
|
|
|
8250
8337
|
}
|
|
8251
8338
|
}
|
|
8252
8339
|
}, []);
|
|
8253
|
-
|
|
8340
|
+
React20.useEffect(() => {
|
|
8254
8341
|
if (product?.productVariants?.length > 0) {
|
|
8255
8342
|
const newVariant = product?.productVariants?.[0];
|
|
8256
8343
|
setSelectedVariant(newVariant);
|
|
8257
8344
|
}
|
|
8258
8345
|
}, [product?.productVariants]);
|
|
8259
|
-
|
|
8346
|
+
React20.useEffect(() => {
|
|
8260
8347
|
if (!product?.id) return;
|
|
8261
8348
|
const fetchRelated = async () => {
|
|
8262
8349
|
try {
|
|
@@ -8297,7 +8384,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8297
8384
|
}
|
|
8298
8385
|
};
|
|
8299
8386
|
const { addToWishlist, removeFromWishlist, isInWishlist } = useWishlist();
|
|
8300
|
-
|
|
8387
|
+
React20.useEffect(() => {
|
|
8301
8388
|
if (product) {
|
|
8302
8389
|
setIsFavorited(isInWishlist(product.id));
|
|
8303
8390
|
}
|
|
@@ -8319,10 +8406,10 @@ function ProductDetailScreen({ productId }) {
|
|
|
8319
8406
|
}
|
|
8320
8407
|
};
|
|
8321
8408
|
if (isLoading) {
|
|
8322
|
-
return /* @__PURE__ */
|
|
8409
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-[520px] animate-pulse rounded-3xl bg-slate-200" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-3 gap-4" }, Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ React20__default.default.createElement("div", { key: index, className: "h-32 animate-pulse rounded-2xl bg-slate-200" })))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4 rounded-3xl bg-white p-6 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-8 w-32 animate-pulse rounded-full bg-slate-200" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-10 w-48 animate-pulse rounded-full bg-slate-200" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-6 w-full animate-pulse rounded-full bg-slate-200" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-12 w-full animate-pulse rounded-2xl bg-slate-200" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-12 w-full animate-pulse rounded-2xl bg-slate-200" })))));
|
|
8323
8410
|
}
|
|
8324
8411
|
if (!product) {
|
|
8325
|
-
return /* @__PURE__ */
|
|
8412
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl bg-white p-10 text-center shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "mx-auto h-10 w-10 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("h1", { className: "mt-6 text-2xl font-semibold text-gray-900" }, "Product not found"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 text-gray-600" }, "It may have been removed or is temporarily unavailable. Discover other pharmacy essentials in our catalogue."), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: "/shop", className: "inline-block" }, /* @__PURE__ */ React20__default.default.createElement(Button, null, "Browse products"))))));
|
|
8326
8413
|
}
|
|
8327
8414
|
product.tags && product.tags.length > 0 ? product.tags.slice(0, 6) : ["Pharmacist approved", "Gentle on daily routines", "Backed by real customers"];
|
|
8328
8415
|
const highlightCards = [
|
|
@@ -8342,29 +8429,29 @@ function ProductDetailScreen({ productId }) {
|
|
|
8342
8429
|
description: "Average rating 4.8/5 with over 120 verified customer experiences."
|
|
8343
8430
|
}
|
|
8344
8431
|
];
|
|
8345
|
-
return /* @__PURE__ */
|
|
8432
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white mb-8" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8346
8433
|
"div",
|
|
8347
8434
|
{
|
|
8348
8435
|
className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]",
|
|
8349
8436
|
"aria-hidden": "true"
|
|
8350
8437
|
}
|
|
8351
|
-
), /* @__PURE__ */
|
|
8438
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_bottom_right,_rgba(255,255,255,0.25),_transparent_55%)] opacity-70" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8352
8439
|
Button,
|
|
8353
8440
|
{
|
|
8354
8441
|
variant: "ghost",
|
|
8355
8442
|
className: "text-white hover:bg-white/10",
|
|
8356
|
-
onClick: () => router.push("/shop")
|
|
8443
|
+
onClick: () => router.push(buildPath("/shop"))
|
|
8357
8444
|
},
|
|
8358
|
-
/* @__PURE__ */
|
|
8445
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ArrowLeft, { className: "h-5 w-5" }),
|
|
8359
8446
|
"Continue shopping"
|
|
8360
|
-
), /* @__PURE__ */
|
|
8447
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "hidden items-center gap-3 text-sm text-white/80 md:flex" }, /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: buildPath("/"), className: "transition hover:text-white" }, "Home"), /* @__PURE__ */ React20__default.default.createElement(lucideReact.ChevronRight, { className: "h-4 w-4" }), /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: buildPath("/shop"), className: "transition hover:text-white" }, "Shop"), /* @__PURE__ */ React20__default.default.createElement(lucideReact.ChevronRight, { className: "h-4 w-4" }), /* @__PURE__ */ React20__default.default.createElement("span", { className: "truncate font-medium text-white" }, product.name))), /* @__PURE__ */ React20__default.default.createElement(
|
|
8361
8448
|
framerMotion.motion.div,
|
|
8362
8449
|
{
|
|
8363
8450
|
initial: { opacity: 0, y: 24 },
|
|
8364
8451
|
animate: { opacity: 1, y: 0 },
|
|
8365
8452
|
className: "max-w-3xl space-y-4"
|
|
8366
8453
|
},
|
|
8367
|
-
product.category && /* @__PURE__ */
|
|
8454
|
+
product.category && /* @__PURE__ */ React20__default.default.createElement(
|
|
8368
8455
|
Badge,
|
|
8369
8456
|
{
|
|
8370
8457
|
variant: "secondary",
|
|
@@ -8372,9 +8459,9 @@ function ProductDetailScreen({ productId }) {
|
|
|
8372
8459
|
},
|
|
8373
8460
|
product.category
|
|
8374
8461
|
),
|
|
8375
|
-
/* @__PURE__ */
|
|
8376
|
-
/* @__PURE__ */
|
|
8377
|
-
)))), /* @__PURE__ */
|
|
8462
|
+
/* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold leading-tight md:text-5xl" }, product.name),
|
|
8463
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-white/80" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 font-medium text-white" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-4 w-4" }), "Ready to ship today"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 font-medium text-white" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Shield, { className: "h-4 w-4" }), "30-day happiness guarantee"))
|
|
8464
|
+
)))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-16 pb-20" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-10" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "rounded-3xl border border-white bg-white/70 p-6 shadow-xl shadow-primary-100/40 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-6 lg:grid-cols-[minmax(0,1fr)_220px]" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8378
8465
|
framerMotion.motion.div,
|
|
8379
8466
|
{
|
|
8380
8467
|
key: variantImages[activeImageIndex],
|
|
@@ -8383,7 +8470,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8383
8470
|
transition: { duration: 0.35 },
|
|
8384
8471
|
className: "relative overflow-hidden rounded-3xl bg-slate-100 h-[420px] md:h-[560px]"
|
|
8385
8472
|
},
|
|
8386
|
-
/* @__PURE__ */
|
|
8473
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
8387
8474
|
Image3__default.default,
|
|
8388
8475
|
{
|
|
8389
8476
|
src: variantImages[activeImageIndex],
|
|
@@ -8394,7 +8481,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8394
8481
|
className: "object-contain"
|
|
8395
8482
|
}
|
|
8396
8483
|
),
|
|
8397
|
-
discount > 0 && /* @__PURE__ */
|
|
8484
|
+
discount > 0 && /* @__PURE__ */ React20__default.default.createElement(
|
|
8398
8485
|
Badge,
|
|
8399
8486
|
{
|
|
8400
8487
|
variant: "danger",
|
|
@@ -8404,7 +8491,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8404
8491
|
discount,
|
|
8405
8492
|
"%"
|
|
8406
8493
|
),
|
|
8407
|
-
!variantInStock && /* @__PURE__ */
|
|
8494
|
+
!variantInStock && /* @__PURE__ */ React20__default.default.createElement(
|
|
8408
8495
|
Badge,
|
|
8409
8496
|
{
|
|
8410
8497
|
variant: "secondary",
|
|
@@ -8412,7 +8499,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8412
8499
|
},
|
|
8413
8500
|
"Out of Stock"
|
|
8414
8501
|
)
|
|
8415
|
-
), /* @__PURE__ */
|
|
8502
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-4" }, product?.productVariants?.length > 0 && /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "mb-2 text-sm font-semibold uppercase tracking-[0.25em] text-slate-400" }, "Variant"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-2" }, product?.productVariants?.map((variant, index) => /* @__PURE__ */ React20__default.default.createElement(
|
|
8416
8503
|
"button",
|
|
8417
8504
|
{
|
|
8418
8505
|
key: variant.id,
|
|
@@ -8421,7 +8508,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8421
8508
|
className: `rounded-full px-4 py-2 text-sm font-medium transition ${selectedVariant?.id === variant.id ? "bg-primary-600 text-white" : "bg-slate-100 text-slate-700 hover:bg-slate-200"}`
|
|
8422
8509
|
},
|
|
8423
8510
|
variant.name
|
|
8424
|
-
)))), /* @__PURE__ */
|
|
8511
|
+
)))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-3 gap-3" }, variantImages.map((image, index) => /* @__PURE__ */ React20__default.default.createElement(
|
|
8425
8512
|
"button",
|
|
8426
8513
|
{
|
|
8427
8514
|
key: image.src + index,
|
|
@@ -8429,7 +8516,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8429
8516
|
onClick: () => setActiveImageIndex(index),
|
|
8430
8517
|
className: `relative aspect-square overflow-hidden rounded-2xl border transition ${activeImageIndex === index ? "border-primary-500 shadow-lg shadow-primary-200/60" : "border-transparent hover:border-primary-200"}`
|
|
8431
8518
|
},
|
|
8432
|
-
/* @__PURE__ */
|
|
8519
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
8433
8520
|
Image3__default.default,
|
|
8434
8521
|
{
|
|
8435
8522
|
src: image.src,
|
|
@@ -8440,18 +8527,18 @@ function ProductDetailScreen({ productId }) {
|
|
|
8440
8527
|
unoptimized: true
|
|
8441
8528
|
}
|
|
8442
8529
|
)
|
|
8443
|
-
)))))), /* @__PURE__ */
|
|
8530
|
+
)))))), /* @__PURE__ */ React20__default.default.createElement("section", { className: "grid gap-6 lg:grid-cols-3" }, highlightCards.map((card) => {
|
|
8444
8531
|
const Icon = card.icon;
|
|
8445
|
-
return /* @__PURE__ */
|
|
8532
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
8446
8533
|
"div",
|
|
8447
8534
|
{
|
|
8448
8535
|
key: card.title,
|
|
8449
8536
|
className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-sm transition hover:-translate-y-1 hover:shadow-lg"
|
|
8450
8537
|
},
|
|
8451
|
-
/* @__PURE__ */
|
|
8452
|
-
/* @__PURE__ */
|
|
8538
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "rounded-2xl bg-primary-50 p-3 text-primary-600" }, /* @__PURE__ */ React20__default.default.createElement(Icon, { className: "h-5 w-5" })), /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-base font-semibold text-slate-900" }, card.title)),
|
|
8539
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 text-sm leading-relaxed text-slate-600" }, card.description)
|
|
8453
8540
|
);
|
|
8454
|
-
})), /* @__PURE__ */
|
|
8541
|
+
})), /* @__PURE__ */ React20__default.default.createElement("section", { className: "grid gap-6 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-8 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-4 pb-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-1 text-amber-500" }, Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ React20__default.default.createElement(lucideReact.Star, { key: index, className: "h-4 w-4 fill-current" }))), /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm font-medium text-slate-500" }, "Rated 4.8 \u2022 Patients love the results")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-8" }, product.description && /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-slate-900" }, "Description"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-base leading-relaxed text-slate-600", dangerouslySetInnerHTML: { __html: product.description } })))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-full rounded-3xl border border-slate-100 bg-gradient-to-br from-primary-50 via-white to-secondary-50 p-8 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-sm font-semibold uppercase tracking-[0.3em] text-primary-500" }, "Care tips"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-4 space-y-4 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "leading-relaxed" }, "Store in a cool, dry place away from direct sunlight. Check packaging for allergen statements."), /* @__PURE__ */ React20__default.default.createElement("p", { className: "leading-relaxed" }, "Consult with your local pharmacist if you are combining with other treatments or have chronic conditions."), /* @__PURE__ */ React20__default.default.createElement("p", { className: "rounded-2xl bg-white/60 p-4 leading-relaxed text-primary-700" }, "Questions? Our care team is on standby \u2014 reach us via chat for tailored support before you checkout.")))), /* @__PURE__ */ React20__default.default.createElement("section", { className: "rounded-3xl border border-slate-100 bg-white p-8 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-xl font-semibold text-slate-900" }, "Product insights"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 grid gap-6 md:grid-cols-2" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-2xl border border-slate-200 bg-slate-50/60 p-5" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.3em] text-slate-500" }, "Availability"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-3 flex items-center gap-2 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Check, { className: "h-4 w-4 text-primary-500" }), product.inStock ? "Available for dispatch today" : "Currently restocking"), product.stock !== void 0 && /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 text-xs text-slate-500" }, product.stock > 0 ? `${product.stock} units remaining in inventory` : "Join the waitlist to be notified first")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-2xl border border-slate-200 bg-slate-50/60 p-5" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.3em] text-slate-500" }, "Product details"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-3 space-y-2 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("p", null, /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-medium text-slate-700" }, "Variant:"), " ", currentVariant.name), /* @__PURE__ */ React20__default.default.createElement("p", null, /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-medium text-slate-700" }, "SKU:"), " ", variantSku), /* @__PURE__ */ React20__default.default.createElement("p", null, /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-medium text-slate-700" }, "Status:"), " ", /* @__PURE__ */ React20__default.default.createElement("span", { className: variantInStock ? "text-green-600" : "text-amber-600" }, variantInStock ? "In Stock" : "Out of Stock")), /* @__PURE__ */ React20__default.default.createElement("p", null, /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-medium text-slate-700" }, "Last updated:"), " ", lastUpdatedLabel), /* @__PURE__ */ React20__default.default.createElement("p", null, /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-medium text-slate-700" }, "Ships from:"), " Local pharmacy distribution center")))))), /* @__PURE__ */ React20__default.default.createElement("aside", { className: "space-y-6 lg:sticky lg:top-24" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-100/40" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-baseline gap-3" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-3xl font-bold text-slate-900" }, selectedVariant ? formatPrice(selectedVariant.finalPrice) : formatPrice(product.price)), variantComparePrice && variantComparePrice > variantPrice && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-base text-slate-400 line-through" }, formatPrice(variantComparePrice)), discount > 0 && /* @__PURE__ */ React20__default.default.createElement(Badge, { variant: "danger", size: "sm" }, "-", discount, "%")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3 rounded-2xl bg-primary-50/80 px-4 py-3 text-sm font-medium text-primary-700" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "h-4 w-4" }), "Pharmacist verified product"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between rounded-2xl border border-slate-200 px-4 py-3" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm font-medium text-slate-600" }, "Qty"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center rounded-full border border-slate-200 bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8455
8542
|
"button",
|
|
8456
8543
|
{
|
|
8457
8544
|
type: "button",
|
|
@@ -8459,8 +8546,8 @@ function ProductDetailScreen({ productId }) {
|
|
|
8459
8546
|
className: "rounded-l-full p-2 hover:bg-primary-100/60",
|
|
8460
8547
|
"aria-label": "Decrease quantity"
|
|
8461
8548
|
},
|
|
8462
|
-
/* @__PURE__ */
|
|
8463
|
-
), /* @__PURE__ */
|
|
8549
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Minus, { className: "h-4 w-4" })
|
|
8550
|
+
), /* @__PURE__ */ React20__default.default.createElement("span", { className: "w-12 text-center text-sm font-semibold text-slate-700" }, quantity), /* @__PURE__ */ React20__default.default.createElement(
|
|
8464
8551
|
"button",
|
|
8465
8552
|
{
|
|
8466
8553
|
type: "button",
|
|
@@ -8468,8 +8555,8 @@ function ProductDetailScreen({ productId }) {
|
|
|
8468
8555
|
className: "rounded-r-full p-2 hover:bg-primary-100/60",
|
|
8469
8556
|
"aria-label": "Increase quantity"
|
|
8470
8557
|
},
|
|
8471
|
-
/* @__PURE__ */
|
|
8472
|
-
)))), selectedVariant && /* @__PURE__ */
|
|
8558
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Plus, { className: "h-4 w-4" })
|
|
8559
|
+
)))), selectedVariant && /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-4 text-sm" }, selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ || selectedVariant.inventoryStatus === "LOW_STOCK" /* LOWSTOCK */ ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-red-600 font-medium" }, "Out of Stock") : /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-green-600 font-medium" }, "In Stock")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 space-x-3" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8473
8560
|
Button,
|
|
8474
8561
|
{
|
|
8475
8562
|
size: "lg",
|
|
@@ -8478,9 +8565,9 @@ function ProductDetailScreen({ productId }) {
|
|
|
8478
8565
|
isLoading: isAddingToCart,
|
|
8479
8566
|
disabled: !selectedVariant || selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */
|
|
8480
8567
|
},
|
|
8481
|
-
/* @__PURE__ */
|
|
8568
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ShoppingCart, { className: "h-5 w-5" }),
|
|
8482
8569
|
!selectedVariant ? "Select a variant" : selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ ? "Out of Stock" : `Add to Cart`
|
|
8483
|
-
), /* @__PURE__ */
|
|
8570
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
8484
8571
|
Button,
|
|
8485
8572
|
{
|
|
8486
8573
|
size: "lg",
|
|
@@ -8488,18 +8575,18 @@ function ProductDetailScreen({ productId }) {
|
|
|
8488
8575
|
className: "w-full",
|
|
8489
8576
|
onClick: handleToggleFavorite
|
|
8490
8577
|
},
|
|
8491
|
-
/* @__PURE__ */
|
|
8578
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
8492
8579
|
lucideReact.Heart,
|
|
8493
8580
|
{
|
|
8494
8581
|
className: `h-5 w-5 ${isFavorited ? "fill-red-500 text-red-500" : "text-slate-500"}`
|
|
8495
8582
|
}
|
|
8496
8583
|
),
|
|
8497
8584
|
isFavorited ? "Saved" : "Save for later"
|
|
8498
|
-
))), /* @__PURE__ */
|
|
8585
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/70 p-6 text-sm text-primary-700 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold uppercase tracking-[0.25em]" }, "Need advice?"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 leading-relaxed" }, "Chat with a pharmacist in real time before completing your purchase. We will help you choose supporting supplements and answer dosing questions.")))), relatedProducts.length > 0 && /* @__PURE__ */ React20__default.default.createElement("section", { className: "mt-20" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-2xl font-semibold text-slate-900" }, "You may also like"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-1 text-sm text-slate-500" }, "Hand-picked recommendations that pair nicely with this product.")), /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: "/shop", className: "hidden md:inline-flex" }, /* @__PURE__ */ React20__default.default.createElement(Button, { variant: "ghost", className: "text-primary-600" }, "View all products"))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 grid gap-6 sm:grid-cols-2 lg:grid-cols-4" }, relatedProducts?.map((relatedProduct) => /* @__PURE__ */ React20__default.default.createElement(ProductCard, { key: relatedProduct.id, product: relatedProduct })))))));
|
|
8499
8586
|
}
|
|
8500
8587
|
function CartItem({ item }) {
|
|
8501
8588
|
const { updateQuantity, removeFromCart } = useCart();
|
|
8502
|
-
const [isUpdating, setIsUpdating] =
|
|
8589
|
+
const [isUpdating, setIsUpdating] = React20.useState(false);
|
|
8503
8590
|
const handleUpdateQuantity = async (newQuantity) => {
|
|
8504
8591
|
if (newQuantity < 1) return;
|
|
8505
8592
|
setIsUpdating(true);
|
|
@@ -8513,7 +8600,7 @@ function CartItem({ item }) {
|
|
|
8513
8600
|
await removeFromCart(item.productVariantId);
|
|
8514
8601
|
};
|
|
8515
8602
|
const itemTotal = item.productVariantData.finalPrice * item.quantity;
|
|
8516
|
-
return /* @__PURE__ */
|
|
8603
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
8517
8604
|
framerMotion.motion.div,
|
|
8518
8605
|
{
|
|
8519
8606
|
layout: true,
|
|
@@ -8522,7 +8609,7 @@ function CartItem({ item }) {
|
|
|
8522
8609
|
exit: { opacity: 0, x: -100 },
|
|
8523
8610
|
className: "flex gap-4 bg-white p-4 rounded-xl border border-gray-200 hover:border-primary-300 transition-colors"
|
|
8524
8611
|
},
|
|
8525
|
-
/* @__PURE__ */
|
|
8612
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative w-24 h-24 rounded-lg overflow-hidden flex-shrink-0 bg-gray-100" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8526
8613
|
Image3__default.default,
|
|
8527
8614
|
{
|
|
8528
8615
|
src: item.productVariantData.productMedia[0]?.file || "/placeholder-product.jpg",
|
|
@@ -8531,46 +8618,47 @@ function CartItem({ item }) {
|
|
|
8531
8618
|
className: "object-cover"
|
|
8532
8619
|
}
|
|
8533
8620
|
)),
|
|
8534
|
-
/* @__PURE__ */
|
|
8621
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-900 truncate" }, item.productVariantData.name), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-gray-500 mt-1" }, formatPrice(item.productVariantData.finalPrice), " each"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3 mt-3" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center border-2 border-gray-200 rounded-lg" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8535
8622
|
"button",
|
|
8536
8623
|
{
|
|
8537
8624
|
onClick: () => handleUpdateQuantity(item.quantity - 1),
|
|
8538
8625
|
disabled: isUpdating || item.quantity <= 0,
|
|
8539
8626
|
className: "p-2 hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
8540
8627
|
},
|
|
8541
|
-
/* @__PURE__ */
|
|
8542
|
-
), /* @__PURE__ */
|
|
8628
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Minus, { className: "w-4 h-4" })
|
|
8629
|
+
), /* @__PURE__ */ React20__default.default.createElement("span", { className: "px-4 font-medium min-w-[3rem] text-center" }, isUpdating ? /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-block h-4 w-4 align-middle animate-spin rounded-full border-2 border-gray-300 border-t-gray-600" }) : item.quantity), /* @__PURE__ */ React20__default.default.createElement(
|
|
8543
8630
|
"button",
|
|
8544
8631
|
{
|
|
8545
8632
|
onClick: () => handleUpdateQuantity(item.quantity + 1),
|
|
8546
8633
|
disabled: isUpdating || item.quantity >= item.productVariantData.inventoryCount,
|
|
8547
8634
|
className: "p-2 hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
8548
8635
|
},
|
|
8549
|
-
/* @__PURE__ */
|
|
8550
|
-
)), /* @__PURE__ */
|
|
8636
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Plus, { className: "w-4 h-4" })
|
|
8637
|
+
)), /* @__PURE__ */ React20__default.default.createElement(
|
|
8551
8638
|
"button",
|
|
8552
8639
|
{
|
|
8553
8640
|
onClick: handleRemove,
|
|
8554
8641
|
className: "p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors",
|
|
8555
8642
|
"aria-label": "Remove item"
|
|
8556
8643
|
},
|
|
8557
|
-
/* @__PURE__ */
|
|
8644
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Trash2, { className: "w-5 h-5" })
|
|
8558
8645
|
))),
|
|
8559
|
-
/* @__PURE__ */
|
|
8646
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "text-right" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xl font-bold text-gray-900" }, formatPrice(itemTotal)))
|
|
8560
8647
|
);
|
|
8561
8648
|
}
|
|
8562
8649
|
function CartScreen() {
|
|
8563
8650
|
const router = navigation.useRouter();
|
|
8564
8651
|
const { cart, isLoading } = useCart();
|
|
8652
|
+
const { buildPath } = useBasePath();
|
|
8565
8653
|
if (!cart || cart.cartBody.items.length === 0) {
|
|
8566
|
-
return /* @__PURE__ */
|
|
8654
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-gradient-to-br from-primary-700 via-primary-600 to-secondary-600 flex items-center justify-center" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "mx-auto px-20 py-5 bg-white rounded-3xl" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8567
8655
|
EmptyState,
|
|
8568
8656
|
{
|
|
8569
8657
|
icon: lucideReact.ShoppingBag,
|
|
8570
8658
|
title: "Your bag feels a little empty",
|
|
8571
8659
|
description: "Add pharmacy favorites to unlock quick shipping, curated bundles, and personalized recommendations.",
|
|
8572
8660
|
actionLabel: "Discover products",
|
|
8573
|
-
onAction: () => router.push("/shop")
|
|
8661
|
+
onAction: () => router.push(buildPath("/shop"))
|
|
8574
8662
|
}
|
|
8575
8663
|
)));
|
|
8576
8664
|
}
|
|
@@ -8578,16 +8666,16 @@ function CartScreen() {
|
|
|
8578
8666
|
const shipping = 0;
|
|
8579
8667
|
const tax = 0;
|
|
8580
8668
|
const total = subtotal + shipping + tax;
|
|
8581
|
-
return /* @__PURE__ */
|
|
8669
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16 mb-8" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8582
8670
|
framerMotion.motion.div,
|
|
8583
8671
|
{
|
|
8584
8672
|
initial: { opacity: 0, y: 24 },
|
|
8585
8673
|
animate: { opacity: 1, y: 0 },
|
|
8586
8674
|
className: "flex flex-col gap-6 md:flex-row md:items-center md:justify-between"
|
|
8587
8675
|
},
|
|
8588
|
-
/* @__PURE__ */
|
|
8589
|
-
/* @__PURE__ */
|
|
8590
|
-
))), /* @__PURE__ */
|
|
8676
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "max-w-2xl space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold tracking-wide text-white/80 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.HeartPulse, { className: "h-4 w-4" }), "Wellness essentials, ready when you are"), /* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Your curated cart"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-white/75 md:text-lg" }, "Review your selections, unlock exclusive perks, and check out with pharmacist-backed confidence.")),
|
|
8677
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl bg-white/15 p-6 backdrop-blur-md" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.35em] text-white/70" }, "Cart summary"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-4 text-4xl font-semibold" }, formatPrice(total)), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-white/70" }, "Taxes and shipping calculated below"))
|
|
8678
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-16 pb-20" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8591
8679
|
framerMotion.motion.section,
|
|
8592
8680
|
{
|
|
8593
8681
|
initial: { opacity: 0, y: 24 },
|
|
@@ -8595,10 +8683,10 @@ function CartScreen() {
|
|
|
8595
8683
|
transition: { delay: 0.05 },
|
|
8596
8684
|
className: "space-y-6 rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50"
|
|
8597
8685
|
},
|
|
8598
|
-
/* @__PURE__ */
|
|
8599
|
-
isLoading && /* @__PURE__ */
|
|
8600
|
-
/* @__PURE__ */
|
|
8601
|
-
), /* @__PURE__ */
|
|
8686
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center justify-between gap-4" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-xl font-semibold text-slate-900" }, "Items (", cart.cartBody.items.length, ")"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "inline-flex items-center gap-2 rounded-full bg-primary-50 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-primary-700" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "h-4 w-4" }), "Guaranteed cold-chain handling")),
|
|
8687
|
+
isLoading && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-block h-3 w-3 animate-spin rounded-full border-2 border-slate-300 border-t-slate-600" }), "Updating cart\u2026"),
|
|
8688
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-5" }, cart.cartBody.items.map((item) => /* @__PURE__ */ React20__default.default.createElement(CartItem, { key: item.productVariantId, item })))
|
|
8689
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
8602
8690
|
framerMotion.motion.aside,
|
|
8603
8691
|
{
|
|
8604
8692
|
initial: { opacity: 0, y: 24 },
|
|
@@ -8606,42 +8694,42 @@ function CartScreen() {
|
|
|
8606
8694
|
transition: { delay: 0.1 },
|
|
8607
8695
|
className: "space-y-6 lg:sticky lg:top-28"
|
|
8608
8696
|
},
|
|
8609
|
-
/* @__PURE__ */
|
|
8697
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-xl font-semibold text-slate-900" }, "Checkout summary"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-1 rounded-full bg-primary-50 px-3 py-1 text-xs font-semibold text-primary-700" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.BadgePercent, { className: "h-4 w-4" }), "Savings applied")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 space-y-4 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Subtotal"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-semibold text-slate-900" }, formatPrice(subtotal))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Shipping"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-semibold" }, "Will be calculated at checkout")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-2xl bg-slate-50 p-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between text-base font-semibold text-slate-900" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Order total"), /* @__PURE__ */ React20__default.default.createElement("span", null, formatPrice(total))), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 text-xs text-slate-500" }, "Prices include pharmacy-grade quality control and packaging."))), /* @__PURE__ */ React20__default.default.createElement(
|
|
8610
8698
|
Button,
|
|
8611
8699
|
{
|
|
8612
8700
|
size: "lg",
|
|
8613
8701
|
className: "mt-6 w-full",
|
|
8614
|
-
onClick: () => router.push("/checkout")
|
|
8702
|
+
onClick: () => router.push(buildPath("/checkout"))
|
|
8615
8703
|
},
|
|
8616
8704
|
"Secure checkout",
|
|
8617
|
-
/* @__PURE__ */
|
|
8618
|
-
), /* @__PURE__ */
|
|
8705
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ArrowRight, { className: "h-5 w-5" })
|
|
8706
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
8619
8707
|
"button",
|
|
8620
8708
|
{
|
|
8621
8709
|
type: "button",
|
|
8622
|
-
onClick: () => router.push("/shop"),
|
|
8710
|
+
onClick: () => router.push(buildPath("/shop")),
|
|
8623
8711
|
className: "mt-4 w-full text-sm font-semibold text-primary-600 transition hover:text-primary-700"
|
|
8624
8712
|
},
|
|
8625
8713
|
"Continue shopping"
|
|
8626
8714
|
)),
|
|
8627
|
-
/* @__PURE__ */
|
|
8715
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/70 p-6 text-sm text-primary-700 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold uppercase tracking-[0.3em]" }, "Need help?"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 leading-relaxed" }, "Chat with a pharmacist to optimize your regimen or discuss substitutions before you check out."))
|
|
8628
8716
|
)))));
|
|
8629
8717
|
}
|
|
8630
8718
|
function useAddresses() {
|
|
8631
|
-
const [addresses, setAddresses] =
|
|
8632
|
-
const [isLoading, setIsLoading] =
|
|
8633
|
-
const [error, setError] =
|
|
8634
|
-
const refresh =
|
|
8719
|
+
const [addresses, setAddresses] = React20.useState([]);
|
|
8720
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
8721
|
+
const [error, setError] = React20.useState(null);
|
|
8722
|
+
const refresh = React20.useCallback(async () => {
|
|
8635
8723
|
setIsLoading(true);
|
|
8636
8724
|
setError(null);
|
|
8637
8725
|
const response = await new AddressesApi(AXIOS_CONFIG).getMyAddresses();
|
|
8638
8726
|
setAddresses(response.data || []);
|
|
8639
8727
|
setIsLoading(false);
|
|
8640
8728
|
}, []);
|
|
8641
|
-
|
|
8729
|
+
React20.useEffect(() => {
|
|
8642
8730
|
refresh();
|
|
8643
8731
|
}, [refresh]);
|
|
8644
|
-
const sortedAddresses =
|
|
8732
|
+
const sortedAddresses = React20.useMemo(() => {
|
|
8645
8733
|
return [...addresses].sort((a, b) => {
|
|
8646
8734
|
if (a.isDefault === b.isDefault) {
|
|
8647
8735
|
return (b.updatedAt.toISOString() || "").localeCompare(a.updatedAt.toISOString() || "");
|
|
@@ -8649,26 +8737,26 @@ function useAddresses() {
|
|
|
8649
8737
|
return a.isDefault ? -1 : 1;
|
|
8650
8738
|
});
|
|
8651
8739
|
}, [addresses]);
|
|
8652
|
-
const defaultAddress =
|
|
8740
|
+
const defaultAddress = React20.useMemo(
|
|
8653
8741
|
() => sortedAddresses.find((address) => address.isDefault) || null,
|
|
8654
8742
|
[sortedAddresses]
|
|
8655
8743
|
);
|
|
8656
|
-
const addAddress =
|
|
8744
|
+
const addAddress = React20.useCallback(async (payload) => {
|
|
8657
8745
|
const response = await new AddressesApi(AXIOS_CONFIG).createAddressForUser(payload);
|
|
8658
8746
|
setAddresses((prev) => [...prev, response.data]);
|
|
8659
8747
|
return response.data;
|
|
8660
8748
|
}, []);
|
|
8661
|
-
const updateAddress =
|
|
8749
|
+
const updateAddress = React20.useCallback(async (id, payload) => {
|
|
8662
8750
|
const response = await new AddressesApi(AXIOS_CONFIG).updateUserAddress(payload, id);
|
|
8663
8751
|
setAddresses((prev) => prev.map((address) => address.id === id ? response.data : address));
|
|
8664
8752
|
return response.data;
|
|
8665
8753
|
}, []);
|
|
8666
|
-
const removeAddress =
|
|
8754
|
+
const removeAddress = React20.useCallback(async (id) => {
|
|
8667
8755
|
await new AddressesApi(AXIOS_CONFIG).deleteUserAddress(id);
|
|
8668
8756
|
setAddresses((prev) => prev.filter((address) => address.id !== id));
|
|
8669
8757
|
return;
|
|
8670
8758
|
}, []);
|
|
8671
|
-
const markAsDefault =
|
|
8759
|
+
const markAsDefault = React20.useCallback(async (id) => {
|
|
8672
8760
|
const response = await new AddressesApi(AXIOS_CONFIG).updateDefaultAddress(id);
|
|
8673
8761
|
setAddresses((prev) => prev.map((address) => address.id === id ? response.data : address));
|
|
8674
8762
|
return response.data;
|
|
@@ -8686,7 +8774,7 @@ function useAddresses() {
|
|
|
8686
8774
|
};
|
|
8687
8775
|
}
|
|
8688
8776
|
function Card({ className = "", ...props }) {
|
|
8689
|
-
return /* @__PURE__ */
|
|
8777
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
8690
8778
|
"div",
|
|
8691
8779
|
{
|
|
8692
8780
|
className: `rounded-lg border bg-white shadow-sm ${className}`,
|
|
@@ -8695,7 +8783,7 @@ function Card({ className = "", ...props }) {
|
|
|
8695
8783
|
);
|
|
8696
8784
|
}
|
|
8697
8785
|
function Modal({ isOpen, onClose, title, children, size = "md" }) {
|
|
8698
|
-
|
|
8786
|
+
React20.useEffect(() => {
|
|
8699
8787
|
if (isOpen) {
|
|
8700
8788
|
document.body.style.overflow = "hidden";
|
|
8701
8789
|
} else {
|
|
@@ -8711,7 +8799,7 @@ function Modal({ isOpen, onClose, title, children, size = "md" }) {
|
|
|
8711
8799
|
lg: "max-w-2xl",
|
|
8712
8800
|
xl: "max-w-4xl"
|
|
8713
8801
|
};
|
|
8714
|
-
return /* @__PURE__ */
|
|
8802
|
+
return /* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, isOpen && /* @__PURE__ */ React20__default.default.createElement(React20__default.default.Fragment, null, /* @__PURE__ */ React20__default.default.createElement(
|
|
8715
8803
|
framerMotion.motion.div,
|
|
8716
8804
|
{
|
|
8717
8805
|
initial: { opacity: 0 },
|
|
@@ -8720,7 +8808,7 @@ function Modal({ isOpen, onClose, title, children, size = "md" }) {
|
|
|
8720
8808
|
onClick: onClose,
|
|
8721
8809
|
className: "fixed inset-0 bg-black/50 backdrop-blur-sm z-50"
|
|
8722
8810
|
}
|
|
8723
|
-
), /* @__PURE__ */
|
|
8811
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
8724
8812
|
framerMotion.motion.div,
|
|
8725
8813
|
{
|
|
8726
8814
|
initial: { opacity: 0, scale: 0.95, y: 20 },
|
|
@@ -8728,15 +8816,15 @@ function Modal({ isOpen, onClose, title, children, size = "md" }) {
|
|
|
8728
8816
|
exit: { opacity: 0, scale: 0.95, y: 20 },
|
|
8729
8817
|
className: `bg-white rounded-2xl shadow-2xl w-full ${sizes[size]} max-h-[90vh] overflow-hidden flex flex-col`
|
|
8730
8818
|
},
|
|
8731
|
-
title && /* @__PURE__ */
|
|
8819
|
+
title && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between p-6 border-b border-gray-200" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-2xl font-bold text-gray-900" }, title), /* @__PURE__ */ React20__default.default.createElement(
|
|
8732
8820
|
"button",
|
|
8733
8821
|
{
|
|
8734
8822
|
onClick: onClose,
|
|
8735
8823
|
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors"
|
|
8736
8824
|
},
|
|
8737
|
-
/* @__PURE__ */
|
|
8825
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.X, { className: "w-5 h-5" })
|
|
8738
8826
|
)),
|
|
8739
|
-
/* @__PURE__ */
|
|
8827
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-1 overflow-y-auto p-6" }, children)
|
|
8740
8828
|
))));
|
|
8741
8829
|
}
|
|
8742
8830
|
var addressSchema = zod.z.object({
|
|
@@ -8750,7 +8838,7 @@ var addressSchema = zod.z.object({
|
|
|
8750
8838
|
phone: zod.z.string().min(10, "Phone number is required")
|
|
8751
8839
|
});
|
|
8752
8840
|
function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, initialAddress }) {
|
|
8753
|
-
const [isSubmitting, setIsSubmitting] =
|
|
8841
|
+
const [isSubmitting, setIsSubmitting] = React20.useState(false);
|
|
8754
8842
|
const {
|
|
8755
8843
|
register,
|
|
8756
8844
|
handleSubmit,
|
|
@@ -8769,7 +8857,7 @@ function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, i
|
|
|
8769
8857
|
country: initialAddress?.country || "United States"
|
|
8770
8858
|
}
|
|
8771
8859
|
});
|
|
8772
|
-
|
|
8860
|
+
React20.useState(() => {
|
|
8773
8861
|
});
|
|
8774
8862
|
const onSubmit = async (data) => {
|
|
8775
8863
|
setIsSubmitting(true);
|
|
@@ -8907,7 +8995,7 @@ var PAYMENT_METHODS = [
|
|
|
8907
8995
|
{
|
|
8908
8996
|
label: "Card",
|
|
8909
8997
|
value: "Card",
|
|
8910
|
-
icon: /* @__PURE__ */
|
|
8998
|
+
icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.CreditCard, { className: "w-5 h-5" }),
|
|
8911
8999
|
description: "Pay securely with your credit or debit card",
|
|
8912
9000
|
className: "border-blue-500 hover:bg-blue-50",
|
|
8913
9001
|
activeClass: "bg-blue-50 border-blue-500 text-blue-700"
|
|
@@ -8915,7 +9003,7 @@ var PAYMENT_METHODS = [
|
|
|
8915
9003
|
{
|
|
8916
9004
|
label: "Cash",
|
|
8917
9005
|
value: "Cash",
|
|
8918
|
-
icon: /* @__PURE__ */
|
|
9006
|
+
icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.PackageCheck, { className: "w-5 h-5" }),
|
|
8919
9007
|
description: "Pay with cash on delivery or at pickup",
|
|
8920
9008
|
className: "border-amber-500 hover:bg-amber-50",
|
|
8921
9009
|
activeClass: "bg-amber-50 border-amber-500 text-amber-700"
|
|
@@ -8923,7 +9011,7 @@ var PAYMENT_METHODS = [
|
|
|
8923
9011
|
{
|
|
8924
9012
|
label: "Credit",
|
|
8925
9013
|
value: "Credit",
|
|
8926
|
-
icon: /* @__PURE__ */
|
|
9014
|
+
icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "w-5 h-5" }),
|
|
8927
9015
|
description: "Use your account credit",
|
|
8928
9016
|
className: "border-emerald-500 hover:bg-emerald-50",
|
|
8929
9017
|
activeClass: "bg-emerald-50 border-emerald-500 text-emerald-700"
|
|
@@ -8933,25 +9021,26 @@ function CheckoutScreen() {
|
|
|
8933
9021
|
const router = navigation.useRouter();
|
|
8934
9022
|
const { cart, clearCart } = useCart();
|
|
8935
9023
|
const { isAuthenticated, user } = useAuth();
|
|
8936
|
-
const
|
|
8937
|
-
const [
|
|
8938
|
-
const [
|
|
8939
|
-
const [
|
|
8940
|
-
const [
|
|
8941
|
-
const [
|
|
8942
|
-
const [
|
|
8943
|
-
const [
|
|
8944
|
-
const [
|
|
8945
|
-
const [
|
|
9024
|
+
const { buildPath } = useBasePath();
|
|
9025
|
+
const [isSubmitting, setIsSubmitting] = React20.useState(false);
|
|
9026
|
+
const [isDelivery, setIsDelivery] = React20.useState(true);
|
|
9027
|
+
const [paymentMethod, setPaymentMethod] = React20.useState("Card");
|
|
9028
|
+
const [error, setError] = React20.useState(null);
|
|
9029
|
+
const [selectedAddressId, setSelectedAddressId] = React20.useState(null);
|
|
9030
|
+
const [selectedStoreAddressId, setSelectedStoreAddressId] = React20.useState(null);
|
|
9031
|
+
const [storeAddresses, setStoreAddresses] = React20.useState([]);
|
|
9032
|
+
const [isAddressModalOpen, setIsAddressModalOpen] = React20.useState(false);
|
|
9033
|
+
const [editingAddress, setEditingAddress] = React20.useState(null);
|
|
9034
|
+
const [shippingPrice, setShippingPrice] = React20.useState(0);
|
|
8946
9035
|
const {
|
|
8947
9036
|
addresses: userAddresses,
|
|
8948
9037
|
defaultAddress
|
|
8949
9038
|
} = useAddresses();
|
|
8950
|
-
const [selectedShippingRateId, setSelectedShippingRateId] =
|
|
8951
|
-
const [shippingRates, setShippingRates] =
|
|
8952
|
-
const [shippingRatesLoading, setShippingRatesLoading] =
|
|
8953
|
-
const [shippingRatesError, setShippingRatesError] =
|
|
8954
|
-
const [storeData, setStoreData] =
|
|
9039
|
+
const [selectedShippingRateId, setSelectedShippingRateId] = React20.useState(null);
|
|
9040
|
+
const [shippingRates, setShippingRates] = React20.useState([]);
|
|
9041
|
+
const [shippingRatesLoading, setShippingRatesLoading] = React20.useState(false);
|
|
9042
|
+
const [shippingRatesError, setShippingRatesError] = React20.useState(null);
|
|
9043
|
+
const [storeData, setStoreData] = React20.useState(null);
|
|
8955
9044
|
const { addresses, isLoading, refresh, removeAddress } = useAddresses();
|
|
8956
9045
|
const {
|
|
8957
9046
|
register,
|
|
@@ -8976,7 +9065,7 @@ function CheckoutScreen() {
|
|
|
8976
9065
|
}
|
|
8977
9066
|
});
|
|
8978
9067
|
const sameAsShipping = watch("sameAsShipping", true);
|
|
8979
|
-
|
|
9068
|
+
React20.useEffect(() => {
|
|
8980
9069
|
if (sameAsShipping) {
|
|
8981
9070
|
setValue("billing.name", watch("shipping.name"));
|
|
8982
9071
|
setValue("billing.phone", watch("shipping.phone"));
|
|
@@ -8988,7 +9077,7 @@ function CheckoutScreen() {
|
|
|
8988
9077
|
setValue("billing.country", watch("shipping.country"));
|
|
8989
9078
|
}
|
|
8990
9079
|
}, [sameAsShipping, watch("shipping.name"), watch("shipping.phone"), watch("shipping.street1"), watch("shipping.street2"), watch("shipping.city"), watch("shipping.state"), watch("shipping.zip"), watch("shipping.country")]);
|
|
8991
|
-
|
|
9080
|
+
React20.useEffect(() => {
|
|
8992
9081
|
if (defaultAddress && !selectedAddressId) {
|
|
8993
9082
|
setSelectedAddressId(defaultAddress.id);
|
|
8994
9083
|
setValue("shipping.name", defaultAddress.name);
|
|
@@ -9023,7 +9112,7 @@ function CheckoutScreen() {
|
|
|
9023
9112
|
setShippingRates([]);
|
|
9024
9113
|
setSelectedShippingRateId(null);
|
|
9025
9114
|
};
|
|
9026
|
-
|
|
9115
|
+
React20.useEffect(() => {
|
|
9027
9116
|
if (!isDelivery || !selectedAddressId || !cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
|
|
9028
9117
|
setShippingRates([]);
|
|
9029
9118
|
setSelectedShippingRateId(null);
|
|
@@ -9052,7 +9141,7 @@ function CheckoutScreen() {
|
|
|
9052
9141
|
}
|
|
9053
9142
|
})();
|
|
9054
9143
|
}, [isDelivery, selectedAddressId, cart]);
|
|
9055
|
-
|
|
9144
|
+
React20.useEffect(() => {
|
|
9056
9145
|
if (!isDelivery) {
|
|
9057
9146
|
const stores = [
|
|
9058
9147
|
{ id: "store1", name: "Main Pharmacy", street1: "123 Main St", city: "Seattle" },
|
|
@@ -9075,7 +9164,7 @@ function CheckoutScreen() {
|
|
|
9075
9164
|
setError(null);
|
|
9076
9165
|
if (!isAuthenticated) {
|
|
9077
9166
|
sonner.toast.error("Please login to continue");
|
|
9078
|
-
setTimeout(() => router.push("/login?redirect=/checkout"), 50);
|
|
9167
|
+
setTimeout(() => router.push(buildPath("/login?redirect=/checkout")), 50);
|
|
9079
9168
|
return;
|
|
9080
9169
|
}
|
|
9081
9170
|
if (!cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
|
|
@@ -9126,7 +9215,7 @@ function CheckoutScreen() {
|
|
|
9126
9215
|
}
|
|
9127
9216
|
}
|
|
9128
9217
|
setIsSubmitting(true);
|
|
9129
|
-
sonner.toast("Submitting order...", { icon: /* @__PURE__ */
|
|
9218
|
+
sonner.toast("Submitting order...", { icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.CreditCard, { className: "h-4 w-4" }) });
|
|
9130
9219
|
try {
|
|
9131
9220
|
const items = (cart?.cartBody?.items || []).map((item) => ({
|
|
9132
9221
|
productVariantId: String(item.productVariantId),
|
|
@@ -9170,11 +9259,11 @@ function CheckoutScreen() {
|
|
|
9170
9259
|
}
|
|
9171
9260
|
sonner.toast.success("Order placed successfully!");
|
|
9172
9261
|
await clearCart();
|
|
9173
|
-
router.push(`/orders/${response.data?.id}`);
|
|
9262
|
+
router.push(buildPath(`/orders/${response.data?.id}`));
|
|
9174
9263
|
} else {
|
|
9175
9264
|
sonner.toast.success("Order placed successfully!");
|
|
9176
9265
|
await clearCart();
|
|
9177
|
-
router.push(`/orders/${response.data?.id}`);
|
|
9266
|
+
router.push(buildPath(`/orders/${response.data?.id}`));
|
|
9178
9267
|
}
|
|
9179
9268
|
} catch (err) {
|
|
9180
9269
|
const msg = err?.message || err?.response?.data?.message || "Failed to place order";
|
|
@@ -9185,39 +9274,39 @@ function CheckoutScreen() {
|
|
|
9185
9274
|
}
|
|
9186
9275
|
};
|
|
9187
9276
|
if (!cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
|
|
9188
|
-
router.push("/cart");
|
|
9277
|
+
router.push(buildPath("/cart"));
|
|
9189
9278
|
return null;
|
|
9190
9279
|
}
|
|
9191
9280
|
const subtotal = cart.total;
|
|
9192
9281
|
const tax = 0;
|
|
9193
9282
|
const total = subtotal + shippingPrice + tax;
|
|
9194
|
-
return /* @__PURE__ */
|
|
9283
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9195
9284
|
framerMotion.motion.div,
|
|
9196
9285
|
{
|
|
9197
9286
|
initial: { opacity: 0, y: 24 },
|
|
9198
9287
|
animate: { opacity: 1, y: 0 },
|
|
9199
9288
|
className: "space-y-6"
|
|
9200
9289
|
},
|
|
9201
|
-
/* @__PURE__ */
|
|
9202
|
-
/* @__PURE__ */
|
|
9203
|
-
/* @__PURE__ */
|
|
9204
|
-
/* @__PURE__ */
|
|
9290
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "h-4 w-4" }), "Secure checkout"),
|
|
9291
|
+
/* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Provide delivery details"),
|
|
9292
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "text-white/75 md:text-lg" }, "Our pharmacists handle every package with care. Share your shipping and billing information so we can dispatch your order within the next 12 hours."),
|
|
9293
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-3" }, checkoutSteps.map((step) => /* @__PURE__ */ React20__default.default.createElement(
|
|
9205
9294
|
"div",
|
|
9206
9295
|
{
|
|
9207
9296
|
key: step.id,
|
|
9208
9297
|
className: `flex items-center gap-3 rounded-2xl px-4 py-2 text-sm font-semibold ${step.status === "complete" ? "bg-white/20 text-white" : step.status === "current" ? "bg-white text-primary-700" : "bg-white/10 text-white/60"}`
|
|
9209
9298
|
},
|
|
9210
|
-
/* @__PURE__ */
|
|
9299
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "flex h-7 w-7 items-center justify-center rounded-full bg-white/20 text-xs font-bold" }, step.id),
|
|
9211
9300
|
step.label
|
|
9212
9301
|
)))
|
|
9213
|
-
)))), /* @__PURE__ */
|
|
9302
|
+
)))), /* @__PURE__ */ React20__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit) }, error && /* @__PURE__ */ React20__default.default.createElement("div", { className: "mb-4 text-red-600 font-semibold" }, error), /* @__PURE__ */ React20__default.default.createElement("div", { className: "pt-12 container mx-auto grid gap-10 px-4 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9214
9303
|
framerMotion.motion.div,
|
|
9215
9304
|
{
|
|
9216
9305
|
initial: { opacity: 0, y: 24 },
|
|
9217
9306
|
animate: { opacity: 1, y: 0 },
|
|
9218
9307
|
className: "space-y-8"
|
|
9219
9308
|
},
|
|
9220
|
-
/* @__PURE__ */
|
|
9309
|
+
/* @__PURE__ */ React20__default.default.createElement("section", { className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center justify-between gap-4" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-xl font-semibold text-slate-900" }, "Shipping information"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-500" }, "We use temperature-aware packaging and real-time tracking on every shipment.")), /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-primary-50 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-primary-700" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Truck, { className: "h-4 w-4" }), "Dispatch in 12h")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 grid grid-cols-1 gap-4 md:grid-cols-2" }, isDelivery && /* @__PURE__ */ React20__default.default.createElement("div", { className: "md:col-span-2 space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("label", { className: "block font-semibold" }, "Select Address"), /* @__PURE__ */ React20__default.default.createElement(
|
|
9221
9310
|
Button,
|
|
9222
9311
|
{
|
|
9223
9312
|
type: "button",
|
|
@@ -9228,15 +9317,15 @@ function CheckoutScreen() {
|
|
|
9228
9317
|
setIsAddressModalOpen(true);
|
|
9229
9318
|
}
|
|
9230
9319
|
},
|
|
9231
|
-
/* @__PURE__ */
|
|
9320
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
9232
9321
|
"Add New Address"
|
|
9233
|
-
)), userAddresses.length > 0 ? /* @__PURE__ */
|
|
9322
|
+
)), userAddresses.length > 0 ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4" }, userAddresses.map((addr) => /* @__PURE__ */ React20__default.default.createElement(
|
|
9234
9323
|
"label",
|
|
9235
9324
|
{
|
|
9236
9325
|
key: addr.id,
|
|
9237
9326
|
className: `group relative flex items-start gap-3 p-4 rounded-2xl border ${selectedAddressId === addr.id ? "border-primary-500 bg-primary-50 shadow-sm" : "border-slate-200 bg-white"} cursor-pointer hover:border-primary-300 transition-colors`
|
|
9238
9327
|
},
|
|
9239
|
-
/* @__PURE__ */
|
|
9328
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
9240
9329
|
"input",
|
|
9241
9330
|
{
|
|
9242
9331
|
type: "radio",
|
|
@@ -9257,7 +9346,7 @@ function CheckoutScreen() {
|
|
|
9257
9346
|
className: "mt-1"
|
|
9258
9347
|
}
|
|
9259
9348
|
),
|
|
9260
|
-
/* @__PURE__ */
|
|
9349
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold text-slate-900" }, addr.name), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-600" }, addr.street1), addr.street2 && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-600" }, addr.street2), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-600" }, addr.city, ", ", addr.state, " ", addr.zip), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-600" }, addr.country), addr.phone && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-600 mt-1" }, addr.phone), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-3 flex items-center gap-2" }, addr.isDefault && /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-1 rounded-full bg-primary-100 px-2.5 py-0.5 text-xs font-semibold text-primary-700" }, "Default"), /* @__PURE__ */ React20__default.default.createElement(
|
|
9261
9350
|
"button",
|
|
9262
9351
|
{
|
|
9263
9352
|
type: "button",
|
|
@@ -9268,9 +9357,9 @@ function CheckoutScreen() {
|
|
|
9268
9357
|
},
|
|
9269
9358
|
className: "inline-flex items-center gap-1 rounded-full border border-slate-200 px-2.5 py-0.5 text-xs font-medium text-slate-600 hover:border-primary-300 hover:text-primary-600"
|
|
9270
9359
|
},
|
|
9271
|
-
/* @__PURE__ */
|
|
9360
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Edit3, { className: "h-3.5 w-3.5" }),
|
|
9272
9361
|
" Edit"
|
|
9273
|
-
), /* @__PURE__ */
|
|
9362
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9274
9363
|
"button",
|
|
9275
9364
|
{
|
|
9276
9365
|
type: "button",
|
|
@@ -9288,23 +9377,23 @@ function CheckoutScreen() {
|
|
|
9288
9377
|
},
|
|
9289
9378
|
className: "inline-flex items-center gap-1 rounded-full border border-red-200 px-2.5 py-0.5 text-xs font-semibold text-red-600 hover:border-red-300 hover:text-red-700"
|
|
9290
9379
|
},
|
|
9291
|
-
/* @__PURE__ */
|
|
9380
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Trash2, { className: "h-3.5 w-3.5" }),
|
|
9292
9381
|
" Delete"
|
|
9293
9382
|
)))
|
|
9294
|
-
))) : /* @__PURE__ */
|
|
9383
|
+
))) : /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-center py-8 bg-slate-50 rounded-lg" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.MapPin, { className: "h-12 w-12 mx-auto text-slate-400" }), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 text-slate-600" }, "No addresses found"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-500" }, "Add a new address to continue"))), !isDelivery && storeAddresses.length > 0 && /* @__PURE__ */ React20__default.default.createElement("div", { className: "md:col-span-2" }, /* @__PURE__ */ React20__default.default.createElement("label", { className: "block mb-2 font-semibold" }, "Select Pickup Location"), /* @__PURE__ */ React20__default.default.createElement(
|
|
9295
9384
|
"select",
|
|
9296
9385
|
{
|
|
9297
9386
|
className: "w-full border rounded p-2",
|
|
9298
9387
|
value: selectedStoreAddressId || "",
|
|
9299
9388
|
onChange: (e) => setSelectedStoreAddressId(e.target.value)
|
|
9300
9389
|
},
|
|
9301
|
-
storeAddresses.map((addr) => /* @__PURE__ */
|
|
9390
|
+
storeAddresses.map((addr) => /* @__PURE__ */ React20__default.default.createElement("option", { key: addr.id, value: addr.id }, addr.name, " - ", addr.street1, ", ", addr.city))
|
|
9302
9391
|
)))),
|
|
9303
|
-
isDelivery && selectedAddressId && /* @__PURE__ */
|
|
9392
|
+
isDelivery && selectedAddressId && /* @__PURE__ */ React20__default.default.createElement(Card, { className: "p-6 border border-gray-200 rounded-xl shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3 text-xl font-semibold text-gray-900 pb-4 mb-6 border-b" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Truck, { className: "text-accent w-6 h-6" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "Shipping Options")), shippingRatesLoading ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-center py-12" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-accent" }), /* @__PURE__ */ React20__default.default.createElement("span", { className: "ml-3 text-gray-600" }, "Loading shipping options...")) : shippingRatesError ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "w-16 h-16 mx-auto mb-4 bg-red-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React20__default.default.createElement("svg", { className: "w-8 h-8 text-red-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React20__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }))), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-red-500 text-lg font-medium" }, "Error loading shipping options"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-red-400 text-sm mt-1" }, shippingRatesError)) : shippingRates && shippingRates.length > 0 ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4" }, shippingRates.map((rate) => {
|
|
9304
9393
|
const isSelected = !!selectedShippingRateId && selectedShippingRateId === rate.objectId;
|
|
9305
9394
|
const isTest = rate.test;
|
|
9306
9395
|
const hasAttributes = rate.attributes && rate.attributes.length > 0;
|
|
9307
|
-
return /* @__PURE__ */
|
|
9396
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
9308
9397
|
"div",
|
|
9309
9398
|
{
|
|
9310
9399
|
key: rate.objectId,
|
|
@@ -9313,7 +9402,7 @@ function CheckoutScreen() {
|
|
|
9313
9402
|
onMouseLeave: () => setShippingPrice(parseFloat(rate.amountLocal)),
|
|
9314
9403
|
className: `relative p-5 border-2 rounded-xl cursor-pointer transition-all duration-200 hover:shadow-md ${isSelected ? "border-primary-500 bg-primary-50 ring-2 ring-primary-200" : "border-gray-200 hover:border-gray-300"}`
|
|
9315
9404
|
},
|
|
9316
|
-
/* @__PURE__ */
|
|
9405
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start gap-4 flex-1" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-shrink-0" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9317
9406
|
Image3__default.default,
|
|
9318
9407
|
{
|
|
9319
9408
|
src: rate.providerImage75 || "/placeholder-product.jpg",
|
|
@@ -9326,18 +9415,18 @@ function CheckoutScreen() {
|
|
|
9326
9415
|
width: 48,
|
|
9327
9416
|
height: 48
|
|
9328
9417
|
}
|
|
9329
|
-
)), /* @__PURE__ */
|
|
9418
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, rate.provider, " ", rate.servicelevel?.name), isTest && /* @__PURE__ */ React20__default.default.createElement("span", { className: "px-2 py-1 text-xs font-medium bg-orange-100 text-orange-800 rounded-full" }, "TEST")), hasAttributes && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-2 mb-3" }, rate.attributes.map((attr) => /* @__PURE__ */ React20__default.default.createElement(
|
|
9330
9419
|
"span",
|
|
9331
9420
|
{
|
|
9332
9421
|
key: attr,
|
|
9333
9422
|
className: `px-2 py-1 text-xs font-medium rounded-full ${attr === "FASTEST" ? "bg-green-100 text-green-800" : attr === "BESTVALUE" ? "bg-blue-100 text-blue-800" : attr === "CHEAPEST" ? "bg-purple-100 text-purple-800" : "bg-gray-100 text-gray-800"}`
|
|
9334
9423
|
},
|
|
9335
9424
|
attr
|
|
9336
|
-
))), /* @__PURE__ */
|
|
9337
|
-
isSelected && /* @__PURE__ */
|
|
9425
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-1 text-sm text-gray-600" }, rate.durationTerms && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React20__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" })), /* @__PURE__ */ React20__default.default.createElement("span", null, rate.durationTerms)), rate.estimatedDays && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React20__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" })), /* @__PURE__ */ React20__default.default.createElement("span", null, "Estimated ", rate.estimatedDays, " day", rate.estimatedDays !== 1 ? "s" : "")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React20__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" })), /* @__PURE__ */ React20__default.default.createElement("span", null, "Carrier: ", rate.provider)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React20__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1" })), /* @__PURE__ */ React20__default.default.createElement("span", null, "Currency: ", rate.currency))))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col items-end" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-2xl font-bold text-gray-900" }, formatPrice(parseFloat(rate.amount))), rate.amount !== rate.amountLocal && /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-sm text-gray-500" }, rate.amountLocal, " ", rate.currencyLocal))),
|
|
9426
|
+
isSelected && /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute top-3 right-3" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "w-6 h-6 bg-primary-500 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Check, { className: "w-4 h-4 text-white" })))
|
|
9338
9427
|
);
|
|
9339
|
-
})) : /* @__PURE__ */
|
|
9340
|
-
), /* @__PURE__ */
|
|
9428
|
+
})) : /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Truck, { className: "w-8 h-8 text-gray-400" })), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-gray-500 text-lg font-medium" }, "No shipping options available"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-gray-400 text-sm mt-1" }, "Please check the shipping address or try a different location.")))
|
|
9429
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9341
9430
|
framerMotion.motion.aside,
|
|
9342
9431
|
{
|
|
9343
9432
|
initial: { opacity: 0, y: 32 },
|
|
@@ -9345,22 +9434,22 @@ function CheckoutScreen() {
|
|
|
9345
9434
|
transition: { duration: 0.5, ease: "easeOut", delay: 0.1 },
|
|
9346
9435
|
className: "space-y-10 lg:sticky lg:top-24"
|
|
9347
9436
|
},
|
|
9348
|
-
/* @__PURE__ */
|
|
9437
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-xl shadow-primary-50/50 transition hover:shadow-primary-100/60" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-2xl font-semibold text-slate-900" }, "Order Summary"), /* @__PURE__ */ React20__default.default.createElement("section", { className: "mt-6 space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-xs font-semibold text-slate-700 uppercase tracking-wider" }, "Delivery Method"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-1 gap-3" }, [
|
|
9349
9438
|
{
|
|
9350
9439
|
label: "Delivery",
|
|
9351
|
-
icon: /* @__PURE__ */
|
|
9440
|
+
icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.Truck, { className: "w-5 h-5" }),
|
|
9352
9441
|
value: true,
|
|
9353
9442
|
desc: "Shipped to your address"
|
|
9354
9443
|
},
|
|
9355
9444
|
{
|
|
9356
9445
|
label: "Pickup",
|
|
9357
|
-
icon: /* @__PURE__ */
|
|
9446
|
+
icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.MapPin, { className: "w-5 h-5" }),
|
|
9358
9447
|
value: false,
|
|
9359
9448
|
desc: "Collect from pharmacy"
|
|
9360
9449
|
}
|
|
9361
9450
|
].map((option) => {
|
|
9362
9451
|
const active = isDelivery === option.value;
|
|
9363
|
-
return /* @__PURE__ */
|
|
9452
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
9364
9453
|
"button",
|
|
9365
9454
|
{
|
|
9366
9455
|
key: option.label,
|
|
@@ -9369,18 +9458,18 @@ function CheckoutScreen() {
|
|
|
9369
9458
|
"aria-pressed": active,
|
|
9370
9459
|
className: `relative flex w-full items-center justify-between rounded-xl border-2 p-3 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 focus-visible:ring-offset-2 ${active ? "border-primary-500 bg-primary-50 shadow-sm" : "border-slate-200 bg-white hover:border-primary-200 hover:bg-primary-50/40"}`
|
|
9371
9460
|
},
|
|
9372
|
-
/* @__PURE__ */
|
|
9461
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9373
9462
|
"div",
|
|
9374
9463
|
{
|
|
9375
9464
|
className: `p-2 rounded-lg ${active ? "bg-primary-100 text-primary-600" : "bg-slate-100 text-slate-600 group-hover:bg-slate-50"}`
|
|
9376
9465
|
},
|
|
9377
9466
|
option.icon
|
|
9378
|
-
), /* @__PURE__ */
|
|
9379
|
-
active && /* @__PURE__ */
|
|
9467
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-left" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "font-medium text-slate-900" }, option.label), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs text-slate-500" }, option.desc))),
|
|
9468
|
+
active && /* @__PURE__ */ React20__default.default.createElement("div", { className: "w-5 h-5 rounded-full bg-primary-500 flex items-center justify-center text-white shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Check, { className: "w-3 h-3" }))
|
|
9380
9469
|
);
|
|
9381
|
-
}))), /* @__PURE__ */
|
|
9470
|
+
}))), /* @__PURE__ */ React20__default.default.createElement("section", { className: "mt-8 space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-xs font-semibold text-slate-700 uppercase tracking-wider" }, "Payment Method"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, PAYMENT_METHODS.map((pm) => {
|
|
9382
9471
|
const active = paymentMethod === pm.value;
|
|
9383
|
-
return /* @__PURE__ */
|
|
9472
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
9384
9473
|
"button",
|
|
9385
9474
|
{
|
|
9386
9475
|
key: pm.value,
|
|
@@ -9388,22 +9477,22 @@ function CheckoutScreen() {
|
|
|
9388
9477
|
onClick: () => setPaymentMethod(pm.value),
|
|
9389
9478
|
className: `w-full flex items-center justify-between rounded-xl border-2 p-3 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 ${active ? `${pm.activeClass} border-current shadow-sm` : `${pm.className} border-slate-200 hover:border-primary-200 hover:shadow-sm`}`
|
|
9390
9479
|
},
|
|
9391
|
-
/* @__PURE__ */
|
|
9480
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9392
9481
|
"div",
|
|
9393
9482
|
{
|
|
9394
9483
|
className: `p-1.5 rounded-md ${pm.value === "Card" ? "bg-blue-100 text-blue-600" : pm.value === "Cash" ? "bg-amber-100 text-amber-600" : "bg-emerald-100 text-emerald-600"} ${active ? "bg-opacity-30" : "bg-opacity-100"}`
|
|
9395
9484
|
},
|
|
9396
9485
|
pm.icon
|
|
9397
|
-
), /* @__PURE__ */
|
|
9398
|
-
active && /* @__PURE__ */
|
|
9486
|
+
), /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm font-medium text-slate-900" }, pm.label)),
|
|
9487
|
+
active && /* @__PURE__ */ React20__default.default.createElement("div", { className: "w-4 h-4 rounded-full bg-primary-500 flex items-center justify-center text-white shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Check, { className: "w-2.5 h-2.5" }))
|
|
9399
9488
|
);
|
|
9400
|
-
})), /* @__PURE__ */
|
|
9489
|
+
})), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs text-slate-500 mt-2 pl-1 leading-relaxed" }, paymentMethod === "Card" && "You will be redirected to a secure payment page.", paymentMethod === "Cash" && "Pay with cash at the time of delivery or pickup.", paymentMethod === "Credit" && "Use your available account credit for this order.")), /* @__PURE__ */ React20__default.default.createElement("section", { className: "mt-8 pt-6 border-t border-slate-100" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "max-h-60 space-y-4 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-slate-200 hover:scrollbar-thumb-slate-300" }, cart?.cartBody?.items?.map((item) => /* @__PURE__ */ React20__default.default.createElement(
|
|
9401
9490
|
"div",
|
|
9402
9491
|
{
|
|
9403
9492
|
key: item.productId,
|
|
9404
9493
|
className: "flex gap-4 rounded-2xl border border-slate-100 p-4 hover:bg-slate-50/50 transition"
|
|
9405
9494
|
},
|
|
9406
|
-
/* @__PURE__ */
|
|
9495
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex h-16 w-16 items-center justify-center rounded-xl bg-slate-100 text-slate-400" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9407
9496
|
Image3__default.default,
|
|
9408
9497
|
{
|
|
9409
9498
|
src: item.productVariantData.productMedia?.[0]?.file || "/placeholder-product.jpg",
|
|
@@ -9413,9 +9502,9 @@ function CheckoutScreen() {
|
|
|
9413
9502
|
className: "object-contain"
|
|
9414
9503
|
}
|
|
9415
9504
|
)),
|
|
9416
|
-
/* @__PURE__ */
|
|
9417
|
-
/* @__PURE__ */
|
|
9418
|
-
))), /* @__PURE__ */
|
|
9505
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold text-slate-900" }, item?.productVariantData?.name), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs text-slate-500" }, "Qty ", item.quantity)),
|
|
9506
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold text-slate-900" }, formatPrice(item.productVariantData.finalPrice * item.quantity))
|
|
9507
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 space-y-3 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Subtotal"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-semibold text-slate-900" }, formatPrice(subtotal))), isDelivery && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Shipping"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-semibold" }, formatPrice(shippingPrice))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Estimated tax"), /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-semibold" }, formatPrice(tax))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-2xl bg-slate-50 p-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between text-base font-semibold text-slate-900" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Total Due"), /* @__PURE__ */ React20__default.default.createElement("span", null, formatPrice(total))), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-1 text-xs text-slate-500" }, "Tax is estimated. Final amount confirmed after payment.")))), /* @__PURE__ */ React20__default.default.createElement(
|
|
9419
9508
|
Button,
|
|
9420
9509
|
{
|
|
9421
9510
|
type: "submit",
|
|
@@ -9423,11 +9512,11 @@ function CheckoutScreen() {
|
|
|
9423
9512
|
isLoading: isSubmitting,
|
|
9424
9513
|
className: "mt-6 w-full transition-transform hover:scale-[1.02] active:scale-[0.99]"
|
|
9425
9514
|
},
|
|
9426
|
-
/* @__PURE__ */
|
|
9515
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.CreditCard, { className: "h-5 w-5" }),
|
|
9427
9516
|
isSubmitting ? "Placing order..." : "Place Secure Order"
|
|
9428
|
-
), /* @__PURE__ */
|
|
9429
|
-
/* @__PURE__ */
|
|
9430
|
-
))), /* @__PURE__ */
|
|
9517
|
+
), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-4 flex items-center justify-center gap-2 text-xs text-slate-500" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Lock, { className: "h-4 w-4" }), "Fully encrypted checkout \u2014 cancel anytime before shipment.")),
|
|
9518
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/80 p-6 text-sm text-primary-700 shadow-sm hover:shadow-md transition-shadow" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold uppercase tracking-[0.3em] text-primary-800" }, "Why Patients Choose Us"), /* @__PURE__ */ React20__default.default.createElement("ul", { className: "mt-4 space-y-3 text-primary-700 leading-relaxed" }, /* @__PURE__ */ React20__default.default.createElement("li", { className: "flex items-start gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.PackageCheck, { className: "mt-0.5 h-4 w-4 shrink-0" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "Pharmacy-grade verification on every order.")), /* @__PURE__ */ React20__default.default.createElement("li", { className: "flex items-start gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "mt-0.5 h-4 w-4 shrink-0" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "Cold-chain logistics for sensitive medications.")), /* @__PURE__ */ React20__default.default.createElement("li", { className: "flex items-start gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Truck, { className: "mt-0.5 h-4 w-4 shrink-0" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "Real-time tracking and SMS updates from prep to delivery."))))
|
|
9519
|
+
))), /* @__PURE__ */ React20__default.default.createElement(
|
|
9431
9520
|
AddressFormModal,
|
|
9432
9521
|
{
|
|
9433
9522
|
isOpen: isAddressModalOpen,
|
|
@@ -9458,11 +9547,12 @@ var loginSchema = zod.z.object({
|
|
|
9458
9547
|
});
|
|
9459
9548
|
function LoginScreen() {
|
|
9460
9549
|
const router = navigation.useRouter();
|
|
9550
|
+
const { buildPath } = useBasePath();
|
|
9461
9551
|
const searchParams = navigation.useSearchParams();
|
|
9462
|
-
const redirectUrl = searchParams?.get("redirect") || "/";
|
|
9552
|
+
const redirectUrl = searchParams?.get("redirect") || buildPath("/");
|
|
9463
9553
|
const { login } = useAuth();
|
|
9464
|
-
const [showPassword, setShowPassword] =
|
|
9465
|
-
const [isSubmitting, setIsSubmitting] =
|
|
9554
|
+
const [showPassword, setShowPassword] = React20.useState(false);
|
|
9555
|
+
const [isSubmitting, setIsSubmitting] = React20.useState(false);
|
|
9466
9556
|
const {
|
|
9467
9557
|
register,
|
|
9468
9558
|
handleSubmit,
|
|
@@ -9482,7 +9572,7 @@ function LoginScreen() {
|
|
|
9482
9572
|
setIsSubmitting(false);
|
|
9483
9573
|
}
|
|
9484
9574
|
};
|
|
9485
|
-
return /* @__PURE__ */
|
|
9575
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid min-h-screen overflow-hidden bg-white lg:grid-cols-[1.1fr_0.9fr]" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9486
9576
|
framerMotion.motion.section,
|
|
9487
9577
|
{
|
|
9488
9578
|
initial: { opacity: 0, x: -24 },
|
|
@@ -9490,18 +9580,18 @@ function LoginScreen() {
|
|
|
9490
9580
|
transition: { duration: 0.4 },
|
|
9491
9581
|
className: "relative flex flex-col justify-between bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] px-10 py-14 text-white"
|
|
9492
9582
|
},
|
|
9493
|
-
/* @__PURE__ */
|
|
9494
|
-
/* @__PURE__ */
|
|
9495
|
-
/* @__PURE__ */
|
|
9583
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.HeartPulse, { className: "h-4 w-4" }), "Hey Pharmacist"), /* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold leading-tight lg:text-5xl" }, "Pharmacy-grade care for your household"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-xl text-white/80" }, "Log in to unlock personalized regimens, pharmacist support, and fast delivery on wellness essentials curated just for you.")),
|
|
9584
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 rounded-3xl bg-white/10 p-6 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "h-5 w-5 text-white" }), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-white/80" }, "HIPAA-compliant security keeps your health information protected.")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-5 w-5 text-white" }), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-white/80" }, "Pharmacists ready to chat in under 10 minutes for medication support."))),
|
|
9585
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-6 text-sm text-white/80" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Need an account?"), /* @__PURE__ */ React20__default.default.createElement(
|
|
9496
9586
|
Link8__default.default,
|
|
9497
9587
|
{
|
|
9498
9588
|
href: "/register",
|
|
9499
9589
|
className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-4 py-2 font-semibold transition hover:bg-white/25"
|
|
9500
9590
|
},
|
|
9501
9591
|
"Create one now",
|
|
9502
|
-
/* @__PURE__ */
|
|
9592
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ArrowRight, { className: "h-4 w-4" })
|
|
9503
9593
|
))
|
|
9504
|
-
), /* @__PURE__ */
|
|
9594
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9505
9595
|
framerMotion.motion.section,
|
|
9506
9596
|
{
|
|
9507
9597
|
initial: { opacity: 0, x: 24 },
|
|
@@ -9509,7 +9599,7 @@ function LoginScreen() {
|
|
|
9509
9599
|
transition: { duration: 0.4 },
|
|
9510
9600
|
className: "flex items-center justify-center px-6 py-12 lg:px-16"
|
|
9511
9601
|
},
|
|
9512
|
-
/* @__PURE__ */
|
|
9602
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "w-full max-w-md space-y-10" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-3xl font-bold text-slate-900" }, "Sign in"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-500" }, "Welcome back! Enter your details to continue your personalized care plan.")), /* @__PURE__ */ React20__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-6 rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement(
|
|
9513
9603
|
Input,
|
|
9514
9604
|
{
|
|
9515
9605
|
type: "email",
|
|
@@ -9518,7 +9608,7 @@ function LoginScreen() {
|
|
|
9518
9608
|
...register("email"),
|
|
9519
9609
|
error: errors.email?.message
|
|
9520
9610
|
}
|
|
9521
|
-
)), /* @__PURE__ */
|
|
9611
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9522
9612
|
Input,
|
|
9523
9613
|
{
|
|
9524
9614
|
type: showPassword ? "text" : "password",
|
|
@@ -9527,28 +9617,28 @@ function LoginScreen() {
|
|
|
9527
9617
|
...register("password"),
|
|
9528
9618
|
error: errors.password?.message
|
|
9529
9619
|
}
|
|
9530
|
-
), /* @__PURE__ */
|
|
9620
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9531
9621
|
"button",
|
|
9532
9622
|
{
|
|
9533
9623
|
type: "button",
|
|
9534
9624
|
onClick: () => setShowPassword((prev) => !prev),
|
|
9535
9625
|
className: "absolute right-3 top-[42px] text-slate-400 transition hover:text-slate-600"
|
|
9536
9626
|
},
|
|
9537
|
-
showPassword ? /* @__PURE__ */
|
|
9538
|
-
)), /* @__PURE__ */
|
|
9627
|
+
showPassword ? /* @__PURE__ */ React20__default.default.createElement(lucideReact.EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ React20__default.default.createElement(lucideReact.Eye, { className: "h-5 w-5" })
|
|
9628
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between text-sm" }, /* @__PURE__ */ React20__default.default.createElement("label", { className: "flex items-center gap-2 text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9539
9629
|
"input",
|
|
9540
9630
|
{
|
|
9541
9631
|
type: "checkbox",
|
|
9542
9632
|
className: "h-4 w-4 rounded border-slate-300 text-primary-600 focus:ring-primary-500"
|
|
9543
9633
|
}
|
|
9544
|
-
), "Remember me"), /* @__PURE__ */
|
|
9634
|
+
), "Remember me"), /* @__PURE__ */ React20__default.default.createElement(
|
|
9545
9635
|
Link8__default.default,
|
|
9546
9636
|
{
|
|
9547
9637
|
href: "/forgot-password",
|
|
9548
9638
|
className: "font-medium text-primary-600 transition hover:text-primary-700"
|
|
9549
9639
|
},
|
|
9550
9640
|
"Forgot password?"
|
|
9551
|
-
)), /* @__PURE__ */
|
|
9641
|
+
)), /* @__PURE__ */ React20__default.default.createElement(
|
|
9552
9642
|
Button,
|
|
9553
9643
|
{
|
|
9554
9644
|
type: "submit",
|
|
@@ -9557,7 +9647,7 @@ function LoginScreen() {
|
|
|
9557
9647
|
className: "w-full"
|
|
9558
9648
|
},
|
|
9559
9649
|
"Sign in securely"
|
|
9560
|
-
)), /* @__PURE__ */
|
|
9650
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-slate-50 p-6 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Lock, { className: "mt-0.5 h-5 w-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold text-slate-800" }, "Secure by design"), /* @__PURE__ */ React20__default.default.createElement("p", null, "Encrypted sessions, multi-factor ready, and privacy-first policies keep your personal data safe.")))))
|
|
9561
9651
|
)));
|
|
9562
9652
|
}
|
|
9563
9653
|
var registerSchema = zod.z.object({
|
|
@@ -9579,9 +9669,10 @@ var BENEFITS = [
|
|
|
9579
9669
|
function RegisterScreen() {
|
|
9580
9670
|
const router = navigation.useRouter();
|
|
9581
9671
|
const { register: registerUser } = useAuth();
|
|
9582
|
-
const
|
|
9583
|
-
const [
|
|
9584
|
-
const [
|
|
9672
|
+
const { buildPath } = useBasePath();
|
|
9673
|
+
const [showPassword, setShowPassword] = React20.useState(false);
|
|
9674
|
+
const [showConfirmPassword, setShowConfirmPassword] = React20.useState(false);
|
|
9675
|
+
const [isSubmitting, setIsSubmitting] = React20.useState(false);
|
|
9585
9676
|
const {
|
|
9586
9677
|
register,
|
|
9587
9678
|
handleSubmit,
|
|
@@ -9600,14 +9691,14 @@ function RegisterScreen() {
|
|
|
9600
9691
|
role: "User" /* User */
|
|
9601
9692
|
});
|
|
9602
9693
|
sonner.toast.success("Account created successfully!");
|
|
9603
|
-
router.push("/");
|
|
9694
|
+
router.push(buildPath("/"));
|
|
9604
9695
|
} catch (error) {
|
|
9605
9696
|
sonner.toast.error(error.response?.data?.message || "Failed to create account");
|
|
9606
9697
|
} finally {
|
|
9607
9698
|
setIsSubmitting(false);
|
|
9608
9699
|
}
|
|
9609
9700
|
};
|
|
9610
|
-
return /* @__PURE__ */
|
|
9701
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid min-h-screen overflow-hidden bg-white lg:grid-cols-[0.95fr_1.05fr]" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9611
9702
|
framerMotion.motion.section,
|
|
9612
9703
|
{
|
|
9613
9704
|
initial: { opacity: 0, x: -24 },
|
|
@@ -9615,9 +9706,9 @@ function RegisterScreen() {
|
|
|
9615
9706
|
transition: { duration: 0.4 },
|
|
9616
9707
|
className: "flex flex-col justify-between bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] px-10 py-14 text-white"
|
|
9617
9708
|
},
|
|
9618
|
-
/* @__PURE__ */
|
|
9619
|
-
/* @__PURE__ */
|
|
9620
|
-
/* @__PURE__ */
|
|
9709
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.HeartPulse, { className: "h-4 w-4" }), "Join Hey Pharmacist"), /* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold leading-tight lg:text-5xl" }, "Create your wellness account"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-xl text-white/80" }, "Unlock concierge-level pharmacy support, curated product recommendations, and smarter refills designed for busy families.")),
|
|
9710
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4 rounded-3xl bg-white/10 p-6 backdrop-blur" }, BENEFITS.map((benefit) => /* @__PURE__ */ React20__default.default.createElement("div", { key: benefit, className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.CheckCircle2, { className: "h-5 w-5 text-white" }), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-white/85" }, benefit)))),
|
|
9711
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-6 text-sm text-white/80" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Already part of the community?"), /* @__PURE__ */ React20__default.default.createElement(
|
|
9621
9712
|
Link8__default.default,
|
|
9622
9713
|
{
|
|
9623
9714
|
href: "/login",
|
|
@@ -9625,7 +9716,7 @@ function RegisterScreen() {
|
|
|
9625
9716
|
},
|
|
9626
9717
|
"Sign in"
|
|
9627
9718
|
))
|
|
9628
|
-
), /* @__PURE__ */
|
|
9719
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9629
9720
|
framerMotion.motion.section,
|
|
9630
9721
|
{
|
|
9631
9722
|
initial: { opacity: 0, x: 24 },
|
|
@@ -9633,13 +9724,13 @@ function RegisterScreen() {
|
|
|
9633
9724
|
transition: { duration: 0.4 },
|
|
9634
9725
|
className: "flex items-center justify-center px-6 py-12 lg:px-16"
|
|
9635
9726
|
},
|
|
9636
|
-
/* @__PURE__ */
|
|
9727
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "w-full max-w-lg space-y-10" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-3xl font-bold text-slate-900" }, "Create an account"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-500" }, "Start your personalized care journey with pharmacist-backed guidance.")), /* @__PURE__ */ React20__default.default.createElement(
|
|
9637
9728
|
"form",
|
|
9638
9729
|
{
|
|
9639
9730
|
onSubmit: handleSubmit(onSubmit),
|
|
9640
9731
|
className: "space-y-6 rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50"
|
|
9641
9732
|
},
|
|
9642
|
-
/* @__PURE__ */
|
|
9733
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9643
9734
|
Input,
|
|
9644
9735
|
{
|
|
9645
9736
|
label: "First name",
|
|
@@ -9647,7 +9738,7 @@ function RegisterScreen() {
|
|
|
9647
9738
|
...register("firstName"),
|
|
9648
9739
|
error: errors.firstName?.message
|
|
9649
9740
|
}
|
|
9650
|
-
), /* @__PURE__ */
|
|
9741
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9651
9742
|
Input,
|
|
9652
9743
|
{
|
|
9653
9744
|
label: "Last name",
|
|
@@ -9656,7 +9747,7 @@ function RegisterScreen() {
|
|
|
9656
9747
|
error: errors.lastName?.message
|
|
9657
9748
|
}
|
|
9658
9749
|
)),
|
|
9659
|
-
/* @__PURE__ */
|
|
9750
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
9660
9751
|
Input,
|
|
9661
9752
|
{
|
|
9662
9753
|
type: "email",
|
|
@@ -9666,7 +9757,7 @@ function RegisterScreen() {
|
|
|
9666
9757
|
error: errors.email?.message
|
|
9667
9758
|
}
|
|
9668
9759
|
),
|
|
9669
|
-
/* @__PURE__ */
|
|
9760
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
9670
9761
|
Input,
|
|
9671
9762
|
{
|
|
9672
9763
|
type: "tel",
|
|
@@ -9676,7 +9767,7 @@ function RegisterScreen() {
|
|
|
9676
9767
|
error: errors.phone?.message
|
|
9677
9768
|
}
|
|
9678
9769
|
),
|
|
9679
|
-
/* @__PURE__ */
|
|
9770
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9680
9771
|
Input,
|
|
9681
9772
|
{
|
|
9682
9773
|
type: showPassword ? "text" : "password",
|
|
@@ -9685,16 +9776,16 @@ function RegisterScreen() {
|
|
|
9685
9776
|
...register("password"),
|
|
9686
9777
|
error: errors.password?.message
|
|
9687
9778
|
}
|
|
9688
|
-
), /* @__PURE__ */
|
|
9779
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9689
9780
|
"button",
|
|
9690
9781
|
{
|
|
9691
9782
|
type: "button",
|
|
9692
9783
|
onClick: () => setShowPassword((prev) => !prev),
|
|
9693
9784
|
className: "absolute right-3 top-[42px] text-slate-400 transition hover:text-slate-600"
|
|
9694
9785
|
},
|
|
9695
|
-
showPassword ? /* @__PURE__ */
|
|
9786
|
+
showPassword ? /* @__PURE__ */ React20__default.default.createElement(lucideReact.EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ React20__default.default.createElement(lucideReact.Eye, { className: "h-5 w-5" })
|
|
9696
9787
|
)),
|
|
9697
|
-
/* @__PURE__ */
|
|
9788
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9698
9789
|
Input,
|
|
9699
9790
|
{
|
|
9700
9791
|
type: showConfirmPassword ? "text" : "password",
|
|
@@ -9703,16 +9794,16 @@ function RegisterScreen() {
|
|
|
9703
9794
|
...register("confirmPassword"),
|
|
9704
9795
|
error: errors.confirmPassword?.message
|
|
9705
9796
|
}
|
|
9706
|
-
), /* @__PURE__ */
|
|
9797
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9707
9798
|
"button",
|
|
9708
9799
|
{
|
|
9709
9800
|
type: "button",
|
|
9710
9801
|
onClick: () => setShowConfirmPassword((prev) => !prev),
|
|
9711
9802
|
className: "absolute right-3 top-[42px] text-slate-400 transition hover:text-slate-600"
|
|
9712
9803
|
},
|
|
9713
|
-
showConfirmPassword ? /* @__PURE__ */
|
|
9804
|
+
showConfirmPassword ? /* @__PURE__ */ React20__default.default.createElement(lucideReact.EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ React20__default.default.createElement(lucideReact.Eye, { className: "h-5 w-5" })
|
|
9714
9805
|
)),
|
|
9715
|
-
/* @__PURE__ */
|
|
9806
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start gap-3 rounded-2xl bg-slate-50 p-4 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Shield, { className: "mt-0.5 h-5 w-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "By creating an account, you agree to our", " ", /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: "/terms", className: "font-semibold text-primary-600 hover:text-primary-700" }, "Terms of Service"), " ", "and", " ", /* @__PURE__ */ React20__default.default.createElement(
|
|
9716
9807
|
Link8__default.default,
|
|
9717
9808
|
{
|
|
9718
9809
|
href: "/privacy",
|
|
@@ -9720,7 +9811,7 @@ function RegisterScreen() {
|
|
|
9720
9811
|
},
|
|
9721
9812
|
"Privacy Policy"
|
|
9722
9813
|
), ". We protect your information with bank-level encryption.")),
|
|
9723
|
-
/* @__PURE__ */
|
|
9814
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
9724
9815
|
Button,
|
|
9725
9816
|
{
|
|
9726
9817
|
type: "submit",
|
|
@@ -9728,10 +9819,10 @@ function RegisterScreen() {
|
|
|
9728
9819
|
isLoading: isSubmitting,
|
|
9729
9820
|
className: "w-full"
|
|
9730
9821
|
},
|
|
9731
|
-
/* @__PURE__ */
|
|
9822
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.UserPlus, { className: "h-5 w-5" }),
|
|
9732
9823
|
"Create my account"
|
|
9733
9824
|
)
|
|
9734
|
-
), /* @__PURE__ */
|
|
9825
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-slate-50 p-6 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Heart, { className: "mt-0.5 h-5 w-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold text-slate-800" }, "Members love us"), /* @__PURE__ */ React20__default.default.createElement("p", null, "92% of patients report improved adherence after receiving pharmacist touchpoints through their Hey Pharmacist account.")))))
|
|
9735
9826
|
)));
|
|
9736
9827
|
}
|
|
9737
9828
|
var profileSchema = zod.z.object({
|
|
@@ -9743,7 +9834,8 @@ var profileSchema = zod.z.object({
|
|
|
9743
9834
|
function ProfileScreen() {
|
|
9744
9835
|
const router = navigation.useRouter();
|
|
9745
9836
|
const { user, updateUser, logout } = useAuth();
|
|
9746
|
-
const
|
|
9837
|
+
const { buildPath } = useBasePath();
|
|
9838
|
+
const [isSubmitting, setIsSubmitting] = React20.useState(false);
|
|
9747
9839
|
const {
|
|
9748
9840
|
register,
|
|
9749
9841
|
handleSubmit,
|
|
@@ -9771,10 +9863,10 @@ function ProfileScreen() {
|
|
|
9771
9863
|
const handleLogout = async () => {
|
|
9772
9864
|
await logout();
|
|
9773
9865
|
sonner.toast.success("Logged out successfully");
|
|
9774
|
-
router.push("/");
|
|
9866
|
+
router.push(buildPath("/"));
|
|
9775
9867
|
};
|
|
9776
9868
|
if (!user) {
|
|
9777
|
-
router.push("/login");
|
|
9869
|
+
router.push(buildPath("/login"));
|
|
9778
9870
|
return null;
|
|
9779
9871
|
}
|
|
9780
9872
|
const quickLinks = [
|
|
@@ -9782,46 +9874,46 @@ function ProfileScreen() {
|
|
|
9782
9874
|
icon: lucideReact.Package,
|
|
9783
9875
|
label: "Order history",
|
|
9784
9876
|
description: "Track shipments and download invoices",
|
|
9785
|
-
href: "/orders"
|
|
9877
|
+
href: buildPath("/orders")
|
|
9786
9878
|
},
|
|
9787
9879
|
{
|
|
9788
9880
|
icon: lucideReact.Heart,
|
|
9789
9881
|
label: "Wishlist",
|
|
9790
9882
|
description: "Curate go-to remedies and favorites",
|
|
9791
|
-
href: "/wishlist"
|
|
9883
|
+
href: buildPath("/wishlist")
|
|
9792
9884
|
},
|
|
9793
9885
|
{
|
|
9794
9886
|
icon: lucideReact.MapPin,
|
|
9795
9887
|
label: "Delivery addresses",
|
|
9796
9888
|
description: "Manage saved delivery locations",
|
|
9797
|
-
href: "/account/addresses"
|
|
9889
|
+
href: buildPath("/account/addresses")
|
|
9798
9890
|
}
|
|
9799
9891
|
];
|
|
9800
|
-
return /* @__PURE__ */
|
|
9892
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white mb-8" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9801
9893
|
framerMotion.motion.div,
|
|
9802
9894
|
{
|
|
9803
9895
|
initial: { opacity: 0, y: 24 },
|
|
9804
9896
|
animate: { opacity: 1, y: 0 },
|
|
9805
9897
|
className: "flex flex-col gap-8 md:flex-row md:items-center md:justify-between"
|
|
9806
9898
|
},
|
|
9807
|
-
/* @__PURE__ */
|
|
9808
|
-
/* @__PURE__ */
|
|
9899
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-5" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.HeartPulse, { className: "h-4 w-4" }), "My account"), /* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Hello, ", user.firstname, " ", user.lastname), /* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "Manage profile details, shipping preferences, and personalized recommendations. Our pharmacists keep your care plan up to date."), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-4 text-sm text-white/80" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-4 py-2" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShieldCheck, { className: "h-4 w-4" }), "Account secured with multi-factor ready login"))),
|
|
9900
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col items-center gap-4 rounded-3xl bg-white/15 p-6 text-center backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex h-24 w-24 items-center justify-center rounded-full bg-white/20 text-3xl font-bold text-white" }, getInitials(user?.firstname || "", user?.lastname || "") || ""), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-white/80" }, user.email), /* @__PURE__ */ React20__default.default.createElement(
|
|
9809
9901
|
Button,
|
|
9810
9902
|
{
|
|
9811
9903
|
variant: "ghost",
|
|
9812
9904
|
className: "text-white hover:bg-white/20",
|
|
9813
|
-
onClick: () => router.push("/account/change-password")
|
|
9905
|
+
onClick: () => router.push(buildPath("/account/change-password"))
|
|
9814
9906
|
},
|
|
9815
9907
|
"Change password"
|
|
9816
9908
|
))
|
|
9817
|
-
))), /* @__PURE__ */
|
|
9909
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-16 pb-20" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9818
9910
|
framerMotion.motion.div,
|
|
9819
9911
|
{
|
|
9820
9912
|
initial: { opacity: 0, y: 24 },
|
|
9821
9913
|
animate: { opacity: 1, y: 0 },
|
|
9822
9914
|
className: "space-y-6"
|
|
9823
9915
|
},
|
|
9824
|
-
/* @__PURE__ */
|
|
9916
|
+
/* @__PURE__ */ React20__default.default.createElement("section", { className: "rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-xl font-semibold text-slate-900" }, "Personal information"), /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-5 w-5 text-primary-500" })), /* @__PURE__ */ React20__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit), className: "mt-6 space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9825
9917
|
Input,
|
|
9826
9918
|
{
|
|
9827
9919
|
label: "First name",
|
|
@@ -9829,7 +9921,7 @@ function ProfileScreen() {
|
|
|
9829
9921
|
...register("firstName"),
|
|
9830
9922
|
error: errors.firstName?.message
|
|
9831
9923
|
}
|
|
9832
|
-
), /* @__PURE__ */
|
|
9924
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9833
9925
|
Input,
|
|
9834
9926
|
{
|
|
9835
9927
|
label: "Last name",
|
|
@@ -9837,7 +9929,7 @@ function ProfileScreen() {
|
|
|
9837
9929
|
...register("lastName"),
|
|
9838
9930
|
error: errors.lastName?.message
|
|
9839
9931
|
}
|
|
9840
|
-
)), /* @__PURE__ */
|
|
9932
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9841
9933
|
Input,
|
|
9842
9934
|
{
|
|
9843
9935
|
type: "email",
|
|
@@ -9847,7 +9939,7 @@ function ProfileScreen() {
|
|
|
9847
9939
|
...register("email"),
|
|
9848
9940
|
error: errors.email?.message
|
|
9849
9941
|
}
|
|
9850
|
-
), /* @__PURE__ */
|
|
9942
|
+
), /* @__PURE__ */ React20__default.default.createElement(lucideReact.Mail, { className: "absolute left-3 top-[38px] h-4 w-4 text-slate-400" })), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9851
9943
|
Input,
|
|
9852
9944
|
{
|
|
9853
9945
|
type: "tel",
|
|
@@ -9857,7 +9949,7 @@ function ProfileScreen() {
|
|
|
9857
9949
|
...register("phone"),
|
|
9858
9950
|
error: errors.phone?.message
|
|
9859
9951
|
}
|
|
9860
|
-
), /* @__PURE__ */
|
|
9952
|
+
), /* @__PURE__ */ React20__default.default.createElement(lucideReact.Phone, { className: "absolute left-3 top-[38px] h-4 w-4 text-slate-400" })), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
9861
9953
|
Button,
|
|
9862
9954
|
{
|
|
9863
9955
|
type: "submit",
|
|
@@ -9865,26 +9957,26 @@ function ProfileScreen() {
|
|
|
9865
9957
|
isLoading: isSubmitting
|
|
9866
9958
|
},
|
|
9867
9959
|
"Save changes"
|
|
9868
|
-
), /* @__PURE__ */
|
|
9960
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9869
9961
|
Button,
|
|
9870
9962
|
{
|
|
9871
9963
|
type: "button",
|
|
9872
9964
|
variant: "outline",
|
|
9873
9965
|
size: "lg",
|
|
9874
|
-
onClick: () => router.push("/orders")
|
|
9966
|
+
onClick: () => router.push(buildPath("/orders"))
|
|
9875
9967
|
},
|
|
9876
9968
|
"View recent orders"
|
|
9877
9969
|
)))),
|
|
9878
|
-
/* @__PURE__ */
|
|
9970
|
+
/* @__PURE__ */ React20__default.default.createElement("section", { className: "grid gap-4 md:grid-cols-2" }, quickLinks.map((item) => /* @__PURE__ */ React20__default.default.createElement(
|
|
9879
9971
|
Link8__default.default,
|
|
9880
9972
|
{
|
|
9881
9973
|
key: item.href,
|
|
9882
9974
|
href: item.href,
|
|
9883
9975
|
className: "group rounded-3xl border border-slate-100 bg-white p-6 shadow-sm transition hover:-translate-y-1 hover:shadow-lg"
|
|
9884
9976
|
},
|
|
9885
|
-
/* @__PURE__ */
|
|
9977
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "rounded-2xl bg-primary-50 p-3 text-primary-600" }, /* @__PURE__ */ React20__default.default.createElement(item.icon, { className: "h-5 w-5" })), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-base font-semibold text-slate-900 group-hover:text-primary-600" }, item.label), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-500" }, item.description)))
|
|
9886
9978
|
)))
|
|
9887
|
-
), /* @__PURE__ */
|
|
9979
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
9888
9980
|
framerMotion.motion.aside,
|
|
9889
9981
|
{
|
|
9890
9982
|
initial: { opacity: 0, y: 24 },
|
|
@@ -9892,30 +9984,31 @@ function ProfileScreen() {
|
|
|
9892
9984
|
transition: { delay: 0.1 },
|
|
9893
9985
|
className: "space-y-6"
|
|
9894
9986
|
},
|
|
9895
|
-
/* @__PURE__ */
|
|
9987
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-slate-900" }, "Care preferences"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 text-sm text-slate-600" }, "Customize how we support you. Set refill reminders or manage communication preferences to stay aligned with your wellness goals."), /* @__PURE__ */ React20__default.default.createElement(
|
|
9896
9988
|
Button,
|
|
9897
9989
|
{
|
|
9898
9990
|
variant: "outline",
|
|
9899
9991
|
className: "mt-4 w-full",
|
|
9900
|
-
onClick: () => router.push("/account/preferences")
|
|
9992
|
+
onClick: () => router.push(buildPath("/account/preferences"))
|
|
9901
9993
|
},
|
|
9902
9994
|
"Manage preferences"
|
|
9903
9995
|
)),
|
|
9904
|
-
/* @__PURE__ */
|
|
9905
|
-
/* @__PURE__ */
|
|
9996
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/70 p-6 text-sm text-primary-700 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold uppercase tracking-[0.3em]" }, "Pharmacist tip"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 leading-relaxed" }, "Keep your phone number current so pharmacists can reach you quickly with dosage advice or time-sensitive updates about your order.")),
|
|
9997
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
9906
9998
|
"button",
|
|
9907
9999
|
{
|
|
9908
10000
|
onClick: handleLogout,
|
|
9909
10001
|
className: "flex w-full items-center justify-center gap-2 rounded-3xl border border-red-200 bg-red-50 px-4 py-3 text-sm font-semibold text-red-600 transition hover:bg-red-100"
|
|
9910
10002
|
},
|
|
9911
|
-
/* @__PURE__ */
|
|
10003
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.LogOut, { className: "h-4 w-4" }),
|
|
9912
10004
|
"Log out"
|
|
9913
10005
|
)
|
|
9914
10006
|
)))));
|
|
9915
10007
|
}
|
|
9916
10008
|
function OrderCard({ order }) {
|
|
10009
|
+
const { buildPath } = useBasePath();
|
|
9917
10010
|
const config = order.orderStatus;
|
|
9918
|
-
return /* @__PURE__ */
|
|
10011
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
9919
10012
|
framerMotion.motion.div,
|
|
9920
10013
|
{
|
|
9921
10014
|
initial: { opacity: 0, y: 20 },
|
|
@@ -9923,9 +10016,9 @@ function OrderCard({ order }) {
|
|
|
9923
10016
|
whileHover: { y: -4 },
|
|
9924
10017
|
className: "bg-white rounded-2xl p-6 shadow-sm hover:shadow-xl transition-all duration-300 border border-gray-100"
|
|
9925
10018
|
},
|
|
9926
|
-
/* @__PURE__ */
|
|
9927
|
-
/* @__PURE__ */
|
|
9928
|
-
/* @__PURE__ */
|
|
10019
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex justify-between items-start mb-4" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-bold text-gray-900 flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Package, { className: "w-5 h-5 text-primary-600" }), "Order #", order?._id?.slice(0, 6) || ""), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-gray-500 mt-1 flex items-center gap-2" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Calendar, { className: "w-4 h-4" }), formatDate(order.createdAt || /* @__PURE__ */ new Date(), "long"))), /* @__PURE__ */ React20__default.default.createElement(Badge, { variant: config }, config)),
|
|
10020
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-2 mb-4" }, order.items?.slice(0, 2).map((item) => /* @__PURE__ */ React20__default.default.createElement("div", { key: item.productVariantId, className: "flex items-center gap-3 text-sm" }, /* @__PURE__ */ React20__default.default.createElement(Image3__default.default, { src: item?.productVariantData?.productMedia?.[0]?.file || "/placeholder-product.jpg", alt: item?.productVariantData?.name || "Product image", width: 48, height: 48, className: "w-12 h-12 rounded-lg bg-gray-100 flex-shrink-0" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-medium text-gray-900 truncate" }, item.productVariantData.name), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-gray-500" }, "Qty: ", item.quantity)), /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold text-gray-900" }, formatPrice(item.productVariantData.finalPrice)))), order.items?.length && order.items?.length > 2 && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-gray-500 pl-15" }, "+", order.items.length - 2, " more item", order.items.length - 2 > 1 ? "s" : "")),
|
|
10021
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex justify-between items-center pt-4 border-t border-gray-200" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-gray-500" }, "Total Amount"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-2xl font-bold text-gray-900" }, formatPrice(order.grandTotal || 0))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex gap-2" }, order.payment.paymentStatus !== "Paid" /* Paid */ && order.payment.paymentMethod === "Card" /* Card */ && /* @__PURE__ */ React20__default.default.createElement(
|
|
9929
10022
|
"a",
|
|
9930
10023
|
{
|
|
9931
10024
|
href: order?.payment?.paymentIntent?.hostedInvoiceUrl || "",
|
|
@@ -9933,16 +10026,16 @@ function OrderCard({ order }) {
|
|
|
9933
10026
|
rel: "noopener noreferrer",
|
|
9934
10027
|
className: "inline-flex items-center gap-2 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
|
|
9935
10028
|
},
|
|
9936
|
-
/* @__PURE__ */
|
|
10029
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.CreditCard, { className: "w-4 h-4" }),
|
|
9937
10030
|
"Pay Now"
|
|
9938
10031
|
)))
|
|
9939
10032
|
);
|
|
9940
10033
|
}
|
|
9941
10034
|
function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
9942
|
-
const [orders, setOrders] =
|
|
9943
|
-
const [isLoading, setIsLoading] =
|
|
9944
|
-
const [error, setError] =
|
|
9945
|
-
const [pagination, setPagination] =
|
|
10035
|
+
const [orders, setOrders] = React20.useState([]);
|
|
10036
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
10037
|
+
const [error, setError] = React20.useState(null);
|
|
10038
|
+
const [pagination, setPagination] = React20.useState({
|
|
9946
10039
|
page: 1,
|
|
9947
10040
|
limit: 10,
|
|
9948
10041
|
total: 0,
|
|
@@ -9950,7 +10043,7 @@ function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
|
9950
10043
|
});
|
|
9951
10044
|
const { user } = useAuth();
|
|
9952
10045
|
const resolvedUserId = user?._id || user?.id;
|
|
9953
|
-
const fetchOrders =
|
|
10046
|
+
const fetchOrders = React20.useCallback(async () => {
|
|
9954
10047
|
setIsLoading(true);
|
|
9955
10048
|
setError(null);
|
|
9956
10049
|
try {
|
|
@@ -9977,7 +10070,7 @@ function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
|
9977
10070
|
setIsLoading(false);
|
|
9978
10071
|
}
|
|
9979
10072
|
}, [page, limit, resolvedUserId, orderStatus, paymentStatus]);
|
|
9980
|
-
|
|
10073
|
+
React20.useEffect(() => {
|
|
9981
10074
|
fetchOrders();
|
|
9982
10075
|
}, [fetchOrders]);
|
|
9983
10076
|
return {
|
|
@@ -9989,10 +10082,10 @@ function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
|
9989
10082
|
};
|
|
9990
10083
|
}
|
|
9991
10084
|
function useOrder(id) {
|
|
9992
|
-
const [order, setOrder] =
|
|
9993
|
-
const [isLoading, setIsLoading] =
|
|
9994
|
-
const [error, setError] =
|
|
9995
|
-
const fetchOrder =
|
|
10085
|
+
const [order, setOrder] = React20.useState(null);
|
|
10086
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
10087
|
+
const [error, setError] = React20.useState(null);
|
|
10088
|
+
const fetchOrder = React20.useCallback(async () => {
|
|
9996
10089
|
setIsLoading(true);
|
|
9997
10090
|
setError(null);
|
|
9998
10091
|
try {
|
|
@@ -10004,7 +10097,7 @@ function useOrder(id) {
|
|
|
10004
10097
|
setIsLoading(false);
|
|
10005
10098
|
}
|
|
10006
10099
|
}, [id]);
|
|
10007
|
-
|
|
10100
|
+
React20.useEffect(() => {
|
|
10008
10101
|
if (id) {
|
|
10009
10102
|
fetchOrder();
|
|
10010
10103
|
}
|
|
@@ -10012,10 +10105,10 @@ function useOrder(id) {
|
|
|
10012
10105
|
return { order, isLoading, error, refetch: fetchOrder };
|
|
10013
10106
|
}
|
|
10014
10107
|
function useCurrentOrders() {
|
|
10015
|
-
const [orders, setOrders] =
|
|
10016
|
-
const [isLoading, setIsLoading] =
|
|
10017
|
-
const [error, setError] =
|
|
10018
|
-
const fetchCurrentOrders =
|
|
10108
|
+
const [orders, setOrders] = React20.useState([]);
|
|
10109
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
10110
|
+
const [error, setError] = React20.useState(null);
|
|
10111
|
+
const fetchCurrentOrders = React20.useCallback(async () => {
|
|
10019
10112
|
setIsLoading(true);
|
|
10020
10113
|
setError(null);
|
|
10021
10114
|
try {
|
|
@@ -10027,7 +10120,7 @@ function useCurrentOrders() {
|
|
|
10027
10120
|
setIsLoading(false);
|
|
10028
10121
|
}
|
|
10029
10122
|
}, []);
|
|
10030
|
-
|
|
10123
|
+
React20.useEffect(() => {
|
|
10031
10124
|
fetchCurrentOrders();
|
|
10032
10125
|
}, [fetchCurrentOrders]);
|
|
10033
10126
|
return { orders, isLoading, error, refetch: fetchCurrentOrders };
|
|
@@ -10041,11 +10134,11 @@ function FilterChips({
|
|
|
10041
10134
|
maxVisible = 4,
|
|
10042
10135
|
variant = "primary"
|
|
10043
10136
|
}) {
|
|
10044
|
-
const [isOverflowOpen, setIsOverflowOpen] =
|
|
10045
|
-
const [filterSearchTerm, setFilterSearchTerm] =
|
|
10046
|
-
const overflowMenuRef =
|
|
10137
|
+
const [isOverflowOpen, setIsOverflowOpen] = React20.useState(false);
|
|
10138
|
+
const [filterSearchTerm, setFilterSearchTerm] = React20.useState("");
|
|
10139
|
+
const overflowMenuRef = React20.useRef(null);
|
|
10047
10140
|
const color = variant === "primary" ? "primary" : "secondary";
|
|
10048
|
-
const { visibleFilters, overflowFilters } =
|
|
10141
|
+
const { visibleFilters, overflowFilters } = React20.useMemo(() => {
|
|
10049
10142
|
const basePrimary = filters.slice(0, maxVisible);
|
|
10050
10143
|
if (basePrimary.includes(selected)) {
|
|
10051
10144
|
return {
|
|
@@ -10065,18 +10158,18 @@ function FilterChips({
|
|
|
10065
10158
|
overflowFilters: filters.filter((filter) => !uniquePrimary.includes(filter))
|
|
10066
10159
|
};
|
|
10067
10160
|
}, [filters, maxVisible, selected]);
|
|
10068
|
-
const filteredOverflowFilters =
|
|
10161
|
+
const filteredOverflowFilters = React20.useMemo(() => {
|
|
10069
10162
|
if (!filterSearchTerm.trim()) return overflowFilters;
|
|
10070
10163
|
return overflowFilters.filter(
|
|
10071
10164
|
(filter) => filter.toLowerCase().includes(filterSearchTerm.toLowerCase())
|
|
10072
10165
|
);
|
|
10073
10166
|
}, [filterSearchTerm, overflowFilters]);
|
|
10074
|
-
|
|
10167
|
+
React20.useEffect(() => {
|
|
10075
10168
|
if (!isOverflowOpen) {
|
|
10076
10169
|
setFilterSearchTerm("");
|
|
10077
10170
|
}
|
|
10078
10171
|
}, [isOverflowOpen]);
|
|
10079
|
-
|
|
10172
|
+
React20.useEffect(() => {
|
|
10080
10173
|
function handleClickOutside(event) {
|
|
10081
10174
|
if (overflowMenuRef.current && !overflowMenuRef.current.contains(event.target)) {
|
|
10082
10175
|
setIsOverflowOpen(false);
|
|
@@ -10089,7 +10182,7 @@ function FilterChips({
|
|
|
10089
10182
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
10090
10183
|
};
|
|
10091
10184
|
}, [isOverflowOpen]);
|
|
10092
|
-
return /* @__PURE__ */
|
|
10185
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:gap-4" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement(Icon, { className: "h-4 w-4" }), label), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-2 md:flex-row md:items-center md:gap-3" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-2" }, visibleFilters.map((filter) => /* @__PURE__ */ React20__default.default.createElement(
|
|
10093
10186
|
"button",
|
|
10094
10187
|
{
|
|
10095
10188
|
key: filter,
|
|
@@ -10098,16 +10191,16 @@ function FilterChips({
|
|
|
10098
10191
|
className: `rounded-full border px-3 py-1 text-sm font-medium transition ${selected === filter ? `border-${color}-600 bg-${color}-600 text-white shadow-lg shadow-${color}-500/30` : `border-slate-200 bg-slate-50 text-slate-600 hover:border-${color}-300 hover:text-${color}-600`}`
|
|
10099
10192
|
},
|
|
10100
10193
|
filter
|
|
10101
|
-
))), overflowFilters.length > 0 && /* @__PURE__ */
|
|
10194
|
+
))), overflowFilters.length > 0 && /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative", ref: overflowMenuRef }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10102
10195
|
"button",
|
|
10103
10196
|
{
|
|
10104
10197
|
type: "button",
|
|
10105
10198
|
onClick: () => setIsOverflowOpen((prev) => !prev),
|
|
10106
10199
|
className: `flex items-center gap-2 rounded-full border px-3 py-1 text-sm font-medium transition ${overflowFilters.includes(selected) ? `border-${color}-600 bg-${color}-50 text-${color}-700 shadow-lg shadow-${color}-500/20` : "border-slate-200 bg-white text-slate-600 hover:border-slate-300"}`
|
|
10107
10200
|
},
|
|
10108
|
-
/* @__PURE__ */
|
|
10109
|
-
/* @__PURE__ */
|
|
10110
|
-
), /* @__PURE__ */
|
|
10201
|
+
/* @__PURE__ */ React20__default.default.createElement("span", null, overflowFilters.includes(selected) ? selected : "More"),
|
|
10202
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: `inline-flex h-5 min-w-[1.5rem] items-center justify-center rounded-full bg-${color}-100 px-1 text-xs font-semibold text-${color}-600` }, overflowFilters.length)
|
|
10203
|
+
), /* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, isOverflowOpen && /* @__PURE__ */ React20__default.default.createElement(
|
|
10111
10204
|
framerMotion.motion.div,
|
|
10112
10205
|
{
|
|
10113
10206
|
initial: { opacity: 0, y: 8 },
|
|
@@ -10116,7 +10209,7 @@ function FilterChips({
|
|
|
10116
10209
|
transition: { duration: 0.15 },
|
|
10117
10210
|
className: "absolute right-0 z-50 mt-2 w-64 rounded-2xl border border-slate-100 bg-white shadow-xl shadow-primary-50"
|
|
10118
10211
|
},
|
|
10119
|
-
/* @__PURE__ */
|
|
10212
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "border-b border-slate-100 px-4 py-3" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" }), /* @__PURE__ */ React20__default.default.createElement(
|
|
10120
10213
|
"input",
|
|
10121
10214
|
{
|
|
10122
10215
|
type: "text",
|
|
@@ -10126,7 +10219,7 @@ function FilterChips({
|
|
|
10126
10219
|
className: "w-full rounded-full border border-slate-200 bg-slate-50 py-2 pl-9 pr-3 text-sm text-slate-600 outline-none transition focus:border-primary-300 focus:bg-white focus:ring-2 focus:ring-primary-200"
|
|
10127
10220
|
}
|
|
10128
10221
|
))),
|
|
10129
|
-
/* @__PURE__ */
|
|
10222
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "max-h-60 overflow-y-auto px-2 py-2" }, filteredOverflowFilters.length > 0 ? filteredOverflowFilters.map((filter) => /* @__PURE__ */ React20__default.default.createElement(
|
|
10130
10223
|
"button",
|
|
10131
10224
|
{
|
|
10132
10225
|
key: filter,
|
|
@@ -10137,10 +10230,10 @@ function FilterChips({
|
|
|
10137
10230
|
},
|
|
10138
10231
|
className: `flex w-full items-center justify-between rounded-xl px-3 py-2 text-sm font-medium transition ${selected === filter ? `bg-${color}-600 text-white shadow-lg shadow-${color}-500/30` : "text-slate-600 hover:bg-slate-100"}`
|
|
10139
10232
|
},
|
|
10140
|
-
/* @__PURE__ */
|
|
10141
|
-
selected === filter && /* @__PURE__ */
|
|
10142
|
-
)) : /* @__PURE__ */
|
|
10143
|
-
/* @__PURE__ */
|
|
10233
|
+
/* @__PURE__ */ React20__default.default.createElement("span", null, filter),
|
|
10234
|
+
selected === filter && /* @__PURE__ */ React20__default.default.createElement(lucideReact.Check, { className: "h-4 w-4" })
|
|
10235
|
+
)) : /* @__PURE__ */ React20__default.default.createElement("p", { className: "px-3 py-4 text-sm text-slate-500" }, "No items found.")),
|
|
10236
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between gap-2 border-t border-slate-100 px-4 py-3" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-xs font-semibold uppercase tracking-wide text-slate-400" }, "Quick actions"), /* @__PURE__ */ React20__default.default.createElement(
|
|
10144
10237
|
"button",
|
|
10145
10238
|
{
|
|
10146
10239
|
type: "button",
|
|
@@ -10158,19 +10251,20 @@ var STATUS_FILTERS = ["All", ...Object.values(ManualOrderDTOOrderStatusEnum)];
|
|
|
10158
10251
|
var PAYMENT_FILTERS = ["All", ...Object.values(PaymentPaymentStatusEnum)];
|
|
10159
10252
|
function OrdersScreen() {
|
|
10160
10253
|
const router = navigation.useRouter();
|
|
10161
|
-
const
|
|
10162
|
-
const [
|
|
10163
|
-
const [
|
|
10254
|
+
const { buildPath } = useBasePath();
|
|
10255
|
+
const [page, setPage] = React20.useState(1);
|
|
10256
|
+
const [selectedFilter, setSelectedFilter] = React20.useState("All");
|
|
10257
|
+
const [selectedPaymentFilter, setSelectedPaymentFilter] = React20.useState("All");
|
|
10164
10258
|
const { orders, isLoading, pagination } = useOrders(
|
|
10165
10259
|
page,
|
|
10166
10260
|
10,
|
|
10167
10261
|
selectedFilter,
|
|
10168
10262
|
selectedPaymentFilter
|
|
10169
10263
|
);
|
|
10170
|
-
const [isOverflowOpen, setIsOverflowOpen] =
|
|
10171
|
-
const [filterSearchTerm, setFilterSearchTerm] =
|
|
10172
|
-
const overflowMenuRef =
|
|
10173
|
-
const filteredOrders =
|
|
10264
|
+
const [isOverflowOpen, setIsOverflowOpen] = React20.useState(false);
|
|
10265
|
+
const [filterSearchTerm, setFilterSearchTerm] = React20.useState("");
|
|
10266
|
+
const overflowMenuRef = React20.useRef(null);
|
|
10267
|
+
const filteredOrders = React20.useMemo(() => {
|
|
10174
10268
|
return orders.filter((order) => {
|
|
10175
10269
|
const matchesStatus = selectedFilter === "All" || order?.orderStatus?.toLowerCase() === selectedFilter.toLowerCase();
|
|
10176
10270
|
const matchesPayment = selectedPaymentFilter === "All" || order?.payment?.paymentStatus?.toLowerCase() === selectedPaymentFilter.toLowerCase();
|
|
@@ -10179,12 +10273,12 @@ function OrdersScreen() {
|
|
|
10179
10273
|
}, [orders, selectedFilter, selectedPaymentFilter]);
|
|
10180
10274
|
const hasOrders = filteredOrders.length > 0;
|
|
10181
10275
|
const MAX_VISIBLE_FILTERS = 4;
|
|
10182
|
-
|
|
10276
|
+
React20.useEffect(() => {
|
|
10183
10277
|
if (!isOverflowOpen) {
|
|
10184
10278
|
setFilterSearchTerm("");
|
|
10185
10279
|
}
|
|
10186
10280
|
}, [isOverflowOpen]);
|
|
10187
|
-
|
|
10281
|
+
React20.useEffect(() => {
|
|
10188
10282
|
function handleClickOutside(event) {
|
|
10189
10283
|
if (overflowMenuRef.current && !overflowMenuRef.current.contains(event.target)) {
|
|
10190
10284
|
setIsOverflowOpen(false);
|
|
@@ -10197,23 +10291,23 @@ function OrdersScreen() {
|
|
|
10197
10291
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
10198
10292
|
};
|
|
10199
10293
|
}, [isOverflowOpen]);
|
|
10200
|
-
return /* @__PURE__ */
|
|
10294
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white mb-8" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10201
10295
|
framerMotion.motion.div,
|
|
10202
10296
|
{
|
|
10203
10297
|
initial: { opacity: 0, y: 24 },
|
|
10204
10298
|
animate: { opacity: 1, y: 0 },
|
|
10205
10299
|
className: "space-y-6"
|
|
10206
10300
|
},
|
|
10207
|
-
/* @__PURE__ */
|
|
10208
|
-
/* @__PURE__ */
|
|
10209
|
-
))), /* @__PURE__ */
|
|
10301
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.CalendarDays, { className: "h-4 w-4" }), "Order history"),
|
|
10302
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "All of your pharmacy orders"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "Access receipts, shipping statuses, and reorder suggestions in one organized timeline curated by our pharmacists.")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl bg-white/15 p-6 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.35em] text-white/70" }, "Quick tip"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 text-sm text-white/80" }, "Use filters to review previous prescriptions, reorder favorites, or download invoices for insurance claims.")))
|
|
10303
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-16 pb-16 container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10210
10304
|
framerMotion.motion.div,
|
|
10211
10305
|
{
|
|
10212
10306
|
initial: { opacity: 0, y: 24 },
|
|
10213
10307
|
animate: { opacity: 1, y: 0 },
|
|
10214
10308
|
className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50"
|
|
10215
10309
|
},
|
|
10216
|
-
/* @__PURE__ */
|
|
10310
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3 text-sm text-slate-500" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-4 w-4 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "Explore your complete order archive with pharmacist notes.")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-4 md:items-end" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10217
10311
|
FilterChips,
|
|
10218
10312
|
{
|
|
10219
10313
|
label: "Status filters",
|
|
@@ -10227,7 +10321,7 @@ function OrdersScreen() {
|
|
|
10227
10321
|
maxVisible: MAX_VISIBLE_FILTERS,
|
|
10228
10322
|
variant: "primary"
|
|
10229
10323
|
}
|
|
10230
|
-
), /* @__PURE__ */
|
|
10324
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10231
10325
|
FilterChips,
|
|
10232
10326
|
{
|
|
10233
10327
|
label: "Payment status",
|
|
@@ -10242,26 +10336,26 @@ function OrdersScreen() {
|
|
|
10242
10336
|
variant: "primary"
|
|
10243
10337
|
}
|
|
10244
10338
|
))),
|
|
10245
|
-
/* @__PURE__ */
|
|
10339
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 space-y-4" }, isLoading ? Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ React20__default.default.createElement(OrderCardSkeleton, { key: index })) : hasOrders ? filteredOrders.map((order) => /* @__PURE__ */ React20__default.default.createElement(OrderCard, { key: order.id, order })) : /* @__PURE__ */ React20__default.default.createElement(
|
|
10246
10340
|
EmptyState,
|
|
10247
10341
|
{
|
|
10248
10342
|
icon: lucideReact.Package,
|
|
10249
10343
|
title: "No orders found for these filters",
|
|
10250
10344
|
description: "Adjust the status or payment filters, or browse the shop for new essentials.",
|
|
10251
10345
|
actionLabel: "Shop products",
|
|
10252
|
-
onAction: () => router.push("/shop")
|
|
10346
|
+
onAction: () => router.push(buildPath("/shop"))
|
|
10253
10347
|
}
|
|
10254
10348
|
)),
|
|
10255
|
-
!isLoading && pagination.totalPages > 1 && hasOrders && /* @__PURE__ */
|
|
10349
|
+
!isLoading && pagination.totalPages > 1 && hasOrders && /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-10 flex flex-wrap items-center justify-center gap-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10256
10350
|
Button,
|
|
10257
10351
|
{
|
|
10258
10352
|
variant: "outline",
|
|
10259
10353
|
onClick: () => setPage((current) => Math.max(1, current - 1)),
|
|
10260
10354
|
disabled: page === 1
|
|
10261
10355
|
},
|
|
10262
|
-
/* @__PURE__ */
|
|
10356
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ChevronLeft, { className: "h-5 w-5" }),
|
|
10263
10357
|
"Previous"
|
|
10264
|
-
), /* @__PURE__ */
|
|
10358
|
+
), /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm font-semibold text-slate-600" }, "Page ", page, " of ", pagination.totalPages), /* @__PURE__ */ React20__default.default.createElement(
|
|
10265
10359
|
Button,
|
|
10266
10360
|
{
|
|
10267
10361
|
variant: "outline",
|
|
@@ -10269,25 +10363,26 @@ function OrdersScreen() {
|
|
|
10269
10363
|
disabled: page === pagination.totalPages
|
|
10270
10364
|
},
|
|
10271
10365
|
"Next",
|
|
10272
|
-
/* @__PURE__ */
|
|
10366
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ChevronRight, { className: "h-5 w-5" })
|
|
10273
10367
|
))
|
|
10274
10368
|
))));
|
|
10275
10369
|
}
|
|
10276
10370
|
function CurrentOrdersScreen() {
|
|
10277
10371
|
const router = navigation.useRouter();
|
|
10278
10372
|
const { orders, isLoading } = useCurrentOrders();
|
|
10373
|
+
const { buildPath } = useBasePath();
|
|
10279
10374
|
const hasOrders = orders.length > 0;
|
|
10280
|
-
return /* @__PURE__ */
|
|
10375
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-6 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10281
10376
|
framerMotion.motion.div,
|
|
10282
10377
|
{
|
|
10283
10378
|
initial: { opacity: 0, y: 24 },
|
|
10284
10379
|
animate: { opacity: 1, y: 0 },
|
|
10285
10380
|
className: "space-y-4"
|
|
10286
10381
|
},
|
|
10287
|
-
/* @__PURE__ */
|
|
10288
|
-
/* @__PURE__ */
|
|
10289
|
-
/* @__PURE__ */
|
|
10290
|
-
), /* @__PURE__ */
|
|
10382
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Truck, { className: "h-4 w-4" }), "Live order tracking"),
|
|
10383
|
+
/* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Current orders"),
|
|
10384
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "Follow your pharmacy orders from preparation to delivery. Real-time updates, SMS alerts, and pharmacist oversight come standard.")
|
|
10385
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10291
10386
|
framerMotion.motion.div,
|
|
10292
10387
|
{
|
|
10293
10388
|
initial: { opacity: 0, y: 24 },
|
|
@@ -10295,34 +10390,34 @@ function CurrentOrdersScreen() {
|
|
|
10295
10390
|
transition: { delay: 0.1 },
|
|
10296
10391
|
className: "rounded-3xl bg-white/15 p-6 backdrop-blur"
|
|
10297
10392
|
},
|
|
10298
|
-
/* @__PURE__ */
|
|
10299
|
-
/* @__PURE__ */
|
|
10393
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.35em] text-white/70" }, "Quick actions"),
|
|
10394
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-4 space-y-3 text-sm text-white/80" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10300
10395
|
Link8__default.default,
|
|
10301
10396
|
{
|
|
10302
|
-
href: "/orders",
|
|
10397
|
+
href: buildPath("/orders"),
|
|
10303
10398
|
className: "flex items-center justify-between rounded-2xl bg-white/10 px-4 py-3 transition hover:bg-white/20"
|
|
10304
10399
|
},
|
|
10305
|
-
/* @__PURE__ */
|
|
10306
|
-
/* @__PURE__ */
|
|
10307
|
-
), /* @__PURE__ */
|
|
10308
|
-
)))), /* @__PURE__ */
|
|
10400
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "font-semibold text-white" }, "View order history"),
|
|
10401
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.ArrowUpRight, { className: "h-4 w-4" })
|
|
10402
|
+
), /* @__PURE__ */ React20__default.default.createElement("p", null, "Need help fast? Chat with a pharmacist and we will triage your request in under 10 minutes."))
|
|
10403
|
+
)))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-16 pb-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10309
10404
|
framerMotion.motion.section,
|
|
10310
10405
|
{
|
|
10311
10406
|
initial: { opacity: 0, y: 24 },
|
|
10312
10407
|
animate: { opacity: 1, y: 0 },
|
|
10313
10408
|
className: "grid gap-6 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]"
|
|
10314
10409
|
},
|
|
10315
|
-
/* @__PURE__ */
|
|
10410
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-6" }, isLoading ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4" }, Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ React20__default.default.createElement(OrderCardSkeleton, { key: index }))) : hasOrders ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4" }, orders.map((order) => /* @__PURE__ */ React20__default.default.createElement(OrderCard, { key: order.id, order }))) : /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-10 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10316
10411
|
EmptyState,
|
|
10317
10412
|
{
|
|
10318
10413
|
icon: lucideReact.PackageCheck,
|
|
10319
10414
|
title: "No active orders",
|
|
10320
10415
|
description: "Start a new order to see live preparation, packing, and delivery updates here.",
|
|
10321
10416
|
actionLabel: "Shop wellness essentials",
|
|
10322
|
-
onAction: () => router.push("/shop")
|
|
10417
|
+
onAction: () => router.push(buildPath("/shop"))
|
|
10323
10418
|
}
|
|
10324
10419
|
))),
|
|
10325
|
-
/* @__PURE__ */
|
|
10420
|
+
/* @__PURE__ */ React20__default.default.createElement("aside", { className: "space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-lg font-semibold text-slate-900" }, "Real-time milestones"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-4 space-y-4 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start gap-3 rounded-2xl bg-slate-50 p-4" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Warehouse, { className: "h-5 w-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold text-slate-800" }, "Preparation"), /* @__PURE__ */ React20__default.default.createElement("p", null, "Our pharmacists verify ingredients and pack thermo-sensitive items."))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start gap-3 rounded-2xl bg-slate-50 p-4" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Truck, { className: "h-5 w-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold text-slate-800" }, "In transit"), /* @__PURE__ */ React20__default.default.createElement("p", null, "Track live courier location with ETA updates tailored to your delivery window."))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-start gap-3 rounded-2xl bg-slate-50 p-4" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.BellRing, { className: "h-5 w-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold text-slate-800" }, "Arrival alerts"), /* @__PURE__ */ React20__default.default.createElement("p", null, "Receive SMS and email notifications when parcels are out for delivery."))))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/70 p-6 text-sm text-primary-700 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "font-semibold uppercase tracking-[0.3em]" }, "Need support?"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 leading-relaxed" }, "Our fulfillment team is online 7 days a week. Message us if you need to adjust delivery instructions or review dosage guidance.")))
|
|
10326
10421
|
))));
|
|
10327
10422
|
}
|
|
10328
10423
|
var addressFormSchema = zod.z.object({
|
|
@@ -10355,12 +10450,12 @@ function formatAddressSnippet(address) {
|
|
|
10355
10450
|
function getAddressTypeCopy(type) {
|
|
10356
10451
|
switch (type) {
|
|
10357
10452
|
case "Billing":
|
|
10358
|
-
return { label: "Billing", icon: /* @__PURE__ */
|
|
10453
|
+
return { label: "Billing", icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.Home, { className: "h-4 w-4" }) };
|
|
10359
10454
|
case "Both":
|
|
10360
|
-
return { label: "Billing & Shipping", icon: /* @__PURE__ */
|
|
10455
|
+
return { label: "Billing & Shipping", icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.Globe, { className: "h-4 w-4" }) };
|
|
10361
10456
|
case "Shipping":
|
|
10362
10457
|
default:
|
|
10363
|
-
return { label: "Shipping", icon: /* @__PURE__ */
|
|
10458
|
+
return { label: "Shipping", icon: /* @__PURE__ */ React20__default.default.createElement(lucideReact.MapPin, { className: "h-4 w-4" }) };
|
|
10364
10459
|
}
|
|
10365
10460
|
}
|
|
10366
10461
|
function AddressesScreen() {
|
|
@@ -10374,8 +10469,8 @@ function AddressesScreen() {
|
|
|
10374
10469
|
removeAddress,
|
|
10375
10470
|
markAsDefault
|
|
10376
10471
|
} = useAddresses();
|
|
10377
|
-
const [isModalOpen, setIsModalOpen] =
|
|
10378
|
-
const [editingAddress, setEditingAddress] =
|
|
10472
|
+
const [isModalOpen, setIsModalOpen] = React20.useState(false);
|
|
10473
|
+
const [editingAddress, setEditingAddress] = React20.useState(null);
|
|
10379
10474
|
const {
|
|
10380
10475
|
register,
|
|
10381
10476
|
handleSubmit,
|
|
@@ -10385,7 +10480,7 @@ function AddressesScreen() {
|
|
|
10385
10480
|
resolver: zod$1.zodResolver(addressFormSchema),
|
|
10386
10481
|
defaultValues: FORM_DEFAULTS
|
|
10387
10482
|
});
|
|
10388
|
-
|
|
10483
|
+
React20.useEffect(() => {
|
|
10389
10484
|
if (editingAddress) {
|
|
10390
10485
|
reset({
|
|
10391
10486
|
fullName: editingAddress.name,
|
|
@@ -10480,7 +10575,7 @@ You can add it back at any time.`
|
|
|
10480
10575
|
});
|
|
10481
10576
|
}
|
|
10482
10577
|
};
|
|
10483
|
-
const stats =
|
|
10578
|
+
const stats = React20.useMemo(() => {
|
|
10484
10579
|
const shippingCount = addresses.filter((address) => address.addressType !== "Billing").length;
|
|
10485
10580
|
const billingCount = addresses.filter((address) => address.addressType !== "Shipping").length;
|
|
10486
10581
|
return [
|
|
@@ -10504,18 +10599,18 @@ You can add it back at any time.`
|
|
|
10504
10599
|
}
|
|
10505
10600
|
];
|
|
10506
10601
|
}, [addresses]);
|
|
10507
|
-
return /* @__PURE__ */
|
|
10602
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white mb-8" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.3),_transparent_60%)]" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-6 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10508
10603
|
framerMotion.motion.div,
|
|
10509
10604
|
{
|
|
10510
10605
|
initial: { opacity: 0, y: 24 },
|
|
10511
10606
|
animate: { opacity: 1, y: 0 },
|
|
10512
10607
|
className: "space-y-5"
|
|
10513
10608
|
},
|
|
10514
|
-
/* @__PURE__ */
|
|
10515
|
-
/* @__PURE__ */
|
|
10516
|
-
/* @__PURE__ */
|
|
10517
|
-
/* @__PURE__ */
|
|
10518
|
-
), /* @__PURE__ */
|
|
10609
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.MapPin, { className: "h-4 w-4" }), "Address book"),
|
|
10610
|
+
/* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Manage where your care arrives"),
|
|
10611
|
+
/* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "Add home, office, or loved ones' addresses and toggle a default for lightning-fast checkout and delivery."),
|
|
10612
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-white/75" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-4 w-4 text-white" }), "Default address: ", defaultAddress ? defaultAddress.name : "Not set"), /* @__PURE__ */ React20__default.default.createElement(Button, { variant: "ghost", className: "text-white hover:bg-white/10", onClick: openCreateModal }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Plus, { className: "h-5 w-5" }), "Add address"))
|
|
10613
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10519
10614
|
framerMotion.motion.div,
|
|
10520
10615
|
{
|
|
10521
10616
|
initial: { opacity: 0, y: 24 },
|
|
@@ -10523,14 +10618,14 @@ You can add it back at any time.`
|
|
|
10523
10618
|
transition: { delay: 0.1 },
|
|
10524
10619
|
className: "grid gap-4 rounded-3xl bg-white/15 p-6 text-sm text-white/80 backdrop-blur"
|
|
10525
10620
|
},
|
|
10526
|
-
stats.map((stat) => /* @__PURE__ */
|
|
10527
|
-
)))), /* @__PURE__ */
|
|
10621
|
+
stats.map((stat) => /* @__PURE__ */ React20__default.default.createElement("div", { key: stat.id, className: "flex items-center justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.3em] text-white/70" }, stat.label), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-white" }, stat.helper)), /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-3xl font-semibold text-white" }, stat.value)))
|
|
10622
|
+
)))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-16 pb-20" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, isLoading ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3" }, Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ React20__default.default.createElement(
|
|
10528
10623
|
"div",
|
|
10529
10624
|
{
|
|
10530
10625
|
key: index,
|
|
10531
10626
|
className: "h-56 animate-pulse rounded-3xl border border-slate-100 bg-white"
|
|
10532
10627
|
}
|
|
10533
|
-
))) : error ? /* @__PURE__ */
|
|
10628
|
+
))) : error ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-red-100 bg-red-50 p-6 text-sm text-red-700" }, error.message) : addresses.length === 0 ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-12 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10534
10629
|
EmptyState,
|
|
10535
10630
|
{
|
|
10536
10631
|
icon: lucideReact.MapPin,
|
|
@@ -10539,9 +10634,9 @@ You can add it back at any time.`
|
|
|
10539
10634
|
actionLabel: "Add your first address",
|
|
10540
10635
|
onAction: openCreateModal
|
|
10541
10636
|
}
|
|
10542
|
-
)) : /* @__PURE__ */
|
|
10637
|
+
)) : /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3" }, addresses.map((address) => {
|
|
10543
10638
|
const typeCopy = getAddressTypeCopy(address.addressType);
|
|
10544
|
-
return /* @__PURE__ */
|
|
10639
|
+
return /* @__PURE__ */ React20__default.default.createElement(
|
|
10545
10640
|
framerMotion.motion.div,
|
|
10546
10641
|
{
|
|
10547
10642
|
key: address.id,
|
|
@@ -10549,39 +10644,39 @@ You can add it back at any time.`
|
|
|
10549
10644
|
animate: { opacity: 1, y: 0 },
|
|
10550
10645
|
className: "group relative flex h-full flex-col rounded-3xl border border-slate-100 bg-white p-6 shadow-sm transition hover:-translate-y-1 hover:shadow-xl"
|
|
10551
10646
|
},
|
|
10552
|
-
address.isDefault && /* @__PURE__ */
|
|
10553
|
-
/* @__PURE__ */
|
|
10554
|
-
/* @__PURE__ */
|
|
10555
|
-
/* @__PURE__ */
|
|
10647
|
+
address.isDefault && /* @__PURE__ */ React20__default.default.createElement("span", { className: "absolute right-6 top-6 inline-flex items-center gap-2 rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold text-amber-700" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Crown, { className: "h-4 w-4" }), "Default"),
|
|
10648
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "rounded-full bg-primary-50 p-3 text-primary-600" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.User, { className: "h-5 w-5" })), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-base font-semibold text-slate-900" }, address.name), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs uppercase tracking-[0.3em] text-slate-400" }, typeCopy.label))),
|
|
10649
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 flex flex-1 flex-col gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("p", null, formatAddressSnippet(address)), /* @__PURE__ */ React20__default.default.createElement("p", { className: "inline-flex items-center gap-2 text-slate-500" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Phone, { className: "h-4 w-4 text-slate-400" }), address.phone || "Not provided")),
|
|
10650
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-6 flex items-center justify-between gap-3" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10556
10651
|
"button",
|
|
10557
10652
|
{
|
|
10558
10653
|
type: "button",
|
|
10559
10654
|
onClick: () => openEditModal(address),
|
|
10560
10655
|
className: "inline-flex items-center gap-2 rounded-full border border-slate-200 px-3 py-1 text-sm font-medium text-slate-600 transition hover:border-primary-300 hover:text-primary-600"
|
|
10561
10656
|
},
|
|
10562
|
-
/* @__PURE__ */
|
|
10657
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Edit3, { className: "h-4 w-4" }),
|
|
10563
10658
|
"Edit"
|
|
10564
|
-
), /* @__PURE__ */
|
|
10659
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2" }, !address.isDefault && /* @__PURE__ */ React20__default.default.createElement(
|
|
10565
10660
|
"button",
|
|
10566
10661
|
{
|
|
10567
10662
|
type: "button",
|
|
10568
10663
|
onClick: () => handleSetDefault(address),
|
|
10569
10664
|
className: "inline-flex items-center gap-2 rounded-full border border-amber-200 px-3 py-1 text-sm font-semibold text-amber-600 transition hover:border-amber-300 hover:text-amber-700"
|
|
10570
10665
|
},
|
|
10571
|
-
/* @__PURE__ */
|
|
10666
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Star, { className: "h-4 w-4" }),
|
|
10572
10667
|
"Make default"
|
|
10573
|
-
), /* @__PURE__ */
|
|
10668
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10574
10669
|
"button",
|
|
10575
10670
|
{
|
|
10576
10671
|
type: "button",
|
|
10577
10672
|
onClick: () => handleDelete(address),
|
|
10578
10673
|
className: "inline-flex items-center gap-2 rounded-full border border-red-200 px-3 py-1 text-sm font-semibold text-red-600 transition hover:border-red-300 hover:text-red-700"
|
|
10579
10674
|
},
|
|
10580
|
-
/* @__PURE__ */
|
|
10675
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Trash2, { className: "h-4 w-4" }),
|
|
10581
10676
|
"Delete"
|
|
10582
10677
|
)))
|
|
10583
10678
|
);
|
|
10584
|
-
})))), /* @__PURE__ */
|
|
10679
|
+
})))), /* @__PURE__ */ React20__default.default.createElement(
|
|
10585
10680
|
Modal,
|
|
10586
10681
|
{
|
|
10587
10682
|
isOpen: isModalOpen,
|
|
@@ -10589,7 +10684,7 @@ You can add it back at any time.`
|
|
|
10589
10684
|
title: editingAddress ? "Edit address" : "Add new address",
|
|
10590
10685
|
size: "lg"
|
|
10591
10686
|
},
|
|
10592
|
-
/* @__PURE__ */
|
|
10687
|
+
/* @__PURE__ */ React20__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10593
10688
|
Input,
|
|
10594
10689
|
{
|
|
10595
10690
|
label: "Full name",
|
|
@@ -10597,7 +10692,7 @@ You can add it back at any time.`
|
|
|
10597
10692
|
...register("fullName"),
|
|
10598
10693
|
error: errors.fullName?.message
|
|
10599
10694
|
}
|
|
10600
|
-
), /* @__PURE__ */
|
|
10695
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10601
10696
|
Input,
|
|
10602
10697
|
{
|
|
10603
10698
|
label: "Phone number",
|
|
@@ -10605,7 +10700,7 @@ You can add it back at any time.`
|
|
|
10605
10700
|
...register("phone"),
|
|
10606
10701
|
error: errors.phone?.message
|
|
10607
10702
|
}
|
|
10608
|
-
)), /* @__PURE__ */
|
|
10703
|
+
)), /* @__PURE__ */ React20__default.default.createElement(
|
|
10609
10704
|
Input,
|
|
10610
10705
|
{
|
|
10611
10706
|
label: "Address line 1",
|
|
@@ -10613,7 +10708,7 @@ You can add it back at any time.`
|
|
|
10613
10708
|
...register("addressLine1"),
|
|
10614
10709
|
error: errors.addressLine1?.message
|
|
10615
10710
|
}
|
|
10616
|
-
), /* @__PURE__ */
|
|
10711
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10617
10712
|
Input,
|
|
10618
10713
|
{
|
|
10619
10714
|
label: "Address line 2 (optional)",
|
|
@@ -10621,7 +10716,7 @@ You can add it back at any time.`
|
|
|
10621
10716
|
...register("addressLine2"),
|
|
10622
10717
|
error: errors.addressLine2?.message
|
|
10623
10718
|
}
|
|
10624
|
-
), /* @__PURE__ */
|
|
10719
|
+
), /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10625
10720
|
Input,
|
|
10626
10721
|
{
|
|
10627
10722
|
label: "City",
|
|
@@ -10629,7 +10724,7 @@ You can add it back at any time.`
|
|
|
10629
10724
|
...register("city"),
|
|
10630
10725
|
error: errors.city?.message
|
|
10631
10726
|
}
|
|
10632
|
-
), /* @__PURE__ */
|
|
10727
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10633
10728
|
Input,
|
|
10634
10729
|
{
|
|
10635
10730
|
label: "State / Region",
|
|
@@ -10637,7 +10732,7 @@ You can add it back at any time.`
|
|
|
10637
10732
|
...register("state"),
|
|
10638
10733
|
error: errors.state?.message
|
|
10639
10734
|
}
|
|
10640
|
-
)), /* @__PURE__ */
|
|
10735
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10641
10736
|
Input,
|
|
10642
10737
|
{
|
|
10643
10738
|
label: "Postal code",
|
|
@@ -10645,7 +10740,7 @@ You can add it back at any time.`
|
|
|
10645
10740
|
...register("zipCode"),
|
|
10646
10741
|
error: errors.zipCode?.message
|
|
10647
10742
|
}
|
|
10648
|
-
), /* @__PURE__ */
|
|
10743
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10649
10744
|
Input,
|
|
10650
10745
|
{
|
|
10651
10746
|
label: "Country",
|
|
@@ -10653,35 +10748,35 @@ You can add it back at any time.`
|
|
|
10653
10748
|
...register("country"),
|
|
10654
10749
|
error: errors.country?.message
|
|
10655
10750
|
}
|
|
10656
|
-
)), /* @__PURE__ */
|
|
10751
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React20__default.default.createElement("label", { className: "flex flex-col gap-2 rounded-2xl border border-slate-200 p-4" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-sm font-semibold text-slate-700" }, "Address type"), /* @__PURE__ */ React20__default.default.createElement(
|
|
10657
10752
|
"select",
|
|
10658
10753
|
{
|
|
10659
10754
|
...register("addressType"),
|
|
10660
10755
|
className: "rounded-xl border border-slate-200 px-3 py-2 text-sm text-slate-700 focus:border-primary-400 focus:outline-none focus:ring-2 focus:ring-primary-500/20"
|
|
10661
10756
|
},
|
|
10662
|
-
/* @__PURE__ */
|
|
10663
|
-
/* @__PURE__ */
|
|
10664
|
-
/* @__PURE__ */
|
|
10665
|
-
)), /* @__PURE__ */
|
|
10757
|
+
/* @__PURE__ */ React20__default.default.createElement("option", { value: "Shipping" }, "Shipping"),
|
|
10758
|
+
/* @__PURE__ */ React20__default.default.createElement("option", { value: "Billing" }, "Billing"),
|
|
10759
|
+
/* @__PURE__ */ React20__default.default.createElement("option", { value: "Both" }, "Billing & Shipping")
|
|
10760
|
+
)), /* @__PURE__ */ React20__default.default.createElement("label", { className: "flex items-center justify-between gap-4 rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm font-medium text-slate-700" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Set as default address"), /* @__PURE__ */ React20__default.default.createElement(
|
|
10666
10761
|
"input",
|
|
10667
10762
|
{
|
|
10668
10763
|
type: "checkbox",
|
|
10669
10764
|
...register("isDefault"),
|
|
10670
10765
|
className: "h-4 w-4 rounded border-primary-300 text-primary-600 focus:ring-primary-500"
|
|
10671
10766
|
}
|
|
10672
|
-
))), /* @__PURE__ */
|
|
10767
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-end gap-3" }, /* @__PURE__ */ React20__default.default.createElement(Button, { type: "button", variant: "outline", onClick: closeModal }, "Cancel"), /* @__PURE__ */ React20__default.default.createElement(Button, { type: "submit", isLoading: isSubmitting }, editingAddress ? "Save changes" : "Save address")))
|
|
10673
10768
|
));
|
|
10674
10769
|
}
|
|
10675
10770
|
function useWishlistProducts(productIds = []) {
|
|
10676
|
-
const [products, setProducts] =
|
|
10677
|
-
const [isLoading, setIsLoading] =
|
|
10678
|
-
const [error, setError] =
|
|
10679
|
-
const [cache] =
|
|
10680
|
-
const uniqueIds =
|
|
10771
|
+
const [products, setProducts] = React20.useState([]);
|
|
10772
|
+
const [isLoading, setIsLoading] = React20.useState(false);
|
|
10773
|
+
const [error, setError] = React20.useState(null);
|
|
10774
|
+
const [cache] = React20.useState(() => /* @__PURE__ */ new Map());
|
|
10775
|
+
const uniqueIds = React20.useMemo(
|
|
10681
10776
|
() => Array.from(new Set((productIds || []).filter(Boolean))),
|
|
10682
10777
|
[productIds]
|
|
10683
10778
|
);
|
|
10684
|
-
const fetchProducts =
|
|
10779
|
+
const fetchProducts = React20.useCallback(async () => {
|
|
10685
10780
|
if (uniqueIds.length === 0) {
|
|
10686
10781
|
setProducts([]);
|
|
10687
10782
|
setIsLoading(false);
|
|
@@ -10709,7 +10804,7 @@ function useWishlistProducts(productIds = []) {
|
|
|
10709
10804
|
setIsLoading(false);
|
|
10710
10805
|
}
|
|
10711
10806
|
}, [cache, uniqueIds]);
|
|
10712
|
-
|
|
10807
|
+
React20.useEffect(() => {
|
|
10713
10808
|
fetchProducts();
|
|
10714
10809
|
}, [fetchProducts]);
|
|
10715
10810
|
return {
|
|
@@ -10728,6 +10823,7 @@ var SORT_OPTIONS = [
|
|
|
10728
10823
|
];
|
|
10729
10824
|
function WishlistScreen() {
|
|
10730
10825
|
const router = navigation.useRouter();
|
|
10826
|
+
const { buildPath } = useBasePath();
|
|
10731
10827
|
const { isAuthenticated } = useAuth() || {};
|
|
10732
10828
|
const {
|
|
10733
10829
|
products: wishlistItems,
|
|
@@ -10740,10 +10836,10 @@ function WishlistScreen() {
|
|
|
10740
10836
|
const { products: wishlistProducts, isLoading, error } = useWishlistProducts(
|
|
10741
10837
|
wishlistItems
|
|
10742
10838
|
);
|
|
10743
|
-
const [onlyInStock, setOnlyInStock] =
|
|
10744
|
-
const [viewMode, setViewMode] =
|
|
10745
|
-
const [sortOption, setSortOption] =
|
|
10746
|
-
|
|
10839
|
+
const [onlyInStock, setOnlyInStock] = React20.useState(false);
|
|
10840
|
+
const [viewMode, setViewMode] = React20.useState("list");
|
|
10841
|
+
const [sortOption, setSortOption] = React20.useState("featured");
|
|
10842
|
+
React20.useEffect(() => {
|
|
10747
10843
|
if (error) {
|
|
10748
10844
|
sonner.toast.error("We had trouble loading your saved products. Please try again.");
|
|
10749
10845
|
}
|
|
@@ -10765,11 +10861,11 @@ function WishlistScreen() {
|
|
|
10765
10861
|
console.error("Error clearing wishlist:", err);
|
|
10766
10862
|
}
|
|
10767
10863
|
};
|
|
10768
|
-
const totalValue =
|
|
10864
|
+
const totalValue = React20.useMemo(
|
|
10769
10865
|
() => wishlistProducts.reduce((sum, product) => sum + (product.finalPrice ?? 0), 0),
|
|
10770
10866
|
[wishlistProducts]
|
|
10771
10867
|
);
|
|
10772
|
-
|
|
10868
|
+
React20.useMemo(
|
|
10773
10869
|
() => wishlistProducts.reduce((sum, product) => {
|
|
10774
10870
|
const before = product.priceBeforeDiscount ?? product.finalPrice ?? 0;
|
|
10775
10871
|
const after = product.finalPrice ?? 0;
|
|
@@ -10778,11 +10874,11 @@ function WishlistScreen() {
|
|
|
10778
10874
|
}, 0),
|
|
10779
10875
|
[wishlistProducts]
|
|
10780
10876
|
);
|
|
10781
|
-
|
|
10877
|
+
React20.useMemo(
|
|
10782
10878
|
() => wishlistProducts.filter((product) => (product.inventoryCount ?? 0) > 0).length,
|
|
10783
10879
|
[wishlistProducts]
|
|
10784
10880
|
);
|
|
10785
|
-
const processedProducts =
|
|
10881
|
+
const processedProducts = React20.useMemo(() => {
|
|
10786
10882
|
let list = [...wishlistProducts];
|
|
10787
10883
|
if (onlyInStock) {
|
|
10788
10884
|
list = list.filter((product) => (product.inventoryCount ?? 0) > 0);
|
|
@@ -10808,14 +10904,14 @@ function WishlistScreen() {
|
|
|
10808
10904
|
return list;
|
|
10809
10905
|
}, [wishlistProducts, onlyInStock, sortOption]);
|
|
10810
10906
|
const emptyAfterFiltering = !isLoading && wishlistProducts.length > 0 && processedProducts.length === 0;
|
|
10811
|
-
return /* @__PURE__ */
|
|
10907
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50 pb-16" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] pb-32 pt-16 text-white" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 opacity-40 mix-blend-soft-light", "aria-hidden": "true" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute -top-1/2 right-1/2 h-[40rem] w-[40rem] rounded-full bg-white/10 blur-3xl" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute left-1/4 top-1/4 h-48 w-48 rounded-full bg-white/20 blur-2xl" })), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "max-w-3xl space-y-6" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-4 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Heart, { className: "h-4 w-4" }), "Wishlist"), /* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold leading-tight md:text-5xl" }, "Curate your pharmacy must-haves in one calming space"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "We keep your favourite products ready for reorder, refill reminders, and quick checkout\u2014exactly when you need them.")))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-20" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10812
10908
|
framerMotion.motion.div,
|
|
10813
10909
|
{
|
|
10814
10910
|
initial: { opacity: 0, y: 24 },
|
|
10815
10911
|
animate: { opacity: 1, y: 0 },
|
|
10816
10912
|
className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-xl shadow-primary-50"
|
|
10817
10913
|
},
|
|
10818
|
-
/* @__PURE__ */
|
|
10914
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-6" }, !isAuthenticated && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex min-h-[40vh] items-center justify-center" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "max-w-lg rounded-3xl border border-slate-100 bg-white p-10 text-center shadow-lg shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-primary-50 text-primary-600" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Heart, { className: "h-8 w-8" })), /* @__PURE__ */ React20__default.default.createElement("h2", { className: "mt-6 text-3xl font-bold text-slate-900" }, "Sign in to see your favourites"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 text-slate-500" }, "Create your curated shelf of products and we'll keep them ready whenever you return."), /* @__PURE__ */ React20__default.default.createElement(Button, { className: "mt-6", onClick: () => router.push(buildPath("/login")) }, "Sign In"))), isAuthenticated && /* @__PURE__ */ React20__default.default.createElement(React20__default.default.Fragment, null, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React20__default.default.createElement("h2", { className: "text-2xl font-semibold text-slate-900" }, "Your saved collection"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-500" }, "Total value: ", /* @__PURE__ */ React20__default.default.createElement("span", { className: "font-semibold text-primary-600" }, formatPrice(totalValue)), onlyInStock && " \u2022 Showing items ready to ship")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement("label", { className: "inline-flex cursor-pointer items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-1.5 text-sm font-medium text-slate-600 transition hover:border-primary-200 hover:text-primary-600" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10819
10915
|
"input",
|
|
10820
10916
|
{
|
|
10821
10917
|
type: "checkbox",
|
|
@@ -10823,54 +10919,54 @@ function WishlistScreen() {
|
|
|
10823
10919
|
onChange: (event) => setOnlyInStock(event.target.checked),
|
|
10824
10920
|
className: "h-4 w-4 rounded border-slate-300 text-primary-600 focus:ring-primary-500"
|
|
10825
10921
|
}
|
|
10826
|
-
), "Only show in-stock"), /* @__PURE__ */
|
|
10922
|
+
), "Only show in-stock"), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-1.5 text-sm text-slate-600" }, /* @__PURE__ */ React20__default.default.createElement("span", null, "Sort"), /* @__PURE__ */ React20__default.default.createElement(
|
|
10827
10923
|
"select",
|
|
10828
10924
|
{
|
|
10829
10925
|
value: sortOption,
|
|
10830
10926
|
onChange: (event) => setSortOption(event.target.value),
|
|
10831
10927
|
className: "bg-transparent text-sm font-medium text-slate-700 outline-none"
|
|
10832
10928
|
},
|
|
10833
|
-
SORT_OPTIONS.map((option) => /* @__PURE__ */
|
|
10834
|
-
)), /* @__PURE__ */
|
|
10929
|
+
SORT_OPTIONS.map((option) => /* @__PURE__ */ React20__default.default.createElement("option", { key: option.value, value: option.value }, option.label))
|
|
10930
|
+
)), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex overflow-hidden rounded-full border border-slate-200 bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10835
10931
|
"button",
|
|
10836
10932
|
{
|
|
10837
10933
|
type: "button",
|
|
10838
10934
|
onClick: () => setViewMode("grid"),
|
|
10839
10935
|
className: `flex items-center gap-1 px-3 py-1.5 text-sm font-medium transition ${viewMode === "grid" ? "bg-primary-600 text-white shadow-lg shadow-primary-500/30" : "text-slate-600 hover:bg-white"}`
|
|
10840
10936
|
},
|
|
10841
|
-
/* @__PURE__ */
|
|
10937
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Grid, { className: "h-4 w-4" }),
|
|
10842
10938
|
"Grid"
|
|
10843
|
-
), /* @__PURE__ */
|
|
10939
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10844
10940
|
"button",
|
|
10845
10941
|
{
|
|
10846
10942
|
type: "button",
|
|
10847
10943
|
onClick: () => setViewMode("list"),
|
|
10848
10944
|
className: `flex items-center gap-1 px-3 py-1.5 text-sm font-medium transition ${viewMode === "list" ? "bg-primary-600 text-white shadow-lg shadow-primary-500/30" : "text-slate-600 hover:bg-white"}`
|
|
10849
10945
|
},
|
|
10850
|
-
/* @__PURE__ */
|
|
10946
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.List, { className: "h-4 w-4" }),
|
|
10851
10947
|
"List"
|
|
10852
|
-
)), wishlistCount > 0 && /* @__PURE__ */
|
|
10948
|
+
)), wishlistCount > 0 && /* @__PURE__ */ React20__default.default.createElement(
|
|
10853
10949
|
Button,
|
|
10854
10950
|
{
|
|
10855
10951
|
variant: "ghost",
|
|
10856
10952
|
className: "text-sm font-semibold text-slate-500 hover:text-red-500",
|
|
10857
10953
|
onClick: handleClearWishlist
|
|
10858
10954
|
},
|
|
10859
|
-
/* @__PURE__ */
|
|
10955
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Trash2, { className: "h-4 w-4" }),
|
|
10860
10956
|
"Clear all"
|
|
10861
|
-
))), isLoading && /* @__PURE__ */
|
|
10957
|
+
))), isLoading && /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3" }, Array.from({ length: Math.min(wishlistCount || 3, 6) }).map((_, index) => /* @__PURE__ */ React20__default.default.createElement(
|
|
10862
10958
|
"div",
|
|
10863
10959
|
{
|
|
10864
10960
|
key: index,
|
|
10865
10961
|
className: "h-72 animate-pulse rounded-2xl border border-slate-200 bg-slate-100"
|
|
10866
10962
|
}
|
|
10867
|
-
))), !isLoading && wishlistCount === 0 && /* @__PURE__ */
|
|
10963
|
+
))), !isLoading && wishlistCount === 0 && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex min-h-[30vh] items-center justify-center" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "max-w-2xl rounded-3xl border border-slate-100 bg-white p-12 text-center shadow-xl shadow-primary-50" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "mx-auto flex h-20 w-20 items-center justify-center rounded-full bg-primary-100 text-primary-600" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-10 w-10" })), /* @__PURE__ */ React20__default.default.createElement("h2", { className: "mt-6 text-4xl font-bold text-slate-900" }, "Start your wellness wishlist"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-4 text-lg text-slate-500" }, "Bookmark pharmacy essentials, supplements, or skincare picks and we'll keep them safe until you're ready to checkout."), /* @__PURE__ */ React20__default.default.createElement("div", { className: "mt-8 flex flex-wrap justify-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(Button, { onClick: () => router.push(buildPath("/shop")) }, "Discover products"), /* @__PURE__ */ React20__default.default.createElement(Button, { variant: "outline", onClick: () => router.push(buildPath("/categories")) }, "Browse categories")))), !isLoading && processedProducts.length > 0 && /* @__PURE__ */ React20__default.default.createElement(React20__default.default.Fragment, null, viewMode === "grid" ? /* @__PURE__ */ React20__default.default.createElement(
|
|
10868
10964
|
framerMotion.motion.div,
|
|
10869
10965
|
{
|
|
10870
10966
|
layout: true,
|
|
10871
10967
|
className: "grid grid-cols-1 gap-5 sm:grid-cols-2 xl:grid-cols-3"
|
|
10872
10968
|
},
|
|
10873
|
-
/* @__PURE__ */
|
|
10969
|
+
/* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, processedProducts.map((product) => /* @__PURE__ */ React20__default.default.createElement(
|
|
10874
10970
|
framerMotion.motion.div,
|
|
10875
10971
|
{
|
|
10876
10972
|
key: product.id,
|
|
@@ -10880,17 +10976,17 @@ function WishlistScreen() {
|
|
|
10880
10976
|
exit: { opacity: 0, y: -20 },
|
|
10881
10977
|
transition: { duration: 0.2 }
|
|
10882
10978
|
},
|
|
10883
|
-
/* @__PURE__ */
|
|
10979
|
+
/* @__PURE__ */ React20__default.default.createElement(
|
|
10884
10980
|
ProductCard,
|
|
10885
10981
|
{
|
|
10886
10982
|
product,
|
|
10887
|
-
onClickProduct: (p) => router.push(`/products/${p.id}`),
|
|
10983
|
+
onClickProduct: (p) => router.push(buildPath(`/products/${p.id}`)),
|
|
10888
10984
|
onFavorite: () => handleRemoveFromWishlist(product.id),
|
|
10889
10985
|
isFavorited: true
|
|
10890
10986
|
}
|
|
10891
10987
|
)
|
|
10892
10988
|
)))
|
|
10893
|
-
) : /* @__PURE__ */
|
|
10989
|
+
) : /* @__PURE__ */ React20__default.default.createElement(framerMotion.motion.div, { layout: true, className: "space-y-4" }, /* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, processedProducts.map((product) => /* @__PURE__ */ React20__default.default.createElement(
|
|
10894
10990
|
framerMotion.motion.div,
|
|
10895
10991
|
{
|
|
10896
10992
|
key: product.id,
|
|
@@ -10901,7 +10997,7 @@ function WishlistScreen() {
|
|
|
10901
10997
|
transition: { duration: 0.2 },
|
|
10902
10998
|
className: "flex flex-col gap-4 rounded-2xl border border-slate-100 bg-slate-50 p-4 shadow-sm shadow-primary-50 sm:flex-row sm:items-center"
|
|
10903
10999
|
},
|
|
10904
|
-
/* @__PURE__ */
|
|
11000
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative h-28 w-full overflow-hidden rounded-2xl bg-white sm:w-40" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10905
11001
|
Image3__default.default,
|
|
10906
11002
|
{
|
|
10907
11003
|
fill: true,
|
|
@@ -10910,14 +11006,14 @@ function WishlistScreen() {
|
|
|
10910
11006
|
className: "h-full w-full object-cover"
|
|
10911
11007
|
}
|
|
10912
11008
|
)),
|
|
10913
|
-
/* @__PURE__ */
|
|
11009
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-1 flex-col gap-2" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-slate-900" }, product.name), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm text-slate-500" }, product.parentCategories?.map((category) => category?.name).join(", ") || "General wellness")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "text-right" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-lg font-bold text-primary-600" }, formatPrice(product.finalPrice ?? 0)), product.isDiscounted && /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-xs text-emerald-500" }, "You save ", formatPrice(Math.max((product.priceBeforeDiscount ?? 0) - (product.finalPrice ?? 0), 0))))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap items-center gap-3 text-xs text-slate-500" }, /* @__PURE__ */ React20__default.default.createElement("span", { className: `inline-flex items-center gap-1 rounded-full px-2.5 py-1 font-medium ${product.inventoryCount > 0 ? "bg-emerald-100 text-emerald-700" : "bg-rose-100 text-rose-700"}` }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Package, { className: "h-3.5 w-3.5" }), product.inventoryCount > 0 ? "In stock" : "Backordered"), product.totalSold > 0 && /* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-1 rounded-full bg-slate-200 px-2.5 py-1 font-medium text-slate-700" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-3.5 w-3.5" }), product.totalSold, "+ purchased")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
10914
11010
|
Button,
|
|
10915
11011
|
{
|
|
10916
11012
|
size: "sm",
|
|
10917
|
-
onClick: () => router.push(`/products/${product.id}`)
|
|
11013
|
+
onClick: () => router.push(buildPath(`/products/${product.id}`))
|
|
10918
11014
|
},
|
|
10919
11015
|
"View details"
|
|
10920
|
-
), /* @__PURE__ */
|
|
11016
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
10921
11017
|
Button,
|
|
10922
11018
|
{
|
|
10923
11019
|
size: "sm",
|
|
@@ -10927,19 +11023,20 @@ function WishlistScreen() {
|
|
|
10927
11023
|
},
|
|
10928
11024
|
"Remove"
|
|
10929
11025
|
)))
|
|
10930
|
-
))))), isAuthenticated && emptyAfterFiltering && /* @__PURE__ */
|
|
11026
|
+
))))), isAuthenticated && emptyAfterFiltering && /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col items-center justify-center rounded-2xl border border-dashed border-slate-200 bg-slate-50 p-12 text-center" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-slate-200 text-slate-500" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Package, { className: "h-8 w-8" })), /* @__PURE__ */ React20__default.default.createElement("h3", { className: "mt-6 text-2xl font-semibold text-slate-900" }, "Nothing matches those filters"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-2 max-w-md text-sm text-slate-500" }, "Try showing out-of-stock items or adjust your sort order to revisit everything you\u2019ve saved."), /* @__PURE__ */ React20__default.default.createElement(Button, { className: "mt-6", variant: "outline", onClick: () => setOnlyInStock(false) }, "Show all saved products"))))
|
|
10931
11027
|
))));
|
|
10932
11028
|
}
|
|
10933
11029
|
function SearchPage() {
|
|
10934
11030
|
const router = navigation.useRouter();
|
|
11031
|
+
const { buildPath } = useBasePath();
|
|
10935
11032
|
const searchParams = navigation.useSearchParams();
|
|
10936
11033
|
const searchQuery = searchParams.get("q") || "";
|
|
10937
|
-
const [products, setProducts] =
|
|
10938
|
-
const [isLoading, setIsLoading] =
|
|
10939
|
-
const [searchInput, setSearchInput] =
|
|
10940
|
-
const [hasSearched, setHasSearched] =
|
|
11034
|
+
const [products, setProducts] = React20.useState([]);
|
|
11035
|
+
const [isLoading, setIsLoading] = React20.useState(true);
|
|
11036
|
+
const [searchInput, setSearchInput] = React20.useState(searchQuery);
|
|
11037
|
+
const [hasSearched, setHasSearched] = React20.useState(false);
|
|
10941
11038
|
const { isInWishlist } = useWishlist();
|
|
10942
|
-
|
|
11039
|
+
React20.useEffect(() => {
|
|
10943
11040
|
const fetchSearchResults = async () => {
|
|
10944
11041
|
if (!searchQuery.trim()) {
|
|
10945
11042
|
setProducts([]);
|
|
@@ -11032,38 +11129,39 @@ function SearchPage() {
|
|
|
11032
11129
|
{
|
|
11033
11130
|
product,
|
|
11034
11131
|
isFavorited: isInWishlist(product.id),
|
|
11035
|
-
onClickProduct: (p) => router.push(`/products/${p.id}`)
|
|
11132
|
+
onClickProduct: (p) => router.push(buildPath(`/products/${p.id}`))
|
|
11036
11133
|
}
|
|
11037
11134
|
))) : hasSearched ? /* @__PURE__ */ React.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React.createElement("div", { className: "text-gray-500 text-lg mb-4" }, 'No products found for "', searchQuery, '"'), /* @__PURE__ */ React.createElement("p", { className: "text-gray-500 mb-6" }, "Try different keywords or check out our", " ", /* @__PURE__ */ React.createElement(Link8__default.default, { href: "/shop", className: "text-primary-600 hover:underline ml-1 font-medium" }, "featured products"))) : /* @__PURE__ */ React.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React.createElement("p", { className: "text-gray-500" }, "Enter a search term to find products"))));
|
|
11038
11135
|
}
|
|
11039
11136
|
function CategoriesScreen() {
|
|
11040
11137
|
const { categories, isLoading } = useCategories();
|
|
11041
11138
|
const router = navigation.useRouter();
|
|
11042
|
-
|
|
11139
|
+
const { buildPath } = useBasePath();
|
|
11140
|
+
return /* @__PURE__ */ React20__default.default.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React20__default.default.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white mb-8" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11043
11141
|
framerMotion.motion.div,
|
|
11044
11142
|
{
|
|
11045
11143
|
initial: { opacity: 0, y: 24 },
|
|
11046
11144
|
animate: { opacity: 1, y: 0 },
|
|
11047
11145
|
className: "space-y-6"
|
|
11048
11146
|
},
|
|
11049
|
-
/* @__PURE__ */
|
|
11050
|
-
/* @__PURE__ */
|
|
11051
|
-
))), /* @__PURE__ */
|
|
11147
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Package, { className: "h-4 w-4" }), "Product Categories"),
|
|
11148
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React20__default.default.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Browse Our Product Range"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "Explore our comprehensive selection of healthcare products, carefully curated by our pharmacists to meet all your wellness needs.")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "rounded-3xl bg-white/15 p-6 backdrop-blur" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.35em] text-white/70" }, "Quick tip"), /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-3 text-sm text-white/80" }, "Use the categories below to quickly find the products you're looking for, or use the search function for specific items.")))
|
|
11149
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative -mt-16 pb-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11052
11150
|
framerMotion.motion.div,
|
|
11053
11151
|
{
|
|
11054
11152
|
initial: { opacity: 0, y: 24 },
|
|
11055
11153
|
animate: { opacity: 1, y: 0 },
|
|
11056
11154
|
className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50"
|
|
11057
11155
|
},
|
|
11058
|
-
/* @__PURE__ */
|
|
11059
|
-
isLoading ? /* @__PURE__ */
|
|
11156
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3 text-sm text-slate-500 mb-6" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Sparkles, { className: "h-4 w-4 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "Browse our complete product catalog organized by categories.")),
|
|
11157
|
+
isLoading ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6" }, [...Array(8)].map((_, i) => /* @__PURE__ */ React20__default.default.createElement("div", { key: i, className: "animate-pulse" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "bg-gray-200 rounded-lg aspect-square mb-2" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-4 bg-gray-200 rounded w-3/4 mb-1" }), /* @__PURE__ */ React20__default.default.createElement("div", { className: "h-3 bg-gray-200 rounded w-1/2" })))) : categories.length > 0 ? /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6" }, categories.map((category) => /* @__PURE__ */ React20__default.default.createElement(
|
|
11060
11158
|
Link8__default.default,
|
|
11061
11159
|
{
|
|
11062
11160
|
key: category.id,
|
|
11063
|
-
href: `/shop?category=${category.name}
|
|
11161
|
+
href: buildPath(`/shop?category=${category.name}`),
|
|
11064
11162
|
className: "group block overflow-hidden rounded-xl border border-gray-100 bg-white p-4 text-center transition hover:shadow-lg hover:border-primary-500"
|
|
11065
11163
|
},
|
|
11066
|
-
/* @__PURE__ */
|
|
11164
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "relative aspect-square w-full overflow-hidden rounded-lg bg-gray-50 mb-3" }, category.image ? /* @__PURE__ */ React20__default.default.createElement(
|
|
11067
11165
|
Image3__default.default,
|
|
11068
11166
|
{
|
|
11069
11167
|
src: category.image,
|
|
@@ -11072,24 +11170,24 @@ function CategoriesScreen() {
|
|
|
11072
11170
|
className: "object-cover transition-transform group-hover:scale-105",
|
|
11073
11171
|
sizes: "(max-width: 768px) 50vw, (max-width: 1200px) 33vw, 25vw"
|
|
11074
11172
|
}
|
|
11075
|
-
) : /* @__PURE__ */
|
|
11076
|
-
/* @__PURE__ */
|
|
11077
|
-
category.productCount > 0 && /* @__PURE__ */
|
|
11078
|
-
))) : /* @__PURE__ */
|
|
11173
|
+
) : /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex h-full w-full items-center justify-center bg-gray-100 text-gray-400" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Package, { className: "h-12 w-12" }))),
|
|
11174
|
+
/* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-900 group-hover:text-primary-600 transition-colors" }, category.name),
|
|
11175
|
+
category.productCount > 0 && /* @__PURE__ */ React20__default.default.createElement("p", { className: "mt-1 text-sm text-gray-500" }, category.productCount, " ", category.productCount === 1 ? "product" : "products")
|
|
11176
|
+
))) : /* @__PURE__ */ React20__default.default.createElement(
|
|
11079
11177
|
EmptyState,
|
|
11080
11178
|
{
|
|
11081
11179
|
title: "No categories found",
|
|
11082
11180
|
description: "There are currently no product categories available.",
|
|
11083
11181
|
icon: lucideReact.Package,
|
|
11084
11182
|
actionLabel: "Shop products",
|
|
11085
|
-
onAction: () => router.push("/shop")
|
|
11183
|
+
onAction: () => router.push(buildPath("/shop"))
|
|
11086
11184
|
}
|
|
11087
11185
|
)
|
|
11088
11186
|
))));
|
|
11089
11187
|
}
|
|
11090
11188
|
function NewAddressPage() {
|
|
11091
11189
|
const router = navigation.useRouter();
|
|
11092
|
-
const [isSubmitting, setIsSubmitting] =
|
|
11190
|
+
const [isSubmitting, setIsSubmitting] = React20.useState(false);
|
|
11093
11191
|
const {
|
|
11094
11192
|
register,
|
|
11095
11193
|
handleSubmit,
|
|
@@ -11231,17 +11329,18 @@ function Header() {
|
|
|
11231
11329
|
const { cart } = useCart() || { cart: { } };
|
|
11232
11330
|
const { getWishlistCount } = useWishlist();
|
|
11233
11331
|
const wishlistCount = getWishlistCount?.() || 0;
|
|
11234
|
-
const [isMobileMenuOpen, setIsMobileMenuOpen] =
|
|
11235
|
-
const [isSearchOpen, setIsSearchOpen] =
|
|
11236
|
-
const [searchQuery, setSearchQuery] =
|
|
11332
|
+
const [isMobileMenuOpen, setIsMobileMenuOpen] = React20.useState(false);
|
|
11333
|
+
const [isSearchOpen, setIsSearchOpen] = React20.useState(false);
|
|
11334
|
+
const [searchQuery, setSearchQuery] = React20.useState("");
|
|
11335
|
+
const { buildPath } = useBasePath();
|
|
11237
11336
|
const navLinks = [
|
|
11238
|
-
{ href: "/shop", label: "Shop" },
|
|
11239
|
-
{ href: "/categories", label: "Categories" },
|
|
11240
|
-
{ href: "/orders", label: "Orders" },
|
|
11241
|
-
{ href: "/about", label: "About" },
|
|
11242
|
-
{ href: "/contact", label: "Contact" }
|
|
11337
|
+
{ href: buildPath("/shop"), label: "Shop" },
|
|
11338
|
+
{ href: buildPath("/categories"), label: "Categories" },
|
|
11339
|
+
{ href: buildPath("/orders"), label: "Orders" },
|
|
11340
|
+
{ href: buildPath("/about"), label: "About" },
|
|
11341
|
+
{ href: buildPath("/contact"), label: "Contact" }
|
|
11243
11342
|
];
|
|
11244
|
-
return /* @__PURE__ */
|
|
11343
|
+
return /* @__PURE__ */ React20__default.default.createElement("header", { className: "sticky top-0 z-40 bg-white/80 backdrop-blur-xl border-b border-gray-200 shadow-sm" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center justify-between h-20" }, /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: buildPath("/"), className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative w-12 h-12" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11245
11344
|
Image3__default.default,
|
|
11246
11345
|
{
|
|
11247
11346
|
src: config.logo,
|
|
@@ -11249,7 +11348,7 @@ function Header() {
|
|
|
11249
11348
|
fill: true,
|
|
11250
11349
|
className: "object-contain"
|
|
11251
11350
|
}
|
|
11252
|
-
)), /* @__PURE__ */
|
|
11351
|
+
)), /* @__PURE__ */ React20__default.default.createElement("span", { className: "text-2xl font-bold text-gray-900 hidden sm:block" }, config.storeName)), /* @__PURE__ */ React20__default.default.createElement("nav", { className: "hidden lg:flex items-center gap-8" }, navLinks.map((link) => /* @__PURE__ */ React20__default.default.createElement(
|
|
11253
11352
|
Link8__default.default,
|
|
11254
11353
|
{
|
|
11255
11354
|
key: link.href,
|
|
@@ -11257,16 +11356,16 @@ function Header() {
|
|
|
11257
11356
|
className: "text-gray-700 hover:text-primary-600 font-medium transition-colors relative group"
|
|
11258
11357
|
},
|
|
11259
11358
|
link.label,
|
|
11260
|
-
/* @__PURE__ */
|
|
11261
|
-
))), /* @__PURE__ */
|
|
11359
|
+
/* @__PURE__ */ React20__default.default.createElement("span", { className: "absolute bottom-0 left-0 w-0 h-0.5 bg-primary-600 group-hover:w-full transition-all duration-300" })
|
|
11360
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11262
11361
|
"button",
|
|
11263
11362
|
{
|
|
11264
11363
|
onClick: () => setIsSearchOpen(!isSearchOpen),
|
|
11265
11364
|
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
11266
11365
|
"aria-label": "Search"
|
|
11267
11366
|
},
|
|
11268
|
-
/* @__PURE__ */
|
|
11269
|
-
), /* @__PURE__ */
|
|
11367
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Search, { className: "w-5 h-5 text-gray-700" })
|
|
11368
|
+
), /* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, isSearchOpen && /* @__PURE__ */ React20__default.default.createElement(
|
|
11270
11369
|
framerMotion.motion.div,
|
|
11271
11370
|
{
|
|
11272
11371
|
initial: { opacity: 0, width: 0 },
|
|
@@ -11274,7 +11373,7 @@ function Header() {
|
|
|
11274
11373
|
exit: { opacity: 0, width: 0 },
|
|
11275
11374
|
className: "absolute right-0 top-full mt-2 bg-white rounded-lg shadow-lg overflow-hidden"
|
|
11276
11375
|
},
|
|
11277
|
-
/* @__PURE__ */
|
|
11376
|
+
/* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center p-2 w-64" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Search, { className: "w-5 h-5 text-gray-400 mr-2" }), /* @__PURE__ */ React20__default.default.createElement(
|
|
11278
11377
|
"input",
|
|
11279
11378
|
{
|
|
11280
11379
|
type: "text",
|
|
@@ -11282,43 +11381,43 @@ function Header() {
|
|
|
11282
11381
|
onChange: (e) => setSearchQuery(e.target.value),
|
|
11283
11382
|
onKeyDown: (e) => {
|
|
11284
11383
|
if (e.key === "Enter" && searchQuery.trim()) {
|
|
11285
|
-
window.location.href = `/search?q=${encodeURIComponent(searchQuery.trim())}
|
|
11384
|
+
window.location.href = buildPath(`/search?q=${encodeURIComponent(searchQuery.trim())}`);
|
|
11286
11385
|
}
|
|
11287
11386
|
},
|
|
11288
11387
|
placeholder: "Search products...",
|
|
11289
11388
|
className: "w-full outline-none text-gray-700",
|
|
11290
11389
|
autoFocus: true
|
|
11291
11390
|
}
|
|
11292
|
-
), searchQuery && /* @__PURE__ */
|
|
11391
|
+
), searchQuery && /* @__PURE__ */ React20__default.default.createElement(
|
|
11293
11392
|
"button",
|
|
11294
11393
|
{
|
|
11295
11394
|
onClick: () => setSearchQuery(""),
|
|
11296
11395
|
className: "text-gray-400 hover:text-gray-600"
|
|
11297
11396
|
},
|
|
11298
|
-
/* @__PURE__ */
|
|
11397
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.X, { className: "w-4 h-4" })
|
|
11299
11398
|
))
|
|
11300
|
-
))), /* @__PURE__ */
|
|
11399
|
+
))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: buildPath("/wishlist"), className: "relative p-2 text-gray-700 hover:text-red-500 transition-colors" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Heart, { className: "w-6 h-6" }), wishlistCount > 0 && /* @__PURE__ */ React20__default.default.createElement("span", { className: "absolute -top-1 -right-1 bg-red-500 text-white text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center" }, wishlistCount)), /* @__PURE__ */ React20__default.default.createElement(Link8__default.default, { href: buildPath("/cart"), className: "relative p-2 text-gray-700 hover:text-primary-600 transition-colors" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.ShoppingCart, { className: "w-6 h-6" }), cart?.cartBody?.items?.length && cart.cartBody?.items?.length > 0 ? /* @__PURE__ */ React20__default.default.createElement("span", { className: "absolute -top-1 -right-1 bg-red-500 text-white text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center" }, cart.cartBody?.items?.length) : null), isAuthenticated ? /* @__PURE__ */ React20__default.default.createElement(
|
|
11301
11400
|
Link8__default.default,
|
|
11302
11401
|
{
|
|
11303
|
-
href: "/account",
|
|
11402
|
+
href: buildPath("/account"),
|
|
11304
11403
|
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors"
|
|
11305
11404
|
},
|
|
11306
|
-
/* @__PURE__ */
|
|
11307
|
-
) : /* @__PURE__ */
|
|
11405
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.User, { className: "w-6 h-6 text-gray-700" })
|
|
11406
|
+
) : /* @__PURE__ */ React20__default.default.createElement(
|
|
11308
11407
|
Link8__default.default,
|
|
11309
11408
|
{
|
|
11310
|
-
href: "/login",
|
|
11409
|
+
href: buildPath("/login"),
|
|
11311
11410
|
className: "hidden sm:block px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium"
|
|
11312
11411
|
},
|
|
11313
11412
|
"Sign In"
|
|
11314
|
-
)), /* @__PURE__ */
|
|
11413
|
+
)), /* @__PURE__ */ React20__default.default.createElement(
|
|
11315
11414
|
"button",
|
|
11316
11415
|
{
|
|
11317
11416
|
className: "lg:hidden p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
11318
11417
|
onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen)
|
|
11319
11418
|
},
|
|
11320
|
-
isMobileMenuOpen ? /* @__PURE__ */
|
|
11321
|
-
)), /* @__PURE__ */
|
|
11419
|
+
isMobileMenuOpen ? /* @__PURE__ */ React20__default.default.createElement(lucideReact.X, { className: "w-6 h-6" }) : /* @__PURE__ */ React20__default.default.createElement(lucideReact.Menu, { className: "w-6 h-6" })
|
|
11420
|
+
)), /* @__PURE__ */ React20__default.default.createElement(framerMotion.AnimatePresence, null, isMobileMenuOpen && /* @__PURE__ */ React20__default.default.createElement(
|
|
11322
11421
|
framerMotion.motion.div,
|
|
11323
11422
|
{
|
|
11324
11423
|
initial: { opacity: 0, height: 0 },
|
|
@@ -11326,7 +11425,7 @@ function Header() {
|
|
|
11326
11425
|
exit: { opacity: 0, height: 0 },
|
|
11327
11426
|
className: "lg:hidden overflow-hidden border-t border-gray-200"
|
|
11328
11427
|
},
|
|
11329
|
-
/* @__PURE__ */
|
|
11428
|
+
/* @__PURE__ */ React20__default.default.createElement("nav", { className: "flex flex-col gap-1 py-2" }, navLinks.map((link) => /* @__PURE__ */ React20__default.default.createElement(
|
|
11330
11429
|
Link8__default.default,
|
|
11331
11430
|
{
|
|
11332
11431
|
key: link.href,
|
|
@@ -11335,10 +11434,10 @@ function Header() {
|
|
|
11335
11434
|
onClick: () => setIsMobileMenuOpen(false)
|
|
11336
11435
|
},
|
|
11337
11436
|
link.label
|
|
11338
|
-
)), !isAuthenticated && /* @__PURE__ */
|
|
11437
|
+
)), !isAuthenticated && /* @__PURE__ */ React20__default.default.createElement(
|
|
11339
11438
|
Link8__default.default,
|
|
11340
11439
|
{
|
|
11341
|
-
href: "/login",
|
|
11440
|
+
href: buildPath("/login"),
|
|
11342
11441
|
onClick: () => setIsMobileMenuOpen(false),
|
|
11343
11442
|
className: "px-4 py-3 text-primary-600 hover:bg-gray-50 rounded-lg font-medium"
|
|
11344
11443
|
},
|
|
@@ -11348,67 +11447,74 @@ function Header() {
|
|
|
11348
11447
|
}
|
|
11349
11448
|
function Footer() {
|
|
11350
11449
|
const { config } = useTheme();
|
|
11450
|
+
const { buildPath } = useBasePath();
|
|
11351
11451
|
const footerLinks = {
|
|
11352
11452
|
shop: [
|
|
11353
|
-
{ label: "All Products", href: "/shop" },
|
|
11354
|
-
{ label: "Categories", href: "/categories" },
|
|
11355
|
-
{ label: "Featured", href: "/featured" },
|
|
11356
|
-
{ label: "New Arrivals", href: "/new" }
|
|
11453
|
+
{ label: "All Products", href: buildPath("/shop") },
|
|
11454
|
+
{ label: "Categories", href: buildPath("/categories") },
|
|
11455
|
+
{ label: "Featured", href: buildPath("/featured") },
|
|
11456
|
+
{ label: "New Arrivals", href: buildPath("/new") }
|
|
11357
11457
|
],
|
|
11358
11458
|
account: [
|
|
11359
|
-
{ label: "My Account", href: "/account" },
|
|
11360
|
-
{ label: "Orders", href: "/orders" },
|
|
11361
|
-
{ label: "Wishlist", href: "/wishlist" },
|
|
11362
|
-
{ label: "Cart", href: "/cart" }
|
|
11459
|
+
{ label: "My Account", href: buildPath("/account") },
|
|
11460
|
+
{ label: "Orders", href: buildPath("/orders") },
|
|
11461
|
+
{ label: "Wishlist", href: buildPath("/wishlist") },
|
|
11462
|
+
{ label: "Cart", href: buildPath("/cart") }
|
|
11363
11463
|
],
|
|
11364
11464
|
support: [
|
|
11365
|
-
{ label: "Contact Us", href: "/contact" },
|
|
11366
|
-
{ label: "FAQs", href: "/faqs" },
|
|
11367
|
-
{ label: "Shipping Info", href: "/shipping" },
|
|
11368
|
-
{ label: "Returns", href: "/returns" }
|
|
11369
|
-
]
|
|
11370
|
-
|
|
11465
|
+
{ label: "Contact Us", href: buildPath("/contact") },
|
|
11466
|
+
{ label: "FAQs", href: buildPath("/faqs") },
|
|
11467
|
+
{ label: "Shipping Info", href: buildPath("/shipping") },
|
|
11468
|
+
{ label: "Returns", href: buildPath("/returns") }
|
|
11469
|
+
],
|
|
11470
|
+
legal: [
|
|
11471
|
+
{ label: "Privacy Policy", href: buildPath("/privacy") },
|
|
11472
|
+
{ label: "Terms of Service", href: buildPath("/terms") },
|
|
11473
|
+
{ label: "Cookie Policy", href: buildPath("/cookies") }
|
|
11474
|
+
]
|
|
11475
|
+
};
|
|
11476
|
+
return /* @__PURE__ */ React20__default.default.createElement("footer", { className: "bg-gray-900 text-gray-300" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "container mx-auto px-4 py-16" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-12" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "lg:col-span-2" }, /* @__PURE__ */ React20__default.default.createElement("h3", { className: "text-2xl font-bold text-white mb-4" }, config.storeName), /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-gray-400 mb-6 max-w-md" }, "Your trusted online store for quality products. We deliver excellence with every order."), /* @__PURE__ */ React20__default.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Mail, { className: "w-5 h-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "support@", config.storeName.toLowerCase().replace(/\s+/g, ""), ".com")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.Phone, { className: "w-5 h-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "+1 (555) 123-4567")), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React20__default.default.createElement(lucideReact.MapPin, { className: "w-5 h-5 text-primary-500" }), /* @__PURE__ */ React20__default.default.createElement("span", null, "123 Store Street, City, Country")))), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h4", { className: "text-lg font-semibold text-white mb-4" }, "Shop"), /* @__PURE__ */ React20__default.default.createElement("ul", { className: "space-y-2" }, footerLinks.shop.map((link) => /* @__PURE__ */ React20__default.default.createElement("li", { key: link.href }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11371
11477
|
Link8__default.default,
|
|
11372
11478
|
{
|
|
11373
11479
|
href: link.href,
|
|
11374
11480
|
className: "hover:text-primary-500 transition-colors"
|
|
11375
11481
|
},
|
|
11376
11482
|
link.label
|
|
11377
|
-
))))), /* @__PURE__ */
|
|
11483
|
+
))))), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h4", { className: "text-lg font-semibold text-white mb-4" }, "Account"), /* @__PURE__ */ React20__default.default.createElement("ul", { className: "space-y-2" }, footerLinks.account.map((link) => /* @__PURE__ */ React20__default.default.createElement("li", { key: link.href }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11378
11484
|
Link8__default.default,
|
|
11379
11485
|
{
|
|
11380
11486
|
href: link.href,
|
|
11381
11487
|
className: "hover:text-primary-500 transition-colors"
|
|
11382
11488
|
},
|
|
11383
11489
|
link.label
|
|
11384
|
-
))))), /* @__PURE__ */
|
|
11490
|
+
))))), /* @__PURE__ */ React20__default.default.createElement("div", null, /* @__PURE__ */ React20__default.default.createElement("h4", { className: "text-lg font-semibold text-white mb-4" }, "Support"), /* @__PURE__ */ React20__default.default.createElement("ul", { className: "space-y-2" }, footerLinks.support.map((link) => /* @__PURE__ */ React20__default.default.createElement("li", { key: link.href }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11385
11491
|
Link8__default.default,
|
|
11386
11492
|
{
|
|
11387
11493
|
href: link.href,
|
|
11388
11494
|
className: "hover:text-primary-500 transition-colors"
|
|
11389
11495
|
},
|
|
11390
11496
|
link.label
|
|
11391
|
-
)))))), /* @__PURE__ */
|
|
11497
|
+
)))))), /* @__PURE__ */ React20__default.default.createElement("div", { className: "border-t border-gray-800 mt-12 pt-8 flex flex-col md:flex-row justify-between items-center gap-4" }, /* @__PURE__ */ React20__default.default.createElement("p", { className: "text-gray-400 text-sm" }, "\xA9 ", (/* @__PURE__ */ new Date()).getFullYear(), " ", config.storeName, ". All rights reserved."), /* @__PURE__ */ React20__default.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React20__default.default.createElement(
|
|
11392
11498
|
"a",
|
|
11393
11499
|
{
|
|
11394
11500
|
href: "#",
|
|
11395
11501
|
className: "w-10 h-10 bg-gray-800 hover:bg-primary-600 rounded-full flex items-center justify-center transition-colors"
|
|
11396
11502
|
},
|
|
11397
|
-
/* @__PURE__ */
|
|
11398
|
-
), /* @__PURE__ */
|
|
11503
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Facebook, { className: "w-5 h-5" })
|
|
11504
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
11399
11505
|
"a",
|
|
11400
11506
|
{
|
|
11401
11507
|
href: "#",
|
|
11402
11508
|
className: "w-10 h-10 bg-gray-800 hover:bg-primary-600 rounded-full flex items-center justify-center transition-colors"
|
|
11403
11509
|
},
|
|
11404
|
-
/* @__PURE__ */
|
|
11405
|
-
), /* @__PURE__ */
|
|
11510
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Twitter, { className: "w-5 h-5" })
|
|
11511
|
+
), /* @__PURE__ */ React20__default.default.createElement(
|
|
11406
11512
|
"a",
|
|
11407
11513
|
{
|
|
11408
11514
|
href: "#",
|
|
11409
11515
|
className: "w-10 h-10 bg-gray-800 hover:bg-primary-600 rounded-full flex items-center justify-center transition-colors"
|
|
11410
11516
|
},
|
|
11411
|
-
/* @__PURE__ */
|
|
11517
|
+
/* @__PURE__ */ React20__default.default.createElement(lucideReact.Instagram, { className: "w-5 h-5" })
|
|
11412
11518
|
)))));
|
|
11413
11519
|
}
|
|
11414
11520
|
|
|
@@ -11454,6 +11560,7 @@ exports.initializeApiAdapter = initializeApiAdapter;
|
|
|
11454
11560
|
exports.truncate = truncate;
|
|
11455
11561
|
exports.useAddresses = useAddresses;
|
|
11456
11562
|
exports.useAuth = useAuth;
|
|
11563
|
+
exports.useBasePath = useBasePath;
|
|
11457
11564
|
exports.useCart = useCart;
|
|
11458
11565
|
exports.useCategories = useCategories;
|
|
11459
11566
|
exports.useCurrentOrders = useCurrentOrders;
|