hey-pharmacist-ecommerce 1.0.5 → 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.
- package/README.md +107 -1
- package/dist/index.d.mts +3636 -316
- package/dist/index.d.ts +3636 -316
- package/dist/index.js +6802 -3866
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6756 -3818
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -14
- package/src/components/AddressFormModal.tsx +171 -0
- package/src/components/CartItem.tsx +17 -12
- package/src/components/FilterChips.tsx +195 -0
- package/src/components/Header.tsx +121 -71
- package/src/components/OrderCard.tsx +18 -25
- package/src/components/ProductCard.tsx +209 -72
- package/src/components/ui/Button.tsx +13 -5
- package/src/components/ui/Card.tsx +46 -0
- package/src/hooks/useAddresses.ts +83 -0
- package/src/hooks/useOrders.ts +37 -19
- package/src/hooks/useProducts.ts +55 -63
- package/src/hooks/useWishlistProducts.ts +75 -0
- package/src/index.ts +3 -19
- package/src/lib/Apis/api.ts +1 -0
- package/src/lib/Apis/apis/cart-api.ts +3 -3
- package/src/lib/Apis/apis/inventory-api.ts +0 -108
- package/src/lib/Apis/apis/stores-api.ts +70 -0
- package/src/lib/Apis/apis/wishlist-api.ts +447 -0
- package/src/lib/Apis/models/cart-item-populated.ts +0 -1
- package/src/lib/Apis/models/create-single-variant-product-dto.ts +3 -10
- package/src/lib/Apis/models/create-variant-dto.ts +26 -33
- package/src/lib/Apis/models/extended-product-dto.ts +20 -24
- package/src/lib/Apis/models/index.ts +2 -1
- package/src/lib/Apis/models/order-time-line-dto.ts +49 -0
- package/src/lib/Apis/models/order.ts +3 -8
- package/src/lib/Apis/models/populated-order.ts +3 -8
- package/src/lib/Apis/models/product-variant.ts +29 -0
- package/src/lib/Apis/models/update-product-variant-dto.ts +16 -23
- package/src/lib/Apis/models/wishlist.ts +51 -0
- package/src/lib/Apis/wrapper.ts +18 -7
- package/src/lib/api-adapter/index.ts +0 -12
- package/src/lib/types/index.ts +16 -61
- package/src/lib/utils/colors.ts +7 -4
- package/src/lib/utils/format.ts +1 -1
- package/src/lib/validations/address.ts +14 -0
- package/src/providers/AuthProvider.tsx +61 -31
- package/src/providers/CartProvider.tsx +18 -28
- package/src/providers/EcommerceProvider.tsx +7 -0
- package/src/providers/FavoritesProvider.tsx +86 -0
- package/src/providers/ThemeProvider.tsx +16 -1
- package/src/providers/WishlistProvider.tsx +174 -0
- package/src/screens/AddressesScreen.tsx +484 -0
- package/src/screens/CartScreen.tsx +120 -84
- package/src/screens/CategoriesScreen.tsx +120 -0
- package/src/screens/CheckoutScreen.tsx +919 -241
- package/src/screens/CurrentOrdersScreen.tsx +125 -61
- package/src/screens/HomeScreen.tsx +209 -0
- package/src/screens/LoginScreen.tsx +133 -88
- package/src/screens/NewAddressScreen.tsx +187 -0
- package/src/screens/OrdersScreen.tsx +162 -50
- package/src/screens/ProductDetailScreen.tsx +641 -190
- package/src/screens/ProfileScreen.tsx +192 -116
- package/src/screens/RegisterScreen.tsx +193 -144
- package/src/screens/SearchResultsScreen.tsx +165 -0
- package/src/screens/ShopScreen.tsx +1110 -146
- package/src/screens/WishlistScreen.tsx +428 -0
- package/src/lib/Apis/models/inventory-paginated-response.ts +0 -75
- package/src/lib/api/auth.ts +0 -81
- package/src/lib/api/cart.ts +0 -42
- package/src/lib/api/orders.ts +0 -53
- package/src/lib/api/products.ts +0 -51
- package/src/lib/api-adapter/auth-adapter.ts +0 -196
- package/src/lib/api-adapter/cart-adapter.ts +0 -193
- package/src/lib/api-adapter/mappers.ts +0 -152
- package/src/lib/api-adapter/orders-adapter.ts +0 -195
- package/src/lib/api-adapter/products-adapter.ts +0 -194
|
@@ -5,16 +5,24 @@ import { motion } from 'framer-motion';
|
|
|
5
5
|
import { useForm } from 'react-hook-form';
|
|
6
6
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
8
|
+
import { useRouter, useSearchParams } from 'next/navigation';
|
|
9
|
+
import Link from 'next/link';
|
|
10
|
+
import {
|
|
11
|
+
ArrowRight,
|
|
12
|
+
Eye,
|
|
13
|
+
EyeOff,
|
|
14
|
+
HeartPulse,
|
|
15
|
+
Lock,
|
|
16
|
+
ShieldCheck,
|
|
17
|
+
Sparkles,
|
|
18
|
+
} from 'lucide-react';
|
|
10
19
|
import { Input } from '@/components/ui/Input';
|
|
20
|
+
import { Button } from '@/components/ui/Button';
|
|
11
21
|
import { useAuth } from '@/providers/AuthProvider';
|
|
12
|
-
import { useRouter, useSearchParams } from 'next/navigation';
|
|
13
22
|
import { toast } from 'sonner';
|
|
14
|
-
import Link from 'next/link';
|
|
15
23
|
|
|
16
24
|
const loginSchema = z.object({
|
|
17
|
-
email: z.string().email('
|
|
25
|
+
email: z.string().email('Enter a valid email address'),
|
|
18
26
|
password: z.string().min(6, 'Password must be at least 6 characters'),
|
|
19
27
|
});
|
|
20
28
|
|
|
@@ -50,100 +58,137 @@ export function LoginScreen() {
|
|
|
50
58
|
};
|
|
51
59
|
|
|
52
60
|
return (
|
|
53
|
-
<div className="min-h-screen bg-
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<div className="
|
|
62
|
-
<
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
<
|
|
61
|
+
<div className="min-h-screen bg-slate-50">
|
|
62
|
+
<div className="grid min-h-screen overflow-hidden bg-white lg:grid-cols-[1.1fr_0.9fr]">
|
|
63
|
+
<motion.section
|
|
64
|
+
initial={{ opacity: 0, x: -24 }}
|
|
65
|
+
animate={{ opacity: 1, x: 0 }}
|
|
66
|
+
transition={{ duration: 0.4 }}
|
|
67
|
+
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"
|
|
68
|
+
>
|
|
69
|
+
<div className="space-y-6">
|
|
70
|
+
<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">
|
|
71
|
+
<HeartPulse className="h-4 w-4" />
|
|
72
|
+
Hey Pharmacist
|
|
73
|
+
</span>
|
|
74
|
+
<h1 className="text-4xl font-bold leading-tight lg:text-5xl">
|
|
75
|
+
Pharmacy-grade care for your household
|
|
76
|
+
</h1>
|
|
77
|
+
<p className="max-w-xl text-white/80">
|
|
78
|
+
Log in to unlock personalized regimens, pharmacist support, and fast delivery on
|
|
79
|
+
wellness essentials curated just for you.
|
|
80
|
+
</p>
|
|
67
81
|
</div>
|
|
68
82
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
<div className="grid gap-4 rounded-3xl bg-white/10 p-6 backdrop-blur">
|
|
84
|
+
<div className="flex items-center gap-3">
|
|
85
|
+
<ShieldCheck className="h-5 w-5 text-white" />
|
|
86
|
+
<p className="text-sm text-white/80">
|
|
87
|
+
HIPAA-compliant security keeps your health information protected.
|
|
88
|
+
</p>
|
|
89
|
+
</div>
|
|
90
|
+
<div className="flex items-center gap-3">
|
|
91
|
+
<Sparkles className="h-5 w-5 text-white" />
|
|
92
|
+
<p className="text-sm text-white/80">
|
|
93
|
+
Pharmacists ready to chat in under 10 minutes for medication support.
|
|
94
|
+
</p>
|
|
79
95
|
</div>
|
|
96
|
+
</div>
|
|
80
97
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
/>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
<div className="flex items-center gap-6 text-sm text-white/80">
|
|
99
|
+
<span>Need an account?</span>
|
|
100
|
+
<Link
|
|
101
|
+
href="/register"
|
|
102
|
+
className="inline-flex items-center gap-2 rounded-full bg-white/15 px-4 py-2 font-semibold transition hover:bg-white/25"
|
|
103
|
+
>
|
|
104
|
+
Create one now
|
|
105
|
+
<ArrowRight className="h-4 w-4" />
|
|
106
|
+
</Link>
|
|
107
|
+
</div>
|
|
108
|
+
</motion.section>
|
|
109
|
+
|
|
110
|
+
<motion.section
|
|
111
|
+
initial={{ opacity: 0, x: 24 }}
|
|
112
|
+
animate={{ opacity: 1, x: 0 }}
|
|
113
|
+
transition={{ duration: 0.4 }}
|
|
114
|
+
className="flex items-center justify-center px-6 py-12 lg:px-16"
|
|
115
|
+
>
|
|
116
|
+
<div className="w-full max-w-md space-y-10">
|
|
117
|
+
<div className="space-y-2">
|
|
118
|
+
<h2 className="text-3xl font-bold text-slate-900">Sign in</h2>
|
|
119
|
+
<p className="text-sm text-slate-500">
|
|
120
|
+
Welcome back! Enter your details to continue your personalized care plan.
|
|
121
|
+
</p>
|
|
100
122
|
</div>
|
|
101
123
|
|
|
102
|
-
<
|
|
103
|
-
<
|
|
104
|
-
<
|
|
105
|
-
type="
|
|
106
|
-
|
|
124
|
+
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6 rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50">
|
|
125
|
+
<div>
|
|
126
|
+
<Input
|
|
127
|
+
type="email"
|
|
128
|
+
label="Email address"
|
|
129
|
+
placeholder="you@example.com"
|
|
130
|
+
{...register('email')}
|
|
131
|
+
error={errors.email?.message}
|
|
107
132
|
/>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
133
|
+
</div>
|
|
134
|
+
<div className="relative">
|
|
135
|
+
<Input
|
|
136
|
+
type={showPassword ? 'text' : 'password'}
|
|
137
|
+
label="Password"
|
|
138
|
+
placeholder="••••••••"
|
|
139
|
+
{...register('password')}
|
|
140
|
+
error={errors.password?.message}
|
|
141
|
+
/>
|
|
142
|
+
<button
|
|
143
|
+
type="button"
|
|
144
|
+
onClick={() => setShowPassword((prev) => !prev)}
|
|
145
|
+
className="absolute right-3 top-[42px] text-slate-400 transition hover:text-slate-600"
|
|
146
|
+
>
|
|
147
|
+
{showPassword ? <EyeOff className="h-5 w-5" /> : <Eye className="h-5 w-5" />}
|
|
148
|
+
</button>
|
|
149
|
+
</div>
|
|
117
150
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
151
|
+
<div className="flex items-center justify-between text-sm">
|
|
152
|
+
<label className="flex items-center gap-2 text-slate-600">
|
|
153
|
+
<input
|
|
154
|
+
type="checkbox"
|
|
155
|
+
className="h-4 w-4 rounded border-slate-300 text-primary-600 focus:ring-primary-500"
|
|
156
|
+
/>
|
|
157
|
+
Remember me
|
|
158
|
+
</label>
|
|
159
|
+
<Link
|
|
160
|
+
href="/forgot-password"
|
|
161
|
+
className="font-medium text-primary-600 transition hover:text-primary-700"
|
|
162
|
+
>
|
|
163
|
+
Forgot password?
|
|
164
|
+
</Link>
|
|
165
|
+
</div>
|
|
127
166
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
167
|
+
<Button
|
|
168
|
+
type="submit"
|
|
169
|
+
size="lg"
|
|
170
|
+
isLoading={isSubmitting}
|
|
171
|
+
className="w-full"
|
|
172
|
+
>
|
|
173
|
+
Sign in securely
|
|
174
|
+
</Button>
|
|
175
|
+
</form>
|
|
176
|
+
|
|
177
|
+
<div className="rounded-3xl border border-slate-100 bg-slate-50 p-6 text-sm text-slate-600">
|
|
178
|
+
<div className="flex items-start gap-3">
|
|
179
|
+
<Lock className="mt-0.5 h-5 w-5 text-primary-500" />
|
|
180
|
+
<div>
|
|
181
|
+
<p className="font-semibold text-slate-800">Secure by design</p>
|
|
182
|
+
<p>
|
|
183
|
+
Encrypted sessions, multi-factor ready, and privacy-first policies keep your
|
|
184
|
+
personal data safe.
|
|
185
|
+
</p>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
135
188
|
</div>
|
|
136
189
|
</div>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
<Link href="/register">
|
|
140
|
-
<Button variant="outline" size="lg" className="w-full">
|
|
141
|
-
Create an Account
|
|
142
|
-
</Button>
|
|
143
|
-
</Link>
|
|
144
|
-
</div>
|
|
145
|
-
</motion.div>
|
|
190
|
+
</motion.section>
|
|
191
|
+
</div>
|
|
146
192
|
</div>
|
|
147
193
|
);
|
|
148
194
|
}
|
|
149
|
-
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { useRouter } from 'next/navigation';
|
|
5
|
+
import { useForm } from 'react-hook-form';
|
|
6
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
7
|
+
import { Button } from '@/components/ui/Button';
|
|
8
|
+
import { Input } from '@/components/ui/Input';
|
|
9
|
+
import { addressSchema, type AddressFormData } from '@/lib/validations/address';
|
|
10
|
+
import { AddressesApi } from '@/lib/Apis/apis/addresses-api';
|
|
11
|
+
import { AXIOS_CONFIG } from '@/lib/Apis/wrapper';
|
|
12
|
+
import { toast } from 'sonner';
|
|
13
|
+
import { ArrowLeft, MapPin } from 'lucide-react';
|
|
14
|
+
|
|
15
|
+
export default function NewAddressPage() {
|
|
16
|
+
const router = useRouter();
|
|
17
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
register,
|
|
21
|
+
handleSubmit,
|
|
22
|
+
formState: { errors }
|
|
23
|
+
} = useForm<AddressFormData>({
|
|
24
|
+
resolver: zodResolver(addressSchema),
|
|
25
|
+
defaultValues: {
|
|
26
|
+
country: 'United States'
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const onSubmit = async (data: AddressFormData) => {
|
|
31
|
+
setIsSubmitting(true);
|
|
32
|
+
try {
|
|
33
|
+
console.log('Submitting address data:', data);
|
|
34
|
+
const api = new AddressesApi(AXIOS_CONFIG);
|
|
35
|
+
const response = await api.createAddressForUser({
|
|
36
|
+
name: data.name,
|
|
37
|
+
street1: data.street1,
|
|
38
|
+
street2: data.street2,
|
|
39
|
+
city: data.city,
|
|
40
|
+
state: data.state,
|
|
41
|
+
zip: data.zip,
|
|
42
|
+
country: data.country,
|
|
43
|
+
phone: data.phone,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
toast.success('Address added successfully');
|
|
47
|
+
router.back();
|
|
48
|
+
|
|
49
|
+
} catch (error: any) {
|
|
50
|
+
let errorMessage = 'An unexpected error occurred';
|
|
51
|
+
|
|
52
|
+
// Handle specific API errors
|
|
53
|
+
if (error.response?.data?.message) {
|
|
54
|
+
errorMessage = error.response.data.message;
|
|
55
|
+
} else if (error.message) {
|
|
56
|
+
errorMessage = error.message;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Handle validation errors
|
|
60
|
+
if (error.response?.status === 400) {
|
|
61
|
+
errorMessage = error.response.data?.message || 'Please check your address details and try again';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Handle network errors
|
|
65
|
+
if (error.message === 'Network Error') {
|
|
66
|
+
errorMessage = 'Unable to connect to the server. Please check your internet connection.';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
toast.error('Unable to save address', {
|
|
70
|
+
description: errorMessage,
|
|
71
|
+
duration: 5000
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Show additional guidance for certain error types
|
|
75
|
+
if (error.response?.status === 422) {
|
|
76
|
+
toast.info('Address validation failed', {
|
|
77
|
+
description: 'Make sure your address is complete and formatted correctly.',
|
|
78
|
+
duration: 6000
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
} finally {
|
|
82
|
+
setIsSubmitting(false);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className="min-h-screen bg-slate-50">
|
|
88
|
+
<div className="relative bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white">
|
|
89
|
+
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" />
|
|
90
|
+
<div className="relative container mx-auto px-4 py-8">
|
|
91
|
+
<button
|
|
92
|
+
onClick={() => router.back()}
|
|
93
|
+
className="inline-flex items-center gap-2 rounded-lg bg-white/10 px-4 py-2 text-sm font-medium text-white hover:bg-white/20 transition-colors"
|
|
94
|
+
>
|
|
95
|
+
<ArrowLeft className="h-4 w-4" />
|
|
96
|
+
Back
|
|
97
|
+
</button>
|
|
98
|
+
<div className="mt-6 flex items-center gap-4">
|
|
99
|
+
<div className="rounded-full bg-white/10 p-3">
|
|
100
|
+
<MapPin className="h-6 w-6" />
|
|
101
|
+
</div>
|
|
102
|
+
<div>
|
|
103
|
+
<h1 className="text-3xl font-bold">Add New Address</h1>
|
|
104
|
+
<p className="mt-1 text-white/75">
|
|
105
|
+
Enter your delivery address details below.
|
|
106
|
+
</p>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div className="container mx-auto px-4 py-8">
|
|
113
|
+
<div className="max-w-2xl mx-auto">
|
|
114
|
+
<div className="bg-white rounded-2xl shadow-xl p-6">
|
|
115
|
+
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
|
|
116
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
117
|
+
<Input
|
|
118
|
+
label="Full name"
|
|
119
|
+
placeholder="John Doe"
|
|
120
|
+
{...register('name')}
|
|
121
|
+
error={errors.name?.message}
|
|
122
|
+
/>
|
|
123
|
+
<Input
|
|
124
|
+
label="Phone number"
|
|
125
|
+
placeholder="+1 (555) 123-4567"
|
|
126
|
+
{...register('phone')}
|
|
127
|
+
error={errors.phone?.message}
|
|
128
|
+
/>
|
|
129
|
+
<div className="md:col-span-2">
|
|
130
|
+
<Input
|
|
131
|
+
label="Address line 1"
|
|
132
|
+
placeholder="123 Main St"
|
|
133
|
+
{...register('street1')}
|
|
134
|
+
error={errors.street1?.message}
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
<div className="md:col-span-2">
|
|
138
|
+
<Input
|
|
139
|
+
label="Address line 2 (optional)"
|
|
140
|
+
placeholder="Apt 4B"
|
|
141
|
+
{...register('street2')}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
<Input
|
|
145
|
+
label="City"
|
|
146
|
+
placeholder="New York"
|
|
147
|
+
{...register('city')}
|
|
148
|
+
error={errors.city?.message}
|
|
149
|
+
/>
|
|
150
|
+
<Input
|
|
151
|
+
label="State"
|
|
152
|
+
placeholder="NY"
|
|
153
|
+
{...register('state')}
|
|
154
|
+
error={errors.state?.message}
|
|
155
|
+
/>
|
|
156
|
+
<Input
|
|
157
|
+
label="ZIP code"
|
|
158
|
+
placeholder="10001"
|
|
159
|
+
{...register('zip')}
|
|
160
|
+
error={errors.zip?.message}
|
|
161
|
+
/>
|
|
162
|
+
<Input
|
|
163
|
+
label="Country"
|
|
164
|
+
placeholder="United States"
|
|
165
|
+
{...register('country')}
|
|
166
|
+
error={errors.country?.message}
|
|
167
|
+
/>
|
|
168
|
+
</div>
|
|
169
|
+
<div className="flex justify-end gap-4">
|
|
170
|
+
<Button
|
|
171
|
+
type="button"
|
|
172
|
+
variant="outline"
|
|
173
|
+
onClick={() => router.back()}
|
|
174
|
+
>
|
|
175
|
+
Cancel
|
|
176
|
+
</Button>
|
|
177
|
+
<Button type="submit" disabled={isSubmitting}>
|
|
178
|
+
{isSubmitting ? 'Adding Address...' : 'Add Address'}
|
|
179
|
+
</Button>
|
|
180
|
+
</div>
|
|
181
|
+
</form>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
}
|