-
+
+ {
+ FILTER_PAGE.includes(router.pathname) && (
+
+ )
+ }
+
+
+
@@ -72,6 +85,16 @@ const HeaderMenu = memo(({ isFull, openModalAuthen, openModalInfo }: Props) => {
+
+ {
+ FILTER_PAGE.includes(router.pathname) && (
+
+
+
+ )
+ }
)
diff --git a/src/components/common/InputCommon/InputCommon.module.scss b/src/components/common/InputCommon/InputCommon.module.scss
index acfc07647..6b12d2bbd 100644
--- a/src/components/common/InputCommon/InputCommon.module.scss
+++ b/src/components/common/InputCommon/InputCommon.module.scss
@@ -15,9 +15,9 @@
.icon + .inputCommon {
padding-left: 4.8rem;
}
-
+
.inputCommon {
- @apply block w-full transition-all duration-200 rounded;
+ @apply block w-full transition-all duration-200 rounded bg-white;
padding: 1.2rem 1.6rem;
border: 1px solid var(--border-line);
&:hover,
diff --git a/src/components/common/InputCommon/InputCommon.tsx b/src/components/common/InputCommon/InputCommon.tsx
index 943b0a632..0389c99b3 100644
--- a/src/components/common/InputCommon/InputCommon.tsx
+++ b/src/components/common/InputCommon/InputCommon.tsx
@@ -6,6 +6,7 @@ import s from './InputCommon.module.scss';
type Ref = {
focus: () => void
+ getValue: () => string | number
} | null;
interface Props {
children?: React.ReactNode,
diff --git a/src/components/common/Layout/Layout.module.scss b/src/components/common/Layout/Layout.module.scss
index e495667eb..30e4a077d 100644
--- a/src/components/common/Layout/Layout.module.scss
+++ b/src/components/common/Layout/Layout.module.scss
@@ -6,3 +6,8 @@
flex: 1;
}
}
+.filter{
+ @screen xl {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/src/components/common/Layout/Layout.tsx b/src/components/common/Layout/Layout.tsx
index a808c33ff..204956fbd 100644
--- a/src/components/common/Layout/Layout.tsx
+++ b/src/components/common/Layout/Layout.tsx
@@ -1,10 +1,13 @@
import { CommerceProvider } from '@framework'
import { useRouter } from 'next/router'
import { FC } from 'react'
+import { FilterProvider } from 'src/components/contexts/FilterContext'
import { useModalCommon } from 'src/components/hooks'
+import { BRAND, CATEGORY, FEATURED } from 'src/utils/constanst.utils'
import { CartDrawer, CustomShapeSvg } from '..'
import Footer from '../Footer/Footer'
import Header from '../Header/Header'
+import MenuNavigationProductList from '../MenuNavigationProductList/MenuNavigationProductList'
import s from './Layout.module.scss'
interface Props {
@@ -16,6 +19,7 @@ interface Props {
const Layout: FC
= ({ children }) => {
const { locale = 'en-US' } = useRouter()
const { visible: visibleCartDrawer, openModal, closeModal: closeCartDrawer } = useModalCommon({ initialValue: false })
+ const { visible: visibleFilter, openModal: openFilter, closeModal: closeFilter } = useModalCommon({ initialValue: false })
const toggle = () => {
if (visibleCartDrawer) {
@@ -24,18 +28,27 @@ const Layout: FC = ({ children }) => {
openModal()
}
}
+ const toggleFilter = () => {
+ console.log("click")
+ if (visibleFilter) {
+ closeFilter()
+ } else {
+ openFilter()
+ }
+ }
return (
-
-
- {children}
-
-
-
-
-
+
+
+ {children}
+
+
+
+
+
+
)
diff --git a/src/components/common/MenuFilter/MenuFilter.module.scss b/src/components/common/MenuFilter/MenuFilter.module.scss
index c0810c4bd..87a792297 100644
--- a/src/components/common/MenuFilter/MenuFilter.module.scss
+++ b/src/components/common/MenuFilter/MenuFilter.module.scss
@@ -1,9 +1,7 @@
@import "../../../styles/utilities";
.menuFilterWrapper{
@apply spacing-horizontal;
- @screen md {
- @apply hidden;
- }
+
.menuFilterHeading{
@apply sub-headline font-bold ;
color: var(--text-active);
diff --git a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss
index 3eeda052c..042785c05 100644
--- a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss
+++ b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss
@@ -1,18 +1,17 @@
@import "../../../styles/utilities";
.menuNavigationProductListDesktop{
- @screen sm-only {
+ @screen sm {
@apply hidden;
}
+
+ @screen xl {
+ @apply block;
+ }
}
.menuNavigationProductListMobile{
@apply relative transition-all duration-100;
- @screen md{
- @apply hidden;
- }
- @screen xl{
- @apply hidden;
- }
+
&.isShow{
&::after{
content: "";
diff --git a/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss b/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss
index be232308a..19bd605f8 100644
--- a/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss
+++ b/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss
@@ -1,9 +1,7 @@
@import "../../../../styles/utilities";
.menuSortWrapper{
@apply spacing-horizontal;
- @screen md {
- @apply hidden;
- }
+
.menuSortHeading{
@apply sub-headline font-bold ;
color: var(--text-active);
diff --git a/src/components/common/ModalCommon/ModalCommon.tsx b/src/components/common/ModalCommon/ModalCommon.tsx
index 75222c162..7f9bc07d8 100644
--- a/src/components/common/ModalCommon/ModalCommon.tsx
+++ b/src/components/common/ModalCommon/ModalCommon.tsx
@@ -1,6 +1,6 @@
import React, { useRef } from 'react'
import { Close } from 'src/components/icons'
-import { useOnClickOutside } from 'src/utils/useClickOutSide'
+import { useOnClickOutside } from 'src/components/hooks/useClickOutSide'
import s from './ModalCommon.module.scss'
export interface ModalCommonProps {
onClose: () => void
diff --git a/src/components/common/TabCommon/TabCommon.module.scss b/src/components/common/TabCommon/TabCommon.module.scss
index 529d82f0d..d8b5d0f9a 100644
--- a/src/components/common/TabCommon/TabCommon.module.scss
+++ b/src/components/common/TabCommon/TabCommon.module.scss
@@ -25,4 +25,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/components/common/TabCommon/TabCommon.tsx b/src/components/common/TabCommon/TabCommon.tsx
index 9a65b7879..7214361f7 100644
--- a/src/components/common/TabCommon/TabCommon.tsx
+++ b/src/components/common/TabCommon/TabCommon.tsx
@@ -82,4 +82,4 @@ import React, {
)
}
- export default TabCommon
\ No newline at end of file
+ export default TabCommon
diff --git a/src/components/common/TabCommon/components/TabItem/TabItem.module.scss b/src/components/common/TabCommon/components/TabItem/TabItem.module.scss
index e378955db..159a38f57 100644
--- a/src/components/common/TabCommon/components/TabItem/TabItem.module.scss
+++ b/src/components/common/TabCommon/components/TabItem/TabItem.module.scss
@@ -10,4 +10,4 @@
&.tabItemActive {
@apply font-bold;
}
-}
\ No newline at end of file
+}
diff --git a/src/components/common/TabCommon/components/TabItem/TabItem.tsx b/src/components/common/TabCommon/components/TabItem/TabItem.tsx
index fc9a20822..cc1737e44 100644
--- a/src/components/common/TabCommon/components/TabItem/TabItem.tsx
+++ b/src/components/common/TabCommon/components/TabItem/TabItem.tsx
@@ -1,5 +1,9 @@
import classNames from 'classnames'
+<<<<<<< HEAD
+import React, { RefObject, useRef } from 'react'
+=======
import React from 'react'
+>>>>>>> 88f90912429447f6ae7bafa77484465965e0ee13
import s from './TabItem.module.scss'
interface TabItemProps {
@@ -28,4 +32,8 @@ const TabItem = ({
)
}
-export default TabItem
\ No newline at end of file
+<<<<<<< HEAD
+export default TabItem
+=======
+export default TabItem
+>>>>>>> 88f90912429447f6ae7bafa77484465965e0ee13
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index 5b821317f..7de333d3a 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -32,6 +32,7 @@ export { default as ModalConfirm} from "./ModalConfirm/ModalConfirm"
export { default as ModalInfo} from "./ModalInfo/ModalInfo"
export { default as ProductList} from "./ProductList/ProductList"
export { default as ModalCreateUserInfo} from './ModalCreateUserInfo/ModalCreateUserInfo'
+export { default as CardItemCheckout} from './CardItemCheckout/CardItemCheckout'
export { default as CardBlog} from './CardBlog/CardBlog'
export { default as RelevantBlogPosts} from './RelevantBlogPosts/RelevantBlogPosts'
export { default as CollapseCommon} from './CollapseCommon/CollapseCommon'
@@ -40,6 +41,8 @@ export { default as ImgWithLink} from './ImgWithLink/ImgWithLink'
export { default as RecipeDetail} from './RecipeDetail/RecipeDetail'
export { default as DrawerCommon} from './DrawerCommon/DrawerCommon'
export { default as CartDrawer} from './CartDrawer/CartDrawer'
+export { default as TabPane} from './TabCommon/components/TabPane/TabPane'
+export { default as TabCommon} from './TabCommon/TabCommon'
export { default as StaticImage} from './StaticImage/StaticImage'
export { default as EmptyCommon} from './EmptyCommon/EmptyCommon'
export { default as CustomShapeSvg} from './CustomShapeSvg/CustomShapeSvg'
diff --git a/src/components/contexts/FilterContext.tsx b/src/components/contexts/FilterContext.tsx
new file mode 100644
index 000000000..36a10ce9f
--- /dev/null
+++ b/src/components/contexts/FilterContext.tsx
@@ -0,0 +1,43 @@
+import { createContext, ReactNode, useContext, useState } from "react";
+import { filterContextType } from "src/utils/types.utils";
+
+const contextDefaultValues: filterContextType = {
+ visible: false,
+ open: () => {},
+ close: () => {},
+};
+
+const FilterContext = createContext(contextDefaultValues);
+
+export function useAuth() {
+ return useContext(FilterContext);
+}
+
+type FilterProviderProps = {
+ children: ReactNode;
+};
+
+export function FilterProvider({ children }: FilterProviderProps) {
+ const [visible, setVisible] = useState(false);
+
+ const open = () => {
+ setVisible(true);
+ };
+
+ const close = () => {
+ setVisible(false);
+ };
+
+ const value = {
+ visible,
+ open,
+ close,
+ };
+ return (
+ <>
+
+ {children}
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/src/utils/useClickOutSide.ts b/src/components/hooks/useClickOutSide.ts
similarity index 92%
rename from src/utils/useClickOutSide.ts
rename to src/components/hooks/useClickOutSide.ts
index d68e742fb..ff69007a8 100644
--- a/src/utils/useClickOutSide.ts
+++ b/src/components/hooks/useClickOutSide.ts
@@ -1,5 +1,5 @@
import { RefObject, useEffect } from 'react'
-import { MouseAndTouchEvent } from './types.utils'
+import { MouseAndTouchEvent } from '../../utils/types.utils'
export function useOnClickOutside(
ref: RefObject,
diff --git a/src/components/icons/IconCirclePlus.tsx b/src/components/icons/IconCirclePlus.tsx
new file mode 100644
index 000000000..c59766d89
--- /dev/null
+++ b/src/components/icons/IconCirclePlus.tsx
@@ -0,0 +1,20 @@
+import React from 'react'
+
+const IconCirclePlus = () => {
+ return (
+
+ )
+}
+
+export default IconCirclePlus
diff --git a/src/components/icons/IconDoneCheckout.tsx b/src/components/icons/IconDoneCheckout.tsx
new file mode 100644
index 000000000..418472d23
--- /dev/null
+++ b/src/components/icons/IconDoneCheckout.tsx
@@ -0,0 +1,20 @@
+import React from 'react'
+
+const IconDoneCheckout = () => {
+ return (
+
+ )
+}
+
+export default IconDoneCheckout
diff --git a/src/components/icons/IconFilter.tsx b/src/components/icons/IconFilter.tsx
new file mode 100644
index 000000000..2c06b9139
--- /dev/null
+++ b/src/components/icons/IconFilter.tsx
@@ -0,0 +1,22 @@
+import React from 'react'
+
+interface Props {}
+
+const IconFilter = (props: Props) => {
+ return (
+
+ )
+}
+
+export default IconFilter
diff --git a/src/components/icons/Shipping.tsx b/src/components/icons/Shipping.tsx
new file mode 100644
index 000000000..2288c142c
--- /dev/null
+++ b/src/components/icons/Shipping.tsx
@@ -0,0 +1,20 @@
+import React from 'react'
+
+const Shipping = () => {
+ return (
+
+ )
+}
+
+export default Shipping
diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts
index 477d8863c..7dd36b14f 100644
--- a/src/components/icons/index.ts
+++ b/src/components/icons/index.ts
@@ -22,10 +22,14 @@ export { default as IconPassword } from './IconPassword'
export { default as IconPasswordCross } from './IconPasswordCross'
export { default as IconError } from './IconError'
export { default as IconCheck } from './IconCheck'
+export { default as Shipping} from './Shipping'
export { default as IconTime } from './IconTime'
export { default as IconPeople } from './IconPeople'
export { default as IconLocation } from './IconLocation'
export { default as IconClose } from './IconClose'
export { default as IconDelete } from './IconDelete'
export { default as IconPlus } from './IconPlus'
-export { default as IconMinus } from './IconMinus'
\ No newline at end of file
+export { default as IconMinus } from './IconMinus'
+export { default as IconCirclePlus } from './IconCirclePlus'
+export { default as IconDoneCheckout } from './IconDoneCheckout'
+export { default as IconFilter } from './IconFilter'
diff --git a/src/components/modules/account/AccountNavigation/AccountNavigation.tsx b/src/components/modules/account/AccountNavigation/AccountNavigation.tsx
index cf12cdbfb..929f386f2 100644
--- a/src/components/modules/account/AccountNavigation/AccountNavigation.tsx
+++ b/src/components/modules/account/AccountNavigation/AccountNavigation.tsx
@@ -63,6 +63,7 @@ const AccountNavigation = ({ defaultActiveIndex, children } : AccountNavigationP
})
}
+
)
}
diff --git a/src/components/modules/account/AccountNavigation/components/AccountNavigationItem.tsx b/src/components/modules/account/AccountNavigation/components/AccountNavigationItem.tsx
index 9f94fb1fc..9ac8a387f 100644
--- a/src/components/modules/account/AccountNavigation/components/AccountNavigationItem.tsx
+++ b/src/components/modules/account/AccountNavigation/components/AccountNavigationItem.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { RefObject } from "react";
import classNames from "classnames";
import s from './AccountNavigationItem.module.scss'
diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss b/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss
new file mode 100644
index 000000000..403bdb76b
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.module.scss
@@ -0,0 +1,38 @@
+.warpper {
+ padding: 3.2rem;
+ min-width: 100%;
+ @screen lg {
+ max-width: 56.3rem;
+ @apply flex justify-between flex-col border-l-2 border-solid border-line;
+ }
+ .title {
+ display: none;
+ font-weight: bold;
+ font-size: 2rem;
+ line-height: 2.8rem;
+ @screen md {
+ display: block;
+ }
+ }
+ .list {
+ 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 {
+ @apply flex justify-between items-center text-label;
+ .total {
+ font-weight: bold;
+ font-size: 2rem;
+ line-height: 2.8rem;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx
new file mode 100644
index 000000000..259397980
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutBill/CheckoutBill.tsx
@@ -0,0 +1,46 @@
+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'
+
+interface CheckoutBillProps {
+ data: CardItemCheckoutProps[]
+}
+
+const CheckoutBill = ({ data }: CheckoutBillProps) => {
+ return (
+
+
+ Your cart ({data.length})
+
+
+ {data.map((item) => {
+ return
+ })}
+
+
+
+ Apply Promotion Code
+
+
+
+
+ Subtotal
+
RP 120.500
+
+
+
+ Estimated Total
+
RP 120.500
+
+
+
+
+ )
+}
+
+export default CheckoutBill
diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.module.scss b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.module.scss
new file mode 100644
index 000000000..cadf9f684
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.module.scss
@@ -0,0 +1,17 @@
+.warpper{
+ @apply w-full;
+ padding: 3.2rem;
+ .title{
+ margin-bottom: 3.2rem;
+ @apply flex justify-between items-center;
+ .viewCart{
+ margin-right: 5.6rem;
+ @apply text-primary font-bold;
+ display: block;
+ cursor: pointer;
+ @screen lg {
+ display: none;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx
new file mode 100644
index 000000000..423f92635
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/CheckoutInfo.tsx
@@ -0,0 +1,94 @@
+import React, { useState } from 'react'
+import { Logo } from 'src/components/common'
+import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse'
+import { removeItem } from 'src/utils/funtion.utils'
+import { CheckOutForm } from 'src/utils/types.utils'
+import s from './CheckoutInfo.module.scss'
+import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm'
+import PaymentInfoForm from './components/PaymentInfoForm/PaymentInfoForm'
+import ShippingInfoForm from './components/ShippingInfoForm/ShippingInfoForm'
+interface CheckoutInfoProps {
+ onViewCart:()=>void
+}
+
+const CheckoutInfo = ({onViewCart}: CheckoutInfoProps) => {
+ const [active, setActive] = useState(1)
+ const [done, setDone] = useState
([])
+ const [info, setInfo] = useState({})
+
+ const onEdit = (id:number) => {
+ setActive(id)
+ setDone(removeItem(done,id))
+ }
+
+ const onConfirm = (id:number,formInfo:CheckOutForm) => {
+ if(id+1>formList.length){
+ console.log({...info,...formInfo})
+ }else{
+ if(done.length>0){
+ for (let i = id+1; i <= formList.length; i++) {
+ if(!done.includes(i)){
+ setActive(i)
+ }
+ }
+ }else{
+ setActive(id+1)
+ }
+ setDone([...done,id])
+ }
+ setInfo({...info,...formInfo})
+ }
+
+ const getNote = (id:number) => {
+ switch (id) {
+ case 1:
+ return `${info.name}, ${info.email}`
+ case 2:
+ return `${info.address}, ${info.state}, ${info.city}, ${info.code}, ${info.phone}, `
+ default:
+ return ""
+ }
+ }
+
+ const formList = [
+ {
+ id: 1,
+ title: 'Customer Information',
+ form: ,
+ },
+ {
+ id: 2,
+ title: 'Shipping Information',
+ form: ,
+ },
+ {
+ id: 3,
+ title: 'Payment Information',
+ form: ,
+ },
+ ]
+ return (
+
+
+ {formList.map((item) => {
+ let note = getNote(item.id)
+ return
+ {item.form}
+
+ })}
+
+ )
+}
+
+export default CheckoutInfo
diff --git a/src/components/modules/checkout/CheckoutInfo/components/BankTransfer/BankTransfer.module.scss b/src/components/modules/checkout/CheckoutInfo/components/BankTransfer/BankTransfer.module.scss
new file mode 100644
index 000000000..44ac98048
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/BankTransfer/BankTransfer.module.scss
@@ -0,0 +1,15 @@
+.warpper{
+ .info{
+ .line{
+ @apply flex justify-start items-center;
+ .title{
+ margin-right: 3.2rem;
+ min-width: 19.4rem;
+ @apply text-label;
+ }
+ .hightlight{
+ @apply text-active;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/checkout/CheckoutInfo/components/BankTransfer/BankTransfer.tsx b/src/components/modules/checkout/CheckoutInfo/components/BankTransfer/BankTransfer.tsx
new file mode 100644
index 000000000..7de11245c
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/BankTransfer/BankTransfer.tsx
@@ -0,0 +1,26 @@
+import React from 'react'
+import s from './BankTransfer.module.scss'
+interface BankTransferProps {}
+
+const BankTransfer = ({}: BankTransferProps) => {
+ return (
+
+
+
+
Account Name:
+
Duong Dinh Vu
+
+
+
Account Number:
+
1234 1234 1234 1234
+
+
+
Bank Name:
+
Techcombank - HCMC
+
+
+
+ )
+}
+
+export default BankTransfer
diff --git a/src/components/modules/checkout/CheckoutInfo/components/CreditCardForm/CreditCardForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/CreditCardForm/CreditCardForm.module.scss
new file mode 100644
index 000000000..62dbbc8d3
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/CreditCardForm/CreditCardForm.module.scss
@@ -0,0 +1,12 @@
+@import "../../../../../../styles/utilities";
+.warpper{
+ @apply u-form;
+ .line{
+ >div{
+ width: 50%;
+ }
+ }
+ .checkbox{
+ margin-top: 1.6rem;
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/checkout/CheckoutInfo/components/CreditCardForm/CreditCardForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CreditCardForm/CreditCardForm.tsx
new file mode 100644
index 000000000..d289165e0
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/CreditCardForm/CreditCardForm.tsx
@@ -0,0 +1,27 @@
+import React, { useRef } from 'react'
+import { CheckboxCommon, Inputcommon } from 'src/components/common'
+import { CustomInputCommon } from 'src/utils/type.utils'
+import s from "./CreditCardForm.module.scss"
+interface CreditCardFormProps {
+
+}
+
+const CreditCardForm = ({}: CreditCardFormProps) => {
+ const cardNumberRef = useRef(null)
+ const dateRef = useRef(null)
+ const cvsRef = useRef(null)
+ return (
+
+ )
+}
+
+export default CreditCardForm
diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss
new file mode 100644
index 000000000..b0ecf8144
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.module.scss
@@ -0,0 +1,15 @@
+@import "../../../../../../styles/utilities";
+.warpper{
+ @apply u-form;
+ @screen md {
+ padding: 0 5.6rem;
+ }
+ .bottom{
+ margin-top: 2.4rem;
+ @apply flex justify-between items-center;
+ .note{
+ font-size: 1.2rem;
+ line-height: 2rem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx
new file mode 100644
index 000000000..8496b119d
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/CustomerInfoForm/CustomerInfoForm.tsx
@@ -0,0 +1,54 @@
+import Link from 'next/link'
+import React, { useRef } from 'react'
+import { ButtonCommon, Inputcommon } from 'src/components/common'
+import InputCommon from 'src/components/common/InputCommon/InputCommon'
+import { CheckOutForm } from 'src/utils/types.utils'
+import s from './CustomerInfoForm.module.scss'
+interface CustomerInfoFormProps {
+ onConfirm?: (id: number, formInfo: CheckOutForm) => void
+ id: number
+}
+
+const CustomerInfoForm = ({ id, onConfirm }: CustomerInfoFormProps) => {
+ const nameRef = useRef>(null)
+ const emailRef = useRef>(null)
+
+ const handleConfirmClick = () => {
+ onConfirm &&
+ onConfirm(id, {
+ name: nameRef?.current?.getValue().toString(),
+ email: emailRef.current?.getValue().toString(),
+ })
+ }
+
+ return (
+
+
+
+
+
+
+
+ By clicking continue you agree to Casper's{' '}
+ {
+
+ terms and conditions
+
+ }{' '}
+ and{' '}
+ {
+
+ privacy policy
+
+ }
+ .
+
+
+ Continue to Shipping
+
+
+
+ )
+}
+
+export default CustomerInfoForm
diff --git a/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.module.scss
new file mode 100644
index 000000000..15a70659c
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.module.scss
@@ -0,0 +1,16 @@
+.wrapper{
+ @screen md {
+ padding: 0 5.6rem;
+ }
+ .inner{
+ padding: 4rem 0;
+ }
+ .bottom{
+ margin-top: 2.4rem;
+ @apply flex justify-between items-center;
+ .note{
+ font-size: 1.2rem;
+ line-height: 2rem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.tsx
new file mode 100644
index 000000000..dc84fec38
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/PaymentInfoForm/PaymentInfoForm.tsx
@@ -0,0 +1,55 @@
+import React from 'react'
+import { ButtonCommon, TabCommon, TabPane } from 'src/components/common'
+import { CheckOutForm } from 'src/utils/types.utils'
+import BankTransfer from '../BankTransfer/BankTransfer'
+import Link from 'next/link'
+
+import s from './PaymentInfoForm.module.scss'
+import CreditCardForm from '../CreditCardForm/CreditCardForm'
+interface PaymentInfoFormProps {
+ onConfirm?: (id: number, formInfo: CheckOutForm) => void
+ id: number
+}
+
+const PaymentInfoForm = ({onConfirm,id}: PaymentInfoFormProps) => {
+ const handleConfirmClick = () => {
+ onConfirm && onConfirm(id,{})
+ }
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ By clicking continue you agree to Casper's{' '}
+ {
+
+ terms and conditions
+
+ }{' '}
+ and{' '}
+ {
+
+ privacy policy
+
+ }
+ .
+
+
+ Submit Order
+
+
+
+ )
+}
+
+export default PaymentInfoForm
diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss
new file mode 100644
index 000000000..c0c8b2795
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.module.scss
@@ -0,0 +1,39 @@
+@import "../../../../../../styles/utilities";
+
+.warpper{
+ @apply u-form;
+ @screen md {
+ padding: 0 5.6rem;
+ }
+ .bottom{
+ margin-top: 2.4rem;
+ @apply flex justify-between items-center;
+ .note{
+ font-size: 1.2rem;
+ line-height: 2rem;
+ }
+ }
+ .line{
+ >div{
+ width: 50%;
+ }
+ }
+ .method{
+ width: 100%;
+ height: 5.6rem;
+ padding: 1.6rem;
+ border-radius: 0.8rem;
+ @apply flex justify-between items-center border border-solid border-line bg-gray;
+ .left{
+ @apply flex;
+ .name{
+ margin-left: 1.6rem;
+ color: var(--text-active);
+ }
+ }
+ .price{
+ font-weight: bold;
+ color: var(--text-active);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx
new file mode 100644
index 000000000..ac4bc8af5
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx
@@ -0,0 +1,97 @@
+import React, { useRef } from 'react'
+import { ButtonCommon, Inputcommon, SelectCommon } from 'src/components/common'
+import s from './ShippingInfoForm.module.scss'
+import Link from 'next/link'
+import { CustomInputCommon } from 'src/utils/type.utils'
+import { Shipping } from 'src/components/icons'
+import { CheckOutForm } from 'src/utils/types.utils'
+
+interface ShippingInfoFormProps {
+ onConfirm?: (id:number,formInfo:CheckOutForm)=>void
+ id:number
+}
+
+const option = [
+ {
+ name: 'Hồ Chí Minh',
+ },
+ {
+ name: 'Hà Nội',
+ },
+]
+
+const ShippingInfoForm = ({onConfirm,id}: ShippingInfoFormProps) => {
+ const addressRef = useRef(null)
+ const cityRef = useRef(null)
+ const stateRef = useRef(null)
+ const codeRef = useRef(null)
+ const phoneRef = useRef(null)
+ const handleConfirmClick = () => {
+ onConfirm && onConfirm(id,{
+ address: addressRef?.current?.getValue().toString(),
+ city: cityRef.current?.getValue().toString(),
+ state: stateRef?.current?.getValue().toString(),
+ code: Number(codeRef.current?.getValue()),
+ phone: Number(phoneRef?.current?.getValue()),
+ })
+ }
+
+ return (
+
+
+
+
+
+ State
+
+
+
+
+
+
+
+
+
+ Standard Delivery Method
+
+
+
+
+
+
+
+ By clicking continue you agree to Casper's{' '}
+ {
+
+ terms and conditions
+
+ }{' '}
+ and{' '}
+ {
+
+ privacy policy
+
+ }
+ .
+
+
+ Continue to Payment
+
+
+
+ )
+}
+
+export default ShippingInfoForm
diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss
new file mode 100644
index 000000000..1661f243c
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.module.scss
@@ -0,0 +1,56 @@
+@import "../../../../styles/utilities";
+.warrper{
+ @apply flex;
+ .right{
+ display: none;
+ @screen lg {
+ display: block;
+ min-width: 45rem;
+ }
+ @screen xl {
+ min-width: 56.3rem;
+ }
+ }
+ .left{
+ @apply w-full;
+ }
+ .mobile{
+ @apply hidden;
+ &.isShow{
+ @apply block;
+ @screen lg {
+ @apply hidden;
+ }
+ }
+ .modal{
+ background: rgba(0, 0, 0, 0.5);
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 10000;
+ .content{
+ @apply spacing-horizontal;
+ margin-top: 3rem;
+ padding-top: 6.4rem ;
+ padding-bottom: 5rem;
+ background-color: white;
+ overflow: auto;
+ height: 100%;
+ border-radius: 2.4rem 2.4rem 0 0;
+ .head{
+ @apply flex justify-between;
+ h3{
+ @apply heading-3 font-bold;
+ color:var(--text-base);
+ }
+ }
+ button{
+ margin-top: 2rem;
+ width: 100%;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx
new file mode 100644
index 000000000..8cfcc31f3
--- /dev/null
+++ b/src/components/modules/checkout/CheckoutPage/CheckoutPage.tsx
@@ -0,0 +1,37 @@
+import classNames from 'classnames'
+import React, { useState } from 'react'
+import IconHide from 'src/components/icons/IconHide'
+import { CHECKOUT_BILL_DATA } from 'src/utils/demo-data'
+import { CheckoutBill, CheckoutInfo } from '..'
+import s from "./CheckoutPage.module.scss"
+interface CheckoutPageProps {
+}
+
+const CheckoutPage = ({}: CheckoutPageProps) => {
+ const [isShow, setIsShow] = useState(false)
+ const onClose = () => {
+ setIsShow(false)
+ }
+ const onViewCart =() => {
+ setIsShow(true)
+ }
+ return (
+
+
+
+
+
+
+
+
Your Cart({CHECKOUT_BILL_DATA.length})
+
+
+
+
+
+
+
+ )
+}
+
+export default CheckoutPage
diff --git a/src/components/modules/checkout/index.ts b/src/components/modules/checkout/index.ts
new file mode 100644
index 000000000..736375e4c
--- /dev/null
+++ b/src/components/modules/checkout/index.ts
@@ -0,0 +1,3 @@
+export { default as CheckoutInfo } from './CheckoutInfo/CheckoutInfo'
+export { default as CheckoutPage } from './CheckoutPage/CheckoutPage'
+export { default as CheckoutBill } from './CheckoutBill/CheckoutBill'
diff --git a/src/components/modules/product-list/ProductListBanner/ProductListBanner.module.scss b/src/components/modules/product-list/ProductListBanner/ProductListBanner.module.scss
new file mode 100644
index 000000000..a3452e797
--- /dev/null
+++ b/src/components/modules/product-list/ProductListBanner/ProductListBanner.module.scss
@@ -0,0 +1,8 @@
+@import "../../../../styles/_utilities";
+
+.productListBanner{
+ @apply spacing-horizontal;
+ @screen md {
+ padding:0 3.2rem;
+ }
+}
\ No newline at end of file
diff --git a/src/components/modules/product-list/ProductListBanner/ProductListBanner.tsx b/src/components/modules/product-list/ProductListBanner/ProductListBanner.tsx
new file mode 100644
index 000000000..17d48d637
--- /dev/null
+++ b/src/components/modules/product-list/ProductListBanner/ProductListBanner.tsx
@@ -0,0 +1,27 @@
+import React from 'react'
+import { Banner } from 'src/components/common'
+import BannerRight from './assets/bannerrecipes.png'
+import s from './ProductListBanner.module.scss'
+
+interface Props {
+}
+
+const ProductListBanner = ({ }: Props) => {
+ return (
+
+
+
+ )
+}
+
+export default ProductListBanner
diff --git a/src/components/modules/product-list/ProductListBanner/assets/bannerrecipes.png b/src/components/modules/product-list/ProductListBanner/assets/bannerrecipes.png
new file mode 100644
index 000000000..91271cbd2
Binary files /dev/null and b/src/components/modules/product-list/ProductListBanner/assets/bannerrecipes.png differ
diff --git a/src/components/modules/product-list/ProductListFilter/ProductListFilter.module.scss b/src/components/modules/product-list/ProductListFilter/ProductListFilter.module.scss
new file mode 100644
index 000000000..b30b9e1a6
--- /dev/null
+++ b/src/components/modules/product-list/ProductListFilter/ProductListFilter.module.scss
@@ -0,0 +1,88 @@
+@import "../../../../styles/_utilities";
+
+.warpper {
+ @apply spacing-horizontal;
+ @screen md{
+ padding:0 3.2rem;
+ padding-bottom:5.6rem;
+ }
+ .breadcrumb{
+ padding:1rem 0;
+ }
+ .main{
+ @screen md {
+ @apply flex;
+ }
+ .categories{
+ @apply hidden;
+ @screen md {
+ @apply hidden;
+ }
+ @screen xl{
+ @apply block;
+ width:25%;
+ }
+ }
+ .list{
+ @screen md {
+ @apply flex justify-between flex-wrap w-full;
+ margin: 1rem 0;
+ }
+ @screen xl {
+ width:75%;
+ }
+ .inner{
+ @screen md {
+ @apply flex flex-col items-center justify-center;
+ }
+ .boxItem {
+ @screen md {
+ @apply flex justify-between flex-wrap;
+ margin: 1rem 0;
+ }
+ .item {
+ @screen md {
+ width: calc(97% / 2);
+ margin-top:1rem;
+ }
+ @screen lg{
+ width: calc(97% / 3);
+ margin-top:1rem;
+ }
+ }
+ }
+ }
+
+ .boxSelect{
+ @apply w-auto;
+ // padding: 2.5rem 0;
+ display: none;
+
+ @screen xl {
+ @apply block;
+ width: auto;
+ padding:0;
+ }
+ .categorySelectCate{
+ @screen xl {
+ @apply hidden;
+ }
+ }
+ label{
+ @apply font-bold topline ;
+ color:var(--text-active);
+ @screen xl {
+ @apply hidden;
+ }
+ }
+ .select{
+ margin-top: 1rem;
+ }
+ }
+
+ }
+
+ }
+
+
+}
diff --git a/src/components/modules/product-list/ProductListFilter/ProductListFilter.tsx b/src/components/modules/product-list/ProductListFilter/ProductListFilter.tsx
new file mode 100644
index 000000000..5315283dc
--- /dev/null
+++ b/src/components/modules/product-list/ProductListFilter/ProductListFilter.tsx
@@ -0,0 +1,66 @@
+import React from 'react'
+import { HeadingCommon, ProductList, SelectCommon } from 'src/components/common'
+import BreadcrumbCommon from 'src/components/common/BreadcrumbCommon/BreadcrumbCommon'
+import MenuNavigation from 'src/components/common/MenuNavigation/MenuNavigation'
+import { BRAND, CATEGORY, FEATURED} from 'src/utils/constanst.utils'
+import { PRODUCT_DATA_TEST_PAGE } from 'src/utils/demo-data'
+import s from './ProductListFilter.module.scss'
+
+interface ProductListFilterProps {}
+
+const BREADCRUMB = [
+ {
+ name: 'Products',
+ link: `#`,
+ },
+]
+const OPTIONSLECT = [
+ {
+ name: 'Most Viewed',
+ value: 'most-viewed',
+ },
+ {
+ name: 'Lastest Products',
+ value: 'lastest-products',
+ },
+ {
+ name: 'Recent Products',
+ value: 'recent-products',
+ },
+]
+
+const onModalClose = () => {
+
+}
+
+const ProductListFilter = (props: ProductListFilterProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
SPECIAL RECIPES
+
+
+
+
+
+
+ )
+}
+
+export default ProductListFilter
diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts
index e91fb17f6..3757feb1e 100644
--- a/src/utils/constanst.utils.ts
+++ b/src/utils/constanst.utils.ts
@@ -53,4 +53,67 @@ export const KEY = {
export const OPTION_ALL = 'all';
export const DEFAULT_PAGE_SIZE=20;
+
+
+export const CATEGORY = [
+ {
+ name: 'All',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=${OPTION_ALL}`,
+ },
+ {
+ name: 'Veggie',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=veggie`,
+ },
+ {
+ name: 'Seafood',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=seafood`,
+ },
+ {
+ name: 'Frozen',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=frozen`,
+ },
+ {
+ name: 'Coffee Bean',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=coffee_bean`,
+ },
+ {
+ name: 'Sauce',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=sauce`,
+ },
+ ]
+
+ export const BRAND = [
+ {
+ name: 'Maggi',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=maggi`,
+ },
+ {
+ name: 'Chomilex',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chomilex`,
+ },
+ {
+ name: 'Chinsu',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chinsu`,
+ },
+ ]
+
+export const FEATURED = [
+ {
+ name: 'Best Sellers',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=best_sellers`,
+ },
+ {
+ name: 'Sales',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=sales`,
+ },
+ {
+ name: 'New Item',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=new_item`,
+ },
+ {
+ name: 'Viewed',
+ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=viewed`,
+ },
+ ]
+
export const DEFAULT_BLOG_PAGE_SIZE=6;
diff --git a/src/utils/demo-data.ts b/src/utils/demo-data.ts
index 8ecaf4231..d7ec4302c 100644
--- a/src/utils/demo-data.ts
+++ b/src/utils/demo-data.ts
@@ -1,3 +1,4 @@
+import { CardItemCheckoutProps } from "src/components/common/CardItemCheckout/CardItemCheckout"
import { RecipeCardProps } from "src/components/common/RecipeCard/RecipeCard"
export const PRODUCT_DATA_TEST = [
@@ -218,4 +219,35 @@ export const RECIPE_DATA_TEST: RecipeCardProps[] = [
imageSrc: 'https://user-images.githubusercontent.com/76729908/132159262-f28a9fb9-4852-47e6-80b5-d600521b548a.png',
slug:"the-best-recipe-of-beef-noodle-soup"
},
-]
\ No newline at end of file
+]
+
+export const CHECKOUT_BILL_DATA:CardItemCheckoutProps[] = [
+ {
+ name: 'Tomato',
+ slug: "tomato",
+ weight: '250g',
+ category: 'VEGGIE',
+ price: 'Rp 27.500',
+ imageSrc: "https://user-images.githubusercontent.com/76729908/131646227-b5705e64-3b45-47a3-9433-9f4b5ee8d40c.png",
+ quantity:10
+ },
+ {
+ name: 'Carrot',
+ slug: "carrot",
+ weight: '250g',
+ category: 'VEGGIE',
+ price: 'Rp 27.500',
+ imageSrc: "https://user-images.githubusercontent.com/76729908/131646217-23b86160-45c9-4845-8dcc-b3e1a4483edd.png",
+ quantity:1
+ },
+ {
+ name: 'Salad',
+ slug:"salad",
+ weight: '250g',
+ category: 'VEGGIE',
+ price: 'Rp 27.500',
+ imageSrc: "https://user-images.githubusercontent.com/76729908/131646221-aaa1d48d-bb80-470f-9400-ae2aa47285b6.png",
+ quantity:2
+ },
+ ]
+export const PRODUCT_DATA_TEST_PAGE = [...PRODUCT_DATA_TEST, ...PRODUCT_DATA_TEST, ...PRODUCT_DATA_TEST, ...PRODUCT_DATA_TEST, ...PRODUCT_DATA_TEST]
\ No newline at end of file
diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts
index b1e7b5536..619e9ae30 100644
--- a/src/utils/funtion.utils.ts
+++ b/src/utils/funtion.utils.ts
@@ -1,3 +1,11 @@
export function isMobile() {
return window.innerWidth <= 768
+}
+
+export function removeItem(arr: Array, value: T): Array {
+ const index = arr.indexOf(value);
+ if (index > -1) {
+ arr.splice(index, 1);
+ }
+ return [...arr];
}
\ No newline at end of file
diff --git a/src/utils/types.utils.ts b/src/utils/types.utils.ts
index 90fa547c3..e2ce516d4 100644
--- a/src/utils/types.utils.ts
+++ b/src/utils/types.utils.ts
@@ -32,4 +32,22 @@ export interface BlogProps {
imageSrc: string
}
-export type MouseAndTouchEvent = MouseEvent | TouchEvent
\ No newline at end of file
+export interface CheckOutForm {
+ name?: string
+ email?:string
+ address?: string
+ city?:string
+ state?:string
+ code?:number
+ phone?:number
+ method?:string
+ shipping_fee?:number
+}
+
+export type MouseAndTouchEvent = MouseEvent | TouchEvent
+
+export type filterContextType = {
+ visible: boolean;
+ open: () => void;
+ close: () => void;
+};
\ No newline at end of file