diff --git a/.gitignore b/.gitignore
index 22f1bf4f3..61386b73c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
node_modules
/.pnp
.pnp.js
+package-lock.json
# testing
/coverage
diff --git a/pages/index.tsx b/pages/index.tsx
index 6eb35bc03..a61c40d14 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -122,4 +122,4 @@ export default function Home() {
)
}
-// Home.Layout = Layout
+Home.Layout = Layout
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/CollectionHeading/CollectionHeading.module.scss b/src/components/common/CollectionHeading/CollectionHeading.module.scss
index 208a78728..870eda782 100644
--- a/src/components/common/CollectionHeading/CollectionHeading.module.scss
+++ b/src/components/common/CollectionHeading/CollectionHeading.module.scss
@@ -1,6 +1,5 @@
-@import '../../../styles/utilities';
-
.subtitle {
font-size: var(--font-size);
line-height: var(--line-height);
+ margin-top: .4rem;
}
\ No newline at end of file
diff --git a/src/components/common/CollectionHeading/CollectionHeading.tsx b/src/components/common/CollectionHeading/CollectionHeading.tsx
index e52352618..3655d6561 100644
--- a/src/components/common/CollectionHeading/CollectionHeading.tsx
+++ b/src/components/common/CollectionHeading/CollectionHeading.tsx
@@ -1,19 +1,18 @@
import React from 'react'
-// import classNames from 'classnames'
import s from './CollectionHeading.module.scss'
import HeadingCommon from '../HeadingCommon/HeadingCommon'
interface CollectionHeadingProps {
- headingType?: 'default' | 'highlight' | 'light'
- headingText: string;
- subtitle: string
+ type?: 'default' | 'highlight' | 'light';
+ title: string;
+ subtitle: string;
}
-const CollectionHeading = ({ headingType='default', headingText, subtitle }: CollectionHeadingProps) => {
+const CollectionHeading = ({ type = 'default', title, subtitle }: CollectionHeadingProps) => {
return (
-
-
+
)
diff --git a/src/components/common/Footer/Footer.module.scss b/src/components/common/Footer/Footer.module.scss
new file mode 100644
index 000000000..bfe9ceead
--- /dev/null
+++ b/src/components/common/Footer/Footer.module.scss
@@ -0,0 +1,31 @@
+@import "../../../styles/utilities";
+
+.footer {
+ @apply spacing-horizontal;
+ padding-top: 4rem;
+ padding-bottom: 2rem;
+ margin-bottom: 10rem;
+ .footerMenu {
+ padding-bottom: 4rem;
+ }
+ .menu {
+ @apply flex flex-wrap;
+ }
+
+ @screen md {
+ margin-bottom: 0;
+ padding-bottom: 4rem;
+ padding-left: 3.2rem;
+ padding-right: 3.2rem;
+ .footerMenu {
+ @apply flex;
+ padding-bottom: 8rem;
+ .menu {
+ @apply flex-nowrap justify-between;
+ }
+ }
+ }
+ @screen lg {
+ @apply spacing-horizontal;
+ }
+}
diff --git a/src/components/common/Footer/Footer.tsx b/src/components/common/Footer/Footer.tsx
new file mode 100644
index 000000000..a830c60ea
--- /dev/null
+++ b/src/components/common/Footer/Footer.tsx
@@ -0,0 +1,85 @@
+import React from 'react'
+import { ROUTE } from 'src/utils/constanst.utils'
+import FooterColumn from './components/FooterColumn/FooterColumn'
+import FooterSocial from './components/FooterSocial/FooterSocial'
+import s from './Footer.module.scss'
+
+const FOOTER_COLUMNS = [
+ {
+ title: 'Company',
+ items: [
+ {
+ name: 'All Product',
+ link: ROUTE.PRODUCTS,
+ },
+ {
+ name: 'About Us',
+ link: ROUTE.ABOUT,
+ },
+ {
+ name: 'Bussiness',
+ link: ROUTE.BUSSINESS,
+ }
+ ]
+ },
+ {
+ title: 'Resources',
+ items: [
+ {
+ name: 'Contact Us',
+ link: ROUTE.CONTACT,
+ },
+ {
+ name: 'FAQ',
+ link: ROUTE.FAQ,
+ },
+ {
+ name: 'Customer Service',
+ link: ROUTE.CUSTOMER_SERVICE,
+ },
+ ]
+ },
+ {
+ title: 'Quick Links',
+ items: [
+ {
+ name: 'Terms & Conditions',
+ link: ROUTE.TERM_CONDITION,
+ },
+ {
+ name: 'Privacy Policy',
+ link: ROUTE.TERM_CONDITION,
+ },
+ {
+ name: 'Blog',
+ link: ROUTE.TERM_CONDITION,
+ },
+ ]
+ }
+]
+
+interface Props {
+ className?: string
+ children?: any
+}
+
+const Footer = ({ }: Props) => {
+ return (
+
+ )
+}
+
+export default Footer
diff --git a/src/components/common/Footer/components/FooterColumn/FooterColumn.module.scss b/src/components/common/Footer/components/FooterColumn/FooterColumn.module.scss
new file mode 100644
index 000000000..754ebce69
--- /dev/null
+++ b/src/components/common/Footer/components/FooterColumn/FooterColumn.module.scss
@@ -0,0 +1,33 @@
+@import "../../../../../styles/utilities";
+
+.footerColumn {
+ width: 50%;
+ margin-bottom: 4rem;
+ @screen md {
+ padding-right: 6.4rem;
+ width: unset;
+ margin-bottom: 0;
+ }
+
+ @screen lg {
+ padding-right: 12.8rem;
+ }
+ .title {
+ @apply sm-headline text-active;
+ margin-bottom: 2.4rem;
+ }
+ ul {
+ list-style: none;
+ li {
+ &:not(:last-child) {
+ margin-bottom: 1.6rem;
+ }
+ a {
+ @apply transition-all duration-200 no-underline;
+ &:hover {
+ color: var(--primary);
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/common/Footer/components/FooterColumn/FooterColumn.tsx b/src/components/common/Footer/components/FooterColumn/FooterColumn.tsx
new file mode 100644
index 000000000..4adda1985
--- /dev/null
+++ b/src/components/common/Footer/components/FooterColumn/FooterColumn.tsx
@@ -0,0 +1,38 @@
+import Link from 'next/link';
+import React from 'react';
+import s from './FooterColumn.module.scss'
+
+interface Props {
+ title: string,
+ items: { link: string, name: string, isOpenNewTab?: boolean }[],
+}
+
+const FooterColumn = ({ title, items }: Props) => {
+ return (
+
+ );
+};
+
+export default FooterColumn;
\ No newline at end of file
diff --git a/src/components/common/Footer/components/FooterSocial/FooterSocial.module.scss b/src/components/common/Footer/components/FooterSocial/FooterSocial.module.scss
new file mode 100644
index 000000000..cfc2060c5
--- /dev/null
+++ b/src/components/common/Footer/components/FooterSocial/FooterSocial.module.scss
@@ -0,0 +1,43 @@
+@import "../../../../../styles/utilities";
+
+.footerSocial {
+ .title {
+ @apply sm-headline text-active;
+ margin-bottom: 2.4rem;
+ }
+ .socialMedia,
+ .payment {
+ @apply list-none flex items-center;
+ }
+ .socialMedia {
+ li {
+ @apply transition-all duration-200;
+ margin-right: 1.6rem;
+ &:last-child {
+ margin-right: 0;
+ }
+ a {
+ @apply no-underline;
+ }
+ &:hover {
+ svg path {
+ fill: var(--primary);
+ }
+ }
+ }
+ }
+ .payment {
+ margin-top: 3.2rem;
+ li {
+ margin-right: 1.6rem;
+ width: 4rem;
+ img {
+ width: 100%;
+ object-fit: contain;
+ }
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+}
diff --git a/src/components/common/Footer/components/FooterSocial/FooterSocial.tsx b/src/components/common/Footer/components/FooterSocial/FooterSocial.tsx
new file mode 100644
index 000000000..94fb097a8
--- /dev/null
+++ b/src/components/common/Footer/components/FooterSocial/FooterSocial.tsx
@@ -0,0 +1,75 @@
+import React from 'react';
+import IconFacebook from 'src/components/icons/IconFacebook';
+import IconInstagram from 'src/components/icons/IconInstagram';
+import IconTwitter from 'src/components/icons/IconTwitter';
+import IconYoutube from 'src/components/icons/IconYoutube';
+import { SOCIAL_LINKS } from 'src/utils/constanst.utils';
+import IconVisa from '../../../../../assets/imgs/visa.png';
+import IconMasterCard from '../../../../../assets/imgs/mastercard.png';
+import IconGooglePlay from '../../../../../assets/imgs/gpay.png';
+import IconApplePay from '../../../../../assets/imgs/apple_pay.png';
+import s from './FooterSocial.module.scss';
+
+const SOCIAL_MENU = [
+ {
+ icon: ,
+ link: SOCIAL_LINKS.FB,
+ },
+ {
+ icon: ,
+ link: SOCIAL_LINKS.TWITTER,
+ },
+ {
+ icon: ,
+ link: SOCIAL_LINKS.YOUTUBE,
+ },
+ {
+ icon: ,
+ link: SOCIAL_LINKS.IG,
+ },
+]
+
+const PAYMENT_METHODS = [
+ {
+ icon: IconVisa.src,
+ name: 'Visa'
+ },
+ {
+ icon: IconMasterCard.src,
+ name: 'Master Card'
+ },
+ {
+ icon: IconGooglePlay.src,
+ name: 'GooglePay'
+ },
+ {
+ icon: IconApplePay.src,
+ name: 'Apple Pay'
+ },
+]
+
+const FooterSocial = () => {
+ return (
+
+ Social
+
+
+ {
+ PAYMENT_METHODS.map(item => -
+
+ )
+ }
+
+
+ );
+};
+
+export default FooterSocial;
\ No newline at end of file
diff --git a/src/components/common/Header/Header.module.scss b/src/components/common/Header/Header.module.scss
index 0207f107f..ce960228b 100644
--- a/src/components/common/Header/Header.module.scss
+++ b/src/components/common/Header/Header.module.scss
@@ -1,22 +1,16 @@
@import "../../../styles/utilities";
.header {
- .btn {
- // @apply font-bold py-2 px-4 rounded;
+ @apply sticky bg-white shadow-md;
+ top: 0;
+ z-index: 9999;
+ margin-bottom: 3.2rem;
+ &.full {
+ @apply shadow-none;
+ border: 1px solid var(--border-line);
}
- .btnBlue {
- @apply bg-primary hover:bg-warning text-label font-bold py-2 px-4 custom-border-radius;
- }
- .link {
- color: theme("colors.warning");
- }
- .heading {
- @apply text-base font-heading;
- }
- .paragraph {
- @apply topline;
- }
- .logo {
- @apply font-logo;
+ .menu {
+ padding-left: 3.2rem;
+ padding-right: 3.2rem;
}
}
diff --git a/src/components/common/Header/Header.tsx b/src/components/common/Header/Header.tsx
index 0c4bfa92e..dfce58b57 100644
--- a/src/components/common/Header/Header.tsx
+++ b/src/components/common/Header/Header.tsx
@@ -1,4 +1,10 @@
-import { FC } from 'react'
+import classNames from 'classnames'
+import React, { memo, useEffect, useState } from 'react'
+import { isMobile } from 'src/utils/funtion.utils'
+import HeaderHighLight from './components/HeaderHighLight/HeaderHighLight'
+import HeaderMenu from './components/HeaderMenu/HeaderMenu'
+import HeaderSubMenu from './components/HeaderSubMenu/HeaderSubMenu'
+import HeaderSubMenuMobile from './components/HeaderSubMenuMobile/HeaderSubMenuMobile'
import s from './Header.module.scss'
interface Props {
@@ -6,14 +12,37 @@ interface Props {
children?: any
}
-const Header: FC = ({ }: Props) => {
+const Header = memo(({ }: Props) => {
+ const [isFullHeader, setIsFullHeader] = useState(true)
+
+ useEffect(() => {
+ window.addEventListener('scroll', handleScroll)
+ return () => {
+ window.removeEventListener('scroll', handleScroll)
+ }
+ }, [])
+
+ const handleScroll = () => {
+ if (!isMobile()) {
+ if (window.scrollY === 0) {
+ setIsFullHeader(true)
+ } else {
+ setIsFullHeader(false)
+ }
+ }
+ }
return (
-
- This is Header
-
This is heading
-
This is logo text
-
+ <>
+
+
+ >
)
-}
+})
export default Header
diff --git a/src/components/common/Header/components/HeaderHighLight/HeaderHighLight.module.scss b/src/components/common/Header/components/HeaderHighLight/HeaderHighLight.module.scss
new file mode 100644
index 000000000..9717fd29d
--- /dev/null
+++ b/src/components/common/Header/components/HeaderHighLight/HeaderHighLight.module.scss
@@ -0,0 +1,39 @@
+@import "../../../../../styles/utilities";
+
+.headerHighLight {
+ @apply hidden;
+ @screen md {
+ transform: translateY(-10rem);
+ height: 0;
+ &.show {
+ @apply flex justify-between items-center spacing-horizontal bg-primary caption;
+ animation: showHeaderHightlight 0.2s;
+ height: unset;
+ transform: none;
+ padding-top: 0.8rem;
+ padding-bottom: 0.8rem;
+ color: var(--white);
+ .menu {
+ @apply flex items-center list-none;
+ padding: 0.8rem 0;
+ li {
+ &:not(:last-child) {
+ margin-right: 3.2rem;
+ }
+ a {
+ @appy no-underline;
+ }
+ }
+ }
+ }
+ }
+}
+
+@keyframes showHeaderHightlight {
+ 0% {
+ transform: translateY(-4rem);
+ }
+ 100% {
+ transform: none;
+ }
+}
diff --git a/src/components/common/Header/components/HeaderHighLight/HeaderHighLight.tsx b/src/components/common/Header/components/HeaderHighLight/HeaderHighLight.tsx
new file mode 100644
index 000000000..a1759eede
--- /dev/null
+++ b/src/components/common/Header/components/HeaderHighLight/HeaderHighLight.tsx
@@ -0,0 +1,49 @@
+import classNames from 'classnames'
+import Link from 'next/link'
+import { memo, useEffect, useRef } from 'react'
+import { ROUTE } from 'src/utils/constanst.utils'
+import s from './HeaderHighLight.module.scss'
+
+const MENU = [
+ {
+ name: 'Delivery & Policy',
+ link: ROUTE.PRIVACY_POLICY,
+ },
+ {
+ name: 'Blog',
+ link: ROUTE.BLOGS,
+ },
+ {
+ name: 'About Us',
+ link: ROUTE.ABOUT,
+ },
+]
+
+interface Props {
+ children?: any,
+ isShow: boolean,
+}
+
+const HeaderHighLight = memo(({ isShow }: Props) => {
+ return (
+
+
+ Free Shipping on order $49+ / Express $99+
+
+
+
+ )
+})
+
+export default HeaderHighLight
diff --git a/src/components/common/Header/components/HeaderMenu/HeaderMenu.module.scss b/src/components/common/Header/components/HeaderMenu/HeaderMenu.module.scss
new file mode 100644
index 000000000..a61c059e6
--- /dev/null
+++ b/src/components/common/Header/components/HeaderMenu/HeaderMenu.module.scss
@@ -0,0 +1,65 @@
+@import "../../../../../styles/utilities";
+
+.headerMenu {
+ padding-top: 1.6rem;
+ padding-bottom: 0.8rem;
+ @screen md {
+ @apply flex justify-between items-center;
+ padding-top: 0.8rem;
+ padding-bottom: 0.8rem;
+ &.full {
+ padding-top: 2.4rem;
+ padding-bottom: 2.4rem;
+ }
+ }
+ .left {
+ .top {
+ @apply flex justify-between items-center;
+ .iconCart {
+ }
+ }
+ .inputSearch {
+ margin-top: 2.4rem;
+ @screen lg {
+ min-width: 51.2rem;
+ max-width: 50%;
+ }
+ }
+ @screen md {
+ @apply flex items-center;
+ .top {
+ .iconCart {
+ @apply hidden;
+ }
+ }
+ .inputSearch {
+ margin-left: 4.8rem;
+ margin-top: 0;
+ }
+ }
+ }
+ .menu {
+ @apply hidden;
+ @screen md {
+ @apply flex items-center list-none;
+ li {
+ @apply flex justify-center items-center w-full;
+ &:not(:last-child) {
+ margin-right: 4.8rem;
+ @screen lg {
+ margin-right: 6.4rem;
+ }
+ }
+ a {
+ @appy no-underline;
+ &.iconFovourite {
+ svg path {
+ fill: var(--negative);
+ }
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/src/components/common/Header/components/HeaderMenu/HeaderMenu.tsx b/src/components/common/Header/components/HeaderMenu/HeaderMenu.tsx
new file mode 100644
index 000000000..8f19b11e8
--- /dev/null
+++ b/src/components/common/Header/components/HeaderMenu/HeaderMenu.tsx
@@ -0,0 +1,69 @@
+import classNames from 'classnames'
+import Link from 'next/link'
+import { memo } from 'react'
+import InputSearch from 'src/components/common/InputSearch/InputSearch'
+import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown'
+import { IconBuy, IconHeart, IconHistory, IconUser } from 'src/components/icons'
+import { ACCOUNT_TAB, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
+import s from './HeaderMenu.module.scss'
+
+const OPTION_MENU = [
+ {
+ link: ROUTE.ACCOUNT,
+ name: 'Account',
+ },
+ {
+ link: '/',
+ name: 'Logout',
+ },
+
+]
+
+interface Props {
+ children?: any,
+ isFull: boolean,
+}
+
+const HeaderMenu = memo(({ isFull }: 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/HeadingCommon/HeadingCommon.module.scss b/src/components/common/HeadingCommon/HeadingCommon.module.scss
index 8e9b62602..4626706a1 100644
--- a/src/components/common/HeadingCommon/HeadingCommon.module.scss
+++ b/src/components/common/HeadingCommon/HeadingCommon.module.scss
@@ -1,13 +1,13 @@
@import '../../../styles/utilities';
.headingCommon {
- @apply heading-1 font-heading uppercase text-left;
+ @apply heading-1 font-heading text-left;
&.highlight {
color: var(--negative);
}
&.light {
- color: var(--disabled);
+ color: var(--white);
}
&.center {
@apply text-center;
diff --git a/src/components/common/HeadingCommon/HeadingCommon.tsx b/src/components/common/HeadingCommon/HeadingCommon.tsx
index 45c89a3bd..a3c1165bf 100644
--- a/src/components/common/HeadingCommon/HeadingCommon.tsx
+++ b/src/components/common/HeadingCommon/HeadingCommon.tsx
@@ -3,19 +3,19 @@ import classNames from 'classnames'
import s from './HeadingCommon.module.scss'
interface HeadingCommonProps {
- headingType?: 'highlight' | 'light' | 'default';
- textAlign?: 'center' | 'left';
- headingText?: string;
+ type?: 'highlight' | 'light' | 'default';
+ align?: 'center' | 'left';
+ children: string;
}
-const HeadingCommon = ({ headingType='default', textAlign='left', headingText='categories' }: HeadingCommonProps) => {
+const HeadingCommon = ({ type='default', align='left', children }: HeadingCommonProps) => {
return (
- {headingText}
+ >{children}
)
}
diff --git a/src/components/common/InputCommon/InputCommon.module.scss b/src/components/common/InputCommon/InputCommon.module.scss
index 13e27fd5f..27eaed174 100644
--- a/src/components/common/InputCommon/InputCommon.module.scss
+++ b/src/components/common/InputCommon/InputCommon.module.scss
@@ -16,7 +16,7 @@
}
.inputCommon {
@apply block w-full transition-all duration-200 rounded;
- padding: 1.6rem;
+ padding: 1.2rem 1.6rem;
border: 1px solid var(--border-line);
&:hover,
&:focus,
@@ -31,7 +31,8 @@
}
&.custom {
- @apply custom-border-radius border-none;
+ @apply custom-border-radius;
+ border: 1px solid transparent;
background: var(--gray);
&:hover,
&:focus,
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 (
+
+ );
+};
+
+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/ScrollToTop/ScrollTarget.tsx b/src/components/common/ScrollToTop/ScrollTarget.tsx
new file mode 100644
index 000000000..50a839c83
--- /dev/null
+++ b/src/components/common/ScrollToTop/ScrollTarget.tsx
@@ -0,0 +1,15 @@
+import React, { MutableRefObject } from 'react'
+
+interface ScrollTargetProps {
+ refScrollUp: MutableRefObject;
+}
+
+const ScrollTarget = ({ refScrollUp } : ScrollTargetProps) => {
+
+ return (
+
+ )
+
+}
+
+export default ScrollTarget
diff --git a/src/components/common/ScrollToTop/ScrollToTop.module.scss b/src/components/common/ScrollToTop/ScrollToTop.module.scss
new file mode 100644
index 000000000..c010f08ad
--- /dev/null
+++ b/src/components/common/ScrollToTop/ScrollToTop.module.scss
@@ -0,0 +1,24 @@
+@import '../../../styles/utilities';
+
+.scrollToTop {
+ @apply hidden;
+
+ @screen md {
+ &.show {
+ @apply block rounded-lg fixed cursor-pointer;
+ right: 11.2rem;
+ bottom: 21.6rem;
+ width: 6.4rem;
+ height: 6.4rem;
+ background-color: var(--border-line);
+ }
+
+ &.hide {
+ @apply hidden;
+ }
+ }
+
+ .scrollToTopBtn {
+ @apply outline-none w-full h-full;
+ }
+}
\ No newline at end of file
diff --git a/src/components/common/ScrollToTop/ScrollToTop.tsx b/src/components/common/ScrollToTop/ScrollToTop.tsx
new file mode 100644
index 000000000..98e16168d
--- /dev/null
+++ b/src/components/common/ScrollToTop/ScrollToTop.tsx
@@ -0,0 +1,54 @@
+import React, { useState, useEffect, MutableRefObject } from 'react'
+import classNames from 'classnames'
+import s from './ScrollToTop.module.scss'
+
+import ArrowUp from '../../icons/IconArrowUp'
+
+interface ScrollToTopProps {
+ target: MutableRefObject;
+ visibilityHeight?: number;
+}
+
+const ScrollToTop = ({ target, visibilityHeight=450 }: ScrollToTopProps) => {
+
+ const [scrollPosition, setSrollPosition] = useState(0);
+ const [showScrollToTop, setShowScrollToTop] = useState("hide");
+
+ function handleVisibleButton() {
+ const position = window.pageYOffset;
+ setSrollPosition(position);
+
+ if (scrollPosition > visibilityHeight) {
+ return setShowScrollToTop("show")
+ } else if (scrollPosition < visibilityHeight) {
+ return setShowScrollToTop("hide");
+ }
+ };
+
+ function handleScrollUp() {
+ target.current.scrollIntoView({ behavior: "smooth" });
+ }
+
+ function addEventScroll() {
+ window.addEventListener("scroll", handleVisibleButton);
+ }
+
+ useEffect(() => {
+ addEventScroll()
+ });
+
+ return (
+
+ )
+
+}
+
+export default ScrollToTop
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index 3e0ccbf43..f672564e2 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -12,7 +12,13 @@ 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 HeadingCommon } from './HeadingCommon/HeadingCommon'
export { default as CollectionHeading } from './CollectionHeading/CollectionHeading'
+export { default as ScrollToTop } from './ScrollToTop/ScrollToTop'
+export { default as ScrollTarget } from './ScrollToTop/ScrollTarget'
+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/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/IconArrowUp.tsx b/src/components/icons/IconArrowUp.tsx
new file mode 100644
index 000000000..3eac6391b
--- /dev/null
+++ b/src/components/icons/IconArrowUp.tsx
@@ -0,0 +1,10 @@
+const ArrowUp = () => {
+
+ return (
+
+ )
+ }
+
+ export default ArrowUp
\ No newline at end of file
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
index 0d868c5e7..593e9278e 100644
--- a/src/components/icons/IconHeart.tsx
+++ b/src/components/icons/IconHeart.tsx
@@ -1,23 +1,11 @@
+import React from 'react'
-const IconHeart = ({ ...props }) => {
- return (
-
- )
- }
-
- export default IconHeart
\ No newline at end of file
+const IconHeart = () => {
+ return (
+
+ )
+}
+
+export default IconHeart
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/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 c82e4fa76..eeaffb85b 100644
--- a/src/components/icons/index.ts
+++ b/src/components/icons/index.ts
@@ -1,3 +1,10 @@
export { default as IconBuy } from './IconBuy'
+export { default as ArrowUp } from './IconArrowUp'
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 123e581a9..aebbef0c2 100644
--- a/src/styles/_base.scss
+++ b/src/styles/_base.scss
@@ -42,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 251aaf214..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;
@@ -99,6 +100,10 @@
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 {
font-family: var(--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/tailwind.config.js b/tailwind.config.js
index 2882c260c..4867fef18 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -51,10 +51,12 @@ module.exports = {
'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)',
@@ -90,9 +92,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: {
diff --git a/yarn.lock b/yarn.lock
index 37aeb20a2..8b4ce8da1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2888,11 +2888,6 @@
"resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
"version" "1.0.0"
-"fsevents@~2.3.1", "fsevents@~2.3.2":
- "integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="
- "resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
- "version" "2.3.2"
-
"function-bind@^1.1.1":
"integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"