mirror of
https://github.com/vercel/commerce.git
synced 2025-07-07 05:11:22 +00:00
🔀 merge:Merge branch 'common' of github.com:KieIO/grocery-vercel-commerce into m2-datnguyen
:%s
This commit is contained in:
commit
7cede5cc8c
@ -42,6 +42,7 @@
|
|||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-fast-marquee": "^1.1.4",
|
"react-fast-marquee": "^1.1.4",
|
||||||
"react-merge-refs": "^1.1.0",
|
"react-merge-refs": "^1.1.0",
|
||||||
|
"react-player": "^2.9.0",
|
||||||
"react-use-measure": "^2.0.4",
|
"react-use-measure": "^2.0.4",
|
||||||
"sass": "^1.38.0",
|
"sass": "^1.38.0",
|
||||||
"swell-js": "^4.0.0-next.0",
|
"swell-js": "^4.0.0-next.0",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
import { FeaturedProductCard, Layout, ProductCaroucel, RecipeCard } from 'src/components/common'
|
import { FeaturedProductCard, Layout, ProductCaroucel, RecipeCard } from 'src/components/common'
|
||||||
import image5 from "../public/assets/images/image5.png"
|
import image5 from "../public/assets/images/image5.png"
|
||||||
import image6 from "../public/assets/images/image6.png"
|
import image6 from "../public/assets/images/image6.png"
|
||||||
@ -112,12 +113,23 @@ const recipe:RecipeCardProps[] = [{
|
|||||||
description:"The broth for Bun Bo Hue is prepared by slowly simmering various types of beef and pork bones (ox tail, beef shank, pork neck bones, pork feet,...",
|
description:"The broth for Bun Bo Hue is prepared by slowly simmering various types of beef and pork bones (ox tail, beef shank, pork neck bones, pork feet,...",
|
||||||
imageSrc: image14.src
|
imageSrc: image14.src
|
||||||
}]
|
}]
|
||||||
|
=======
|
||||||
|
import { Layout } from 'src/components/common';
|
||||||
|
import { HomeBanner, HomeCTA, HomeSubscribe, HomeVideo } from 'src/components/modules/home';
|
||||||
|
>>>>>>> 499221a7b8217276dbba438808a6ad3ece216a4d
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<<<<<<< HEAD
|
||||||
<CollectionCarcoucel data={dataTest} itemKey="product-1" title="VEGGIE" subTitle= "Last call! Shop deep deals on 100+ bulk picks while you can." />
|
<CollectionCarcoucel data={dataTest} itemKey="product-1" title="VEGGIE" subTitle= "Last call! Shop deep deals on 100+ bulk picks while you can." />
|
||||||
<HomeRecipe data={recipe} itemKey="product-2" title="Special Recipes"/>
|
<HomeRecipe data={recipe} itemKey="product-2" title="Special Recipes"/>
|
||||||
|
=======
|
||||||
|
<HomeBanner />
|
||||||
|
<HomeVideo />
|
||||||
|
<HomeCTA />
|
||||||
|
<HomeSubscribe />
|
||||||
|
>>>>>>> 499221a7b8217276dbba438808a6ad3ece216a4d
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
border: 1px solid var(--primary);
|
border: 1px solid var(--primary);
|
||||||
}
|
}
|
||||||
&.large {
|
&.large {
|
||||||
|
margin-bottom: 2.8rem;
|
||||||
.inner {
|
.inner {
|
||||||
@screen xl {
|
@screen xl {
|
||||||
@apply bg-right-bottom;
|
@apply bg-right-bottom;
|
||||||
|
@ -5,9 +5,13 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
<<<<<<< HEAD
|
||||||
// padding: 1.6rem 3.2rem;
|
// padding: 1.6rem 3.2rem;
|
||||||
padding: 0.8rem 1.6rem;
|
padding: 0.8rem 1.6rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
=======
|
||||||
|
padding: 1.2rem 3.2rem;
|
||||||
|
>>>>>>> 499221a7b8217276dbba438808a6ad3ece216a4d
|
||||||
&:disabled {
|
&:disabled {
|
||||||
filter: brightness(0.9);
|
filter: brightness(0.9);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
@ -51,10 +55,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.lightBorderNone {
|
||||||
|
@apply bg-white text-primary;
|
||||||
|
&.loading {
|
||||||
|
&::before {
|
||||||
|
border-top-color: var(--primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.ghost {
|
&.ghost {
|
||||||
|
<<<<<<< HEAD
|
||||||
@apply bg-white;
|
@apply bg-white;
|
||||||
color: var(--text-active);
|
color: var(--text-active);
|
||||||
border: 1px solid var(--text-active);
|
border: 1px solid var(--text-active);
|
||||||
|
=======
|
||||||
|
@apply bg-white text-primary;
|
||||||
|
border: 1px solid var(--primary);
|
||||||
|
>>>>>>> 499221a7b8217276dbba438808a6ad3ece216a4d
|
||||||
&.loading {
|
&.loading {
|
||||||
&::before {
|
&::before {
|
||||||
border-top-color: var(--text-active);
|
border-top-color: var(--text-active);
|
||||||
@ -70,7 +88,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.large {
|
&.large {
|
||||||
padding: 3.2rem 4.8rem;
|
padding: 1.6rem 4.8rem;
|
||||||
&.onlyIcon {
|
&.onlyIcon {
|
||||||
padding: 1.6rem;
|
padding: 1.6rem;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import s from './ButtonCommon.module.scss'
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children?: React.ReactNode,
|
children?: React.ReactNode,
|
||||||
type?: 'primary' | 'light' | 'ghost',
|
type?: 'primary' | 'light' | 'ghost' | 'lightBorderNone',
|
||||||
size?: 'default' | 'large',
|
size?: 'default' | 'large',
|
||||||
icon?: React.ReactNode,
|
icon?: React.ReactNode,
|
||||||
isIconSuffix?: boolean,
|
isIconSuffix?: boolean,
|
||||||
|
@ -40,5 +40,12 @@
|
|||||||
border: 1px solid var(--primary);
|
border: 1px solid var(--primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.bgTransparent {
|
||||||
|
background: rgb(227, 242, 233, 0.3);
|
||||||
|
color: var(--white);
|
||||||
|
&::placeholder {
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import classNames from 'classnames';
|
||||||
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||||
import { KEY } from 'src/utils/constanst.utils';
|
import { KEY } from 'src/utils/constanst.utils';
|
||||||
import s from './InputCommon.module.scss';
|
import s from './InputCommon.module.scss';
|
||||||
@ -9,14 +10,15 @@ interface Props {
|
|||||||
children?: React.ReactNode,
|
children?: React.ReactNode,
|
||||||
value?: string | number,
|
value?: string | number,
|
||||||
placeholder?: string,
|
placeholder?: string,
|
||||||
type?: 'text' | 'number',
|
type?: 'text' | 'number' | 'email',
|
||||||
styleType?: 'default' | 'custom',
|
styleType?: 'default' | 'custom',
|
||||||
|
backgroundTransparent?: boolean,
|
||||||
icon?: React.ReactNode,
|
icon?: React.ReactNode,
|
||||||
onChange?: (value: string | number) => void,
|
onChange?: (value: string | number) => void,
|
||||||
onEnter?: (value: string | number) => void,
|
onEnter?: (value: string | number) => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputCommon = forwardRef<Ref, Props>(({ value, placeholder, type, styleType = 'default', icon,
|
const InputCommon = forwardRef<Ref, Props>(({ value, placeholder, type, styleType = 'default', icon, backgroundTransparent = false,
|
||||||
onChange, onEnter }: Props, ref) => {
|
onChange, onEnter }: Props, ref) => {
|
||||||
const inputElementRef = useRef<HTMLInputElement>(null);
|
const inputElementRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
@ -24,6 +26,10 @@ const InputCommon = forwardRef<Ref, Props>(({ value, placeholder, type, styleTyp
|
|||||||
focus: () => {
|
focus: () => {
|
||||||
inputElementRef.current?.focus();
|
inputElementRef.current?.focus();
|
||||||
},
|
},
|
||||||
|
getValue: () => {
|
||||||
|
const value = inputElementRef.current?.value || ''
|
||||||
|
return value
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
@ -32,6 +38,7 @@ const InputCommon = forwardRef<Ref, Props>(({ value, placeholder, type, styleTyp
|
|||||||
|
|
||||||
const handleKeyDown = (e: any) => {
|
const handleKeyDown = (e: any) => {
|
||||||
if (e.key === KEY.ENTER && onEnter) {
|
if (e.key === KEY.ENTER && onEnter) {
|
||||||
|
console.log("on enter***")
|
||||||
const value = inputElementRef.current?.value || ''
|
const value = inputElementRef.current?.value || ''
|
||||||
onEnter(value)
|
onEnter(value)
|
||||||
}
|
}
|
||||||
@ -49,7 +56,11 @@ const InputCommon = forwardRef<Ref, Props>(({ value, placeholder, type, styleTyp
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
className={`${s.inputCommon} ${s[styleType]}`}
|
className={classNames({
|
||||||
|
[s.inputCommon]: true,
|
||||||
|
[s[styleType]]: true,
|
||||||
|
[s.bgTransparent]: backgroundTransparent
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
@import '../../../styles/utilities';
|
|
||||||
|
|
||||||
.heartToggle{
|
.heartToggle{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 2.4rem;
|
width: 2.4rem;
|
||||||
height: 2.4rem;
|
height: 2.4rem;
|
||||||
path{
|
|
||||||
stroke: theme("colors.primary");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.isToggleOn{
|
.isToggleOn{
|
||||||
svg path{
|
svg path{
|
||||||
stroke: theme("colors.primary");
|
stroke: var(--negative);
|
||||||
|
fill: var(--negative);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,20 +5,17 @@ import s from './ItemWishList.module.scss'
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isActive?: boolean,
|
isActive?: boolean,
|
||||||
onClick?: () => void
|
|
||||||
onChange?: () => void
|
onChange?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ItemWishList = memo(({isActive, onClick, onChange}:Props) => {
|
const ItemWishList = memo(({isActive=false, onChange}:Props) => {
|
||||||
const handleClick = () => {
|
|
||||||
isActive = !isActive
|
|
||||||
}
|
|
||||||
return(
|
return(
|
||||||
<div className={classNames({
|
<div className={classNames({
|
||||||
[s.heartToggle]:true,
|
[s.heartToggle]: true,
|
||||||
[s.isToggleOn]:isActive
|
[s.isToggleOn]: isActive
|
||||||
})}
|
})}
|
||||||
onClick={handleClick}>
|
onChange={onChange}
|
||||||
|
>
|
||||||
<IconHeart />
|
<IconHeart />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
.eclipse{
|
.eclipse{
|
||||||
width: 3.2rem;
|
width: 3.2rem;
|
||||||
height: 3.2rem;
|
height: 3.2rem;
|
||||||
background-color: theme("colors.primary");
|
background-color: var(--primary);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-right: 1.2rem;
|
margin-right: 1.2rem;
|
||||||
}
|
}
|
||||||
.conTent{
|
.content{
|
||||||
@apply font-logo;
|
@apply font-logo;
|
||||||
text-transform: uppercase;
|
font-size: 16px;
|
||||||
line-height: 3.2rem;
|
line-height: 32px;
|
||||||
letter-spacing: -0.02rem;
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,15 +1,11 @@
|
|||||||
import s from './Logo.module.scss'
|
import s from './Logo.module.scss'
|
||||||
|
|
||||||
interface Props {
|
const Logo = () => {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const Logo = ({}: Props) => {
|
|
||||||
return(
|
return(
|
||||||
<div className={s.logo}>
|
<div className={s.logo}>
|
||||||
<div className={s.eclipse}>
|
<div className={s.eclipse}>
|
||||||
</div>
|
</div>
|
||||||
<div className={s.conTent}>
|
<div className={s.content}>
|
||||||
ONLINE GROCERY
|
ONLINE GROCERY
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
32
src/components/common/SelectCommon/SelectCommon.module.scss
Normal file
32
src/components/common/SelectCommon/SelectCommon.module.scss
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
@import "../../../styles/utilities";
|
||||||
|
|
||||||
|
.select{
|
||||||
|
@apply rounded-lg border-solid;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1.2rem 1.6rem;
|
||||||
|
&.base{
|
||||||
|
width: 18.6rem;
|
||||||
|
height: 4.8rem;
|
||||||
|
}
|
||||||
|
&.large{
|
||||||
|
width: 34.25rem;
|
||||||
|
height: 5.6rem;
|
||||||
|
}
|
||||||
|
&.default{
|
||||||
|
@apply border;
|
||||||
|
}
|
||||||
|
&.custom{
|
||||||
|
@apply border-2;
|
||||||
|
border-color: var(--border-line);
|
||||||
|
color: var(--text-label);
|
||||||
|
}
|
||||||
|
.option{
|
||||||
|
&:hover{
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
src/components/common/SelectCommon/SelectCommon.tsx
Normal file
27
src/components/common/SelectCommon/SelectCommon.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import s from './SelectCommon.module.scss'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
placeHolder? : string,
|
||||||
|
size?: 'base' | 'large',
|
||||||
|
type?: 'default' | 'custom',
|
||||||
|
option: {name: string}[],
|
||||||
|
}
|
||||||
|
|
||||||
|
const SelectCommon = ({ type = 'default', size = 'base', option, placeHolder }: Props) => {
|
||||||
|
return(
|
||||||
|
<select className={classNames({
|
||||||
|
[s.select] : true,
|
||||||
|
[s[type]]: !!type,
|
||||||
|
[s[size]]: !!size,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<option disabled selected hidden>{placeHolder}</option>
|
||||||
|
{
|
||||||
|
option.map(item => <option className={s.option} value={item.name}> {item.name} </option>)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectCommon
|
19
src/components/common/VideoPlayer/VideoPlayer.tsx
Normal file
19
src/components/common/VideoPlayer/VideoPlayer.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactPlayer from 'react-player/lazy'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
url: string,
|
||||||
|
controls?: boolean,
|
||||||
|
muted?: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
const VideoPlayer = ({ url, controls, muted }: Props) => {
|
||||||
|
return (
|
||||||
|
<ReactPlayer
|
||||||
|
url={url}
|
||||||
|
controls={controls}
|
||||||
|
muted={muted} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VideoPlayer;
|
@ -1,19 +1,16 @@
|
|||||||
@import '../../../styles/utilities';
|
@import "../../../styles/utilities";
|
||||||
|
|
||||||
.viewAll{
|
.viewAll {
|
||||||
display: flex;
|
display: flex;
|
||||||
color: theme("colors.primary");
|
.content {
|
||||||
.conTent{
|
color: var(--primary);
|
||||||
margin: 0.8rem 0.8rem 0.8rem 1.6rem;
|
margin: 0.8rem 0.8rem 0.8rem 1.6rem;
|
||||||
font-family: var(--font-sans);
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.vecTor{
|
.vector {
|
||||||
margin: 0.8rem 0rem 0.8rem 0rem;
|
margin: 0.8rem 0rem 0.8rem 0rem;
|
||||||
svg path{
|
svg path {
|
||||||
fill: theme("colors.primary");
|
fill: var(--primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,18 +3,18 @@ import s from './ViewAllItem.module.scss'
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
link?: string
|
link: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ViewAllItem = ({ link }: Props) => {
|
const ViewAllItem = ({ link }: Props) => {
|
||||||
return(
|
return(
|
||||||
<div className={s.viewAll}>
|
<div className={s.viewAll}>
|
||||||
<Link href={"/all"}>
|
<Link href={link}>
|
||||||
<a className={s.conTent}>
|
<a className={s.content}>
|
||||||
View All
|
View All
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
<div className={s.vecTor}>
|
<div className={s.vector}>
|
||||||
<IconVector />
|
<IconVector />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,3 +22,5 @@ export { default as Banner} from './Banner/Banner'
|
|||||||
export { default as Footer} from './Footer/Footer'
|
export { default as Footer} from './Footer/Footer'
|
||||||
export { default as MenuDropdown} from './MenuDropdown/MenuDropdown'
|
export { default as MenuDropdown} from './MenuDropdown/MenuDropdown'
|
||||||
export { default as NotiMessage} from './NotiMessage/NotiMessage'
|
export { default as NotiMessage} from './NotiMessage/NotiMessage'
|
||||||
|
export { default as VideoPlayer} from './VideoPlayer/VideoPlayer'
|
||||||
|
export { default as SelectCommon} from './SelectCommon/SelectCommon'
|
||||||
|
@ -8,3 +8,4 @@ export { default as IconInfo } from './IconInfo'
|
|||||||
export { default as IconHome } from './IconHome'
|
export { default as IconHome } from './IconHome'
|
||||||
export { default as IconShopping } from './IconShopping'
|
export { default as IconShopping } from './IconShopping'
|
||||||
export { default as IconHeart } from './IconHeart'
|
export { default as IconHeart } from './IconHeart'
|
||||||
|
export { default as IconVector } from './IconVector'
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
.homeBanner {
|
.homeBanner {
|
||||||
@apply spacing-horizontal;
|
@apply spacing-horizontal;
|
||||||
|
margin-bottom: 2.8rem;
|
||||||
.left {
|
.left {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
}
|
}
|
||||||
|
29
src/components/modules/home/HomeCTA/HomeCTA.module.scss
Normal file
29
src/components/modules/home/HomeCTA/HomeCTA.module.scss
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@import "../../../../styles/utilities";
|
||||||
|
|
||||||
|
.homeCTA {
|
||||||
|
@apply spacing-horizontal;
|
||||||
|
margin-top: 1.6rem;
|
||||||
|
margin-bottom: 1.6rem;
|
||||||
|
.inner {
|
||||||
|
@apply flex justify-between items-center bg-primary-light;
|
||||||
|
background-image: url('./assets/bg_home_cta.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center top;
|
||||||
|
border-radius: 2.4rem;
|
||||||
|
padding: 2rem;
|
||||||
|
@screen md {
|
||||||
|
padding-left: 9rem;
|
||||||
|
padding-right: 4.8rem;
|
||||||
|
min-height: 18rem;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
.heading {
|
||||||
|
@apply heading-1 font-heading text-primary;
|
||||||
|
}
|
||||||
|
.sub {
|
||||||
|
@apply font-bold sm-headline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/components/modules/home/HomeCTA/HomeCTA.tsx
Normal file
27
src/components/modules/home/HomeCTA/HomeCTA.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import Link from 'next/link'
|
||||||
|
import React from 'react'
|
||||||
|
import { ButtonCommon } from 'src/components/common'
|
||||||
|
import { ROUTE } from 'src/utils/constanst.utils'
|
||||||
|
import { LANGUAGE } from 'src/utils/language.utils'
|
||||||
|
import s from './HomeCTA.module.scss'
|
||||||
|
|
||||||
|
|
||||||
|
const HomeCTA = () => {
|
||||||
|
return (
|
||||||
|
<section className={s.homeCTA}>
|
||||||
|
<div className={s.inner}>
|
||||||
|
<div className={s.text}>
|
||||||
|
<h1 className={s.heading}>SALE 70%</h1>
|
||||||
|
<div className={s.sub}>for Vegetarian Day</div>
|
||||||
|
</div>
|
||||||
|
<Link href={ROUTE.PRODUCTS}>
|
||||||
|
<a>
|
||||||
|
<ButtonCommon type='ghost' size='large'>{LANGUAGE.BUTTON_LABEL.SHOP_NOW}</ButtonCommon>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HomeCTA
|
BIN
src/components/modules/home/HomeCTA/assets/bg_home_cta.png
Normal file
BIN
src/components/modules/home/HomeCTA/assets/bg_home_cta.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
@ -0,0 +1,14 @@
|
|||||||
|
.formSubscribe {
|
||||||
|
@apply flex flex-col justify-center items-center;
|
||||||
|
margin-top: 3.2rem;
|
||||||
|
button {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
@screen md {
|
||||||
|
@apply flex-row;
|
||||||
|
button {
|
||||||
|
margin-left: 2.4rem;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
import React, { useRef } from 'react'
|
||||||
|
import { ButtonCommon, Inputcommon } from 'src/components/common'
|
||||||
|
import { CustomInputCommon } from 'src/utils/type.utils';
|
||||||
|
import s from './FormSubscribe.module.scss'
|
||||||
|
|
||||||
|
|
||||||
|
const FormSubscribe = () => {
|
||||||
|
const inputElementRef = useRef<CustomInputCommon>(null);
|
||||||
|
|
||||||
|
const handleSubmit = (e?: any) => {
|
||||||
|
// todo
|
||||||
|
let value: string
|
||||||
|
if (typeof (e) === 'string') {
|
||||||
|
value = e
|
||||||
|
} else {
|
||||||
|
e.preventDefault && e.preventDefault()
|
||||||
|
value = inputElementRef.current?.getValue()?.toString() || ''
|
||||||
|
}
|
||||||
|
console.log("email here: ", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={s.formSubscribe}>
|
||||||
|
<Inputcommon
|
||||||
|
type='email'
|
||||||
|
styleType='custom'
|
||||||
|
placeholder="Enter your email"
|
||||||
|
ref={inputElementRef}
|
||||||
|
onEnter={handleSubmit}
|
||||||
|
backgroundTransparent={true}
|
||||||
|
/>
|
||||||
|
<ButtonCommon onClick={handleSubmit} type='lightBorderNone'>Subsribe</ButtonCommon>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormSubscribe
|
@ -0,0 +1,18 @@
|
|||||||
|
@import "../../../../styles/utilities";
|
||||||
|
|
||||||
|
.homeSubscribe {
|
||||||
|
@apply flex flex-col justify-center items-center bg-primary text-center;
|
||||||
|
padding: 4rem 2rem;
|
||||||
|
@screen md {
|
||||||
|
padding-top: 5.6rem;
|
||||||
|
padding-bottom: 5.6rem;
|
||||||
|
}
|
||||||
|
.heading {
|
||||||
|
@apply heading-2 font-heading;
|
||||||
|
color: var(--white);
|
||||||
|
margin-bottom: 2.4rem;
|
||||||
|
}
|
||||||
|
.sub {
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
}
|
15
src/components/modules/home/HomeSubscribe/HomeSubscribe.tsx
Normal file
15
src/components/modules/home/HomeSubscribe/HomeSubscribe.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import FormSubscribe from './FormSubscribe/FormSubscribe'
|
||||||
|
import s from './HomeSubscribe.module.scss'
|
||||||
|
|
||||||
|
const HomeSubscribe = () => {
|
||||||
|
return (
|
||||||
|
<section className={s.homeSubscribe}>
|
||||||
|
<h2 className={s.heading}>Let's stay in touch</h2>
|
||||||
|
<div className={s.sub}>Subscribe to our newsletter for fresh news, seasonal arrivals and delicious recipes.</div>
|
||||||
|
<FormSubscribe />
|
||||||
|
</section >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HomeSubscribe
|
68
src/components/modules/home/HomeVideo/HomeVideo.module.scss
Normal file
68
src/components/modules/home/HomeVideo/HomeVideo.module.scss
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
@import "../../../../styles/utilities";
|
||||||
|
|
||||||
|
.homeVideo {
|
||||||
|
margin: 2rem auto 3rem;
|
||||||
|
.top,
|
||||||
|
.videoWrap > div {
|
||||||
|
@apply spacing-horizontal;
|
||||||
|
}
|
||||||
|
@screen md {
|
||||||
|
margin: 6.4rem auto 5.6rem;
|
||||||
|
.top,
|
||||||
|
.videoWrap > div {
|
||||||
|
max-width: 60rem;
|
||||||
|
margin: auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@screen lg {
|
||||||
|
.top,
|
||||||
|
.videoWrap > div {
|
||||||
|
max-width: 80rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.top {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
@screen md {
|
||||||
|
@apply flex items-center;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
.logo {
|
||||||
|
margin-right: 2.4rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
max-width: 10rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.heading {
|
||||||
|
@apply heading-2 font-heading;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.videoWrap {
|
||||||
|
@apply relative flex justify-center;
|
||||||
|
> div {
|
||||||
|
@apply relative;
|
||||||
|
width: 100% !important;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
&::before {
|
||||||
|
@apply absolute bg-primary;
|
||||||
|
content: "";
|
||||||
|
width: 100%;
|
||||||
|
height: 18rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 0;
|
||||||
|
@screen md {
|
||||||
|
background-image: url("./assets/bg_left.svg"), url("./assets/bg_right.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 5% 0, 95% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
src/components/modules/home/HomeVideo/HomeVideo.tsx
Normal file
31
src/components/modules/home/HomeVideo/HomeVideo.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import Image from 'next/image'
|
||||||
|
import React from 'react'
|
||||||
|
import s from './HomeVideo.module.scss'
|
||||||
|
import LogoBrand from './assets/logo_maggi.png'
|
||||||
|
import { VideoPlayer } from 'src/components/common'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string
|
||||||
|
children?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const HomeVideo = ({ }: Props) => {
|
||||||
|
return (
|
||||||
|
<section className={s.homeVideo}>
|
||||||
|
<div className={s.top}>
|
||||||
|
<div className={s.logo}>
|
||||||
|
<Image src={LogoBrand} />
|
||||||
|
</div>
|
||||||
|
<h2 className={s.heading}>
|
||||||
|
Maggi Sauce Is The Secret Weapon For Making All Your Food
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className={s.videoWrap}>
|
||||||
|
{/* todo: change url video */}
|
||||||
|
<VideoPlayer url='https://www.youtube.com/watch?v=nXH23nYYM3s' controls={true} />
|
||||||
|
</div>
|
||||||
|
</section >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HomeVideo
|
19
src/components/modules/home/HomeVideo/assets/bg_left.svg
Normal file
19
src/components/modules/home/HomeVideo/assets/bg_left.svg
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<svg width="240" height="268" viewBox="0 0 240 268" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g opacity="0.6">
|
||||||
|
<rect x="170.045" y="167.357" width="32.2656" height="16.5938" rx="4" transform="rotate(-16 170.045 167.357)" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<path d="M170.168 201.23C167.732 192.736 172.644 183.875 181.138 181.439L199.117 176.284C207.611 173.848 216.471 178.76 218.907 187.254L234.907 243.052C236.125 247.299 233.669 251.73 229.422 252.948L196.063 262.513C191.816 263.731 187.386 261.275 186.168 257.028L170.168 201.23Z" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="177.519" y="170.009" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(-16 177.519 170.009)" fill="#CDF4DD"/>
|
||||||
|
<rect x="185.494" y="167.723" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(-16 185.494 167.723)" fill="#CDF4DD"/>
|
||||||
|
<rect x="193.47" y="165.436" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(-16 193.47 165.436)" fill="#CDF4DD"/>
|
||||||
|
</g>
|
||||||
|
<g opacity="0.6">
|
||||||
|
<path d="M36.5973 106.436L39.9701 94.6735L64.4373 101.689L60.9881 113.718C59.4878 118.951 60.973 124.584 64.8578 128.397C69.0553 132.516 70.4233 138.726 68.3451 144.228L55.6959 177.716C54.5922 180.638 51.4315 182.224 48.4292 181.363L11.314 170.721C8.31623 169.861 6.47675 166.848 7.08188 163.789L13.7174 130.242C14.9118 124.203 19.3948 119.345 25.3188 117.671C30.7696 116.131 35.036 111.881 36.5973 106.436Z" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="42.3359" y="74.5464" width="32" height="19" rx="6" transform="rotate(16 42.3359 74.5464)" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="70.6162" y="92.0181" width="4" height="32" rx="2" transform="rotate(106 70.6162 92.0181)" fill="#CDF4DD"/>
|
||||||
|
</g>
|
||||||
|
<g opacity="0.6">
|
||||||
|
<path d="M186.052 83.4148L179.934 94.0117L157.891 81.2851L164.148 70.448C166.869 65.7341 166.791 59.9085 163.944 55.2694C160.868 50.2567 161.043 43.9002 164.39 39.0645L184.765 9.63163C186.543 7.06354 189.994 6.28885 192.699 7.85054L226.137 27.156C228.837 28.7153 229.893 32.0836 228.566 34.9057L214.012 65.8511C211.392 71.4217 205.867 75.0504 199.714 75.2416C194.052 75.4176 188.885 78.5093 186.052 83.4148Z" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="172.769" y="112.969" width="32" height="19" rx="6" transform="rotate(-150 172.769 112.969)" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="149.557" y="89.1743" width="4" height="32" rx="2" transform="rotate(-60 149.557 89.1743)" fill="#CDF4DD"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
21
src/components/modules/home/HomeVideo/assets/bg_right.svg
Normal file
21
src/components/modules/home/HomeVideo/assets/bg_right.svg
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<svg width="237" height="252" viewBox="0 0 237 252" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g opacity="0.6">
|
||||||
|
<rect x="196.607" y="142.667" width="32.2656" height="16.5938" rx="4" transform="rotate(16.8391 196.607 142.667)" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<path d="M178.342 171.193C180.901 162.736 189.833 157.955 198.291 160.514L216.192 165.932C224.649 168.492 229.431 177.424 226.871 185.881L210.055 241.439C208.776 245.668 204.31 248.059 200.081 246.779L166.866 236.726C162.637 235.446 160.246 230.98 161.526 226.751L178.342 171.193Z" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="201.447" y="148.949" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(16.8391 201.447 148.949)" fill="#CDF4DD"/>
|
||||||
|
<rect x="209.389" y="151.352" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(16.8391 209.389 151.352)" fill="#CDF4DD"/>
|
||||||
|
<rect x="217.33" y="153.756" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(16.8391 217.33 153.756)" fill="#CDF4DD"/>
|
||||||
|
</g>
|
||||||
|
<g opacity="0.6">
|
||||||
|
<rect x="150.723" y="109.167" width="32.2656" height="16.5938" rx="4" transform="rotate(-150 150.723 109.167)" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<path d="M175.004 85.5494C170.586 93.202 160.8 95.824 153.147 91.4058L136.95 82.0542C129.297 77.6359 126.675 67.8505 131.094 60.1978L160.117 9.92772C162.326 6.10138 167.219 4.79038 171.045 6.99952L201.099 24.3511C204.925 26.5602 206.236 31.4529 204.027 35.2793L175.004 85.5494Z" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="147.439" y="101.949" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(-150 147.439 101.949)" fill="#CDF4DD"/>
|
||||||
|
<rect x="140.254" y="97.8003" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(-150 140.254 97.8003)" fill="#CDF4DD"/>
|
||||||
|
<rect x="133.068" y="93.6519" width="3.6875" height="11.9844" rx="1.84375" transform="rotate(-150 133.068 93.6519)" fill="#CDF4DD"/>
|
||||||
|
</g>
|
||||||
|
<g opacity="0.6">
|
||||||
|
<path d="M32.8015 122.764L35.7266 112.563L56.9458 118.648L53.9545 129.08C52.6533 133.618 53.9413 138.504 57.3104 141.81C60.9508 145.383 62.1371 150.768 60.3348 155.54L49.6241 183.896C48.5204 186.818 45.3597 188.404 42.3573 187.543L11.5784 178.717C8.5806 177.858 6.74113 174.845 7.34625 171.786L12.9588 143.41C13.9947 138.173 17.8826 133.96 23.0201 132.508C27.7474 131.172 31.4475 127.486 32.8015 122.764Z" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="37.7793" y="95.1074" width="27.7521" height="16.4778" rx="6" transform="rotate(16 37.7793 95.1074)" stroke="#CDF4DD" stroke-width="4"/>
|
||||||
|
<rect x="62.3047" y="110.26" width="3.46901" height="27.7521" rx="1.7345" transform="rotate(106 62.3047 110.26)" fill="#CDF4DD"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/components/modules/home/HomeVideo/assets/logo_maggi.png
Normal file
BIN
src/components/modules/home/HomeVideo/assets/logo_maggi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -1,2 +1,8 @@
|
|||||||
export { default as HomeBanner } from './HomeBanner/HomeBanner'
|
export { default as HomeBanner } from './HomeBanner/HomeBanner'
|
||||||
|
<<<<<<< HEAD
|
||||||
export { default as CollectionCarcoucel } from './CollectionCarcoucel/CollectionCarcoucel'
|
export { default as CollectionCarcoucel } from './CollectionCarcoucel/CollectionCarcoucel'
|
||||||
|
=======
|
||||||
|
export { default as HomeCTA } from './HomeCTA/HomeCTA'
|
||||||
|
export { default as HomeSubscribe } from './HomeSubscribe/HomeSubscribe'
|
||||||
|
export { default as HomeVideo } from './HomeVideo/HomeVideo'
|
||||||
|
>>>>>>> 499221a7b8217276dbba438808a6ad3ece216a4d
|
||||||
|
@ -84,6 +84,10 @@
|
|||||||
.spacing-horizontal {
|
.spacing-horizontal {
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
|
@screen md {
|
||||||
|
padding-left: 6.4rem;
|
||||||
|
padding-right: 6.4rem;
|
||||||
|
}
|
||||||
@screen md {
|
@screen md {
|
||||||
padding-left: 11.2rem;
|
padding-left: 11.2rem;
|
||||||
padding-right: 11.2rem;
|
padding-right: 11.2rem;
|
||||||
@ -92,6 +96,10 @@
|
|||||||
.spacing-horizontal-left {
|
.spacing-horizontal-left {
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
@screen md {
|
@screen md {
|
||||||
|
padding-left: 6.4rem;
|
||||||
|
padding-right: 6.4rem;
|
||||||
|
}
|
||||||
|
@screen lg {
|
||||||
padding-left: 11.2rem;
|
padding-left: 11.2rem;
|
||||||
padding-right: 11.2rem;
|
padding-right: 11.2rem;
|
||||||
}
|
}
|
||||||
|
3
src/utils/type.utils.ts
Normal file
3
src/utils/type.utils.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface CustomInputCommon extends HTMLInputElement {
|
||||||
|
getValue: () => string | number
|
||||||
|
}
|
@ -45,6 +45,7 @@ module.exports = {
|
|||||||
'negative-border-line': 'var(--negative-border-line)',
|
'negative-border-line': 'var(--negative-border-line)',
|
||||||
'negative-light': 'var(--negative-light)',
|
'negative-light': 'var(--negative-light)',
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
'line': 'var(--border-line)',
|
'line': 'var(--border-line)',
|
||||||
'background': 'var(--background)',
|
'background': 'var(--background)',
|
||||||
'white': 'var(--white)',
|
'white': 'var(--white)',
|
||||||
@ -53,12 +54,15 @@ module.exports = {
|
|||||||
|
|
||||||
|
|
||||||
'disabled': 'var(--text-disabled)',
|
'disabled': 'var(--text-disabled)',
|
||||||
|
=======
|
||||||
|
>>>>>>> 499221a7b8217276dbba438808a6ad3ece216a4d
|
||||||
line: 'var(--border-line)',
|
line: 'var(--border-line)',
|
||||||
background: 'var(--background)',
|
background: 'var(--background)',
|
||||||
white: 'var(--white)',
|
white: 'var(--white)',
|
||||||
'background-arrow':'var(--background-arrow)',
|
|
||||||
gray: 'var(--gray)',
|
gray: 'var(--gray)',
|
||||||
disabled: 'var(--text-disabled)',
|
disabled: 'var(--text-disabled)',
|
||||||
|
'background-arrow':'var(--background-arrow)',
|
||||||
|
|
||||||
|
|
||||||
// @deprecated (NOT use these variables)
|
// @deprecated (NOT use these variables)
|
||||||
'primary-2': 'var(--primary-2)',
|
'primary-2': 'var(--primary-2)',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user