hey-pharmacist-ecommerce 1.1.13 → 1.1.14
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 +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1039 -857
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1039 -856
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/components/AccountAddressesTab.tsx +209 -0
- package/src/components/AccountOrdersTab.tsx +151 -0
- package/src/components/AccountOverviewTab.tsx +209 -0
- package/src/components/AccountPaymentTab.tsx +116 -0
- package/src/components/AccountSavedItemsTab.tsx +76 -0
- package/src/components/AccountSettingsTab.tsx +116 -0
- package/src/components/AddressFormModal.tsx +23 -10
- package/src/components/CartItem.tsx +60 -56
- package/src/components/Header.tsx +69 -16
- package/src/components/Notification.tsx +148 -0
- package/src/components/ProductCard.tsx +215 -178
- package/src/components/QuickViewModal.tsx +314 -0
- package/src/components/TabNavigation.tsx +48 -0
- package/src/components/ui/Button.tsx +1 -1
- package/src/components/ui/ConfirmModal.tsx +84 -0
- package/src/hooks/usePaymentMethods.ts +58 -0
- package/src/index.ts +0 -1
- package/src/providers/CartProvider.tsx +22 -6
- package/src/providers/EcommerceProvider.tsx +8 -7
- package/src/providers/FavoritesProvider.tsx +10 -3
- package/src/providers/NotificationProvider.tsx +79 -0
- package/src/providers/WishlistProvider.tsx +34 -9
- package/src/screens/AddressesScreen.tsx +72 -61
- package/src/screens/CartScreen.tsx +48 -32
- package/src/screens/ChangePasswordScreen.tsx +155 -0
- package/src/screens/CheckoutScreen.tsx +162 -125
- package/src/screens/EditProfileScreen.tsx +165 -0
- package/src/screens/LoginScreen.tsx +59 -72
- package/src/screens/NewAddressScreen.tsx +16 -10
- package/src/screens/ProductDetailScreen.tsx +334 -234
- package/src/screens/ProfileScreen.tsx +190 -200
- package/src/screens/RegisterScreen.tsx +51 -70
- package/src/screens/SearchResultsScreen.tsx +2 -1
- package/src/screens/ShopScreen.tsx +260 -384
- package/src/screens/WishlistScreen.tsx +226 -224
- package/src/styles/globals.css +9 -0
- package/src/screens/CategoriesScreen.tsx +0 -122
- package/src/screens/HomeScreen.tsx +0 -211
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import { Input } from '@/components/ui/Input';
|
|
20
20
|
import { Button } from '@/components/ui/Button';
|
|
21
21
|
import { useAuth } from '@/providers/AuthProvider';
|
|
22
|
-
import {
|
|
22
|
+
import { useNotification } from '@/providers/NotificationProvider';
|
|
23
23
|
import { CreateUserDtoCustomerTypeEnum, CreateUserDtoRoleEnum } from '@/lib/Apis/models';
|
|
24
24
|
import { useBasePath } from '@/providers/BasePathProvider';
|
|
25
25
|
|
|
@@ -52,6 +52,7 @@ export function RegisterScreen() {
|
|
|
52
52
|
const [showPassword, setShowPassword] = useState(false);
|
|
53
53
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
|
54
54
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
55
|
+
const notification = useNotification();
|
|
55
56
|
|
|
56
57
|
const {
|
|
57
58
|
register,
|
|
@@ -71,108 +72,86 @@ export function RegisterScreen() {
|
|
|
71
72
|
customerType: CreateUserDtoCustomerTypeEnum.Regular,
|
|
72
73
|
role: CreateUserDtoRoleEnum.User,
|
|
73
74
|
});
|
|
74
|
-
|
|
75
|
+
notification.success(
|
|
76
|
+
'Account created',
|
|
77
|
+
'Your Hey Pharmacist account is ready to use.'
|
|
78
|
+
);
|
|
75
79
|
router.push(buildPath('/'));
|
|
76
80
|
} catch (error: any) {
|
|
77
|
-
|
|
81
|
+
notification.error(
|
|
82
|
+
'Could not create account',
|
|
83
|
+
error.response?.data?.message || 'Something went wrong while creating your account. Please try again.'
|
|
84
|
+
);
|
|
78
85
|
} finally {
|
|
79
86
|
setIsSubmitting(false);
|
|
80
87
|
}
|
|
81
88
|
};
|
|
82
89
|
|
|
83
90
|
return (
|
|
84
|
-
<div className="min-h-screen bg-
|
|
85
|
-
<div className="grid min-h-screen overflow-hidden
|
|
86
|
-
<motion.section
|
|
87
|
-
initial={{ opacity: 0, x: -24 }}
|
|
88
|
-
animate={{ opacity: 1, x: 0 }}
|
|
89
|
-
transition={{ duration: 0.4 }}
|
|
90
|
-
className="flex flex-col justify-between bg-gradient-to-br from-slate-700 via-slate-600 to-slate-700 px-10 py-14 text-white"
|
|
91
|
-
>
|
|
92
|
-
<div className="space-y-6">
|
|
93
|
-
<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">
|
|
94
|
-
<HeartPulse className="h-4 w-4" />
|
|
95
|
-
Join Hey Pharmacist
|
|
96
|
-
</span>
|
|
97
|
-
<h1 className="text-4xl font-bold leading-tight lg:text-5xl">
|
|
98
|
-
Create your wellness account
|
|
99
|
-
</h1>
|
|
100
|
-
<p className="max-w-xl text-white/80">
|
|
101
|
-
Unlock concierge-level pharmacy support, curated product recommendations, and smarter
|
|
102
|
-
refills designed for busy families.
|
|
103
|
-
</p>
|
|
104
|
-
</div>
|
|
105
|
-
|
|
106
|
-
<div className="space-y-4 rounded-3xl bg-white/10 p-6 backdrop-blur">
|
|
107
|
-
{BENEFITS.map((benefit) => (
|
|
108
|
-
<div key={benefit} className="flex items-center gap-3">
|
|
109
|
-
<CheckCircle2 className="h-5 w-5 text-white" />
|
|
110
|
-
<p className="text-sm text-white/85">{benefit}</p>
|
|
111
|
-
</div>
|
|
112
|
-
))}
|
|
113
|
-
</div>
|
|
114
|
-
|
|
115
|
-
<div className="flex items-center gap-6 text-sm text-white/80">
|
|
116
|
-
<span>Already part of the community?</span>
|
|
117
|
-
<Link
|
|
118
|
-
href={buildPath('/login')}
|
|
119
|
-
className="inline-flex items-center gap-2 rounded-full bg-white/15 px-4 py-2 font-semibold transition hover:bg-white/25"
|
|
120
|
-
>
|
|
121
|
-
Sign in
|
|
122
|
-
</Link>
|
|
123
|
-
</div>
|
|
124
|
-
</motion.section>
|
|
125
|
-
|
|
91
|
+
<div className="min-h-screen bg-gradient-to-b from-[#F8FAFC] to-[#EBF4FB]">
|
|
92
|
+
<div className="grid min-h-screen overflow-hidden pb-12">
|
|
126
93
|
<motion.section
|
|
127
94
|
initial={{ opacity: 0, x: 24 }}
|
|
128
95
|
animate={{ opacity: 1, x: 0 }}
|
|
129
96
|
transition={{ duration: 0.4 }}
|
|
130
97
|
className="flex items-center justify-center px-6 py-12 lg:px-16"
|
|
131
98
|
>
|
|
132
|
-
<div className="w-full max-w-
|
|
133
|
-
<div className="space-y-
|
|
134
|
-
<
|
|
135
|
-
<
|
|
136
|
-
|
|
99
|
+
<div className="w-full max-w-xl space-y-10 text-center">
|
|
100
|
+
<div className="space-y-2">
|
|
101
|
+
<UserPlus strokeWidth={2} className='h-16 w-16 mx-auto text-white rounded-full bg-primary m-2 mb-4 px-4' />
|
|
102
|
+
<h2 className="text-4xl text-secondary">Create Your Account</h2>
|
|
103
|
+
<p className="text-sm text-muted">Join Holmdel Pharmacy Care for convenient healthcare access
|
|
137
104
|
</p>
|
|
138
105
|
</div>
|
|
139
106
|
|
|
140
107
|
<form
|
|
141
108
|
onSubmit={handleSubmit(onSubmit)}
|
|
142
|
-
className="space-y-6 rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50"
|
|
109
|
+
className="text-start space-y-6 rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50"
|
|
110
|
+
style={{
|
|
111
|
+
boxShadow: '0px 4px 6px -4px #0000001A, 0px 10px 15px -3px #0000001A',
|
|
112
|
+
}}
|
|
143
113
|
>
|
|
144
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
114
|
+
<div className="grid gap-4 md:grid-cols-2 text-start">
|
|
115
|
+
<div>
|
|
116
|
+
<h2 className="text-sm text-secondary mb-3">First name <span className='text-primary-500'>*</span></h2>
|
|
145
117
|
<Input
|
|
146
|
-
label="First name"
|
|
147
118
|
placeholder="Alex"
|
|
148
119
|
{...register('firstName')}
|
|
149
120
|
error={errors.firstName?.message}
|
|
150
121
|
/>
|
|
122
|
+
</div>
|
|
123
|
+
<div>
|
|
124
|
+
<h2 className="text-sm text-secondary mb-3">Last name <span className='text-primary-500'>*</span></h2>
|
|
151
125
|
<Input
|
|
152
|
-
label="Last name"
|
|
153
126
|
placeholder="Morgan"
|
|
154
127
|
{...register('lastName')}
|
|
155
128
|
error={errors.lastName?.message}
|
|
156
129
|
/>
|
|
130
|
+
</div>
|
|
157
131
|
</div>
|
|
132
|
+
<div>
|
|
133
|
+
<h2 className="text-sm text-secondary mb-3">Email Address <span className='text-primary-500'>*</span></h2>
|
|
158
134
|
<Input
|
|
159
135
|
type="email"
|
|
160
|
-
label="Email address"
|
|
161
136
|
placeholder="you@example.com"
|
|
162
137
|
{...register('email')}
|
|
163
138
|
error={errors.email?.message}
|
|
164
139
|
/>
|
|
140
|
+
</div>
|
|
141
|
+
<div>
|
|
142
|
+
<h2 className="text-sm text-secondary mb-3">Phone Number</h2>
|
|
165
143
|
<Input
|
|
166
144
|
type="tel"
|
|
167
|
-
label="Phone number (optional)"
|
|
168
145
|
placeholder="+1 (555) 123-4567"
|
|
169
146
|
{...register('phone')}
|
|
170
147
|
error={errors.phone?.message}
|
|
171
148
|
/>
|
|
149
|
+
</div>
|
|
172
150
|
<div className="relative">
|
|
151
|
+
|
|
152
|
+
<h2 className="text-sm text-secondary mb-3">Password <span className='text-primary-500'>*</span></h2>
|
|
173
153
|
<Input
|
|
174
154
|
type={showPassword ? 'text' : 'password'}
|
|
175
|
-
label="Password"
|
|
176
155
|
placeholder="••••••••"
|
|
177
156
|
{...register('password')}
|
|
178
157
|
error={errors.password?.message}
|
|
@@ -186,9 +165,9 @@ export function RegisterScreen() {
|
|
|
186
165
|
</button>
|
|
187
166
|
</div>
|
|
188
167
|
<div className="relative">
|
|
168
|
+
<h2 className="text-sm text-secondary mb-3">Confirm Password <span className='text-primary-500'>*</span></h2>
|
|
189
169
|
<Input
|
|
190
170
|
type={showConfirmPassword ? 'text' : 'password'}
|
|
191
|
-
label="Confirm password"
|
|
192
171
|
placeholder="••••••••"
|
|
193
172
|
{...register('confirmPassword')}
|
|
194
173
|
error={errors.confirmPassword?.message}
|
|
@@ -203,16 +182,16 @@ export function RegisterScreen() {
|
|
|
203
182
|
</div>
|
|
204
183
|
|
|
205
184
|
<div className="flex items-start gap-3 rounded-2xl bg-slate-50 p-4 text-sm text-slate-600">
|
|
206
|
-
<Shield className="mt-0.5 h-
|
|
185
|
+
<Shield strokeWidth={2} className="mt-0.5 h-8 w-8 text-primary" />
|
|
207
186
|
<span>
|
|
208
187
|
By creating an account, you agree to our{' '}
|
|
209
|
-
<Link href={buildPath('/terms')} className="font-semibold text-primary
|
|
188
|
+
<Link href={buildPath('/terms')} className="font-semibold text-primary hover:opacity-70">
|
|
210
189
|
Terms of Service
|
|
211
190
|
</Link>{' '}
|
|
212
191
|
and{' '}
|
|
213
192
|
<Link
|
|
214
193
|
href={buildPath('/privacy')}
|
|
215
|
-
className="font-semibold text-primary
|
|
194
|
+
className="font-semibold text-primary hover:opacity-70"
|
|
216
195
|
>
|
|
217
196
|
Privacy Policy
|
|
218
197
|
</Link>
|
|
@@ -220,18 +199,16 @@ export function RegisterScreen() {
|
|
|
220
199
|
</span>
|
|
221
200
|
</div>
|
|
222
201
|
|
|
223
|
-
<
|
|
202
|
+
<button
|
|
224
203
|
type="submit"
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
className="w-full"
|
|
204
|
+
disabled={isSubmitting}
|
|
205
|
+
className="w-full bg-secondary hover:opacity-80 text-white font-medium py-3 px-4 rounded-lg transition-colors disabled:opacity-70 disabled:cursor-not-allowed"
|
|
228
206
|
>
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
</Button>
|
|
207
|
+
{isSubmitting ? 'Creating account...' : 'Create my account'}
|
|
208
|
+
</button>
|
|
232
209
|
</form>
|
|
233
210
|
|
|
234
|
-
<div className="rounded-3xl border border-slate-100 bg-slate-50 p-6 text-sm text-slate-600">
|
|
211
|
+
{/* <div className="rounded-3xl border border-slate-100 bg-slate-50 p-6 text-sm text-slate-600">
|
|
235
212
|
<div className="flex items-start gap-3">
|
|
236
213
|
<Heart className="mt-0.5 h-5 w-5 text-primary-500" />
|
|
237
214
|
<div>
|
|
@@ -242,10 +219,14 @@ export function RegisterScreen() {
|
|
|
242
219
|
</p>
|
|
243
220
|
</div>
|
|
244
221
|
</div>
|
|
222
|
+
</div> */}
|
|
223
|
+
|
|
224
|
+
<div className="mt-4">
|
|
225
|
+
<p className="text-muted">Already have an account? <Link href={buildPath('/login')} className="font-medium text-primary transition hover:opacity-90">Sign in</Link></p>
|
|
245
226
|
</div>
|
|
246
227
|
</div>
|
|
247
228
|
</motion.section>
|
|
248
229
|
</div>
|
|
249
230
|
</div>
|
|
250
231
|
);
|
|
251
|
-
}
|
|
232
|
+
}
|
|
@@ -136,6 +136,7 @@ export default function SearchPage() {
|
|
|
136
136
|
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
|
|
137
137
|
{products.map((product) => (
|
|
138
138
|
<ProductCard
|
|
139
|
+
key={product.id}
|
|
139
140
|
product={product}
|
|
140
141
|
isFavorited={isInWishlist(product.id)}
|
|
141
142
|
onClickProduct={(p) => router.push(buildPath(`/products/${p.id}`))}
|
|
@@ -145,7 +146,7 @@ export default function SearchPage() {
|
|
|
145
146
|
) : hasSearched ? (
|
|
146
147
|
<div className="text-center py-12">
|
|
147
148
|
<div className="text-gray-500 text-lg mb-4">
|
|
148
|
-
No products found for
|
|
149
|
+
No products found for "{searchQuery}"
|
|
149
150
|
</div>
|
|
150
151
|
<p className="text-gray-500 mb-6">
|
|
151
152
|
Try different keywords or check out our{" "}
|