hey-pharmacist-ecommerce 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +107 -1
  2. package/dist/index.d.mts +3636 -316
  3. package/dist/index.d.ts +3636 -316
  4. package/dist/index.js +6802 -3865
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +6756 -3817
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +17 -14
  9. package/src/components/AddressFormModal.tsx +171 -0
  10. package/src/components/CartItem.tsx +17 -12
  11. package/src/components/FilterChips.tsx +195 -0
  12. package/src/components/Header.tsx +121 -71
  13. package/src/components/OrderCard.tsx +18 -25
  14. package/src/components/ProductCard.tsx +209 -72
  15. package/src/components/ui/Button.tsx +13 -5
  16. package/src/components/ui/Card.tsx +46 -0
  17. package/src/hooks/useAddresses.ts +83 -0
  18. package/src/hooks/useOrders.ts +37 -19
  19. package/src/hooks/useProducts.ts +55 -63
  20. package/src/hooks/useWishlistProducts.ts +75 -0
  21. package/src/index.ts +3 -19
  22. package/src/lib/Apis/api.ts +1 -0
  23. package/src/lib/Apis/apis/cart-api.ts +3 -3
  24. package/src/lib/Apis/apis/inventory-api.ts +0 -108
  25. package/src/lib/Apis/apis/stores-api.ts +70 -0
  26. package/src/lib/Apis/apis/wishlist-api.ts +447 -0
  27. package/src/lib/Apis/models/cart-item-populated.ts +0 -1
  28. package/src/lib/Apis/models/create-single-variant-product-dto.ts +3 -10
  29. package/src/lib/Apis/models/create-variant-dto.ts +26 -33
  30. package/src/lib/Apis/models/extended-product-dto.ts +20 -24
  31. package/src/lib/Apis/models/index.ts +2 -1
  32. package/src/lib/Apis/models/order-time-line-dto.ts +49 -0
  33. package/src/lib/Apis/models/order.ts +3 -8
  34. package/src/lib/Apis/models/populated-order.ts +3 -8
  35. package/src/lib/Apis/models/product-variant.ts +29 -0
  36. package/src/lib/Apis/models/update-product-variant-dto.ts +16 -23
  37. package/src/lib/Apis/models/wishlist.ts +51 -0
  38. package/src/lib/Apis/wrapper.ts +18 -7
  39. package/src/lib/api-adapter/index.ts +0 -12
  40. package/src/lib/types/index.ts +16 -61
  41. package/src/lib/utils/colors.ts +7 -4
  42. package/src/lib/utils/format.ts +1 -1
  43. package/src/lib/validations/address.ts +14 -0
  44. package/src/providers/AuthProvider.tsx +61 -31
  45. package/src/providers/CartProvider.tsx +18 -28
  46. package/src/providers/EcommerceProvider.tsx +7 -0
  47. package/src/providers/FavoritesProvider.tsx +86 -0
  48. package/src/providers/ThemeProvider.tsx +16 -1
  49. package/src/providers/WishlistProvider.tsx +174 -0
  50. package/src/screens/AddressesScreen.tsx +484 -0
  51. package/src/screens/CartScreen.tsx +120 -84
  52. package/src/screens/CategoriesScreen.tsx +120 -0
  53. package/src/screens/CheckoutScreen.tsx +919 -241
  54. package/src/screens/CurrentOrdersScreen.tsx +125 -61
  55. package/src/screens/HomeScreen.tsx +209 -0
  56. package/src/screens/LoginScreen.tsx +133 -88
  57. package/src/screens/NewAddressScreen.tsx +187 -0
  58. package/src/screens/OrdersScreen.tsx +162 -50
  59. package/src/screens/ProductDetailScreen.tsx +641 -190
  60. package/src/screens/ProfileScreen.tsx +192 -116
  61. package/src/screens/RegisterScreen.tsx +193 -144
  62. package/src/screens/SearchResultsScreen.tsx +165 -0
  63. package/src/screens/ShopScreen.tsx +1110 -146
  64. package/src/screens/WishlistScreen.tsx +428 -0
  65. package/src/lib/Apis/models/inventory-paginated-response.ts +0 -75
  66. package/src/lib/api/auth.ts +0 -81
  67. package/src/lib/api/cart.ts +0 -42
  68. package/src/lib/api/orders.ts +0 -53
  69. package/src/lib/api/products.ts +0 -51
  70. package/src/lib/api-adapter/auth-adapter.ts +0 -196
  71. package/src/lib/api-adapter/cart-adapter.ts +0 -193
  72. package/src/lib/api-adapter/mappers.ts +0 -147
  73. package/src/lib/api-adapter/orders-adapter.ts +0 -195
  74. package/src/lib/api-adapter/products-adapter.ts +0 -194
