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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hey-pharmacist-ecommerce",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Production-ready, multi-tenant e‑commerce UI + API adapter for Next.js with auth, carts, checkout, orders, theming, and pharmacist-focused UX.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -3,34 +3,36 @@
3
3
  import React from 'react';
4
4
  import { Mail, Phone, MapPin, Facebook, Twitter, Instagram } from 'lucide-react';
5
5
  import { useTheme } from '@/providers/ThemeProvider';
6
+ import { useBasePath } from '@/providers/BasePathProvider';
6
7
  import Link from 'next/link';
7
8
 
8
9
  export function Footer() {
9
10
  const { config } = useTheme();
11
+ const { buildPath } = useBasePath();
10
12
 
11
13
  const footerLinks = {
12
14
  shop: [
13
- { label: 'All Products', href: '/shop' },
14
- { label: 'Categories', href: '/categories' },
15
- { label: 'Featured', href: '/featured' },
16
- { label: 'New Arrivals', href: '/new' },
15
+ { label: 'All Products', href: buildPath('/shop') },
16
+ { label: 'Categories', href: buildPath('/categories') },
17
+ { label: 'Featured', href: buildPath('/featured') },
18
+ { label: 'New Arrivals', href: buildPath('/new') },
17
19
  ],
18
20
  account: [
19
- { label: 'My Account', href: '/account' },
20
- { label: 'Orders', href: '/orders' },
21
- { label: 'Wishlist', href: '/wishlist' },
22
- { label: 'Cart', href: '/cart' },
21
+ { label: 'My Account', href: buildPath('/account') },
22
+ { label: 'Orders', href: buildPath('/orders') },
23
+ { label: 'Wishlist', href: buildPath('/wishlist') },
24
+ { label: 'Cart', href: buildPath('/cart') },
23
25
  ],
24
26
  support: [
25
- { label: 'Contact Us', href: '/contact' },
26
- { label: 'FAQs', href: '/faqs' },
27
- { label: 'Shipping Info', href: '/shipping' },
28
- { label: 'Returns', href: '/returns' },
27
+ { label: 'Contact Us', href: buildPath('/contact') },
28
+ { label: 'FAQs', href: buildPath('/faqs') },
29
+ { label: 'Shipping Info', href: buildPath('/shipping') },
30
+ { label: 'Returns', href: buildPath('/returns') },
29
31
  ],
30
32
  legal: [
31
- { label: 'Privacy Policy', href: '/privacy' },
32
- { label: 'Terms of Service', href: '/terms' },
33
- { label: 'Cookie Policy', href: '/cookies' },
33
+ { label: 'Privacy Policy', href: buildPath('/privacy') },
34
+ { label: 'Terms of Service', href: buildPath('/terms') },
35
+ { label: 'Cookie Policy', href: buildPath('/cookies') },
34
36
  ],
35
37
  };
36
38
 
@@ -7,6 +7,7 @@ import { useAuth } from '@/providers/AuthProvider';
7
7
  import { useCart } from '@/providers/CartProvider';
8
8
  import { useTheme } from '@/providers/ThemeProvider';
9
9
  import { useWishlist } from '@/providers/WishlistProvider';
10
+ import { useBasePath } from '@/providers/BasePathProvider';
10
11
  import Link from 'next/link';
11
12
  import Image from 'next/image';
12
13
 
@@ -19,13 +20,14 @@ export function Header() {
19
20
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
20
21
  const [isSearchOpen, setIsSearchOpen] = useState(false);
21
22
  const [searchQuery, setSearchQuery] = useState('');
23
+ const { buildPath } = useBasePath();
22
24
 
23
25
  const navLinks = [
24
- { href: '/shop', label: 'Shop' },
25
- { href: '/categories', label: 'Categories' },
26
- { href: '/orders', label: 'Orders' },
27
- { href: '/about', label: 'About' },
28
- { href: '/contact', label: 'Contact' },
26
+ { href: buildPath('/shop'), label: 'Shop' },
27
+ { href: buildPath('/categories'), label: 'Categories' },
28
+ { href: buildPath('/orders'), label: 'Orders' },
29
+ { href: buildPath('/about'), label: 'About' },
30
+ { href: buildPath('/contact'), label: 'Contact' },
29
31
  ];
30
32
 
31
33
  return (
@@ -33,7 +35,7 @@ export function Header() {
33
35
  <div className="container mx-auto px-4">
34
36
  <div className="flex items-center justify-between h-20">
35
37
  {/* Logo */}
36
- <Link href="/" className="flex items-center gap-3">
38
+ <Link href={buildPath('/')} className="flex items-center gap-3">
37
39
  <div className="relative w-12 h-12">
38
40
  <Image
39
41
  src={config.logo}
@@ -89,7 +91,7 @@ export function Header() {
89
91
  onChange={(e) => setSearchQuery(e.target.value)}
90
92
  onKeyDown={(e) => {
91
93
  if (e.key === 'Enter' && searchQuery.trim()) {
92
- window.location.href = `/search?q=${encodeURIComponent(searchQuery.trim())}`;
94
+ window.location.href = buildPath(`/search?q=${encodeURIComponent(searchQuery.trim())}`);
93
95
  }
94
96
  }}
95
97
  placeholder="Search products..."
@@ -112,7 +114,7 @@ export function Header() {
112
114
 
113
115
  {/* Wishlist and Cart */}
114
116
  <div className="flex items-center gap-4">
115
- <Link href="/wishlist" className="relative p-2 text-gray-700 hover:text-red-500 transition-colors">
117
+ <Link href={buildPath('/wishlist')} className="relative p-2 text-gray-700 hover:text-red-500 transition-colors">
116
118
  <Heart className="w-6 h-6" />
117
119
  {wishlistCount > 0 && (
118
120
  <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">
@@ -121,7 +123,7 @@ export function Header() {
121
123
  )}
122
124
  </Link>
123
125
 
124
- <Link href="/cart" className="relative p-2 text-gray-700 hover:text-primary-600 transition-colors">
126
+ <Link href={buildPath('/cart')} className="relative p-2 text-gray-700 hover:text-primary-600 transition-colors">
125
127
  <ShoppingCart className="w-6 h-6" />
126
128
  {cart?.cartBody?.items?.length && cart.cartBody?.items?.length > 0 ? (
127
129
  <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">
@@ -133,14 +135,14 @@ export function Header() {
133
135
  {/* User Menu */}
134
136
  {isAuthenticated ? (
135
137
  <Link
136
- href="/account"
138
+ href={buildPath('/account')}
137
139
  className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
138
140
  >
139
141
  <User className="w-6 h-6 text-gray-700" />
140
142
  </Link>
141
143
  ) : (
142
144
  <Link
143
- href="/login"
145
+ href={buildPath('/login')}
144
146
  className="hidden sm:block px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium"
145
147
  >
146
148
  Sign In
@@ -183,7 +185,7 @@ export function Header() {
183
185
  ))}
184
186
  {!isAuthenticated && (
185
187
  <Link
186
- href="/login"
188
+ href={buildPath('/login')}
187
189
  onClick={() => setIsMobileMenuOpen(false)}
188
190
  className="px-4 py-3 text-primary-600 hover:bg-gray-50 rounded-lg font-medium"
189
191
  >
@@ -8,12 +8,14 @@ import { formatPrice, formatDate } from '@/lib/utils/format';
8
8
  import { Badge } from './ui/Badge';
9
9
  import Link from 'next/link';
10
10
  import Image from 'next/image';
11
+ import { useBasePath } from '@/providers/BasePathProvider';
11
12
 
12
13
  interface OrderCardProps {
13
14
  order: PopulatedOrder;
14
15
  }
15
16
 
16
17
  export function OrderCard({ order }: OrderCardProps) {
18
+ const { buildPath } = useBasePath();
17
19
  const config = order.orderStatus;
18
20
 
19
21
  return (
@@ -77,7 +79,7 @@ export function OrderCard({ order }: OrderCardProps) {
77
79
  </a>
78
80
  )}
79
81
  {/* <Link
80
- href={`/orders/${order.id}`}
82
+ href={buildPath(`/orders/${order.id}`)}
81
83
  className="inline-flex items-center gap-2 px-4 py-2 border-2 border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
82
84
  >
83
85
  View Details
@@ -9,6 +9,7 @@ import { useWishlist } from '@/providers/WishlistProvider';
9
9
  import Image from 'next/image';
10
10
  import { toast } from 'sonner';
11
11
  import { useRouter } from 'next/navigation';
12
+ import { useBasePath } from '@/providers/BasePathProvider';
12
13
 
13
14
 
14
15
  interface ProductCardProps {
@@ -28,6 +29,7 @@ export function ProductCard({
28
29
  className
29
30
  }: ProductCardProps & { className?: string }) {
30
31
  const router = useRouter();
32
+ const { buildPath } = useBasePath();
31
33
  const [isFavorite, setIsFavorite] = useState(isFavorited);
32
34
  const { addToWishlist, removeFromWishlist, isInWishlist } = useWishlist();
33
35
  const [isHovered, setIsHovered] = useState(false);
@@ -233,7 +235,7 @@ export function ProductCard({
233
235
  type="button"
234
236
  onClick={(e) => {
235
237
  e.stopPropagation();
236
- router.push(`/products/${product._id}`);
238
+ router.push(buildPath(`/products/${product._id}`));
237
239
  }}
238
240
  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`}
239
241
  >
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ export { ThemeProvider, useTheme } from './providers/ThemeProvider';
6
6
  export { AuthProvider, useAuth } from './providers/AuthProvider';
7
7
  export { CartProvider, useCart } from './providers/CartProvider';
8
8
  export { WishlistProvider, useWishlist } from './providers/WishlistProvider';
9
+ export { useBasePath } from './providers/BasePathProvider';
9
10
 
10
11
  // Screens
11
12
  export { ShopScreen } from './screens/ShopScreen';
@@ -44,12 +44,15 @@ export function getCurrentConfig(): EcommerceConfig {
44
44
  return currentConfig;
45
45
  }
46
46
 
47
- // Token management
48
- const TOKEN_KEY = 'ecommerce_access_token';
47
+ // Token management with store-scoped keys
48
+ function getTokenKey(): string {
49
+ const storeId = currentConfig?.storeId || 'default';
50
+ return `ecommerce_access_token_${storeId}`;
51
+ }
49
52
 
50
53
  export function setAuthToken(token: string): void {
51
54
  if (typeof window !== 'undefined') {
52
- localStorage.setItem(TOKEN_KEY, token);
55
+ localStorage.setItem(getTokenKey(), token);
53
56
  // Update the configuration with new token
54
57
  if (apiConfiguration) {
55
58
  apiConfiguration.accessToken = () => token;
@@ -59,14 +62,14 @@ export function setAuthToken(token: string): void {
59
62
 
60
63
  export function getAuthToken(): string | null {
61
64
  if (typeof window !== 'undefined') {
62
- return localStorage.getItem(TOKEN_KEY);
65
+ return localStorage.getItem(getTokenKey());
63
66
  }
64
67
  return null;
65
68
  }
66
69
 
67
70
  export function clearAuthToken(): void {
68
71
  if (typeof window !== 'undefined') {
69
- localStorage.removeItem(TOKEN_KEY);
72
+ localStorage.removeItem(getTokenKey());
70
73
  // Clear from configuration
71
74
  if (apiConfiguration) {
72
75
  apiConfiguration.accessToken = () => '';
@@ -34,7 +34,20 @@ interface AuthProviderProps {
34
34
  export function AuthProvider({ children }: AuthProviderProps) {
35
35
  const [user, setUser] = useState<UserEntity | null>(null);
36
36
  const [isLoading, setIsLoading] = useState(true);
37
- const USER_KEY = 'ecommerce_user';
37
+
38
+ // Get store-scoped key for user cache
39
+ const getUserKey = () => {
40
+ if (typeof window === 'undefined') return 'ecommerce_user';
41
+ const token = getAuthToken();
42
+ if (!token) return 'ecommerce_user';
43
+ // Use a hash or storeId from token/config to namespace
44
+ try {
45
+ const config = require('@/lib/api-adapter/config').getCurrentConfig();
46
+ return `ecommerce_user_${config?.storeId || 'default'}`;
47
+ } catch {
48
+ return 'ecommerce_user';
49
+ }
50
+ };
38
51
 
39
52
  const refreshUser = useCallback(async () => {
40
53
  try {
@@ -55,7 +68,8 @@ export function AuthProvider({ children }: AuthProviderProps) {
55
68
  // Hydrate user instantly from localStorage for fast UI, then validate in background
56
69
  if (typeof window !== 'undefined') {
57
70
  try {
58
- const cached = localStorage.getItem(USER_KEY);
71
+ const userKey = getUserKey();
72
+ const cached = localStorage.getItem(userKey);
59
73
  if (cached) {
60
74
  const parsed: UserEntity = JSON.parse(cached);
61
75
  setUser(parsed);
@@ -79,7 +93,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
79
93
  }
80
94
  setUser(response.data.userData);
81
95
  if (typeof window !== 'undefined') {
82
- localStorage.setItem(USER_KEY, JSON.stringify(response.data.userData));
96
+ localStorage.setItem(getUserKey(), JSON.stringify(response.data.userData));
83
97
  }
84
98
  return response.data;
85
99
  } finally {
@@ -96,7 +110,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
96
110
  }
97
111
  setUser(response.data.userData);
98
112
  if (typeof window !== 'undefined') {
99
- localStorage.setItem(USER_KEY, JSON.stringify(response.data.userData));
113
+ localStorage.setItem(getUserKey(), JSON.stringify(response.data.userData));
100
114
  }
101
115
  return response.data;
102
116
  } finally {
@@ -110,7 +124,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
110
124
  clearAuthToken();
111
125
  setUser(null);
112
126
  if (typeof window !== 'undefined') {
113
- localStorage.removeItem(USER_KEY);
127
+ localStorage.removeItem(getUserKey());
114
128
  }
115
129
  } finally {
116
130
  setIsLoading(false);
@@ -0,0 +1,36 @@
1
+ 'use client';
2
+
3
+ import React, { createContext, useContext } from 'react';
4
+
5
+ interface BasePathContextValue {
6
+ basePath: string;
7
+ buildPath: (path: string) => string;
8
+ }
9
+
10
+ const BasePathContext = createContext<BasePathContextValue | undefined>(undefined);
11
+
12
+ export function BasePathProvider({ basePath = '', children }: { basePath?: string; children: React.ReactNode }) {
13
+ const normalized = basePath ? (basePath.startsWith('/') ? basePath : `/${basePath}`) : '';
14
+
15
+ const buildPath = (path: string) => {
16
+ if (!normalized) return path;
17
+ if (!path) return normalized;
18
+ if (path.startsWith(normalized + '/')) return path; // already prefixed
19
+ if (path.startsWith('/')) return `${normalized}${path}`;
20
+ return `${normalized}/${path}`;
21
+ };
22
+
23
+ return (
24
+ <BasePathContext.Provider value={{ basePath: normalized, buildPath }}>
25
+ {children}
26
+ </BasePathContext.Provider>
27
+ );
28
+ }
29
+
30
+ export function useBasePath(): BasePathContextValue {
31
+ const ctx = useContext(BasePathContext);
32
+ if (!ctx) throw new Error('useBasePath must be used within BasePathProvider');
33
+ return ctx;
34
+ }
35
+
36
+
@@ -6,6 +6,7 @@ import { ThemeProvider } from './ThemeProvider';
6
6
  import { AuthProvider } from './AuthProvider';
7
7
  import { CartProvider } from './CartProvider';
8
8
  import { WishlistProvider } from './WishlistProvider';
9
+ import { BasePathProvider } from './BasePathProvider';
9
10
  import { initializeApiAdapter } from '@/lib/api-adapter';
10
11
  import { Toaster } from 'sonner';
11
12
  import { QueryClientProvider } from '@tanstack/react-query';
@@ -15,9 +16,10 @@ interface EcommerceProviderProps {
15
16
  config: EcommerceConfig;
16
17
  children: React.ReactNode;
17
18
  withToaster?: boolean;
19
+ basePath?: string;
18
20
  }
19
21
 
20
- export function EcommerceProvider({ config, children, withToaster = true }: EcommerceProviderProps) {
22
+ export function EcommerceProvider({ config, children, withToaster = true, basePath = '' }: EcommerceProviderProps) {
21
23
  useEffect(() => {
22
24
  // Initialize API adapter with store configuration
23
25
  // This sets up the real backend APIs with proper authentication and store ID
@@ -30,14 +32,16 @@ export function EcommerceProvider({ config, children, withToaster = true }: Ecom
30
32
  return (
31
33
  <QueryClientProvider client={client}>
32
34
  <ThemeProvider config={config}>
33
- <AuthProvider>
34
- <CartProvider>
35
- <WishlistProvider>
36
- {children}
37
- {withToaster && <Toaster position="top-right" richColors />}
38
- </WishlistProvider>
39
- </CartProvider>
40
- </AuthProvider>
35
+ <BasePathProvider basePath={basePath}>
36
+ <AuthProvider>
37
+ <CartProvider>
38
+ <WishlistProvider>
39
+ {children}
40
+ {withToaster && <Toaster position="top-right" richColors />}
41
+ </WishlistProvider>
42
+ </CartProvider>
43
+ </AuthProvider>
44
+ </BasePathProvider>
41
45
  </ThemeProvider>
42
46
  </QueryClientProvider>
43
47
  );
@@ -18,10 +18,20 @@ export function FavoritesProvider({ children }: { children: ReactNode }) {
18
18
  const [favorites, setFavorites] = useState<string[]>([]);
19
19
  const [isClient, setIsClient] = useState(false);
20
20
 
21
+ const getFavoritesKey = () => {
22
+ if (typeof window === 'undefined') return 'favorites';
23
+ try {
24
+ const config = require('@/lib/api-adapter/config').getCurrentConfig();
25
+ return `favorites_${config?.storeId || 'default'}`;
26
+ } catch {
27
+ return 'favorites';
28
+ }
29
+ };
30
+
21
31
  // Initialize state on client-side to avoid hydration issues
22
32
  useEffect(() => {
23
33
  setIsClient(true);
24
- const savedFavorites = localStorage?.getItem('favorites');
34
+ const savedFavorites = localStorage?.getItem(getFavoritesKey());
25
35
  if (savedFavorites) {
26
36
  try {
27
37
  setFavorites(JSON.parse(savedFavorites));
@@ -34,7 +44,7 @@ export function FavoritesProvider({ children }: { children: ReactNode }) {
34
44
  // Save to localStorage whenever favorites change
35
45
  useEffect(() => {
36
46
  if (isClient) {
37
- localStorage.setItem('favorites', JSON.stringify(favorites));
47
+ localStorage.setItem(getFavoritesKey(), JSON.stringify(favorites));
38
48
  }
39
49
  }, [favorites, isClient]);
40
50
 
@@ -16,11 +16,13 @@ import { useCart } from '@/providers/CartProvider';
16
16
  import { formatPrice } from '@/lib/utils/format';
17
17
  import { useRouter } from 'next/navigation';
18
18
  import { CartItemPopulated } from '@/lib/Apis';
19
+ import { useBasePath } from '@/providers/BasePathProvider';
19
20
 
20
21
 
21
22
  export function CartScreen() {
22
23
  const router = useRouter();
23
24
  const { cart, isLoading } = useCart();
25
+ const { buildPath } = useBasePath();
24
26
 
25
27
  if (!cart || cart.cartBody.items.length === 0) {
26
28
  return (
@@ -31,7 +33,7 @@ export function CartScreen() {
31
33
  title="Your bag feels a little empty"
32
34
  description="Add pharmacy favorites to unlock quick shipping, curated bundles, and personalized recommendations."
33
35
  actionLabel="Discover products"
34
- onAction={() => router.push('/shop')}
36
+ onAction={() => router.push(buildPath('/shop'))}
35
37
  />
36
38
  </div>
37
39
  </div>
@@ -145,14 +147,14 @@ export function CartScreen() {
145
147
  <Button
146
148
  size="lg"
147
149
  className="mt-6 w-full"
148
- onClick={() => router.push('/checkout')}
150
+ onClick={() => router.push(buildPath('/checkout'))}
149
151
  >
150
152
  Secure checkout
151
153
  <ArrowRight className="h-5 w-5" />
152
154
  </Button>
153
155
  <button
154
156
  type="button"
155
- onClick={() => router.push('/shop')}
157
+ onClick={() => router.push(buildPath('/shop'))}
156
158
  className="mt-4 w-full text-sm font-semibold text-primary-600 transition hover:text-primary-700"
157
159
  >
158
160
  Continue shopping
@@ -8,10 +8,12 @@ import { useCategories } from '@/hooks/useProducts';
8
8
  import Image from 'next/image';
9
9
  import Link from 'next/link';
10
10
  import { useRouter } from 'next/navigation';
11
+ import { useBasePath } from '@/providers/BasePathProvider';
11
12
 
12
13
  export function CategoriesScreen() {
13
14
  const { categories, isLoading } = useCategories();
14
15
  const router = useRouter();
16
+ const { buildPath } = useBasePath();
15
17
 
16
18
  return (
17
19
  <div className="min-h-screen bg-slate-50">
@@ -74,7 +76,7 @@ export function CategoriesScreen() {
74
76
  {categories.map((category) => (
75
77
  <Link
76
78
  key={category.id}
77
- href={`/shop?category=${category.name}`}
79
+ href={buildPath(`/shop?category=${category.name}`)}
78
80
  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"
79
81
  >
80
82
  <div className="relative aspect-square w-full overflow-hidden rounded-lg bg-gray-50 mb-3">
@@ -109,7 +111,7 @@ export function CategoriesScreen() {
109
111
  description="There are currently no product categories available."
110
112
  icon={Package}
111
113
  actionLabel="Shop products"
112
- onAction={() => router.push('/shop')}
114
+ onAction={() => router.push(buildPath('/shop'))}
113
115
  />
114
116
  )}
115
117
  </motion.div>
@@ -29,6 +29,7 @@ import { AXIOS_CONFIG } from '@/lib/Apis/wrapper';
29
29
  import { Card } from '@/components/ui/Card';
30
30
  import { AddressFormModal } from '@/components/AddressFormModal';
31
31
  import { Edit3, Trash2 } from 'lucide-react';
32
+ import { useBasePath } from '@/providers/BasePathProvider';
32
33
 
33
34
  import { addressSchema } from '@/lib/validations/address';
34
35
  import Image from 'next/image';
@@ -77,6 +78,7 @@ export function CheckoutScreen() {
77
78
  const router = useRouter();
78
79
  const { cart, clearCart } = useCart();
79
80
  const { isAuthenticated, user } = useAuth();
81
+ const { buildPath } = useBasePath();
80
82
  const [isSubmitting, setIsSubmitting] = useState(false);
81
83
  const [isDelivery, setIsDelivery] = useState(true); // delivery or pickup
82
84
  const [paymentMethod, setPaymentMethod] = useState('Card');
@@ -282,7 +284,7 @@ export function CheckoutScreen() {
282
284
  setError(null);
283
285
  if (!isAuthenticated) {
284
286
  toast.error('Please login to continue');
285
- setTimeout(() => router.push('/login?redirect=/checkout'), 50);
287
+ setTimeout(() => router.push(buildPath('/login?redirect=/checkout')), 50);
286
288
  return;
287
289
  }
288
290
  if (!cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
@@ -387,11 +389,11 @@ export function CheckoutScreen() {
387
389
  }
388
390
  toast.success('Order placed successfully!');
389
391
  await clearCart();
390
- router.push(`/orders/${response.data?.id}`);
392
+ router.push(buildPath(`/orders/${response.data?.id}`));
391
393
  } else {
392
394
  toast.success('Order placed successfully!');
393
395
  await clearCart();
394
- router.push(`/orders/${response.data?.id}`);
396
+ router.push(buildPath(`/orders/${response.data?.id}`));
395
397
  }
396
398
  } catch (err: any) {
397
399
  const msg = err?.message || (err?.response?.data?.message) || 'Failed to place order';
@@ -403,7 +405,7 @@ export function CheckoutScreen() {
403
405
  };
404
406
 
405
407
  if (!cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
406
- router.push('/cart');
408
+ router.push(buildPath('/cart'));
407
409
  return null;
408
410
  }
409
411
  const subtotal = cart.total;
@@ -15,10 +15,12 @@ import {
15
15
  Truck,
16
16
  Warehouse,
17
17
  } from 'lucide-react';
18
+ import { useBasePath } from '@/providers/BasePathProvider';
18
19
 
19
20
  export function CurrentOrdersScreen() {
20
21
  const router = useRouter();
21
22
  const { orders, isLoading } = useCurrentOrders();
23
+ const { buildPath } = useBasePath();
22
24
 
23
25
  const hasOrders = orders.length > 0;
24
26
 
@@ -54,7 +56,7 @@ export function CurrentOrdersScreen() {
54
56
  </p>
55
57
  <div className="mt-4 space-y-3 text-sm text-white/80">
56
58
  <Link
57
- href="/orders"
59
+ href={buildPath('/orders')}
58
60
  className="flex items-center justify-between rounded-2xl bg-white/10 px-4 py-3 transition hover:bg-white/20"
59
61
  >
60
62
  <span className="font-semibold text-white">View order history</span>
@@ -97,7 +99,7 @@ export function CurrentOrdersScreen() {
97
99
  title="No active orders"
98
100
  description="Start a new order to see live preparation, packing, and delivery updates here."
99
101
  actionLabel="Shop wellness essentials"
100
- onAction={() => router.push('/shop')}
102
+ onAction={() => router.push(buildPath('/shop'))}
101
103
  />
102
104
  </div>
103
105
  )}
@@ -8,10 +8,12 @@ import { ProductCard } from '@/components/ProductCard';
8
8
  import { useWishlist } from '@/providers/WishlistProvider';
9
9
  import { ProductCardSkeleton } from '@/components/ui/Skeleton';
10
10
  import { useRouter } from 'next/navigation';
11
+ import { useBasePath } from '@/providers/BasePathProvider';
11
12
  import { useProducts } from '@/hooks/useProducts';
12
13
 
13
14
  export default function HomeScreen() {
14
- const router = useRouter();
15
+ const router = useRouter();
16
+ const { buildPath } = useBasePath();
15
17
  const { products, isLoading } = useProducts();
16
18
  const { isInWishlist } = useWishlist();
17
19
 
@@ -66,7 +68,7 @@ export default function HomeScreen() {
66
68
  <Button
67
69
  size="lg"
68
70
  variant="secondary"
69
- onClick={() => router.push('/shop')}
71
+ onClick={() => router.push(buildPath('/shop'))}
70
72
  className="text-lg px-8 py-4"
71
73
  >
72
74
  Shop Now
@@ -75,7 +77,7 @@ export default function HomeScreen() {
75
77
  <Button
76
78
  size="lg"
77
79
  variant="outline"
78
- onClick={() => router.push('/about')}
80
+ onClick={() => router.push(buildPath('/about'))}
79
81
  className="text-lg px-8 py-4 bg-white/10 backdrop-blur-sm border-white text-white hover:bg-white/20"
80
82
  >
81
83
  Learn More
@@ -156,7 +158,7 @@ export default function HomeScreen() {
156
158
  <ProductCard
157
159
  product={product}
158
160
  isFavorited={isInWishlist(product.id)}
159
- onClickProduct={(p) => router.push(`/products/${p.id}`)}
161
+ onClickProduct={(p) => router.push(buildPath(`/products/${p.id}`))}
160
162
  />
161
163
  </motion.div>
162
164
  );
@@ -167,7 +169,7 @@ export default function HomeScreen() {
167
169
  <div className="text-center mt-12">
168
170
  <Button
169
171
  size="lg"
170
- onClick={() => router.push('/shop')}
172
+ onClick={() => router.push(buildPath('/shop'))}
171
173
  >
172
174
  View All Products
173
175
  <ArrowRight className="w-5 h-5" />
@@ -194,7 +196,7 @@ export default function HomeScreen() {
194
196
  <Button
195
197
  size="lg"
196
198
  variant="secondary"
197
- onClick={() => router.push('/register')}
199
+ onClick={() => router.push(buildPath('/register'))}
198
200
  className="text-lg px-8 py-4"
199
201
  >
200
202
  Create an Account
@@ -20,6 +20,7 @@ import { Input } from '@/components/ui/Input';
20
20
  import { Button } from '@/components/ui/Button';
21
21
  import { useAuth } from '@/providers/AuthProvider';
22
22
  import { toast } from 'sonner';
23
+ import { useBasePath } from '@/providers/BasePathProvider';
23
24
 
24
25
  const loginSchema = z.object({
25
26
  email: z.string().email('Enter a valid email address'),
@@ -30,8 +31,9 @@ type LoginFormData = z.infer<typeof loginSchema>;
30
31
 
31
32
  export function LoginScreen() {
32
33
  const router = useRouter();
34
+ const { buildPath } = useBasePath();
33
35
  const searchParams = useSearchParams();
34
- const redirectUrl = searchParams?.get('redirect') || '/';
36
+ const redirectUrl = searchParams?.get('redirect') || buildPath('/');
35
37
  const { login } = useAuth();
36
38
  const [showPassword, setShowPassword] = useState(false);
37
39
  const [isSubmitting, setIsSubmitting] = useState(false);