mirror of
https://github.com/vercel/commerce.git
synced 2025-07-26 19:51:23 +00:00
✨ feat: apply coupon code for order
:%s
This commit is contained in:
@@ -18,11 +18,6 @@
|
||||
min-height: 52.8rem;
|
||||
}
|
||||
.bot {
|
||||
.promo {
|
||||
// padding: 3.2rem;
|
||||
@apply bg-gray flex justify-between items-center;
|
||||
min-height: 6.4rem;
|
||||
}
|
||||
.price {
|
||||
margin-top: 3.2rem;
|
||||
.line {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import React from 'react'
|
||||
import s from './CheckoutBill.module.scss'
|
||||
import { CardItemCheckout } from '../../../common'
|
||||
import { CardItemCheckoutProps } from '../../../common/CardItemCheckout/CardItemCheckout'
|
||||
import { IconCirclePlus } from 'src/components/icons'
|
||||
import s from './CheckoutBill.module.scss'
|
||||
import FormPromotionCode from './FormPromotionCode/FormPromotionCode'
|
||||
|
||||
interface CheckoutBillProps {
|
||||
data: CardItemCheckoutProps[]
|
||||
@@ -20,10 +20,7 @@ const CheckoutBill = ({ data }: CheckoutBillProps) => {
|
||||
})}
|
||||
</div>
|
||||
<div className={s.bot}>
|
||||
<div className={s.promo}>
|
||||
Apply Promotion Code
|
||||
<IconCirclePlus />
|
||||
</div>
|
||||
<FormPromotionCode/>
|
||||
<div className={s.price}>
|
||||
<div className={s.line}>
|
||||
Subtotal
|
||||
|
@@ -0,0 +1,19 @@
|
||||
.promo {
|
||||
@apply bg-gray flex justify-between items-center;
|
||||
min-height: 6.4rem;
|
||||
.modalPromotion {
|
||||
min-width: 40rem;
|
||||
.bottom {
|
||||
@apply flex justify-end items-center;
|
||||
margin-top: 3.2rem;
|
||||
button {
|
||||
&:first-child {
|
||||
margin-right: 0.8rem;
|
||||
@screen md {
|
||||
margin-right: 3.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
import { Form, Formik } from 'formik';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { ButtonCommon, InputFiledInForm, ModalCommon } from 'src/components/common';
|
||||
import { useMessage } from 'src/components/contexts';
|
||||
import { useModalCommon } from 'src/components/hooks';
|
||||
import { useApplyCouponCode } from 'src/components/hooks/order';
|
||||
import { IconCirclePlus } from 'src/components/icons';
|
||||
import { LANGUAGE } from 'src/utils/language.utils';
|
||||
import { CustomInputCommon } from 'src/utils/type.utils';
|
||||
import * as Yup from 'yup';
|
||||
import s from './FormPromotionCode.module.scss';
|
||||
|
||||
const displayingErrorMessagesSchema = Yup.object().shape({
|
||||
couponCode: Yup.string().required(LANGUAGE.MESSAGE.REQUIRED),
|
||||
})
|
||||
|
||||
const FormPromotionCode = () => {
|
||||
const { visible, openModal, closeModal } = useModalCommon({ initialValue: false })
|
||||
const { showMessageError, showMessageSuccess } = useMessage()
|
||||
const { applyCouponCode, loading } = useApplyCouponCode()
|
||||
const inputRef = useRef<CustomInputCommon>(null)
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
if (visible) {
|
||||
inputRef.current?.focus()
|
||||
}
|
||||
}, 500);
|
||||
}, [visible])
|
||||
|
||||
const handleSubmit = (values: { couponCode: string }) => {
|
||||
applyCouponCode(values.couponCode, onSubmitCalBack)
|
||||
}
|
||||
|
||||
const onSubmitCalBack = (isSuccess: boolean, msg?: string) => {
|
||||
// TODO:
|
||||
if (isSuccess) {
|
||||
showMessageSuccess("Applied coupon code successfully.", 5000)
|
||||
closeModal()
|
||||
} else {
|
||||
showMessageError(msg)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={s.promo}>
|
||||
Apply Promotion Code
|
||||
<button className={s.buttonAdd} onClick={openModal}>
|
||||
<IconCirclePlus />
|
||||
</button>
|
||||
<ModalCommon
|
||||
visible={visible}
|
||||
onClose={closeModal}
|
||||
>
|
||||
<div className={s.modalPromotion}>
|
||||
<Formik
|
||||
initialValues={{
|
||||
couponCode: ''
|
||||
}}
|
||||
validationSchema={displayingErrorMessagesSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{({ errors, touched, isValid, submitForm }) => (
|
||||
<Form className="u-form">
|
||||
<div className="body">
|
||||
|
||||
<InputFiledInForm
|
||||
name="couponCode"
|
||||
placeholder="Coupon code"
|
||||
error={
|
||||
touched.couponCode && errors.couponCode
|
||||
? errors.couponCode.toString()
|
||||
: ''
|
||||
}
|
||||
isShowIconSuccess={touched.couponCode && !errors.couponCode}
|
||||
onEnter={isValid ? submitForm : undefined}
|
||||
ref={inputRef}
|
||||
/>
|
||||
</div>
|
||||
<div className={s.bottom}>
|
||||
<ButtonCommon disabled={loading} onClick={closeModal} type='light' size='small'>
|
||||
{LANGUAGE.BUTTON_LABEL.CANCEL}
|
||||
</ButtonCommon>
|
||||
<ButtonCommon HTMLType='submit' loading={loading} size='small'>
|
||||
Apply promotion code
|
||||
</ButtonCommon>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</div>
|
||||
</ModalCommon>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormPromotionCode;
|
@@ -132,7 +132,7 @@ const CheckoutInfo = ({ onViewCart }: CheckoutInfoProps) => {
|
||||
{/* TODO: remove */}
|
||||
<ButtonCommon onClick={createOrder}>test create order</ButtonCommon>
|
||||
<ButtonCommon onClick={createOrder}>test get activeStep order</ButtonCommon>
|
||||
|
||||
TOTAL: {order?.totalPrice}
|
||||
|
||||
<div className={s.title}>
|
||||
<Logo />
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Form, Formik } from 'formik'
|
||||
import React, { useRef, useState } from 'react'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { ButtonCommon, InputFiledInForm } from 'src/components/common'
|
||||
import ModalAuthenticate from 'src/components/common/ModalAuthenticate/ModalAuthenticate'
|
||||
import { useMessage } from 'src/components/contexts'
|
||||
@@ -16,6 +16,8 @@ import ModalConfirmLogin from './ModalConfirmLogin/ModalConfirmLogin'
|
||||
interface Props {
|
||||
id: number
|
||||
onConfirm: (id: number) => void
|
||||
activeStep: number
|
||||
|
||||
}
|
||||
|
||||
const displayingErrorMessagesSchema = Yup.object().shape({
|
||||
@@ -24,7 +26,7 @@ const displayingErrorMessagesSchema = Yup.object().shape({
|
||||
emailAddress: Yup.string().email(LANGUAGE.MESSAGE.INVALID_EMAIL).required(LANGUAGE.MESSAGE.REQUIRED),
|
||||
})
|
||||
|
||||
const CustomerInfoForm = ({ id, onConfirm }: Props) => {
|
||||
const CustomerInfoForm = ({ id, onConfirm, activeStep }: Props) => {
|
||||
const firstNameRef = useRef<CustomInputCommon>(null)
|
||||
const { setCustomerForOrder, loading } = useSetCustomerForOrder()
|
||||
const { showMessageError } = useMessage()
|
||||
@@ -32,6 +34,11 @@ const CustomerInfoForm = ({ id, onConfirm }: Props) => {
|
||||
const { visible: visibleModalConfirmLogin, closeModal: closeModalConfirmLogin, openModal: openModalConfirmLogin } = useModalCommon({ initialValue: false })
|
||||
const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false })
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
firstNameRef.current?.focus()
|
||||
}, 500);
|
||||
}, [activeStep])
|
||||
|
||||
const handleSubmit = (values: { firstName: string, lastName: string, emailAddress: string }) => {
|
||||
const { firstName, lastName, emailAddress } = values
|
||||
|
@@ -41,7 +41,7 @@ const provinceOptions = [
|
||||
|
||||
const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps) => {
|
||||
const addressRef = useRef<CustomInputCommon>(null)
|
||||
const { setOrderShippingAddress } = useSetOrderShippingAddress()
|
||||
const { setOrderShippingAddress, loading } = useSetOrderShippingAddress()
|
||||
const { showMessageError } = useMessage()
|
||||
|
||||
useEffect(() => {
|
||||
@@ -171,8 +171,7 @@ const ShippingInfoForm = ({ onConfirm, id, activeStep }: ShippingInfoFormProps)
|
||||
</div>
|
||||
<div className={s.bottom}>
|
||||
<ChekoutNotePolicy />
|
||||
{/* <ButtonCommon HTMLType='submit' loading={loading} size="large"> */}
|
||||
<ButtonCommon HTMLType='submit' size="large">
|
||||
<ButtonCommon HTMLType='submit' loading={loading} size="large">
|
||||
Continue to Payment
|
||||
</ButtonCommon>
|
||||
</div>
|
||||
|
@@ -46,10 +46,7 @@
|
||||
color:var(--text-base);
|
||||
}
|
||||
}
|
||||
button{
|
||||
margin-top: 2rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user