mirror of
https://github.com/vercel/commerce.git
synced 2025-07-29 05:01:22 +00:00
Merge branch 'm4-tan' of github.com:KieIO/grocery-vercel-commerce into m5-datnguyen
This commit is contained in:
34
src/components/common/CardBlog/CardBlog.module.scss
Normal file
34
src/components/common/CardBlog/CardBlog.module.scss
Normal file
@@ -0,0 +1,34 @@
|
||||
@import "../../../styles/utilities";
|
||||
|
||||
.cardBlogWarpper{
|
||||
max-width: 39.2rem;
|
||||
min-height: 34.4rem;
|
||||
@apply inline-flex flex-col justify-start;
|
||||
.image{
|
||||
width: 100%;
|
||||
max-height: 22rem;
|
||||
border-radius: 2.4rem;
|
||||
&:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.title{
|
||||
padding: 1.6rem 0.8rem 0.4rem 0.8rem;
|
||||
@apply font-bold;
|
||||
font-size: 2rem;
|
||||
line-height: 2.8rem;
|
||||
letter-spacing: -0.01em;
|
||||
color: var(--text-active);
|
||||
&:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.description{
|
||||
padding: 0 0.8rem;
|
||||
@apply overflow-hidden overflow-ellipsis ;
|
||||
color: var(--text-label);
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
25
src/components/common/CardBlog/CardBlog.tsx
Normal file
25
src/components/common/CardBlog/CardBlog.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import { RecipeProps } from 'src/utils/types.utils'
|
||||
import s from './CardBlog.module.scss'
|
||||
export interface BlogCardProps extends RecipeProps {
|
||||
link: string,
|
||||
}
|
||||
|
||||
const CardBlog = ({ imageSrc, title, description, link }: BlogCardProps) => {
|
||||
return (
|
||||
<div className={s.cardBlogWarpper}>
|
||||
<Link href={link}>
|
||||
<div className={s.image}>
|
||||
<img src={imageSrc} alt="image cardblog" />
|
||||
</div>
|
||||
</Link>
|
||||
<Link href={link}>
|
||||
<div className={s.title}>{title}</div>
|
||||
</Link>
|
||||
<div className={s.description}>{description}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CardBlog
|
@@ -28,7 +28,6 @@ const CarouselCommon = <T,>({
|
||||
option: { slideChanged,slidesPerView, ...sliderOption },
|
||||
}: CarouselCommonProps<T>) => {
|
||||
const [currentSlide, setCurrentSlide] = React.useState(0)
|
||||
// const [dotActive, setDotActive] = React.useState<number>(0)
|
||||
const [dotArr, setDotArr] = React.useState<number[]>([])
|
||||
const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({
|
||||
...sliderOption,
|
||||
|
@@ -0,0 +1,55 @@
|
||||
@import "../../../styles/utilities";
|
||||
|
||||
.collapseWrapper{
|
||||
@apply border-t border-b;
|
||||
border-color: var(--border-line);
|
||||
max-width: 80.4rem;
|
||||
min-height: 4rem;
|
||||
&.isActive{
|
||||
.title{
|
||||
@apply pb-0;
|
||||
}
|
||||
.contentContainer{
|
||||
@apply block;
|
||||
}
|
||||
.toggle{
|
||||
&:before {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
&:after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
svg:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.title{
|
||||
@apply outline-none flex justify-between font-heading items-center pt-16 pb-16;
|
||||
font-size: 3.2rem;
|
||||
line-height: 4rem;
|
||||
letter-spacing: -0.01em;
|
||||
.toggle{
|
||||
height: 2.2rem;
|
||||
width: 2.2rem;
|
||||
position: relative;
|
||||
&:before,
|
||||
&:after{
|
||||
@apply absolute h-2;
|
||||
content: "";
|
||||
border-radius: 0.8rem;
|
||||
background: var(--text-active);
|
||||
top: 40%;
|
||||
width: 2.2rem;
|
||||
transition: transform 500ms ease;
|
||||
}
|
||||
&:before{
|
||||
transform-origin: center;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
.contentContainer{
|
||||
@apply hidden pb-16;
|
||||
}
|
37
src/components/common/CollapseCommon/CollapseCommon.tsx
Normal file
37
src/components/common/CollapseCommon/CollapseCommon.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import s from './CollapseCommon.module.scss'
|
||||
import { useState } from 'react'
|
||||
import classNames from 'classnames'
|
||||
import CollapseContent from './CollapseContent/CollapseContent'
|
||||
|
||||
interface CollapseProps{
|
||||
title?: string,
|
||||
content: Array<string>,
|
||||
isToggle?: boolean,
|
||||
}
|
||||
const CollapseCommon = ({title, content, isToggle}: CollapseProps) => {
|
||||
const [isActive, changeActive] = useState(isToggle)
|
||||
|
||||
const handleToggle = () => {
|
||||
changeActive(!isActive)
|
||||
}
|
||||
return(
|
||||
<div className={classNames({
|
||||
[s.collapseWrapper] : true,
|
||||
[s.isActive] : isActive
|
||||
})}
|
||||
onClick = { handleToggle }
|
||||
>
|
||||
<div className={s.title}>
|
||||
<a>{title}</a>
|
||||
<div className={s.toggle}></div>
|
||||
</div>
|
||||
<div className={s.contentContainer}>
|
||||
{
|
||||
content.map(item => <CollapseContent content={item} />)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CollapseCommon
|
@@ -0,0 +1,3 @@
|
||||
.content{
|
||||
margin-top: 1.6rem;
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
import classNames from 'classnames'
|
||||
import s from './CollapseContent.module.scss'
|
||||
|
||||
interface CollapseContentProps{
|
||||
content: string
|
||||
}
|
||||
|
||||
const CollapseContent = ({content}: CollapseContentProps) => {
|
||||
return (
|
||||
<div className={s.content}>
|
||||
{content}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CollapseContent
|
@@ -17,9 +17,9 @@ const Layout: FC<Props> = ({ children }) => {
|
||||
return (
|
||||
<CommerceProvider locale={locale}>
|
||||
<div className={s.mainLayout}>
|
||||
<Header />
|
||||
{/* <Header /> */}
|
||||
<main >{children}</main>
|
||||
<Footer />
|
||||
{/* <Footer /> */}
|
||||
</div>
|
||||
</CommerceProvider>
|
||||
|
||||
|
@@ -0,0 +1,16 @@
|
||||
@import '../../../../styles/utilities';
|
||||
.blogCardWarpper {
|
||||
@apply spacing-horizontal;
|
||||
@screen xl {
|
||||
:global(.customArrow) {
|
||||
@screen lg {
|
||||
&:global(.leftArrow) {
|
||||
left: calc(-6.4rem - 2rem);
|
||||
}
|
||||
&:global(.rightArrow) {
|
||||
right: calc(-6.4rem - 2rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
import { TOptionsEvents } from 'keen-slider'
|
||||
import React from 'react'
|
||||
import CarouselCommon, {
|
||||
CarouselCommonProps,
|
||||
} from '../../CarouselCommon/CarouselCommon'
|
||||
import BlogCard, { BlogCardProps } from 'src/components/common/CardBlog/CardBlog'
|
||||
import s from "./BlogPostCarousel.module.scss"
|
||||
|
||||
interface BlogPostCarouselProps
|
||||
extends Omit<CarouselCommonProps<BlogCardProps>, 'Component'|"option"> {
|
||||
option?:TOptionsEvents
|
||||
}
|
||||
|
||||
const OPTION_DEFAULT: TOptionsEvents = {
|
||||
slidesPerView: 1.25,
|
||||
mode: 'free',
|
||||
spacing:24,
|
||||
breakpoints: {
|
||||
'(min-width: 640px)': {
|
||||
slidesPerView: 2,
|
||||
},
|
||||
'(min-width: 1024px)': {
|
||||
slidesPerView: 2.5,
|
||||
},
|
||||
'(min-width: 1440px)': {
|
||||
slidesPerView: 3,
|
||||
},
|
||||
'(min-width: 1536px)': {
|
||||
slidesPerView: 3.5,
|
||||
},
|
||||
},
|
||||
}
|
||||
const BlogPostCarousel = ({ option, data, ...props }: BlogPostCarouselProps) => {
|
||||
return (
|
||||
<div className={s.blogCardWarpper}>
|
||||
<CarouselCommon<BlogCardProps>
|
||||
data={data}
|
||||
Component={BlogCard}
|
||||
{...props}
|
||||
option={{ ...OPTION_DEFAULT, ...option }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default BlogPostCarousel
|
@@ -0,0 +1,16 @@
|
||||
@import '../../../styles/utilities';
|
||||
|
||||
.blogPostWarpper {
|
||||
padding-top: 5.6rem;
|
||||
padding-bottom: 5.2rem;
|
||||
@apply flex flex-col;
|
||||
.top {
|
||||
@apply spacing-horizontal flex w-full justify-between;
|
||||
padding-bottom: 3.2rem;
|
||||
@screen xl {
|
||||
.right {
|
||||
margin-right: 2.476rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
import image15 from '../../../../public/assets/images/image15.png'
|
||||
import image16 from '../../../../public/assets/images/image16.png'
|
||||
import image17 from '../../../../public/assets/images/image17.png'
|
||||
import React from 'react'
|
||||
import { HeadingCommon, ViewAllItem } from 'src/components/common'
|
||||
import { BlogCardProps } from 'src/components/common/CardBlog/CardBlog'
|
||||
import BlogPostCarousel from './BlogPostCarousel/BlogPostCarousel'
|
||||
import s from './RelevantBlogPosts.module.scss'
|
||||
import { ROUTE } from 'src/utils/constanst.utils';
|
||||
|
||||
interface RelevantProps {
|
||||
data?: BlogCardProps[]
|
||||
itemKey?: string
|
||||
title?: string
|
||||
viewAllLink?: string
|
||||
}
|
||||
|
||||
const recipe:BlogCardProps[] = [
|
||||
{
|
||||
title: "Want to Lose Weight? Here are 10 DEBM Diet Guidelines for Beginners",
|
||||
description:"The DEBM diet stands for "+'"Delicious Happy Fun Diet"'+". This diet was popularized by Robert...",
|
||||
imageSrc: image15.src,
|
||||
link: `${ROUTE.BLOG_DETAIL}`
|
||||
},{
|
||||
title: "9 Ways to Make an Aloe Vera Mask at Home",
|
||||
description:"Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
||||
imageSrc: image16.src,
|
||||
link: `${ROUTE.BLOG_DETAIL}`
|
||||
},{
|
||||
title: "Don't Buy Wrong, Here Are 7 Ways to Choose a Ripe Dragon Fruit",
|
||||
description:"Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
||||
imageSrc: image17.src,
|
||||
link: `${ROUTE.BLOG_DETAIL}`
|
||||
},{
|
||||
title: "Want to Lose Weight? Here are 10 DEBM Diet Guidelines for Beginners",
|
||||
description:"The DEBM diet stands for "+'"Delicious Happy Fun Diet"'+". This diet was popularized by Robert...",
|
||||
imageSrc: image15.src,
|
||||
link: `${ROUTE.BLOG_DETAIL}`
|
||||
},{
|
||||
title: "9 Ways to Make an Aloe Vera Mask at Home",
|
||||
description:"Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
||||
imageSrc: image16.src,
|
||||
link: `${ROUTE.BLOG_DETAIL}`
|
||||
},{
|
||||
title: "Don't Buy Wrong, Here Are 7 Ways to Choose a Ripe Dragon Fruit",
|
||||
description:"Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
||||
imageSrc: image17.src,
|
||||
link: `${ROUTE.BLOG_DETAIL}`
|
||||
}]
|
||||
|
||||
const RelevantBlogPosts = ({ data = recipe, itemKey="detail-relevant", title="Relevant Blog Posts" }: RelevantProps) => {
|
||||
return (
|
||||
<div className={s.blogPostWarpper}>
|
||||
<div className={s.top}>
|
||||
<div className={s.left}>
|
||||
<HeadingCommon>{title}</HeadingCommon>
|
||||
</div>
|
||||
<div className={s.right}>
|
||||
<ViewAllItem link="#"/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={s.bot}>
|
||||
<BlogPostCarousel data={data} itemKey={itemKey} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RelevantBlogPosts
|
@@ -34,3 +34,6 @@ export { default as ModalInfo} from "./ModalInfo/ModalInfo"
|
||||
export { default as ProductList} from "./ProductList/ProductList"
|
||||
export { default as ModalCreateUserInfo} from './ModalCreateUserInfo/ModalCreateUserInfo'
|
||||
export { default as CardItemCheckout} from './CardItemCheckout/CardItemCheckout'
|
||||
export { default as CardBlog} from './CardBlog/CardBlog'
|
||||
export { default as RelevantBlogPosts} from './RelevantBlogPosts/RelevantBlogPosts'
|
||||
export { default as CollapseCommon} from './CollapseCommon/CollapseCommon'
|
||||
|
Reference in New Issue
Block a user