diff --git a/package.json b/package.json index 387ca946b..60f049ce4 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,6 @@ "prettier": "^2.3.0", "typescript": "4.3.4" }, - "lint-staged": { "**/*.{js,jsx,ts,tsx}": [ "prettier --write", diff --git a/pages/index.tsx b/pages/index.tsx index 6552bbebc..e67d8048a 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,31 +1,31 @@ -import { CarouselCommon, LabelCommon, Layout, QuanittyInput } from 'src/components/common' +import { Banner, ButtonCommon, ButtonIconBuy, Inputcommon, InputSearch, Layout } from 'src/components/common'; +import { IconBuy } from 'src/components/icons'; +import { HomeBanner } from 'src/components/modules/home'; + -const dataTest = [{ - text: 1 -}, { - text: 2 -}, { - text: 3 -}, { - text: 4 -}, { - text: 5 -}, { - text: 6 -}] -const test = (props: { text: string }) =>
{props.text}
export default function Home() { return ( <> - - - - SEEFOOT - -15% - Waitting - Delivering - Delivered + +
This is home page
+

Go to pages/index.tsx to get your hand dirty!

+

Go to src/components to make your awesome component!

+

Go to src/styles to find global styles!

+ + {/* demo */} +
+ + +
+ }>Button + + + ) } diff --git a/src/assets/imgs/apple_pay.png b/src/assets/imgs/apple_pay.png new file mode 100644 index 000000000..c2c915d66 Binary files /dev/null and b/src/assets/imgs/apple_pay.png differ diff --git a/src/assets/imgs/gpay.png b/src/assets/imgs/gpay.png new file mode 100644 index 000000000..55e5dfbae Binary files /dev/null and b/src/assets/imgs/gpay.png differ diff --git a/src/assets/imgs/mastercard.png b/src/assets/imgs/mastercard.png new file mode 100644 index 000000000..fad380822 Binary files /dev/null and b/src/assets/imgs/mastercard.png differ diff --git a/src/assets/imgs/visa.png b/src/assets/imgs/visa.png new file mode 100644 index 000000000..1ba0cec4b Binary files /dev/null and b/src/assets/imgs/visa.png differ diff --git a/src/components/common/Banner/Banner.module.scss b/src/components/common/Banner/Banner.module.scss new file mode 100644 index 000000000..4cec48628 --- /dev/null +++ b/src/components/common/Banner/Banner.module.scss @@ -0,0 +1,51 @@ +@import "../../../styles/utilities"; + +.banner { + @apply bg-primary-light custom-border-radius-lg overflow-hidden; + @screen md { + border: 1px solid var(--primary); + } + &.large { + .inner { + @screen xl { + @apply bg-right-bottom; + background-size: unset; + } + } + } + .inner { + @apply bg-no-repeat; + background-size: 90%; + background-position: right -500% bottom 0%; + .content { + background-image: linear-gradient( + to right, + rgb(227, 242, 233, 0.9), + rgb(227, 242, 233, 0.5) 80%, + rgb(227, 242, 233, 0) + ); + padding: 1.6rem; + max-width: 37rem; + @screen md { + max-width: 49.6rem; + padding: 4.8rem; + } + .top { + .heading { + @apply heading-1 font-heading; + margin-bottom: 1.6rem; + } + .subHeading { + @apply sub-headline; + @screen md { + @apply caption; + } + } + } + + .bottom { + margin-top: 4rem; + } + } + } +} diff --git a/src/components/common/Banner/Banner.tsx b/src/components/common/Banner/Banner.tsx new file mode 100644 index 000000000..a953052b6 --- /dev/null +++ b/src/components/common/Banner/Banner.tsx @@ -0,0 +1,48 @@ +import classNames from 'classnames' +import Link from 'next/link' +import React, { memo } from 'react' +import { IconArrowRight } from 'src/components/icons' +import { ROUTE } from 'src/utils/constanst.utils' +import { LANGUAGE } from 'src/utils/language.utils' +import ButtonCommon from '../ButtonCommon/ButtonCommon' +import s from './Banner.module.scss' + +interface Props { + imgLink: string, + title: string, + subtitle: string, + buttonLabel?: string, + linkButton?: string, + size?: 'small' | 'large', +} + +const Banner = memo(({ imgLink, title, subtitle, buttonLabel = LANGUAGE.BUTTON_LABEL.SHOP_NOW, linkButton = ROUTE.HOME, size = 'large' }: Props) => { + return ( +
+
+
+
+

+ {title} +

+
+ {subtitle} +
+
+ +
+
+
+ ) +}) + +export default Banner diff --git a/src/components/common/ButtonCommon/ButtonCommon.module.scss b/src/components/common/ButtonCommon/ButtonCommon.module.scss index c9d390574..8dca7e684 100644 --- a/src/components/common/ButtonCommon/ButtonCommon.module.scss +++ b/src/components/common/ButtonCommon/ButtonCommon.module.scss @@ -11,6 +11,20 @@ cursor: not-allowed; color: var(--disabled); } + &:hover { + @apply shadow-md; + &:not(:disabled) { + filter: brightness(1.05); + } + } + &:focus { + outline: none; + filter: brightness(1.05); + } + &:focus-visible { + outline: 2px solid var(--text-active); + } + &.loading { &::before { content: ""; @@ -24,20 +38,6 @@ margin-right: 0.8rem; } } - &:hover { - @apply shadow-md; - &:not(:disabled) { - filter: brightness(1.05); - } - } - - &:focus { - outline: none; - filter: brightness(1.05); - } - &:focus-visible { - outline: 2px solid var(--text-active); - } &.light { @apply text-base bg-white; @@ -60,8 +60,18 @@ } } + &.onlyIcon { + padding: 0.8rem; + .icon { + margin: 0; + } + } + &.large { padding: 3.2rem 4.8rem; + &.onlyIcon { + padding: 1.6rem; + } &.loading { &::before { width: 2.4rem; @@ -70,6 +80,8 @@ } } + + &.preserve { flex-direction: row-reverse; .icon { @@ -79,6 +91,10 @@ .icon { margin: 0 1.6rem 0 0; + } + + .label, + .icon { svg path { fill: currentColor; } diff --git a/src/components/common/ButtonCommon/ButtonCommon.tsx b/src/components/common/ButtonCommon/ButtonCommon.tsx index 920736ef2..385b35077 100644 --- a/src/components/common/ButtonCommon/ButtonCommon.tsx +++ b/src/components/common/ButtonCommon/ButtonCommon.tsx @@ -6,15 +6,15 @@ interface Props { children?: React.ReactNode, type?: 'primary' | 'light' | 'ghost', size?: 'default' | 'large', - icon?: any, + icon?: React.ReactNode, isIconSuffix?: boolean, loading?: boolean, disabled?: boolean, onClick?: () => void, } -const ButtonCommon = memo(({ type = 'primary', size = 'default', - icon, loading, disabled, isIconSuffix, children, onClick }: Props) => { +const ButtonCommon = memo(({ type = 'primary', size = 'default', loading = false, isIconSuffix = false, + icon, disabled, children, onClick }: Props) => { return ( + +
+ +
+ + + + ) +}) + +export default HeaderMenu diff --git a/src/components/common/Header/components/HeaderSubMenu/HeaderNoti/HeaderNoti.module.scss b/src/components/common/Header/components/HeaderSubMenu/HeaderNoti/HeaderNoti.module.scss new file mode 100644 index 000000000..7e678a7ed --- /dev/null +++ b/src/components/common/Header/components/HeaderSubMenu/HeaderNoti/HeaderNoti.module.scss @@ -0,0 +1,3 @@ +.headerNoti { + @apply flex items-center; +} diff --git a/src/components/common/Header/components/HeaderSubMenu/HeaderNoti/HeaderNoti.tsx b/src/components/common/Header/components/HeaderSubMenu/HeaderNoti/HeaderNoti.tsx new file mode 100644 index 000000000..4e5b922c1 --- /dev/null +++ b/src/components/common/Header/components/HeaderSubMenu/HeaderNoti/HeaderNoti.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import NotiMessage from 'src/components/common/NotiMessage/NotiMessage'; +import { IconInfo } from 'src/components/icons'; +import s from './HeaderNoti.module.scss'; + +const HeaderNoti = () => { + return ( + +
+  You can buy fresh products after 11pm or 8am +
+
+ ); +}; + +export default HeaderNoti; \ No newline at end of file diff --git a/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.module.scss b/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.module.scss new file mode 100644 index 000000000..8a1d76c4d --- /dev/null +++ b/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.module.scss @@ -0,0 +1,42 @@ +@import "../../../../../styles/utilities"; + +.headerSubMenu { + @apply hidden; + @screen md { + transform: translateY(-10rem); + height: 0; + &.show { + @apply block; + padding-bottom: 2.4rem; + transform: none; + height: unset; + @screen lg { + @apply flex justify-between items-center; + } + .menu { + @apply flex items-center list-none; + margin-bottom: 2.4rem; + @screen lg { + margin-bottom: 0; + } + li { + &:not(:last-child) { + margin-right: 2.4rem; + @screen lg { + margin-right: 4rem; + } + } + a { + @appy no-underline; + } + &:hover { + @apply text-primary; + } + &.active { + @apply text-primary; + } + } + } + } + } +} diff --git a/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.tsx b/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.tsx new file mode 100644 index 000000000..6a02259b5 --- /dev/null +++ b/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.tsx @@ -0,0 +1,88 @@ +import classNames from 'classnames' +import Link from 'next/link' +import { useRouter } from 'next/router' +import { memo } from 'react' +import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown' +import { ProductFeature, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils' +import HeaderNoti from './HeaderNoti/HeaderNoti' +import s from './HeaderSubMenu.module.scss' + +const MENU = [ + { + name: 'New Items', + link: `${ROUTE.PRODUCTS}?${QUERY_KEY.FEATURED}=${ProductFeature.NewItem}`, + }, + { + name: 'Sales', + link: `${ROUTE.PRODUCTS}?${QUERY_KEY.FEATURED}=${ProductFeature.Sales}`, + }, + { + name: 'Best Sellers', + link: `${ROUTE.PRODUCTS}?${QUERY_KEY.FEATURED}=${ProductFeature.BestSellers}`, + }, + { + name: 'About Us', + link: ROUTE.ABOUT, + }, + { + name: 'Blog', + link: ROUTE.BLOGS, + }, +] + +// note: hard code, remove later +const CATEGORY = [ + { + name: 'Veggie', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=veggie`, + }, + { + name: 'Seafood', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=seafood`, + }, + { + name: 'Frozen', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=frozen`, + }, + { + name: 'Coffee Bean', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=coffee-bean`, + }, + { + name: 'Sauce', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=sauce`, + }, +] +interface Props { + children?: any, + isShow: boolean, +} + +const HeaderSubMenu = memo(({ isShow }: Props) => { + const router = useRouter() + + return ( +
+
    + {/* todo: handle active item */} +
  • + Categories +
  • + { + MENU.map(item =>
  • + + + {item.name} + + + +
  • ) + } +
+ +
+ ) +}) + +export default HeaderSubMenu diff --git a/src/components/common/Header/components/HeaderSubMenuMobile/HeaderSubMenuMobile.module.scss b/src/components/common/Header/components/HeaderSubMenuMobile/HeaderSubMenuMobile.module.scss new file mode 100644 index 000000000..5480b5d10 --- /dev/null +++ b/src/components/common/Header/components/HeaderSubMenuMobile/HeaderSubMenuMobile.module.scss @@ -0,0 +1,50 @@ +@import "../../../../../styles/utilities"; + +.headerSubMenuMobile { + @apply fixed w-full bg-white; + bottom: 0; + left: 0; + padding: 2rem 1rem; + border-top: 1px solid var(--border-line); + box-shadow: -5px 6px 10px rgba(0, 0, 0, 0.2); + .menu { + @apply grid grid-cols-4; + li { + a { + @apply transition-all duration-200 no-underline; + &:hover { + color: var(--primary); + } + } + .menuItem { + @apply flex flex-col justify-center items-center sm-label; + .icon { + position: relative; + margin-bottom: 0.5rem; + svg path { + fill: currentColor; + } + } + &.active { + @apply text-primary; + } + &.dot { + .icon { + &::after { + @apply absolute bg-negative rounded-full; + content: ""; + top: 0; + right: 0; + $size: 1rem; + width: $size; + height: $size; + } + } + } + } + } + } + @screen md { + @apply hidden; + } +} diff --git a/src/components/common/Header/components/HeaderSubMenuMobile/HeaderSubMenuMobile.tsx b/src/components/common/Header/components/HeaderSubMenuMobile/HeaderSubMenuMobile.tsx new file mode 100644 index 000000000..d2cf1bf3e --- /dev/null +++ b/src/components/common/Header/components/HeaderSubMenuMobile/HeaderSubMenuMobile.tsx @@ -0,0 +1,66 @@ +import classNames from 'classnames' +import Link from 'next/link' +import { useRouter } from 'next/router' +import { memo } from 'react' +import { IconHeart, IconHome, IconShopping, IconUser } from 'src/components/icons' +import { ACCOUNT_TAB, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils' +import s from './HeaderSubMenuMobile.module.scss' + +const OPTION_MENU = [ + { + link: ROUTE.HOME, + name: 'Home', + icon: , + isMarked: true, + }, + { + link: ROUTE.PRODUCTS, + name: 'Shopping', + icon: , + isMarked: false, + }, + { + link: `${ROUTE.ACCOUNT}?${QUERY_KEY.TAB}=${ACCOUNT_TAB.FAVOURITE}`, + name: 'Favourites', + icon: , + isMarked: false, + }, + { + link: ROUTE.ACCOUNT, + name: 'Account', + icon: , + isMarked: false, + }, +] + +interface Props { + children?: any +} + +const HeaderSubMenuMobile = memo(({ }: Props) => { + const router = useRouter() + return ( +
+ +
+ ) +}) + +export default HeaderSubMenuMobile diff --git a/src/components/common/InputCommon/InputCommon.module.scss b/src/components/common/InputCommon/InputCommon.module.scss index af7cde088..27eaed174 100644 --- a/src/components/common/InputCommon/InputCommon.module.scss +++ b/src/components/common/InputCommon/InputCommon.module.scss @@ -1,5 +1,44 @@ @import "../../../styles/utilities"; -.inputCommon { - @apply custom-border-radius transition-all duration-200; +.inputWrap { + @apply flex items-center relative; + .icon { + @apply absolute; + content: ""; + left: 1.6rem; + margin-right: 1.6rem; + svg path { + fill: currentColor; + } + } + .icon + .inputCommon { + padding-left: 4.8rem; + } + .inputCommon { + @apply block w-full transition-all duration-200 rounded; + padding: 1.2rem 1.6rem; + border: 1px solid var(--border-line); + &:hover, + &:focus, + &:active { + outline: none; + border: 1px solid var(--primary); + @apply shadow-md; + } + + &::placeholder { + @apply text-label; + } + + &.custom { + @apply custom-border-radius; + border: 1px solid transparent; + background: var(--gray); + &:hover, + &:focus, + &:active { + border: 1px solid var(--primary); + } + } + } } diff --git a/src/components/common/InputCommon/InputCommon.tsx b/src/components/common/InputCommon/InputCommon.tsx index 0e6ef87a9..c6446c990 100644 --- a/src/components/common/InputCommon/InputCommon.tsx +++ b/src/components/common/InputCommon/InputCommon.tsx @@ -5,17 +5,19 @@ import s from './InputCommon.module.scss'; type Ref = { focus: () => void } | null; - interface Props { children?: React.ReactNode, value?: string | number, placeholder?: string, type?: 'text' | 'number', + styleType?: 'default' | 'custom', + icon?: React.ReactNode, onChange?: (value: string | number) => void, onEnter?: (value: string | number) => void, } -const InputCommon = forwardRef(({ value, placeholder, type, onChange, onEnter }: Props, ref) => { +const InputCommon = forwardRef(({ value, placeholder, type, styleType = 'default', icon, + onChange, onEnter }: Props, ref) => { const inputElementRef = useRef(null); useImperativeHandle(ref, () => ({ @@ -36,15 +38,20 @@ const InputCommon = forwardRef(({ value, placeholder, type, onChange } return ( - +
+ { + icon && {icon} + } + +
) }) diff --git a/src/components/common/InputSearch/InputSearch.tsx b/src/components/common/InputSearch/InputSearch.tsx new file mode 100644 index 000000000..9c02a239c --- /dev/null +++ b/src/components/common/InputSearch/InputSearch.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { IconSearch } from 'src/components/icons'; +import { LANGUAGE } from 'src/utils/language.utils'; +import { Inputcommon } from '..'; + +interface Props { + onChange?: (value: string | number) => void, + onEnter?: (value: string | number) => void, +} + +const InputSearch = ({ onChange, onEnter }: Props) => { + return ( + } + onChange={onChange} + onEnter={onEnter} + /> + ) +} + +export default InputSearch diff --git a/src/components/common/Layout/Layout.module.scss b/src/components/common/Layout/Layout.module.scss new file mode 100644 index 000000000..e495667eb --- /dev/null +++ b/src/components/common/Layout/Layout.module.scss @@ -0,0 +1,8 @@ +.mainLayout { + display: flex; + flex-direction: column; + min-height: 100vh; + > main { + flex: 1; + } +} diff --git a/src/components/common/Layout/Layout.tsx b/src/components/common/Layout/Layout.tsx index 356ecfce5..aa5da11e1 100644 --- a/src/components/common/Layout/Layout.tsx +++ b/src/components/common/Layout/Layout.tsx @@ -1,7 +1,9 @@ -import { FC, useRef, useEffect } from 'react' -import Header from '../Header/Header' import { CommerceProvider } from '@framework' import { useRouter } from 'next/router' +import { FC } from 'react' +import Footer from '../Footer/Footer' +import Header from '../Header/Header' +import s from './Layout.module.scss' interface Props { className?: string @@ -14,8 +16,11 @@ const Layout: FC = ({ children }) => { return ( -
-
{children}
+
+
+
{children}
+
+
) diff --git a/src/components/common/MenuDropdown/MenuDropdown.module.scss b/src/components/common/MenuDropdown/MenuDropdown.module.scss new file mode 100644 index 000000000..f8a8a20cc --- /dev/null +++ b/src/components/common/MenuDropdown/MenuDropdown.module.scss @@ -0,0 +1,90 @@ +@import "../../../styles/utilities"; + +.menuDropdown { + @apply relative cursor-pointer; + width: fit-content; + &:hover { + .label { + color: var(--primary); + svg path { + fill: currentColor; + } + } + .menu { + @apply block; + animation: menuDropdownAnimation 0.2s ease-out; + } + } + + .label { + @apply flex justify-end items-center transition-all duration-200; + svg path { + width: fit-content; + } + } + + &.arrow { + .label { + margin-right: 1.6rem; + } + &::after { + @apply inline-block absolute transition-all duration-100; + content: ""; + top: 35%; + right: 0; + border: solid currentColor; + border-width: 0 2px 2px 0; + padding: 2px; + transform: rotate(45deg); + } + &:hover { + &::after { + @apply border-primary; + transform: rotate(-135deg); + } + } + } + + .menu { + @apply hidden absolute; + content: ""; + right: 0; + top: 2rem; + height: max-content; + min-width: 19.2rem; + z-index: 100; + &.left { + left: 0; + } + &:hover { + @apply block shadow-md; + } + .menuIner { + @apply rounded list-none bg-white; + border: 1px solid var(--text-active); + margin-top: .4rem; + li { + @apply block w-full transition-all duration-200 cursor-pointer text-active; + padding: 0.8rem 1.6rem; + &:hover { + @apply bg-primary-lightest; + color: var(--primary); + } + a { + @apply block; + } + } + } + } +} + +@keyframes menuDropdownAnimation { + 0% { + opacity: 0; + transform: translateY(1.6rem); + } + 100% { + opacity: 1; + transform: none; + } +} diff --git a/src/components/common/MenuDropdown/MenuDropdown.tsx b/src/components/common/MenuDropdown/MenuDropdown.tsx new file mode 100644 index 000000000..c20ffcaed --- /dev/null +++ b/src/components/common/MenuDropdown/MenuDropdown.tsx @@ -0,0 +1,42 @@ +import classNames from 'classnames'; +import Link from 'next/link'; +import React from 'react'; +import s from './MenuDropdown.module.scss'; + +interface Props { + children?: React.ReactNode, + options: { link: string, name: string }[], + isHasArrow?: boolean, + align?: 'left' +} + +const MenuDropdown = ({ options, children, isHasArrow = true, align }: Props) => { + return ( +
+ + {children} + +
+ +
+
+ ); +}; + +export default MenuDropdown; \ No newline at end of file diff --git a/src/components/common/NotiMessage/NotiMessage.module.scss b/src/components/common/NotiMessage/NotiMessage.module.scss new file mode 100644 index 000000000..a8015ea8e --- /dev/null +++ b/src/components/common/NotiMessage/NotiMessage.module.scss @@ -0,0 +1,9 @@ +@import "../../../styles/utilities"; + +.notiMessage { + @apply caption bg-info-light; + width: fit-content; + color: var(--info-dark); + padding: 0.4rem 1.6rem; + border-radius: 3rem; +} diff --git a/src/components/common/NotiMessage/NotiMessage.tsx b/src/components/common/NotiMessage/NotiMessage.tsx new file mode 100644 index 000000000..20eabdfae --- /dev/null +++ b/src/components/common/NotiMessage/NotiMessage.tsx @@ -0,0 +1,16 @@ +import React from 'react' +import s from './NotiMessage.module.scss' + +interface Props { + children?: React.ReactNode +} + +const NotiMessage = ({ children }: Props) => { + return ( +
+ {children} +
+ ) +} + +export default NotiMessage \ No newline at end of file diff --git a/src/components/common/index.ts b/src/components/common/index.ts index d79c1a9bb..31f33e011 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -8,3 +8,9 @@ export { default as ViewAllItem} from './ViewAllItem/ViewAllItem' export { default as ItemWishList} from './ItemWishList/ItemWishList' export { default as Logo} from './Logo/Logo' export { default as Inputcommon} from './InputCommon/InputCommon' +export { default as InputSearch} from './InputSearch/InputSearch' +export { default as ButtonIconBuy} from './ButtonIconBuy/ButtonIconBuy' +export { default as Banner} from './Banner/Banner' +export { default as Footer} from './Footer/Footer' +export { default as MenuDropdown} from './MenuDropdown/MenuDropdown' +export { default as NotiMessage} from './NotiMessage/NotiMessage' diff --git a/src/components/icons/Heart.tsx b/src/components/icons/Heart.tsx deleted file mode 100644 index f8c39b6e5..000000000 --- a/src/components/icons/Heart.tsx +++ /dev/null @@ -1,20 +0,0 @@ - -const Vector = ({ ...props }) => { - return ( - - - - ) - } - - export default Vector \ No newline at end of file diff --git a/src/components/icons/IconArrowRight.tsx b/src/components/icons/IconArrowRight.tsx new file mode 100644 index 000000000..f6d2fd609 --- /dev/null +++ b/src/components/icons/IconArrowRight.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconArrowRight = () => { + return ( + + + + ) +} + +export default IconArrowRight diff --git a/src/components/icons/IconFacebook.tsx b/src/components/icons/IconFacebook.tsx new file mode 100644 index 000000000..f3d6e72ea --- /dev/null +++ b/src/components/icons/IconFacebook.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconFacebook = () => { + return ( + + + + ) +} + +export default IconFacebook diff --git a/src/components/icons/IconHeart.tsx b/src/components/icons/IconHeart.tsx new file mode 100644 index 000000000..19186bf95 --- /dev/null +++ b/src/components/icons/IconHeart.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconHeart = () => { + return ( + + + + ) +} + +export default IconHeart \ No newline at end of file diff --git a/src/components/icons/IconHistory.tsx b/src/components/icons/IconHistory.tsx new file mode 100644 index 000000000..c36afe78d --- /dev/null +++ b/src/components/icons/IconHistory.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconHistory = () => { + return ( + + + + ) +} + +export default IconHistory diff --git a/src/components/icons/IconHome.tsx b/src/components/icons/IconHome.tsx new file mode 100644 index 000000000..a79260b35 --- /dev/null +++ b/src/components/icons/IconHome.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconHome = () => { + return ( + + + + ) +} + +export default IconHome diff --git a/src/components/icons/IconInfo.tsx b/src/components/icons/IconInfo.tsx new file mode 100644 index 000000000..027ee236b --- /dev/null +++ b/src/components/icons/IconInfo.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconInfo = () => { + return ( + + + + ) +} + +export default IconInfo diff --git a/src/components/icons/IconInstagram.tsx b/src/components/icons/IconInstagram.tsx new file mode 100644 index 000000000..77b028806 --- /dev/null +++ b/src/components/icons/IconInstagram.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconInstagram = () => { + return ( + + + + ) +} + +export default IconInstagram diff --git a/src/components/icons/IconSearch.tsx b/src/components/icons/IconSearch.tsx new file mode 100644 index 000000000..4fc3633b2 --- /dev/null +++ b/src/components/icons/IconSearch.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconSearch = () => { + return ( + + + + ) +} + +export default IconSearch diff --git a/src/components/icons/IconShopping.tsx b/src/components/icons/IconShopping.tsx new file mode 100644 index 000000000..b0d8c279c --- /dev/null +++ b/src/components/icons/IconShopping.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconShopping = () => { + return ( + + + + ) +} + +export default IconShopping diff --git a/src/components/icons/IconTwitter.tsx b/src/components/icons/IconTwitter.tsx new file mode 100644 index 000000000..3d5220607 --- /dev/null +++ b/src/components/icons/IconTwitter.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconTwitter = () => { + return ( + + + + ) +} + +export default IconTwitter diff --git a/src/components/icons/IconUser.tsx b/src/components/icons/IconUser.tsx new file mode 100644 index 000000000..ea25fa34b --- /dev/null +++ b/src/components/icons/IconUser.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconUser = () => { + return ( + + + + ) +} + +export default IconUser diff --git a/src/components/icons/IconYoutube.tsx b/src/components/icons/IconYoutube.tsx new file mode 100644 index 000000000..105bc3332 --- /dev/null +++ b/src/components/icons/IconYoutube.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconYoutube = () => { + return ( + + + + ) +} + +export default IconYoutube diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts index 155948269..33d0f82cc 100644 --- a/src/components/icons/index.ts +++ b/src/components/icons/index.ts @@ -1 +1,9 @@ export { default as IconBuy } from './IconBuy' +export { default as IconSearch } from './IconSearch' +export { default as IconArrowRight } from './IconArrowRight' +export { default as IconUser } from './IconUser' +export { default as IconHistory } from './IconHistory' +export { default as IconInfo } from './IconInfo' +export { default as IconHome } from './IconHome' +export { default as IconShopping } from './IconShopping' +export { default as IconHeart } from './IconHeart' diff --git a/src/components/modules/home/HomeBanner/HomeBanner.module.css b/src/components/modules/home/HomeBanner/HomeBanner.module.css deleted file mode 100644 index 3e25230ff..000000000 --- a/src/components/modules/home/HomeBanner/HomeBanner.module.css +++ /dev/null @@ -1,5 +0,0 @@ -/* style demo here */ - -.homeBanner { - color: green; -} \ No newline at end of file diff --git a/src/components/modules/home/HomeBanner/HomeBanner.module.scss b/src/components/modules/home/HomeBanner/HomeBanner.module.scss new file mode 100644 index 000000000..49b3b944b --- /dev/null +++ b/src/components/modules/home/HomeBanner/HomeBanner.module.scss @@ -0,0 +1,42 @@ +@import "../../../../styles/utilities"; + +.homeBanner { + @apply spacing-horizontal; + .left { + @apply hidden; + } + @screen xl { + @apply grid; + grid-template-columns: 1fr 1.8fr; + .left { + @apply flex items-end justify-center custom-border-radius-lg; + margin-right: 1.6rem; + background-image: url('./assets/home_banner.png'); + background-repeat: no-repeat; + background-size: cover; + + .text { + @apply relative font-heading text-center; + padding: 2.4rem 2.4rem 4.8rem; + width: min-content; + + color: var(--white); + font-size: 8.8rem; + line-height: 8rem; + letter-spacing: -0.03em; + font-weight: bold; + text-transform: uppercase; + &::after { + @apply absolute; + content: ""; + top: -2.4rem; + right: 0.8rem; + width: 5.7rem; + height: 4.7rem; + background-image: url("./assets/text-decorative.svg"); + background-repeat: no-repeat; + } + } + } + } +} diff --git a/src/components/modules/home/HomeBanner/HomeBanner.tsx b/src/components/modules/home/HomeBanner/HomeBanner.tsx index 7a254ec10..8bbf75138 100644 --- a/src/components/modules/home/HomeBanner/HomeBanner.tsx +++ b/src/components/modules/home/HomeBanner/HomeBanner.tsx @@ -1,14 +1,28 @@ -import { FC } from 'react' -import s from './HomeBanner.module.css' +import React from 'react' +import { Banner } from 'src/components/common' +import s from './HomeBanner.module.scss' +import BannerImgRight from './assets/banner_full.png' interface Props { className?: string children?: any } -const HomeBanner: FC = ({ }) => { +const HomeBanner = ({ }: Props) => { return ( -
This is HomeBanner
+
+
+
+ Freshness
guaranteed +
+
+ +
) } diff --git a/src/components/modules/home/HomeBanner/assets/banner.png b/src/components/modules/home/HomeBanner/assets/banner.png new file mode 100644 index 000000000..fc65bdd68 Binary files /dev/null and b/src/components/modules/home/HomeBanner/assets/banner.png differ diff --git a/src/components/modules/home/HomeBanner/assets/banner_full.png b/src/components/modules/home/HomeBanner/assets/banner_full.png new file mode 100644 index 000000000..082f8aacd Binary files /dev/null and b/src/components/modules/home/HomeBanner/assets/banner_full.png differ diff --git a/src/components/modules/home/HomeBanner/assets/home_banner.png b/src/components/modules/home/HomeBanner/assets/home_banner.png new file mode 100644 index 000000000..8fb683a8b Binary files /dev/null and b/src/components/modules/home/HomeBanner/assets/home_banner.png differ diff --git a/src/components/modules/home/HomeBanner/assets/text-decorative.svg b/src/components/modules/home/HomeBanner/assets/text-decorative.svg new file mode 100644 index 000000000..f29ef0517 --- /dev/null +++ b/src/components/modules/home/HomeBanner/assets/text-decorative.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/styles/_base.scss b/src/styles/_base.scss index abffa0914..aebbef0c2 100644 --- a/src/styles/_base.scss +++ b/src/styles/_base.scss @@ -32,7 +32,8 @@ --disabled: #cccccc; --border-line: #ebebeb; - --background: #f8f8f8; + --background: #fff; + --gray: #f8f8f8; --white: #fbfbfb; --background-arrow:rgba(20, 20, 20, 0.05); --font-size: 1.6rem; @@ -41,8 +42,7 @@ // --font-size: 16px; // --line-height: 24px; - --font-sans: "Nunito", cursive, -apple-system, system-ui, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", - sans-serif; + --font-sans: "Nunito", -apple-system, system-ui, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", sans-serif; --font-heading: "Righteous", -apple-system, system-ui, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", sans-serif; --font-logo: "Poppins", -apple-system, system-ui, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", sans-serif; } diff --git a/src/styles/_utilities.scss b/src/styles/_utilities.scss index ef5abebd5..e75d344fe 100644 --- a/src/styles/_utilities.scss +++ b/src/styles/_utilities.scss @@ -1,85 +1,86 @@ @layer utilities { .heading-1 { - font-size: 4.8rem; - line-height: 5.6rem; - letter-spacing: -0.03em; - font-weight: bold; - text-transform: uppercase; - @screen md { - font-size: 6.4rem; - line-height: 8rem; - letter-spacing: -0.03em; - } - } - .heading-2 { - font-size: 4rem; - line-height: 4.8rem; - letter-spacing: -0.02em; - font-weight: bold; - text-transform: uppercase; - @screen md { - font-size: 4.8rem; - line-height: 5.6rem; - letter-spacing: -0.02em; - } - } - .heading-3 { - font-size: 2.4rem; - line-height: 3.2rem; + font-size: 24px; + line-height: 28px; letter-spacing: -0.01em; font-weight: bold; text-transform: uppercase; @screen md { - font-size: 3.2rem; - line-height: 4rem; + font-size: 64px; + line-height: 80px; + letter-spacing: -0.03em; + } + } + .heading-2 { + font-size: 32px; + line-height: 40px; + letter-spacing: -0.02em; + font-weight: bold; + text-transform: uppercase; + @screen md { + font-size: 48px; + line-height: 56px; + letter-spacing: -0.02em; + } + } + .heading-3 { + font-size: 24px; + line-height: 32px; + letter-spacing: -0.01em; + font-weight: bold; + text-transform: uppercase; + @screen md { + font-size: 32px; + line-height: 40px; letter-spacing: -0.01em; } } .sm-headline { - font-size: 1.8rem; - line-height: 2.8rem; + font-size: 18px; + line-height: 28px; letter-spacing: -0.01em; font-weight: bold; @screen md { - font-size: 2rem; - line-height: 2.8rem; + font-size: 20px; + line-height: 28px; letter-spacing: -0.01em; } } .sub-headline { - font-size: 2rem; - line-height: 2.8rem; + font-size: 20px; + line-height: 28px; letter-spacing: -0.01em; @screen md { - font-size: 2.4rem; - line-height: 3.2rem; + font-size: 24px; + line-height: 32px; letter-spacing: -0.01em; } } .topline { - font-size: 1.8rem; - line-height: 2.8rem; + font-size: 18px; + line-height: 28px; letter-spacing: 0.01em; @screen md { - font-size: 2rem; - line-height: 2.8rem; + font-size: 20px; + line-height: 28px; letter-spacing: 0.01em; } } .caption { - font-size: 1.2rem; - line-height: 2rem; + font-size: 12px; + line-height: 20px; letter-spacing: 0.01em; } .sm-label { - font-size: 1rem; - line-height: 1.6rem; + font-size: 10px; + line-height: 16px; } + .spacing-horizontal { padding-left: 2rem; padding-right: 2rem; @@ -96,7 +97,11 @@ } } .custom-border-radius { - border-radius: 60% 10% 60% 2%/ 10% 40% 10% 50%; + border-radius: 60% 10% 60% 2%/ 10% 20% 10% 50%; + } + + .custom-border-radius-lg { + border-radius: 60% 2% 2% 2%/ 6% 50% 50% 50%; } .font-heading { diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts index 94f253622..0d66ecda0 100644 --- a/src/utils/constanst.utils.ts +++ b/src/utils/constanst.utils.ts @@ -1,3 +1,47 @@ +export const SOCIAL_LINKS = { + FB: 'FB', + TWITTER: 'TWITTER', + YOUTUBE: 'YOUTUBE', + IG: 'IG', +} + +export const ROUTE = { + HOME: '/', + PRODUCTS: '/products', + ABOUT: '/about', + ACCOUNT: '/account', + + BUSSINESS: '/bussiness', + CONTACT: '/contact', + FAQ: '/faq', + CUSTOMER_SERVICE: '/customer-service', + TERM_CONDITION: '/term-condition', + PRIVACY_POLICY: '/privacy-policy', + BLOGS: '/blogs', +} + +export const ACCOUNT_TAB = { + CUSTOMER_INFO: '', + ORDER: 'orders', + FAVOURITE: 'wishlist', +} + +export const QUERY_KEY = { + TAB: 'tab', + CATEGORY: 'category', + BRAND: 'brand', + FEATURED: 'feature' +} + +export enum ProductFeature { + BestSellers = 'Best Sellers', + Sales = 'Sales', + NewItem = 'New Item', + Viewed = 'Viewed', + +} + export const KEY = { ENTER: 'Enter', } + diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index 410d3fdcc..b1e7b5536 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -1 +1,3 @@ -// funtion utils here \ No newline at end of file +export function isMobile() { + return window.innerWidth <= 768 +} \ No newline at end of file diff --git a/src/utils/language.utils.ts b/src/utils/language.utils.ts index 4343ed9db..3f8d61926 100644 --- a/src/utils/language.utils.ts +++ b/src/utils/language.utils.ts @@ -3,4 +3,7 @@ export const LANGUAGE = { BUY_NOW: 'Buy now', SHOP_NOW: 'Shop now', }, + PLACE_HOLDER: { + SEARCH: 'Search', + } } \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index d2fe7ee70..c9e77ec87 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -44,14 +44,14 @@ module.exports = { 'negative': 'var(--negative)', 'negative-border-line': 'var(--negative-border-line)', 'negative-light': 'var(--negative-light)', - - 'line': 'var(--border-line)', - 'background': 'var(--background)', - 'white': 'var(--white)', - - 'background-arrow':'var(--background-arrow)', - + 'disabled': 'var(--text-disabled)', + line: 'var(--border-line)', + background: 'var(--background)', + white: 'var(--white)', + 'background-arrow':'var(--background-arrow)', + gray: 'var(--gray)', + disabled: 'var(--text-disabled)', // @deprecated (NOT use these variables) 'primary-2': 'var(--primary-2)', @@ -85,9 +85,9 @@ module.exports = { active: 'var(--text-active)', label: 'var(--text-label)', placeholder: 'var(--text-placeholder)', + primary: 'var(--primary)', // @deprecated (NOT use these variables) - primary: 'var(--text-primary)', secondary: 'var(--text-secondary)', }, boxShadow: {