@@ -2,84 +2,148 @@
2
2
 
3
3
  import React from 'react';
4
4
  import { motion } from 'framer-motion';
5
- import { Truck, Package } from 'lucide-react';
5
+ import { EmptyState } from '@/components/EmptyState';
6
6
  import { OrderCard } from '@/components/OrderCard';
7
7
  import { OrderCardSkeleton } from '@/components/ui/Skeleton';
8
- import { EmptyState } from '@/components/EmptyState';
9
8
  import { useCurrentOrders } from '@/hooks/useOrders';
10
9
  import { useRouter } from 'next/navigation';
11
10
  import Link from 'next/link';
11
+ import {
12
+ ArrowUpRight,
13
+ BellRing,
14
+ PackageCheck,
15
+ Truck,
16
+ Warehouse,
17
+ } from 'lucide-react';
12
18
 
13
19
  export function CurrentOrdersScreen() {
14
20
  const router = useRouter();
15
21
  const { orders, isLoading } = useCurrentOrders();
16
22
 
23
+ const hasOrders = orders.length > 0;
24
+
17
25
  return (
18
- <div className="min-h-screen bg-gray-50 py-12">
19
- <div className="container mx-auto px-4 max-w-5xl">
20
- {/* Header */}
21
- <motion.div
22
- initial={{ opacity: 0, y: 20 }}
23
- animate={{ opacity: 1, y: 0 }}
24
- className="mb-8"
25
- >
26
- <div className="flex items-center justify-between">
27
- <div>
28
- <h1 className="text-4xl font-bold text-gray-900 mb-2 flex items-center gap-3">
29
- <Truck className="w-10 h-10 text-primary-600" />
30
- Current Orders
31
- </h1>
32
- <p className="text-gray-600">
33
- Track your active orders and deliveries
26
+ <div className="min-h-screen bg-slate-50">
27
+ <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">
28
+ <div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" />
29
+ <div className="relative container mx-auto px-4 py-16">
30
+ <div className="flex flex-col gap-6 md:flex-row md:items-center md:justify-between">
31
+ <motion.div
32
+ initial={{ opacity: 0, y: 24 }}
33
+ animate={{ opacity: 1, y: 0 }}
34
+ className="space-y-4"
35
+ >
36
+ <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">
37
+ <Truck className="h-4 w-4" />
38
+ Live order tracking
39
+ </span>
40
+ <h1 className="text-4xl font-bold md:text-5xl">Current orders</h1>
41
+ <p className="max-w-2xl text-white/80 md:text-lg">
42
+ Follow your pharmacy orders from preparation to delivery. Real-time updates, SMS
43
+ alerts, and pharmacist oversight come standard.
34
44
  </p>
35
- </div>
36
- <Link
37
- href="/orders"
38
- className="text-primary-600 hover:text-primary-700 font-medium"
45
+ </motion.div>
46
+ <motion.div
47
+ initial={{ opacity: 0, y: 24 }}
48
+ animate={{ opacity: 1, y: 0 }}
49
+ transition={{ delay: 0.1 }}
50
+ className="rounded-3xl bg-white/15 p-6 backdrop-blur"
39
51
  >
40
- View All Orders
41
- </Link>
52
+ <p className="text-sm font-semibold uppercase tracking-[0.35em] text-white/70">
53
+ Quick actions
54
+ </p>
55
+ <div className="mt-4 space-y-3 text-sm text-white/80">
56
+ <Link
57
+ href="/orders"
58
+ className="flex items-center justify-between rounded-2xl bg-white/10 px-4 py-3 transition hover:bg-white/20"
59
+ >
60
+ <span className="font-semibold text-white">View order history</span>
61
+ <ArrowUpRight className="h-4 w-4" />
62
+ </Link>
63
+ <p>
64
+ Need help fast? Chat with a pharmacist and we will triage your request in under 10
65
+ minutes.
66
+ </p>
67
+ </div>
68
+ </motion.div>
42
69
  </div>
43
- </motion.div>
70
+ </div>
71
+ </section>
44
72
 
45
- {/* Info Banner */}
46
- <motion.div
47
- initial={{ opacity: 0, y: 20 }}
48
- animate={{ opacity: 1, y: 0 }}
49
- transition={{ delay: 0.1 }}
50
- className="bg-blue-50 border border-blue-200 rounded-2xl p-6 mb-8"
51
- >
52
- <h3 className="font-semibold text-blue-900 mb-2">Track Your Orders</h3>
53
- <p className="text-blue-700 text-sm">
54
- Stay updated on your orders' status. You'll receive notifications when your order is
55
- being prepared, shipped, and delivered.
56
- </p>
57
- </motion.div>
73
+ <div className="relative -mt-16 pb-16">
74
+ <div className="container mx-auto px-4">
75
+ <motion.section
76
+ initial={{ opacity: 0, y: 24 }}
77
+ animate={{ opacity: 1, y: 0 }}
78
+ className="grid gap-6 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]"
79
+ >
80
+ <div className="space-y-6">
81
+ {isLoading ? (
82
+ <div className="space-y-4">
83
+ {Array.from({ length: 3 }).map((_, index) => (
84
+ <OrderCardSkeleton key={index} />
85
+ ))}
86
+ </div>
87
+ ) : hasOrders ? (
88
+ <div className="space-y-4">
89
+ {orders.map((order) => (
90
+ <OrderCard key={order.id} order={order} />
91
+ ))}
92
+ </div>
93
+ ) : (
94
+ <div className="rounded-3xl border border-slate-100 bg-white p-10 shadow-sm">
95
+ <EmptyState
96
+ icon={PackageCheck}
97
+ title="No active orders"
98
+ description="Start a new order to see live preparation, packing, and delivery updates here."
99
+ actionLabel="Shop wellness essentials"
100
+ onAction={() => router.push('/shop')}
101
+ />
102
+ </div>
103
+ )}
104
+ </div>
58
105
 
59
- {/* Orders List */}
60
- {isLoading ? (
61
- <div className="space-y-4">
62
- {Array.from({ length: 2 }).map((_, i) => (
63
- <OrderCardSkeleton key={i} />
64
- ))}
65
- </div>
66
- ) : orders.length > 0 ? (
67
- <div className="space-y-4">
68
- {orders.map((order) => (
69
- <OrderCard key={order.id} order={order} />
70
- ))}
71
- </div>
72
- ) : (
73
- <EmptyState
74
- icon={Package}
75
- title="No active orders"
76
- description="You don't have any orders in progress right now"
77
- actionLabel="Start Shopping"
78
- onAction={() => router.push('/shop')}
79
- />
80
- )}
106
+ <aside className="space-y-6">
107
+ <div className="rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50">
108
+ <h2 className="text-lg font-semibold text-slate-900">
109
+ Real-time milestones
110
+ </h2>
111
+ <div className="mt-4 space-y-4 text-sm text-slate-600">
112
+ <div className="flex items-start gap-3 rounded-2xl bg-slate-50 p-4">
113
+ <Warehouse className="h-5 w-5 text-primary-500" />
114
+ <div>
115
+ <p className="font-semibold text-slate-800">Preparation</p>
116
+ <p>Our pharmacists verify ingredients and pack thermo-sensitive items.</p>
117
+ </div>
118
+ </div>
119
+ <div className="flex items-start gap-3 rounded-2xl bg-slate-50 p-4">
120
+ <Truck className="h-5 w-5 text-primary-500" />
121
+ <div>
122
+ <p className="font-semibold text-slate-800">In transit</p>
123
+ <p>Track live courier location with ETA updates tailored to your delivery window.</p>
124
+ </div>
125
+ </div>
126
+ <div className="flex items-start gap-3 rounded-2xl bg-slate-50 p-4">
127
+ <BellRing className="h-5 w-5 text-primary-500" />
128
+ <div>
129
+ <p className="font-semibold text-slate-800">Arrival alerts</p>
130
+ <p>Receive SMS and email notifications when parcels are out for delivery.</p>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+
136
+ <div className="rounded-3xl border border-primary-100 bg-primary-50/70 p-6 text-sm text-primary-700 shadow-sm">
137
+ <p className="font-semibold uppercase tracking-[0.3em]">Need support?</p>
138
+ <p className="mt-3 leading-relaxed">
139
+ Our fulfillment team is online 7 days a week. Message us if you need to adjust
140
+ delivery instructions or review dosage guidance.
141
+ </p>
142
+ </div>
143
+ </aside>
144
+ </motion.section>
145
+ </div>
81
146
  </div>
82
147
  </div>
83
148
  );
84
149
  }
