Merge pull request #56 from KieIO/m7-lytran3

M7 lytran3: Fix header, cart drawer
This commit is contained in:
lytrankieio123 2021-09-15 13:54:14 +07:00 committed by GitHub
commit d44567e9f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 141 additions and 66 deletions

3
next-env.d.ts vendored
View File

@ -1,6 +1,3 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/types/global" /> /// <reference types="next/types/global" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

Binary file not shown.

Binary file not shown.

4
public/fonts/style.css Normal file
View File

@ -0,0 +1,4 @@
@font-face {
font-family: "Norquay-bold";
src: url("./Norquay-bold.otf") format("opentype"), url("./Norquay-bold.woff") format("woff");
}

View File

@ -8,7 +8,6 @@ interface Props {
const option = { const option = {
slidesPerView: 1, slidesPerView: 1,
mode: 'free',
} }
const Banner = memo(({ data }: Props) => { const Banner = memo(({ data }: Props) => {
if (data.length === 1) { if (data.length === 1) {

View File

@ -9,6 +9,7 @@
width: 64px; width: 64px;
height: 64px; height: 64px;
border-radius: .8rem; border-radius: .8rem;
backdrop-filter: saturate(180%) blur(10px);
&:focus { &:focus {
outline: none; outline: none;
} }

View File

@ -4,6 +4,6 @@
.cartDrawer { .cartDrawer {
@apply flex flex-col h-full; @apply flex flex-col h-full;
.body { .body {
@apply flex flex-col justify-center overflow-y-auto overflow-x-hidden h-full custom-scroll; @apply flex flex-col overflow-y-auto overflow-x-hidden h-full custom-scroll;
} }
} }

View File

@ -1,21 +1,36 @@
@import "../../../styles/utilities"; @import "../../../styles/utilities";
.drawerCommon { .drawerCommon {
@apply fixed flex justify-end transition-all duration-200; @apply fixed flex justify-end transition-all duration-500;
overflow: hidden; overflow: hidden;
top: 0; top: 0;
right: 0; right: 0;
height: 100vh; height: 100vh;
width: 90%; width: 100%;
box-shadow: -3px 0 10px rgba(0, 0, 0, 0.15);
z-index: 20000; z-index: 20000;
transform: translateX(110%);
&.show {
.innerWrap {
background: rgba(0, 0, 0, 0.2);
animation: animateBackground 0.8s;
}
transform: none;
}
.innerWrap {
@apply w-full;
background: none;
}
.inner { .inner {
@apply flex flex-col bg-white; @apply flex flex-col bg-white;
width: fit-content; width: fit-content;
height: 100vh; height: 100vh;
width: 100%; width: 100%;
margin-right: 0; margin-left: auto;
box-shadow: -3px 0 10px rgba(0, 0, 0, 0.15);
// transform: none;
@screen md { @screen md {
max-width: 52rem; max-width: 52rem;
} }
@ -39,14 +54,21 @@
overflow-y: auto; overflow-y: auto;
height: 100%; height: 100%;
} }
&.hide {
transform: translateX(110%);
}
@screen md { @screen md {
width: unset;
.inner { .inner {
min-width: 48rem; min-width: 48rem;
} }
} }
} }
@keyframes animateBackground {
0%,
50% {
background: none;
}
100% {
background: rgba(0, 0, 0, 0.2);
}
}

View File

@ -11,22 +11,32 @@ interface Props {
} }
const DrawerCommon = ({ title, visible, children, onClose }: Props) => { const DrawerCommon = ({ title, visible, children, onClose }: Props) => {
const refInner = useRef<HTMLDivElement>(null)
const handleClickOut = (e: any) => {
if (e.target.contains(refInner.current)) {
onClose()
}
}
return ( return (
<div className={classNames({ <div className={classNames({
[s.drawerCommon]: true, [s.drawerCommon]: true,
[s.hide]: !visible [s.show]: visible
})}> })}>
<div className={s.inner}> <div className={s.innerWrap} onClick={handleClickOut}>
<div className={s.top}> <div className={s.inner} ref={refInner}>
<h4 className={s.heading}> <div className={s.top}>
{title} <h4 className={s.heading}>
</h4> {title}
<div className={s.iconClose} onClick={onClose}> </h4>
<IconClose /> <div className={s.iconClose} onClick={onClose}>
<IconClose />
</div>
</div>
<div className={s.content}>
{children}
</div> </div>
</div>
<div className={s.content}>
{children}
</div> </div>
</div> </div>
</div> </div>

View File

@ -12,10 +12,10 @@ import HeaderSubMenuMobile from './components/HeaderSubMenuMobile/HeaderSubMenuM
import s from './Header.module.scss' import s from './Header.module.scss'
interface props { interface props {
toggleFilter: () => void, toggleFilter: () => void,
visibleFilter:boolean visibleFilter: boolean
} }
const Header = memo(({ toggleFilter,visibleFilter }: props) => { const Header = memo(({ toggleFilter, visibleFilter }: props) => {
const headeFullRef = useRef<HTMLDivElement>(null) const headeFullRef = useRef<HTMLDivElement>(null)
const [isFullHeader, setIsFullHeader] = useState<boolean>(true) const [isFullHeader, setIsFullHeader] = useState<boolean>(true)
const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false }) const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false })
@ -30,27 +30,23 @@ const Header = memo(({ toggleFilter,visibleFilter }: props) => {
} }
} }
const headerHeight = useMemo(() => {
return headeFullRef.current?.offsetHeight
}, [headeFullRef.current])
useEffect(() => { useEffect(() => {
const handleScroll = () => { const handleScroll = () => {
if (!isMobile()) { if (!headeFullRef.current || window.scrollY > headeFullRef.current?.offsetHeight) {
if (!headerHeight || window.scrollY > headerHeight) { setIsFullHeader(false)
setIsFullHeader(false)
} else {
setIsFullHeader(true)
}
} else { } else {
setIsFullHeader(true) setIsFullHeader(true)
} }
// if (!isMobile()) {
// } else {
// setIsFullHeader(true)
// }
} }
window.addEventListener('scroll', handleScroll) window.addEventListener('scroll', handleScroll)
return () => { return () => {
window.removeEventListener('scroll', handleScroll) window.removeEventListener('scroll', handleScroll)
} }
}, [headerHeight]) }, [headeFullRef.current])
return ( return (
<> <>
@ -59,16 +55,18 @@ const Header = memo(({ toggleFilter,visibleFilter }: props) => {
[s.show]: !isFullHeader [s.show]: !isFullHeader
})}> })}>
<HeaderMenu <HeaderMenu
isStickyHeader={true}
toggleFilter={toggleFilter} toggleFilter={toggleFilter}
toggleCart={toggleCart} toggleCart={toggleCart}
openModalAuthen={openModalAuthen} openModalAuthen={openModalAuthen}
openModalInfo={openModalInfo} /> openModalInfo={openModalInfo} />
</div> </div>
<header ref={headeFullRef} className={classNames({ [s.header]: true, [s.full]: isFullHeader })}> <header ref={headeFullRef} className={classNames({ [s.header]: true, [s.full]: isFullHeader })}>
<HeaderHighLight /> <HeaderHighLight />
<div className={s.menu}> <div className={s.menu}>
<HeaderMenu <HeaderMenu
isFull={isFullHeader}
visibleFilter={visibleFilter} visibleFilter={visibleFilter}
toggleFilter={toggleFilter} toggleFilter={toggleFilter}
toggleCart={toggleCart} toggleCart={toggleCart}

View File

@ -1,25 +1,46 @@
@import "../../../../../styles/utilities"; @import "../../../../../styles/utilities";
.headerMenu { .headerMenu {
padding-top: 1.6rem; @apply hidden;
padding-top: 0.8rem;
padding-bottom: 0.8rem; padding-bottom: 0.8rem;
&.full {
@apply flex;
}
&.small {
@apply flex;
.left {
.top {
display: none;
@screen md {
display: flex;
}
}
}
}
@screen md { @screen md {
@apply flex justify-between items-center; @apply flex justify-between items-center;
padding-top: 0.8rem; padding-top: 0.8rem;
padding-bottom: 0.8rem; padding-bottom: 0.8rem;
} }
.left { .left {
// margin-bottom: 3.2rem;
flex: 1;
.top { .top {
@apply flex justify-between items-center; @apply flex justify-between items-center;
.iconGroup{ margin-bottom: 2rem;
@screen md {
margin-bottom: 0;
}
.iconGroup {
@apply flex justify-between items-center; @apply flex justify-between items-center;
} }
.iconCart { .iconCart {
margin-left: 1.6rem; margin-left: 1.6rem;
} }
.iconFilter{ .iconFilter {
@apply relative; @apply relative;
.dot{ .dot {
@apply absolute; @apply absolute;
top: -0.08rem; top: -0.08rem;
right: -0.2rem; right: -0.2rem;
@ -28,7 +49,7 @@
height: 1.2rem; height: 1.2rem;
border-radius: 1.2rem; border-radius: 1.2rem;
@apply hidden; @apply hidden;
&.isShow{ &.isShow {
@apply block; @apply block;
} }
} }
@ -36,13 +57,24 @@
display: none; display: none;
} }
} }
} }
.inputSearch { .searchWrap {
margin-top: 2.4rem; @apply flex items-center;
.inputSearch {
flex: 1;
}
.buttonSearch {
margin-left: 1rem;
}
@screen md {
margin: 0 1.6rem 0 4.8rem;
}
@screen lg { @screen lg {
min-width: 51.2rem; min-width: 51.2rem;
max-width: 50%; max-width: 50%;
.buttonSearch {
@apply hidden;
}
} }
} }
@screen md { @screen md {
@ -52,10 +84,6 @@
@apply hidden; @apply hidden;
} }
} }
.inputSearch {
margin-left: 4.8rem;
margin-top: 0;
}
} }
} }
.btnCart { .btnCart {
@ -98,7 +126,7 @@
} }
@screen xl { @screen xl {
.iconFilterDesk { .iconFilterDesk {
display:none; display: none;
} }
} }
} }

