Latest News (#12)

This commit is contained in:
Nazareno Oviedo 2022-04-04 15:46:01 -03:00 committed by GitHub
parent 3caabeb574
commit 3e0a1b51e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 316 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1,19 +1,31 @@
@import '~/css/helpers';
.cardContainer {
width: 100%;
.card {
display: flex;
flex-direction: column;
width: 100%;
padding-bottom: tovw(2px, 'default', 2px);
.eventHeader {
display: flex;
flex-direction: column;
gap: tovw(14px, 'default', 8px);
font-size: tovw(18px, 'default', 12px);
&__header {
font-family: var(--font-dm-mono), sans-serif;
font-size: tovw(18px, 'default', 12px);
font-weight: 400;
line-height: 1.2;
letter-spacing: -0.02rem;
display: flex;
flex-direction: column;
letter-spacing: tovw(-0.6px, 'default', -0.6px);
gap: tovw(14px, 'default', 8px);
div {
display: flex;
color: var(--color-grey-light);
gap: tovw(30px, 'default', 25px);
}
.author {
text-transform: uppercase;
color: var(--color-white);
}
.date,
.hour {
@ -26,47 +38,40 @@
margin-bottom: tovw(1px, 'default', 1px);
}
}
div {
display: flex;
gap: tovw(30px, 'default', 25px);
color: var(--color-grey-light);
}
}
}
.imageContainer {
margin: tovw(25px, 'default', 16px) 0;
.image__container {
width: 100%;
height: tovw(232px, 'default', 200px);
margin: tovw(25px, 'default', 16px) 0;
border-top: tovw(1px, 'default', 1px) solid var(--color-white);
border-bottom: tovw(1px, 'default', 1px) solid var(--color-white);
img {
width: 100%;
height: tovw(232px, 'default', 200px);
border-top: tovw(1px, 'default', 1px) solid var(--color-white);
border-bottom: tovw(1px, 'default', 1px) solid var(--color-white);
height: 100%;
object-fit: cover;
}
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.content {
display: flex;
flex-direction: column;
gap: tovw(24px, 'default', 18px);
a {
width: fit-content;
padding-top: tovw(20px, 'default', 12px);
}
.body {
display: flex;
flex-direction: column;
gap: tovw(24px, 'default', 18px);
p {
font-size: tovw(18px, 'default', 15px);
line-height: 1.4;
margin: 0;
a {
padding-top: tovw(20px, 'default', 12px);
width: fit-content;
}
p {
margin: 0;
font-weight: 400;
line-height: 1.4;
font-size: tovw(18px, 'default', 15px);
@media screen and (max-width: 800px) {
line-height: 1.6;
}
@media screen and (max-width: 800px) {
line-height: 1.6;
}
}
}

View File

@ -1,39 +1,47 @@
import clsx from 'clsx'
import { Calendar, Clock } from '~/components/icons/events'
import Heading from '~/components/primitives/heading'
import Link from '~/components/primitives/link'
import s from './card.module.scss'
interface Props {
interface CardProps {
className?: string
data?: any
isNews?: boolean
}
function Card({ className, data }: Props) {
const Card = ({ className, data, isNews = false }: CardProps) => {
return (
<div className={`${s.cardContainer} ${className}`}>
<div className={s.eventHeader}>
<span className={s.location}>{data?.location?.toUpperCase()}</span>
<div className={clsx(s['card'], className)}>
<div className={s['card__header']}>
{!isNews && (
<span className={s.location}>{data?.location?.toUpperCase()}</span>
)}
<div>
<span className={s.author}>BY {data?.author}</span>
<span className={s.date}>
<Calendar />
{!isNews && <Calendar />}
{data?.date}
</span>
<span className={s.hour}>
<Clock />
{data?.time} HS
</span>
{!isNews && (
<span className={s.hour}>
<Clock />
{data?.time} HS
</span>
)}
</div>
</div>
<div className={s.imageContainer}>
<img src={data?.imgSrc} alt="preview" />
<div className={s['image__container']}>
<img alt={data?.title} loading="lazy" src={data?.imgSrc} />
</div>
<div className={s.body}>
<div className={s['content']}>
<Heading as="h2" variant="sm" font="tthoves">
{data?.title}
</Heading>
<p>{data?.preview}</p>
<Link href={data?.link}>LEARN MORE</Link>
<Link href={data?.link}>{isNews ? 'READ ARTICLE' : 'LEARN MORE'}</Link>
</div>
</div>
)

View File

@ -38,7 +38,7 @@ const Events = () => {
slides: { perView: 2, spacing: 22 }
},
'(min-width: 1600px)': {
slides: { perView: 3.69, spacing: 24 }
slides: { perView: 3.915, spacing: 24 }
}
}
})

View File

@ -0,0 +1,74 @@
import 'keen-slider/keen-slider.min.css'
import { useKeenSlider } from 'keen-slider/react'
import { useState } from 'react'
import Card from '~/components/common/card'
import { ArrowSlider } from '~/components/icons/arrow'
import { Container } from '~/components/layout/container'
import Section from '~/components/layout/section'
import Heading from '~/components/primitives/heading'
import s from './latest-news.module.scss'
import { latestNews } from './news'
const LatestNews = () => {
const [loaded, setLoaded] = useState(false)
const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({
initial: 0,
loop: true,
mode: 'free-snap',
created() {
setLoaded(true)
},
breakpoints: {
'(max-width: 1050px)': {
slides: { perView: 1.12, spacing: 12 }
},
'(min-width: 1050px)': {
slides: { perView: 2, spacing: 22 }
},
'(min-width: 1600px)': {
slides: { perView: 3.915, spacing: 24 }
}
}
})
return (
<Section className={s['section']}>
<Container className={s.heading}>
<Heading as="h2" variant="lg">
Latest news <br /> from Laconic
</Heading>
</Container>
<div className={s['slider__container']}>
<div className={`${s.eventsContainer} keen-slider`} ref={sliderRef}>
{latestNews.map((item, i) => (
<Card key={i} data={item} className={`keen-slider__slide`} isNews />
))}
</div>
</div>
<Container>
{loaded && slider.current && (
<div className={s.navigation}>
<ArrowSlider
onClick={(e: any) =>
e.stopPropagation() || slider.current?.prev()
}
className={s['arrow']}
/>
<ArrowSlider
onClick={(e: any) =>
e.stopPropagation() || slider.current?.next()
}
className={s['arrow']}
/>
</div>
)}
</Container>
</Section>
)
}
export default LatestNews

View File

@ -0,0 +1,132 @@
@import '~/css/helpers';
.section {
display: flex;
align-items: center;
flex-direction: column;
margin-top: tovw(55px, 'default', 20px);
padding: tovw(220px, 'default', 72px) 0;
.slider__container {
width: calc(100% - tovw(205px, 'default', 16px));
margin-right: 0;
margin-left: auto;
@media screen and (max-width: 800px) {
width: calc(100% - tovw(16px, 'mobile'));
}
}
.heading {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: tovw(90px, 'default', 64px);
@media screen and (max-width: 800px) {
align-items: flex-start;
flex-direction: column;
padding-bottom: unset;
border-bottom: unset;
gap: tovw(16px, 'mobile');
}
h2 {
text-shadow: 0 0 tovw(20px, 'default', 20px) rgb(255 255 255 / 0.4);
}
span {
font-family: var(--font-tt-hoves), sans-serif;
font-size: tovw(24px, 'default', 18px);
line-height: 1.32;
width: tovw(350px, 'default', 265px);
}
.gradient {
position: absolute;
z-index: -1;
right: 0;
left: 0;
width: 100%;
height: tovw(500px, 'default', 250px);
margin-left: 0;
content: '';
user-select: none;
pointer-events: none;
opacity: 0.4;
background: linear-gradient(
180deg,
rgb(229 229 229 / 0) 0%,
rgb(241 241 241 / 0.4) 48.91%,
rgb(241 241 241 / 0) 89.23%
);
@media screen and (max-width: 800px) {
display: none;
}
}
}
.eventsContainer {
padding-left: tovw(100px);
@media screen and (max-width: 800px) {
padding-left: 0;
}
&::after,
&::before {
position: absolute;
right: tovw(-20px, 'default', -20px);
width: tovw(280px, 'default', 150px);
height: 100%;
content: '';
background: linear-gradient(
90deg,
rgb(3 3 3 / 0) 0%,
rgb(3 3 3 / 0.95) 35%,
rgb(3 3 3 / 1) 65%
);
@media screen and (max-width: 800px) {
width: tovw(20px, 'default', 20px);
background: linear-gradient(
90deg,
rgb(3 3 3 / 0) 0%,
rgb(3 3 3 / 0.55) 35%,
rgb(3 3 3 / 1) 95%
);
}
}
&::before {
z-index: 5;
right: initial;
left: tovw(-150px);
transform: scaleX(-1);
@media screen and (max-width: 800px) {
content: initial;
}
}
}
.navigation {
display: flex;
width: 100%;
padding-top: tovw(75px, 'default', 45px);
place-content: center;
gap: tovw(25px, 'default', 15px);
@media screen and (max-width: 800px) {
display: none;
}
.arrow {
width: tovw(50px, 'default', 30px);
cursor: pointer;
&:first-child {
transform: rotate(180deg);
}
}
}
}

View File

@ -0,0 +1,38 @@
export const latestNews = [
{
author: 'BRIAN MILLER',
date: '01.31.22',
imgSrc: '/images/blog/post001.jpg',
title: '7 Trends Transforming DeFi 2022',
preview:
'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
link: '/blog/article'
},
{
author: 'STEPHAN WILLSON',
date: '04.25.22',
imgSrc: '/images/blog/post002.jpg',
title: 'State of Verifiable Data',
preview:
'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
link: '/blog/article'
},
{
author: 'BRIAN MILLER',
date: '06.25.22',
imgSrc: '/images/blog/post003.jpg',
title: '7 Trends Transforming DeFi 2022',
preview:
'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
link: '/blog/article'
},
{
author: 'STEPHAN WILLSON',
date: '08.25.22',
imgSrc: '/images/blog/post004.jpg',
title: '7 Trends Transforming DeFi 2022',
preview:
'Sit sed dolor felis quis. Porttitor semper enim placerat luctus purus aliquam. Diam eu varius donec sit urna feugiat libero diam augue.',
link: '/blog/article'
}
]

View File

@ -1,8 +1,8 @@
import { Meta } from '~/components/common/meta'
import { PageLayout } from '~/components/layout/page'
import Events from '~/components/sections/community/events'
import Benefits from '~/components/sections/homepage/benefits'
import Hero from '~/components/sections/homepage/hero'
import LatestNews from '~/components/sections/homepage/latest-news'
import WhatOthersSay from '~/components/sections/homepage/what-others-say'
import { Page } from './_app'
@ -13,7 +13,7 @@ const HomePage: Page = () => {
<Meta />
<Hero />
<Benefits />
<Events />
<LatestNews />
<WhatOthersSay />
</PageLayout>
)