85
-
@@ -0,0 +1,209 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import { motion } from 'framer-motion';
5
+ import { ArrowRight, ShoppingBag, Truck, Shield, CreditCard } from 'lucide-react';
6
+ import { Button } from '@/components/ui/Button';
7
+ import { ProductCard } from '@/components/ProductCard';
8
+ import { useWishlist } from '@/providers/WishlistProvider';
9
+ import { ProductCardSkeleton } from '@/components/ui/Skeleton';
10
+ import { useRouter } from 'next/navigation';
11
+ import { useProducts } from '@/hooks/useProducts';
12
+
13
+ export default function HomeScreen() {
14
+ const router = useRouter();
15
+ const { products, isLoading } = useProducts();
16
+ const { isInWishlist } = useWishlist();
17
+
18
+ const features = [
19
+ {
20
+ icon: Truck,
21
+ title: 'Free Shipping',
22
+ description: 'On orders over $50',
23
+ },
24
+ {
25
+ icon: Shield,
26
+ title: 'Secure Payment',
27
+ description: '100% secure transactions',
28
+ },
29
+ {
30
+ icon: CreditCard,
31
+ title: 'Easy Returns',
32
+ description: '30-day money back guarantee',
33
+ },
34
+ {
35
+ icon: ShoppingBag,
36
+ title: 'Quality Products',
37
+ description: 'Handpicked for you',
38
+ },
39
+ ];
40
+
41
+ return (
42
+ <div>
43
+ {/* Hero Section */}
44
+ <section className="relative bg-gradient-to-br from-primary-600 via-primary-700 to-secondary-600 text-white py-32 overflow-hidden">
45
+ <div className="absolute inset-0 opacity-10">
46
+ <div className="absolute inset-0" style={{
47
+ backgroundImage: 'radial-gradient(circle at 2px 2px, white 1px, transparent 0)',
48
+ backgroundSize: '40px 40px',
49
+ }} />
50
+ </div>
51
+
52
+ <div className="container mx-auto px-4 relative z-10">
53
+ <motion.div
54
+ initial={{ opacity: 0, y: 30 }}
55
+ animate={{ opacity: 1, y: 0 }}
56
+ transition={{ duration: 0.8 }}
57
+ className="max-w-3xl mx-auto text-center"
58
+ >
59
+ <h1 className="text-6xl md:text-7xl font-bold mb-6">
60
+ Shop the Best Products
61
+ </h1>
62
+ <p className="text-xl md:text-2xl text-primary-100 mb-10">
63
+ Discover our curated collection of high-quality products at unbeatable prices
64
+ </p>
65
+ <div className="flex flex-wrap gap-4 justify-center">
66
+ <Button
67
+ size="lg"
68
+ variant="secondary"
69
+ onClick={() => router.push('/shop')}
70
+ className="text-lg px-8 py-4"
71
+ >
72
+ Shop Now
73
+ <ArrowRight className="w-6 h-6" />
74
+ </Button>
75
+ <Button
76
+ size="lg"
77
+ variant="outline"
78
+ onClick={() => router.push('/about')}
79
+ className="text-lg px-8 py-4 bg-white/10 backdrop-blur-sm border-white text-white hover:bg-white/20"
80
+ >
81
+ Learn More
82
+ </Button>
83
+ </div>
84
+ </motion.div>
85
+ </div>
86
+
87
+ {/* Decorative Elements */}
88
+ <div className="absolute bottom-0 left-0 right-0">
89
+ <svg viewBox="0 0 1440 120" fill="none" xmlns="http://www.w3.org/2000/svg">
90
+ <path d="M0 120L60 110C120 100 240 80 360 70C480 60 600 60 720 65C840 70 960 80 1080 85C1200 90 1320 90 1380 90L1440 90V120H1380C1320 120 1200 120 1080 120C960 120 840 120 720 120C600 120 480 120 360 120C240 120 120 120 60 120H0Z" fill="rgb(249, 250, 251)" />
91
+ </svg>
92
+ </div>
93
+ </section>
94
+
95
+ {/* Features Section */}
96
+ <section className="py-20 bg-gray-50">
97
+ <div className="container mx-auto px-4">
98
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
99
+ {features.map((feature, index) => (
100
+ <motion.div
101
+ key={feature.title}
102
+ initial={{ opacity: 0, y: 20 }}
103
+ whileInView={{ opacity: 1, y: 0 }}
104
+ transition={{ delay: index * 0.1 }}
105
+ viewport={{ once: true }}
106
+ className="text-center"
107
+ >
108
+ <div className="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
109
+ <feature.icon className="w-8 h-8 text-primary-600" />
110
+ </div>
111
+ <h3 className="text-xl font-bold text-gray-900 mb-2">
112
+ {feature.title}
113
+ </h3>
114
+ <p className="text-gray-600">{feature.description}</p>
115
+ </motion.div>
116
+ ))}
117
+ </div>
118
+ </div>
119
+ </section>
120
+
121
+ {/* Featured Products Section */}
122
+ <section className="py-20 bg-white">
123
+ <div className="container mx-auto px-4">
124
+ <motion.div
125
+ initial={{ opacity: 0, y: 20 }}
126
+ whileInView={{ opacity: 1, y: 0 }}
127
+ viewport={{ once: true }}
128
+ className="text-center mb-12"
129
+ >
130
+ <h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
131
+ Featured Products
132
+ </h2>
133
+ <p className="text-xl text-gray-600 max-w-2xl mx-auto">
134
+ Check out our handpicked selection of trending products
135
+ </p>
136
+ </motion.div>
137
+
138
+ {isLoading ? (
139
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
140
+ {Array.from({ length: 8 }).map((_, i) => (
141
+ <ProductCardSkeleton key={i} />
142
+ ))}
143
+ </div>
144
+ ) : (
145
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
146
+ {products.map((product, index) => {
147
+
148
+ return (
149
+ <motion.div
150
+ key={product.id}
151
+ initial={{ opacity: 0, y: 20 }}
152
+ whileInView={{ opacity: 1, y: 0 }}
153
+ transition={{ delay: index * 0.1 }}
154
+ viewport={{ once: true }}
155
+ >
156
+ <ProductCard
157
+ product={product}
158
+ isFavorited={isInWishlist(product.id)}
159
+ onClickProduct={(p) => router.push(`/products/${p.id}`)}
160
+ />
161
+ </motion.div>
162
+ );
163
+ })}
164
+ </div>
165
+ )}
166
+
167
+ <div className="text-center mt-12">
168
+ <Button
169
+ size="lg"
170
+ onClick={() => router.push('/shop')}
171
+ >
172
+ View All Products
173
+ <ArrowRight className="w-5 h-5" />
174
+ </Button>
175
+ </div>
176
+ </div>
177
+ </section>
178
+
179
+ {/* CTA Section */}
180
+ <section className="py-20 bg-gradient-to-br from-primary-600 to-secondary-600 text-white">
181
+ <div className="container mx-auto px-4">
182
+ <motion.div
183
+ initial={{ opacity: 0, y: 20 }}
184
+ whileInView={{ opacity: 1, y: 0 }}
185
+ viewport={{ once: true }}
186
+ className="max-w-3xl mx-auto text-center"
187
+ >
188
+ <h2 className="text-4xl md:text-5xl font-bold mb-6">
189
+ Ready to Start Shopping?
190
+ </h2>
191
+ <p className="text-xl text-primary-100 mb-10">
192
+ Join thousands of satisfied customers and discover amazing products today
193
+ </p>
194
+ <Button
195
+ size="lg"
196
+ variant="secondary"
197
+ onClick={() => router.push('/register')}
198
+ className="text-lg px-8 py-4"
199
+ >
200
+ Create an Account
201
+ <ArrowRight className="w-6 h-6" />
202
+ </Button>
203
+ </motion.div>
204
+ </div>
205
+ </section>
206
+ </div>
207
+ );
208
+ }
209
+