View File

@ -2,6 +2,7 @@ import classNames from 'classnames'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { memo, useMemo } from 'react' import { memo, useMemo } from 'react'
import { ButtonCommon } from 'src/components/common'
import InputSearch from 'src/components/common/InputSearch/InputSearch' import InputSearch from 'src/components/common/InputSearch/InputSearch'
import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown' import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown'
import { IconBuy, IconFilter, IconHeart, IconHistory, IconUser } from 'src/components/icons' import { IconBuy, IconFilter, IconHeart, IconHistory, IconUser } from 'src/components/icons'
@ -10,8 +11,9 @@ import Logo from '../../../Logo/Logo'
import s from './HeaderMenu.module.scss' import s from './HeaderMenu.module.scss'
interface Props { interface Props {
children?: any, children?: any,
isFull: boolean, isFull?: boolean,
visibleFilter?:boolean, isStickyHeader?: boolean,
visibleFilter?: boolean,
openModalAuthen: () => void, openModalAuthen: () => void,
openModalInfo: () => void, openModalInfo: () => void,
toggleFilter: () => void, toggleFilter: () => void,
@ -20,7 +22,7 @@ interface Props {
const FILTER_PAGE = [ROUTE.HOME, ROUTE.PRODUCTS] const FILTER_PAGE = [ROUTE.HOME, ROUTE.PRODUCTS]
const HeaderMenu = memo(({ visibleFilter,openModalAuthen, openModalInfo, toggleFilter, toggleCart}: Props) => { const HeaderMenu = memo(({ isFull, isStickyHeader, visibleFilter, openModalAuthen, openModalInfo, toggleFilter, toggleCart }: Props) => {
const router = useRouter() const router = useRouter()
@ -35,7 +37,11 @@ const HeaderMenu = memo(({ visibleFilter,openModalAuthen, openModalInfo, toggleF
}, },
{ {
link: '/account-not-login', link: '/account-not-login',
name: 'Account Not Login', name: 'Account Not Login (Demo)',
},
{
link: '/demo',
name: 'Notifications Empty (Demo)',
}, },
{ {
link: ROUTE.NOTIFICATION, link: ROUTE.NOTIFICATION,
@ -52,7 +58,11 @@ const HeaderMenu = memo(({ visibleFilter,openModalAuthen, openModalInfo, toggleF
], [openModalAuthen]) ], [openModalAuthen])
return ( return (
<section className={s.headerMenu}> <section className={classNames({
[s.headerMenu]: true,
[s.small]: isStickyHeader,
[s.full]: isFull,
})}>
<div className={s.left}> <div className={s.left}>
<div className={s.top}> <div className={s.top}>
<Logo /> <Logo />
@ -60,8 +70,8 @@ const HeaderMenu = memo(({ visibleFilter,openModalAuthen, openModalInfo, toggleF
{ {
FILTER_PAGE.includes(router.pathname) && ( FILTER_PAGE.includes(router.pathname) && (
<button className={s.iconFilter} onClick={toggleFilter}> <button className={s.iconFilter} onClick={toggleFilter}>
<IconFilter/> <IconFilter />
<div className={classNames({[s.dot]:true,[s.isShow]:visibleFilter})}></div> <div className={classNames({ [s.dot]: true, [s.isShow]: visibleFilter })}></div>
</button> </button>
) )
} }
@ -71,8 +81,13 @@ const HeaderMenu = memo(({ visibleFilter,openModalAuthen, openModalInfo, toggleF
</div> </div>
</div> </div>
<div className={s.inputSearch}> <div className={s.searchWrap}>
<InputSearch /> <div className={s.inputSearch}>
<InputSearch />
</div>
<div className={s.buttonSearch}>
<ButtonCommon>Search</ButtonCommon>
</div>
</div> </div>
</div> </div>
<ul className={s.menu}> <ul className={s.menu}>

View File

@ -4,6 +4,9 @@
min-height: 100vh; min-height: 100vh;
> main { > main {
flex: 1; flex: 1;
width: 100%;
max-width: min( 100%, 1536px);
margin: auto;
} }
} }
.filter{ .filter{

View File

@ -31,15 +31,12 @@
width: min-content; width: min-content;
color: var(--white); color: var(--white);
font-size: 7rem; font-size: 8.8rem;
line-height: 8rem; line-height: 8rem;
letter-spacing: -0.03em; letter-spacing: -0.03em;
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
@screen 2xl {
line-height: 8rem;
}
&::after { &::after {
@apply absolute; @apply absolute;
content: ""; content: "";

View File

@ -1,4 +1,5 @@
@import url("https://fonts.googleapis.com/css2?family=Nunito&family=Poppins:wght@500&family=Righteous&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Nunito&family=Poppins:wght@500&family=Righteous&display=swap");
@import '../../public/fonts/style.css';
:root { :root {
--primary: #5b9a74; --primary: #5b9a74;
@ -41,7 +42,7 @@
--line-height: 2.4rem; --line-height: 2.4rem;
--font-sans: "Nunito", -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-heading: "Norquay-bold", "Righteous", -apple-system, system-ui, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", sans-serif;
--font-logo: "Poppins", -apple-system, system-ui, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", sans-serif; --font-logo: "Poppins", -apple-system, system-ui, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", sans-serif;
} }

View File

@ -122,7 +122,7 @@ module.exports = {
'xl': '1280px', 'xl': '1280px',
// => @media (min-width: 1280px) { ... } // => @media (min-width: 1280px) { ... }
'2xl': '1536px', '2xl': '1440px',
// => @media (min-width: 1536px) { ... } // => @media (min-width: 1536px) { ... }
}, },
caroucel: { caroucel: {