feat: CollapseCommon, CardBlog, RelevantBlogPosts

This commit is contained in:
unknown
2021-08-31 07:46:44 +07:00
parent a1c8668315
commit f7a0ec6078
23 changed files with 351 additions and 60 deletions

View 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;
}
}

View 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

View File

@@ -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,

View File

@@ -0,0 +1,25 @@
@import "../../../styles/utilities";
.collapseWrapper{
@apply border-t border-b;
border-color: var(--border-line);
max-width: 80.4rem;
min-height: 4rem;
&.isActive{
.contentContainer{
@apply block;
}
}
svg:hover{
cursor: pointer;
}
}
.title{
@apply outline-none flex justify-between font-heading items-center pt-16;
font-size: 3.2rem;
line-height: 4rem;
letter-spacing: -0.01em;
}
.contentContainer{
@apply hidden pb-16;
}

View File

@@ -0,0 +1,37 @@
import s from './CollapseCommon.module.scss'
import { useState } from 'react'
import classNames from 'classnames'
import { IconPlus, IconMinus } from 'src/components/icons'
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}>
{title}{isActive ? <IconMinus /> : <IconPlus />}
</div>
<div className={s.contentContainer}>
{
content.map(item => <CollapseContent content={item} />)
}
</div>
</div>
)
}
export default CollapseCommon

View File

@@ -0,0 +1,3 @@
.content{
margin-top: 1.6rem;
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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);
}
}
}
}
}

View File

@@ -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

View File

@@ -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;
}
}
}
}

View File

@@ -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

View File

@@ -30,3 +30,6 @@ export { default as VideoPlayer} from './VideoPlayer/VideoPlayer'
export { default as SelectCommon} from './SelectCommon/SelectCommon'
export { default as ModalCommon} from './ModalCommon/ModalCommon'
export { default as ModalCreateUserInfo} from './ModalCreateUserInfo/ModalCreateUserInfo'
export { default as CardBlog} from './CardBlog/CardBlog'
export { default as RelevantBlogPosts} from './RelevantBlogPosts/RelevantBlogPosts'
export { default as CollapseCommon} from './CollapseCommon/CollapseCommon'