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.
Files changed (45) hide show
  1. package/dist/index.d.mts +2 -4
  2. package/dist/index.d.ts +2 -4
  3. package/dist/index.js +1039 -857
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +1039 -856
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +3 -3
  8. package/src/components/AccountAddressesTab.tsx +209 -0
  9. package/src/components/AccountOrdersTab.tsx +151 -0
  10. package/src/components/AccountOverviewTab.tsx +209 -0
  11. package/src/components/AccountPaymentTab.tsx +116 -0
  12. package/src/components/AccountSavedItemsTab.tsx +76 -0
  13. package/src/components/AccountSettingsTab.tsx +116 -0
  14. package/src/components/AddressFormModal.tsx +23 -10
  15. package/src/components/CartItem.tsx +60 -56
  16. package/src/components/Header.tsx +69 -16
  17. package/src/components/Notification.tsx +148 -0
  18. package/src/components/ProductCard.tsx +215 -178
  19. package/src/components/QuickViewModal.tsx +314 -0
  20. package/src/components/TabNavigation.tsx +48 -0
  21. package/src/components/ui/Button.tsx +1 -1
  22. package/src/components/ui/ConfirmModal.tsx +84 -0
  23. package/src/hooks/usePaymentMethods.ts +58 -0
  24. package/src/index.ts +0 -1
  25. package/src/providers/CartProvider.tsx +22 -6
  26. package/src/providers/EcommerceProvider.tsx +8 -7
  27. package/src/providers/FavoritesProvider.tsx +10 -3
  28. package/src/providers/NotificationProvider.tsx +79 -0
  29. package/src/providers/WishlistProvider.tsx +34 -9
  30. package/src/screens/AddressesScreen.tsx +72 -61
  31. package/src/screens/CartScreen.tsx +48 -32
  32. package/src/screens/ChangePasswordScreen.tsx +155 -0
  33. package/src/screens/CheckoutScreen.tsx +162 -125
  34. package/src/screens/EditProfileScreen.tsx +165 -0
  35. package/src/screens/LoginScreen.tsx +59 -72
  36. package/src/screens/NewAddressScreen.tsx +16 -10
  37. package/src/screens/ProductDetailScreen.tsx +334 -234
  38. package/src/screens/ProfileScreen.tsx +190 -200
  39. package/src/screens/RegisterScreen.tsx +51 -70
  40. package/src/screens/SearchResultsScreen.tsx +2 -1
  41. package/src/screens/ShopScreen.tsx +260 -384
  42. package/src/screens/WishlistScreen.tsx +226 -224
  43. package/src/styles/globals.css +9 -0
  44. package/src/screens/CategoriesScreen.tsx +0 -122
  45. 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 { toast } from 'sonner';
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
- toast.success('Account created successfully!');
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
- toast.error(error.response?.data?.message || 'Failed to create account');
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-slate-50">
85
- <div className="grid min-h-screen overflow-hidden bg-white lg:grid-cols-[0.95fr_1.05fr]">
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-lg space-y-10">
133
- <div className="space-y-3">
134
- <h2 className="text-3xl font-bold text-slate-900">Create an account</h2>
135
- <p className="text-sm text-slate-500">
136
- Start your personalized care journey with pharmacist-backed guidance.
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-5 w-5 text-primary-500" />
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-600 hover:text-primary-700">
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-600 hover:text-primary-700"
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
- <Button
202
+ <button
224
203
  type="submit"
225
- size="lg"
226
- isLoading={isSubmitting}
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
- <UserPlus className="h-5 w-5" />
230
- Create my account
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 "{searchQuery}"
149
+ No products found for &quot;{searchQuery}&quot;
149
150
  </div>
150
151
  <p className="text-gray-500 mb-6">
151
152
  Try different keywords or check out our{" "}