feat: implement landing page's new layout

This commit is contained in:
Hossein Mehrabi 2023-12-23 04:44:39 +03:30
parent 99fc7f6c8b
commit acb09eb310
No known key found for this signature in database
GPG Key ID: 45C04964191AFAA1
2 changed files with 143 additions and 172 deletions

View File

@ -1,6 +1,6 @@
import { Button, Typography } from '@acid-info/lsd-react'
import { Typography } from '@acid-info/lsd-react'
import styled from '@emotion/styled'
import React, { useMemo } from 'react'
import React from 'react'
import { Hero } from '../../components/Hero'
import { PostsGrid } from '../../components/PostsGrid'
import { uiConfigs } from '../../configs/ui.configs'
@ -27,45 +27,15 @@ export const HomePage: React.FC<HomePageProps> = ({
data: { highlighted = [], shows = [], tags = [], latest },
...props
}) => {
const query = useRecentPosts({ initialData: latest, limit: 10 })
const [group1, group2] = useMemo(
() => [query.posts.slice(0, 5), query.posts.slice(5)],
[query.posts],
)
const query = useRecentPosts({ initialData: latest, limit: 12 })
return (
<Root {...props}>
<HeroContainer>
<Hero tags={tags} />
</HeroContainer>
<MostRecentContainer>
<Container>
<PostsGrid
posts={group1}
horizontal
displayYear={false}
pattern={[{ cols: 5, size: 'xxsmall' }]}
breakpoints={[
{
breakpoint: 'xs',
pattern: [{ cols: 1.5, size: 'xxsmall', maxWidth: '192px' }],
},
{
breakpoint: 'sm',
pattern: [{ cols: 4, size: 'xxsmall' }],
},
{
breakpoint: 'md',
pattern: [{ cols: 4, size: 'xxsmall' }],
},
]}
/>
</Container>
</MostRecentContainer>
<Container>
<PostsGrid
bordered
posts={highlighted.slice(0, 1)}
pattern={[{ cols: 1, size: 'large' }]}
breakpoints={[
@ -73,58 +43,52 @@ export const HomePage: React.FC<HomePageProps> = ({
breakpoint: 'xs',
pattern: [{ cols: 1, size: 'small' }],
},
]}
/>
<PostsGrid
pattern={[
{ cols: 4, size: 'small' },
{
cols: 2,
size: 'medium',
},
]}
breakpoints={[
{
breakpoint: 'xs',
pattern: [
{
cols: 1,
size: 'small',
},
],
},
{
breakpoint: 'sm',
pattern: [
{
cols: 3,
size: 'small',
},
{
cols: 2,
size: 'medium',
},
],
},
{
breakpoint: 'md',
pattern: [
{
cols: 3,
size: 'small',
},
{
cols: 2,
size: 'medium',
},
],
pattern: [{ cols: 1, size: 'large' }],
},
]}
posts={group2}
bordered
/>
<Section>
<Typography component="h2" variant="subtitle2">
Latest posts
</Typography>
<PostsGrid
pattern={[{ cols: 4, size: 'small' }]}
breakpoints={[
{
breakpoint: 'xs',
pattern: [
{
cols: 1,
size: 'small',
},
],
},
{
breakpoint: 'sm',
pattern: [
{
cols: 2,
size: 'small',
},
],
},
{
breakpoint: 'md',
pattern: [
{
cols: 4,
size: 'small',
},
],
},
]}
posts={query.posts.slice(0, 8)}
/>
</Section>
{query.hasNextPage && (
{/* {query.hasNextPage && (
<div className="load-more">
<Button
onClick={() => query.fetchNextPage()}
@ -136,7 +100,7 @@ export const HomePage: React.FC<HomePageProps> = ({
</Typography>
</Button>
</div>
)}
)} */}
<PodcastShowsPreview data={{ shows }} />
</Container>
@ -175,11 +139,19 @@ const Root = styled('div')`
}
`
const MostRecentContainer = styled.div`
${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'exact')} {
& > div {
padding: 0;
padding-left: var(--main-content-padding);
const Section = styled.div`
border-top: 1px solid rgb(var(--lsd-border-primary));
& > h2 {
padding: var(--lsd-spacing-24) 0;
}
${(props) => lsdUtils.breakpoint(props.theme, 'md', 'down')} {
margin-top: var(--lsd-spacing-16);
& > h2 {
padding: var(--lsd-spacing-16) 0;
${lsdUtils.typography('subtitle3')}
}
}
`

View File

@ -1,9 +1,8 @@
import { Button, Typography } from '@acid-info/lsd-react'
import { Typography } from '@acid-info/lsd-react'
import { css } from '@emotion/react'
import styled from '@emotion/styled'
import clsx from 'clsx'
import Image from 'next/image'
import Link from 'next/link'
import React from 'react'
import { ChevronRightIcon } from '../../components/Icons/ChevronRightIcon'
import { PostsGrid } from '../../components/PostsGrid'
@ -28,54 +27,47 @@ export const PodcastShowsPreview: React.FC<PodcastShowsPreviewProps> = ({
return (
<Root {...props} className={clsx('podcasts', props.className)}>
<div className="podcasts__header">
<Typography variant="subtitle1">Podcasts</Typography>
<Link href="/podcasts">
<Button variant="outlined" size="small">
Go to all podcasts
</Button>
</Link>
<Typography component="h2" variant="h2">
Podcasts
</Typography>
</div>
<div
className={clsx(
'podcasts__shows',
shows.length > 1 && 'podcasts__shows--bordered',
)}
>
<div className={clsx('podcasts__shows')}>
{shows.slice(0, 2).map((show) => (
<div key={show.id} className={clsx('podcasts__show')}>
<div className="podcasts__show-card">
<Image
width={56}
height={56}
alt={show.title}
src={show.logo.url}
className="podcasts__show-logo"
/>
<Typography variant="h3" className="podcasts__show-title">
{show.title}
</Typography>
<div className="podcasts__show-info">
<Image
width={32}
height={32}
alt={show.title}
src={show.logo.url}
className="podcasts__show-logo"
/>
<Typography
component="h3"
variant="subtitle2"
className="podcasts__show-title"
>
{show.title}
</Typography>
<ChevronRightIcon color="primary" />
<Typography
component="a"
variant="body1"
className="podcasts__show-link"
href={getPostLink('podcast', { showSlug: show.slug })}
>
See all
</Typography>
</div>
{show.description && (
<Typography
variant="subtitle2"
variant="subtitle3"
className="podcasts__show-description"
dangerouslySetInnerHTML={{ __html: show.description }}
/>
)}
<Link
href={getPostLink('podcast', { showSlug: show.slug })}
className="podcasts__show-link"
>
<Button
size="small"
variant="outlined"
icon={<ChevronRightIcon color="primary" />}
>
Podcast page
</Button>
</Link>
<Typography className="podcasts__show-hosts">
<Typography variant="subtitle3" className="podcasts__show-hosts">
{show.hosts.length > 0 && (
<span>
Hosted by:{' '}
@ -84,25 +76,31 @@ export const PodcastShowsPreview: React.FC<PodcastShowsPreviewProps> = ({
))}
</span>
)}
<span>{show.numberOfEpisodes} EP</span>
</Typography>
</div>
<div className="podcasts__show-episodes">
<PostsGrid
posts={(show.episodes || []).slice(0, 1)}
shows={shows}
displayPodcastShow
pattern={[
{
cols: 1,
size: 'medium',
},
]}
style={{ marginBottom: 16 }}
/>
<PostsGrid
posts={(show.episodes || [])
.slice(0, 4)
.slice(1, 3)
.map((ep) => ({ ...ep, show }))}
displayPodcastShow={false}
displayPodcastShow
pattern={[
{
cols: 2,
size: 'xsmall',
},
{
cols: 2,
size: 'xsmall',
rowBorder: true,
size: 'small',
},
]}
breakpoints={[
@ -137,61 +135,57 @@ export const PodcastShowsPreview: React.FC<PodcastShowsPreviewProps> = ({
const Root = styled('div')`
& .podcasts {
&__header {
padding: 16px 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-top: 1px solid rgb(var(--lsd-border-primary));
padding-bottom: var(--lsd-spacing-24);
border-bottom: 1px solid rgb(var(--lsd-border-primary));
}
&__shows {
display: grid;
grid-template-columns: repeat(2, 1fr);
padding-top: 24px;
& > div:first-child {
border-right: 1px solid rgb(var(--lsd-border-primary));
padding-right: 16px;
}
&--bordered {
& > div:last-child {
padding-left: 16px;
}
}
margin-top: var(--lsd-spacing-24);
gap: 0 var(--lsd-spacing-16);
}
&__show-card {
margin-top: 24px;
margin: var(--lsd-spacing-24) 0;
align-items: flex-start;
display: flex;
flex-direction: column;
gap: var(--lsd-spacing-24) 0;
}
&__show-info {
display: flex;
flex-direction: row;
align-items: center;
gap: 0 8px;
}
&__show-logo {
width: 56px;
height: 56px;
width: 32px;
height: 32px;
border-radius: 100%;
}
&__show-title {
margin-top: 16px;
margin-left: 8px;
}
&__show-description {
display: block;
margin-top: 8px;
}
&__show-link {
display: block;
margin-top: 24px;
text-decoration: none;
}
&__show-hosts {
display: block;
margin-top: 200px;
span:not(:last-child) {
&:after {
@ -204,9 +198,7 @@ const Root = styled('div')`
}
&__show-episodes {
> div:not(:last-child) {
border-bottom: 1px solid rgb(var(--lsd-border-primary));
}
padding-top: var(--lsd-spacing-24);
}
}
@ -216,27 +208,34 @@ const Root = styled('div')`
'xs',
'exact',
)(css`
.podcasts__shows {
padding-top: 0;
grid-template-columns: repeat(1, 1fr);
}
.podcasts__header {
padding-bottom: var(--lsd-spacing-16);
border-bottom: none;
.podcasts__show {
border-right: none !important;
padding: 0 !important;
&:not(:first-child) {
border-top: 1px solid rgb(var(--lsd-border-primary));
h2 {
${lsdUtils.typography('h3')}
}
}
.podcasts__show-card {
.podcasts__shows {
display: flex;
flex-direction: column;
margin-top: 0;
padding: 24px 0px 16px 0px;
gap: var(--lsd-spacing-32);
}
.podcasts__show {
border-top: 1px solid rgb(var(--lsd-border-primary));
}
.podcasts__show-card {
}
.podcasts__show-hosts {
margin-top: 80px;
}
.podcasts__show-episodes {
padding-top: var(--lsd-spacing-16);
}
`)}
`