@instockng/storefront-ui 1.0.100 → 1.0.101
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/components/Checkout.d.ts +1 -3
- package/dist/components/Checkout.d.ts.map +1 -1
- package/dist/index112.mjs +1 -1
- package/dist/index113.mjs +1 -1
- package/dist/index114.mjs +6 -6
- package/dist/index115.mjs +4 -4
- package/dist/index116.mjs +3 -3
- package/dist/index117.mjs +1 -1
- package/dist/index118.mjs +1 -1
- package/dist/index119.mjs +1 -1
- package/dist/index120.mjs +2 -2
- package/dist/index121.mjs +2 -2
- package/dist/index122.mjs +3 -3
- package/dist/index123.mjs +1 -1
- package/dist/index124.mjs +3 -3
- package/dist/index125.mjs +2 -2
- package/dist/index126.mjs +2 -2
- package/dist/index127.mjs +1 -1
- package/dist/index128.mjs +3 -3
- package/dist/index129.mjs +1 -1
- package/dist/index130.mjs +1 -1
- package/dist/index131.mjs +3 -3
- package/dist/index132.mjs +2 -2
- package/dist/index133.mjs +4 -4
- package/dist/index134.mjs +1 -1
- package/dist/index135.mjs +3 -3
- package/dist/index136.mjs +4 -4
- package/dist/index137.mjs +1 -1
- package/dist/index138.mjs +1 -1
- package/dist/index139.mjs +1 -1
- package/dist/index140.mjs +1 -1
- package/dist/index141.mjs +1 -1
- package/dist/index142.mjs +1 -1
- package/dist/index143.mjs +1 -1
- package/dist/index144.mjs +2 -2
- package/dist/index145.mjs +3 -3
- package/dist/index148.mjs +1 -1
- package/dist/index150.mjs +1 -1
- package/dist/index152.mjs +1 -1
- package/dist/index153.mjs +2 -2
- package/dist/index157.mjs +2 -2
- package/dist/index160.mjs +4 -4
- package/dist/index161.mjs +5 -5
- package/dist/index162.mjs +2 -2
- package/dist/index164.mjs +2 -2
- package/dist/index165.mjs +2 -18
- package/dist/index166.mjs +11 -25
- package/dist/index167.mjs +26 -32
- package/dist/index168.mjs +32 -12
- package/dist/index169.mjs +9 -9
- package/dist/index170.mjs +18 -2
- package/dist/index171.mjs +2 -20
- package/dist/index172.mjs +13 -39
- package/dist/index173.mjs +46 -2
- package/dist/index174.mjs +2 -30
- package/dist/index175.mjs +24 -12
- package/dist/index176.mjs +18 -2
- package/dist/index177.mjs +2 -2
- package/dist/index178.mjs +2 -2
- package/dist/index179.mjs +2 -2
- package/dist/index180.mjs +2 -72
- package/dist/index181.mjs +72 -2
- package/dist/index182.mjs +2 -53
- package/dist/index183.mjs +53 -2
- package/dist/index184.mjs +2 -36
- package/dist/index185.mjs +30 -146
- package/dist/index186.mjs +152 -2
- package/dist/index187.mjs +2 -2
- package/dist/index188.mjs +2 -19
- package/dist/index189.mjs +19 -2
- package/dist/index190.mjs +2 -2
- package/dist/index191.mjs +2 -26
- package/dist/index192.mjs +26 -2
- package/dist/index193.mjs +2 -2
- package/dist/index194.mjs +2 -24
- package/dist/index195.mjs +17 -16
- package/dist/index196.mjs +23 -2
- package/dist/index198.mjs +2 -2
- package/dist/index199.mjs +2 -23
- package/dist/index20.mjs +337 -366
- package/dist/index200.mjs +23 -2
- package/dist/index201.mjs +2 -23
- package/dist/index202.mjs +23 -2
- package/dist/index203.mjs +2 -2
- package/dist/index205.mjs +2 -23
- package/dist/index206.mjs +23 -2
- package/dist/index207.mjs +2 -23
- package/dist/index208.mjs +23 -2
- package/dist/index209.mjs +2 -2
- package/dist/index210.mjs +2 -2
- package/dist/index212.mjs +2 -2
- package/dist/index213.mjs +2 -2
- package/dist/index214.mjs +2 -2
- package/dist/index215.mjs +2 -2
- package/dist/index216.mjs +2 -127
- package/dist/index217.mjs +127 -2
- package/dist/index218.mjs +2 -74
- package/dist/index219.mjs +60 -60
- package/dist/index220.mjs +74 -2
- package/dist/index221.mjs +2 -13
- package/dist/index222.mjs +2 -7
- package/dist/index223.mjs +2 -31
- package/dist/index224.mjs +2 -11
- package/dist/index225.mjs +2 -4
- package/dist/index226.mjs +2 -4
- package/dist/index227.mjs +2 -12
- package/dist/index228.mjs +2 -5
- package/dist/index229.mjs +108 -33
- package/dist/index230.mjs +2 -31
- package/dist/index231.mjs +2 -28
- package/dist/index232.mjs +34 -58
- package/dist/index233.mjs +2 -2
- package/dist/index234.mjs +244 -2
- package/dist/index235.mjs +2 -2
- package/dist/index236.mjs +33 -2
- package/dist/index237.mjs +65 -2
- package/dist/index238.mjs +25 -2
- package/dist/index239.mjs +2 -108
- package/dist/index240.mjs +2 -2
- package/dist/index242.mjs +2 -37
- package/dist/index243.mjs +2 -2
- package/dist/index244.mjs +2 -2
- package/dist/index245.mjs +2 -2
- package/dist/index247.mjs +2 -2
- package/dist/index248.mjs +2 -244
- package/dist/index249.mjs +2 -2
- package/dist/index250.mjs +13 -33
- package/dist/index251.mjs +7 -65
- package/dist/index252.mjs +30 -24
- package/dist/index253.mjs +11 -2
- package/dist/index254.mjs +4 -2
- package/dist/index255.mjs +4 -2
- package/dist/index256.mjs +12 -2
- package/dist/index257.mjs +5 -2
- package/dist/index258.mjs +33 -2
- package/dist/index259.mjs +31 -2
- package/dist/index260.mjs +28 -4
- package/dist/index261.mjs +61 -2
- package/dist/index262.mjs +2 -2
- package/dist/index263.mjs +4 -2
- package/dist/index273.mjs +2 -1
- package/dist/index274.mjs +2 -3
- package/dist/index275.mjs +2 -2
- package/dist/index276.mjs +2 -2
- package/dist/index45.mjs +1 -1
- package/dist/index47.mjs +1 -1
- package/dist/index55.mjs +1 -1
- package/dist/index77.mjs +153 -2
- package/dist/index78.mjs +2 -23
- package/dist/index79.mjs +19 -149
- package/dist/index89.mjs +1 -1
- package/package.json +1 -1
- package/src/components/Checkout.stories.tsx +1 -3
- package/src/components/Checkout.tsx +60 -94
|
@@ -18,7 +18,6 @@ import { FormSelect } from './ui/form-select';
|
|
|
18
18
|
import { Button } from './ui/button';
|
|
19
19
|
import {
|
|
20
20
|
Loader2,
|
|
21
|
-
Mail,
|
|
22
21
|
Phone,
|
|
23
22
|
Zap,
|
|
24
23
|
Banknote,
|
|
@@ -41,19 +40,20 @@ const cleanPhoneNumber = (phone: string): string => {
|
|
|
41
40
|
return phone.replace(/\D/g, '');
|
|
42
41
|
};
|
|
43
42
|
|
|
43
|
+
// Split a full name into first and last name
|
|
44
|
+
const splitFullName = (fullName: string): { firstName: string; lastName: string } => {
|
|
45
|
+
const parts = fullName.trim().split(/\s+/);
|
|
46
|
+
const firstName = parts[0] || '';
|
|
47
|
+
const lastName = parts.slice(1).join(' ') || '-';
|
|
48
|
+
return { firstName, lastName };
|
|
49
|
+
};
|
|
50
|
+
|
|
44
51
|
// Yup validation schemas for each step
|
|
45
52
|
const customerSchema = Yup.object({
|
|
46
|
-
|
|
47
|
-
.required('
|
|
48
|
-
.min(2, '
|
|
49
|
-
.max(
|
|
50
|
-
lastName: Yup.string()
|
|
51
|
-
.required('Last name is required')
|
|
52
|
-
.min(2, 'Last name must be at least 2 characters')
|
|
53
|
-
.max(50, 'Last name must be less than 50 characters'),
|
|
54
|
-
email: Yup.string()
|
|
55
|
-
.required('Email is required')
|
|
56
|
-
.email('Please enter a valid email address'),
|
|
53
|
+
fullName: Yup.string()
|
|
54
|
+
.required('Name is required')
|
|
55
|
+
.min(2, 'Name must be at least 2 characters')
|
|
56
|
+
.max(100, 'Name must be less than 100 characters'),
|
|
57
57
|
phone: Yup.string()
|
|
58
58
|
.required('Phone number is required')
|
|
59
59
|
.test('nigerian-phone', 'Please enter a valid Nigerian phone number (e.g. 0812 564 8668)', (value) => {
|
|
@@ -97,9 +97,7 @@ const paymentSchema = Yup.object({
|
|
|
97
97
|
export type PaymentMethod = 'cod' | 'online';
|
|
98
98
|
|
|
99
99
|
export interface CheckoutFormData {
|
|
100
|
-
|
|
101
|
-
lastName: string;
|
|
102
|
-
email: string;
|
|
100
|
+
fullName: string;
|
|
103
101
|
phone: string;
|
|
104
102
|
address: string;
|
|
105
103
|
city: string;
|
|
@@ -167,10 +165,10 @@ export function Checkout({
|
|
|
167
165
|
// Get TikTok attribution cookies for Events API
|
|
168
166
|
const { ttp, ttclid } = getTikTokCookies();
|
|
169
167
|
|
|
168
|
+
const { firstName, lastName } = splitFullName(formData.fullName);
|
|
170
169
|
const order = await checkout.mutateAsync({
|
|
171
|
-
firstName
|
|
172
|
-
lastName
|
|
173
|
-
email: formData.email,
|
|
170
|
+
firstName,
|
|
171
|
+
lastName,
|
|
174
172
|
phone: formData.phone,
|
|
175
173
|
address: formData.address,
|
|
176
174
|
city: formData.city,
|
|
@@ -239,9 +237,7 @@ export function Checkout({
|
|
|
239
237
|
}, [isOpen]);
|
|
240
238
|
|
|
241
239
|
const [formData, setFormData] = useState<CheckoutFormData>({
|
|
242
|
-
|
|
243
|
-
lastName: initialData?.lastName || '',
|
|
244
|
-
email: initialData?.email || '',
|
|
240
|
+
fullName: initialData?.fullName || '',
|
|
245
241
|
phone: initialData?.phone || '',
|
|
246
242
|
address: initialData?.address || '',
|
|
247
243
|
city: initialData?.city || '',
|
|
@@ -263,11 +259,10 @@ export function Checkout({
|
|
|
263
259
|
|
|
264
260
|
useEffect(() => {
|
|
265
261
|
if (isOpen && cart && !initialData && !hasLoadedCartData) {
|
|
262
|
+
const cartName = [cart.customerFirstName, cart.customerLastName].filter(Boolean).join(' ');
|
|
266
263
|
setFormData((prev) => ({
|
|
267
264
|
...prev,
|
|
268
|
-
|
|
269
|
-
lastName: cart.customerLastName || prev.lastName,
|
|
270
|
-
email: cart.customerEmail || prev.email,
|
|
265
|
+
fullName: cartName || prev.fullName,
|
|
271
266
|
phone: cart.customerPhone || prev.phone,
|
|
272
267
|
deliveryZoneId: cart.deliveryZone?.id || prev.deliveryZoneId,
|
|
273
268
|
}));
|
|
@@ -312,20 +307,16 @@ export function Checkout({
|
|
|
312
307
|
|
|
313
308
|
// Auto-save customer fields on blur
|
|
314
309
|
const handleCustomerFieldBlur = useCallback(
|
|
315
|
-
(field: '
|
|
310
|
+
(field: 'fullName' | 'phone') => {
|
|
316
311
|
const value = formData[field];
|
|
317
312
|
if (!value) return; // Don't save empty values
|
|
318
313
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
else if (field === 'email') updateData.customerEmail = value;
|
|
326
|
-
else if (field === 'phone') updateData.customerPhone = value;
|
|
327
|
-
|
|
328
|
-
updateCartMutation.mutate(updateData);
|
|
314
|
+
if (field === 'fullName') {
|
|
315
|
+
const { firstName, lastName } = splitFullName(value);
|
|
316
|
+
updateCartMutation.mutate({ customerFirstName: firstName, customerLastName: lastName });
|
|
317
|
+
} else if (field === 'phone') {
|
|
318
|
+
updateCartMutation.mutate({ customerPhone: value });
|
|
319
|
+
}
|
|
329
320
|
},
|
|
330
321
|
[formData, updateCartMutation]
|
|
331
322
|
);
|
|
@@ -415,8 +406,9 @@ export function Checkout({
|
|
|
415
406
|
|
|
416
407
|
// Initiate Paystack payment popup
|
|
417
408
|
// The onSuccess callback in the hook will handle the checkout completion
|
|
409
|
+
const { firstName: psFirstName, lastName: psLastName } = splitFullName(formData.fullName);
|
|
418
410
|
paystack.initializePayment({
|
|
419
|
-
email:
|
|
411
|
+
email: cart?.customerEmail || 'customer@example.com',
|
|
420
412
|
amount: amountInKobo,
|
|
421
413
|
currency: 'NGN',
|
|
422
414
|
metadata: {
|
|
@@ -425,9 +417,8 @@ export function Checkout({
|
|
|
425
417
|
address: formData.address,
|
|
426
418
|
city: formData.city,
|
|
427
419
|
delivery_zone_id: selectedDeliveryZoneId || formData.deliveryZoneId,
|
|
428
|
-
firstName:
|
|
429
|
-
lastName:
|
|
430
|
-
email: formData.email,
|
|
420
|
+
firstName: psFirstName,
|
|
421
|
+
lastName: psLastName,
|
|
431
422
|
phone: formData.phone,
|
|
432
423
|
fbc,
|
|
433
424
|
fbp,
|
|
@@ -437,7 +428,7 @@ export function Checkout({
|
|
|
437
428
|
{
|
|
438
429
|
display_name: 'Customer Name',
|
|
439
430
|
variable_name: 'customer_name',
|
|
440
|
-
value:
|
|
431
|
+
value: formData.fullName,
|
|
441
432
|
},
|
|
442
433
|
{
|
|
443
434
|
display_name: 'Phone Number',
|
|
@@ -474,10 +465,10 @@ export function Checkout({
|
|
|
474
465
|
// Get TikTok attribution cookies for Events API
|
|
475
466
|
const { ttp, ttclid } = getTikTokCookies();
|
|
476
467
|
|
|
468
|
+
const { firstName, lastName } = splitFullName(formData.fullName);
|
|
477
469
|
const order = await checkout.mutateAsync({
|
|
478
|
-
firstName
|
|
479
|
-
lastName
|
|
480
|
-
email: formData.email,
|
|
470
|
+
firstName,
|
|
471
|
+
lastName,
|
|
481
472
|
phone: formData.phone,
|
|
482
473
|
address: formData.address,
|
|
483
474
|
city: formData.city,
|
|
@@ -799,57 +790,32 @@ export function Checkout({
|
|
|
799
790
|
{/* Step 1: Customer Information */}
|
|
800
791
|
<div className="w-full min-w-full flex-shrink-0 p-4">
|
|
801
792
|
<div className="space-y-4">
|
|
802
|
-
<
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
name="email"
|
|
829
|
-
value={formData.email}
|
|
830
|
-
onChange={handleInputChange}
|
|
831
|
-
onBlur={() => handleCustomerFieldBlur('email')}
|
|
832
|
-
error={formErrors.email}
|
|
833
|
-
icon={<Mail size={16} />}
|
|
834
|
-
autoCorrect="off"
|
|
835
|
-
required
|
|
836
|
-
/>
|
|
837
|
-
<FormInput
|
|
838
|
-
label="Phone Number"
|
|
839
|
-
type="tel"
|
|
840
|
-
name="phone"
|
|
841
|
-
value={formData.phone}
|
|
842
|
-
onChange={handleInputChange}
|
|
843
|
-
onBlur={() => handleCustomerFieldBlur('phone')}
|
|
844
|
-
placeholder="e.g. 08012345678"
|
|
845
|
-
maxLength={18}
|
|
846
|
-
error={formErrors.phone}
|
|
847
|
-
icon={<Phone size={16} />}
|
|
848
|
-
autoCorrect="off"
|
|
849
|
-
required
|
|
850
|
-
className="font-semibold"
|
|
851
|
-
/>
|
|
852
|
-
</div>
|
|
793
|
+
<FormInput
|
|
794
|
+
label="Full Name"
|
|
795
|
+
type="text"
|
|
796
|
+
name="fullName"
|
|
797
|
+
value={formData.fullName}
|
|
798
|
+
onChange={handleInputChange}
|
|
799
|
+
onBlur={() => handleCustomerFieldBlur('fullName')}
|
|
800
|
+
error={formErrors.fullName}
|
|
801
|
+
autoCorrect="off"
|
|
802
|
+
required
|
|
803
|
+
/>
|
|
804
|
+
<FormInput
|
|
805
|
+
label="Phone Number"
|
|
806
|
+
type="tel"
|
|
807
|
+
name="phone"
|
|
808
|
+
value={formData.phone}
|
|
809
|
+
onChange={handleInputChange}
|
|
810
|
+
onBlur={() => handleCustomerFieldBlur('phone')}
|
|
811
|
+
placeholder="e.g. 08012345678"
|
|
812
|
+
maxLength={18}
|
|
813
|
+
error={formErrors.phone}
|
|
814
|
+
icon={<Phone size={16} />}
|
|
815
|
+
autoCorrect="off"
|
|
816
|
+
required
|
|
817
|
+
className="font-semibold"
|
|
818
|
+
/>
|
|
853
819
|
</div>
|
|
854
820
|
</div>
|
|
855
821
|
|