mirror of
https://github.com/acid-info/logos-press-engine.git
synced 2025-02-23 14:48:08 +00:00
feat: add podcast show page
This commit is contained in:
parent
632f61e8d0
commit
1e7a5d7692
@ -1,12 +1,8 @@
|
|||||||
import { Tags } from '@/components/Tags'
|
|
||||||
import { Typography } from '@acid-info/lsd-react'
|
import { Typography } from '@acid-info/lsd-react'
|
||||||
import styled from '@emotion/styled'
|
import styled from '@emotion/styled'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { LPE } from '../../types/lpe.types'
|
import { LPE } from '../../types/lpe.types'
|
||||||
import { Authors } from '../Authors'
|
|
||||||
import { AuthorsDirection } from '../Authors/Authors'
|
|
||||||
import { LogosCircleIcon } from '../Icons/LogosCircleIcon'
|
|
||||||
import { ResponsiveImage } from '../ResponsiveImage/ResponsiveImage'
|
import { ResponsiveImage } from '../ResponsiveImage/ResponsiveImage'
|
||||||
|
|
||||||
export enum Size {
|
export enum Size {
|
||||||
|
@ -72,7 +72,6 @@ const EpisodeListContainer = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-top: 1px solid rgb(var(--lsd-border-primary));
|
border-top: 1px solid rgb(var(--lsd-border-primary));
|
||||||
margin-top: 140px;
|
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
78
src/components/Podcasts/PodcastShowCard.tsx
Normal file
78
src/components/Podcasts/PodcastShowCard.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { Tags } from '@/components/Tags'
|
||||||
|
import { Typography } from '@acid-info/lsd-react'
|
||||||
|
import styled from '@emotion/styled'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import React, { useMemo } from 'react'
|
||||||
|
import { LPE } from '../../types/lpe.types'
|
||||||
|
|
||||||
|
import { ResponsiveImage } from '../ResponsiveImage/ResponsiveImage'
|
||||||
|
import { LogosCircleIcon } from '../Icons/LogosCircleIcon'
|
||||||
|
|
||||||
|
export enum Size {
|
||||||
|
SMALL = 'small',
|
||||||
|
LARGE = 'large',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
show: LPE.Podcast.Show
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PodcastShowCard({ show }: Props) {
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<LogosCircleIcon width={73} height={73} />
|
||||||
|
<ShowData>
|
||||||
|
<Typography variant="h3">{show.title}</Typography>
|
||||||
|
<HostedBy>
|
||||||
|
<Typography variant="body2">
|
||||||
|
Hosted by:
|
||||||
|
{show.hosts.map((host) => (
|
||||||
|
<Host key={host.name} variant="body2">
|
||||||
|
{host.name}
|
||||||
|
</Host>
|
||||||
|
))}
|
||||||
|
</Typography>
|
||||||
|
</HostedBy>
|
||||||
|
<Description variant="body2">{show.description}</Description>
|
||||||
|
</ShowData>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 68px;
|
||||||
|
`
|
||||||
|
|
||||||
|
const ShowData = styled.div`
|
||||||
|
margin-top: 40px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
`
|
||||||
|
|
||||||
|
const HostedBy = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 16px;
|
||||||
|
`
|
||||||
|
|
||||||
|
const Host = styled(Typography)`
|
||||||
|
margin-left: 8px;
|
||||||
|
&:not(:last-child) {
|
||||||
|
&:after {
|
||||||
|
content: '•';
|
||||||
|
margin-left: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const Description = styled(Typography)`
|
||||||
|
margin-top: 16px;
|
||||||
|
`
|
@ -2,7 +2,6 @@ import styled from '@emotion/styled'
|
|||||||
import { LPE } from '../../types/lpe.types'
|
import { LPE } from '../../types/lpe.types'
|
||||||
import { Button, Typography } from '@acid-info/lsd-react'
|
import { Button, Typography } from '@acid-info/lsd-react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import Image from 'next/image'
|
|
||||||
import { LogosCircleIcon } from '../Icons/LogosCircleIcon'
|
import { LogosCircleIcon } from '../Icons/LogosCircleIcon'
|
||||||
import { HashingItOutIcon } from '../Icons/HashingItOutIcon'
|
import { HashingItOutIcon } from '../Icons/HashingItOutIcon'
|
||||||
|
|
||||||
@ -44,9 +43,6 @@ export default function PodcastsList({ shows }: Props) {
|
|||||||
const PodcastsContainer = styled.article`
|
const PodcastsContainer = styled.article`
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
@media (min-width: 768px) and (max-width: 1200px) {
|
|
||||||
}
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const PodcastCard = styled.div`
|
const PodcastCard = styled.div`
|
||||||
|
44
src/containers/PodcastShowContainer.tsx
Normal file
44
src/containers/PodcastShowContainer.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Grid, GridItem } from '@/components/Grid/Grid'
|
||||||
|
import styled from '@emotion/styled'
|
||||||
|
import { LPE } from '../types/lpe.types'
|
||||||
|
import PodcastsList from '@/components/Podcasts/Podcasts.List'
|
||||||
|
import EpisodesList from '@/components/Podcasts/Episodes.List'
|
||||||
|
import { Typography } from '@acid-info/lsd-react'
|
||||||
|
import { PodcastType } from '@/components/Post/Post'
|
||||||
|
import PodcastShowCard from '@/components/Podcasts/PodcastShowCard'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
show: LPE.Podcast.Show
|
||||||
|
latestEpisodes: LPE.Podcast.Document[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const PodcastShowContainer = (props: Props) => {
|
||||||
|
const { show, latestEpisodes } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PodcastsGrid>
|
||||||
|
<PodcastsBodyContainer className={'w-16'}>
|
||||||
|
<PodcastShowCard show={show} />
|
||||||
|
<EpisodesList
|
||||||
|
header={<Typography variant="body2">Latest Episodes</Typography>}
|
||||||
|
episodes={latestEpisodes}
|
||||||
|
podcastType={PodcastType.LATEST}
|
||||||
|
/>
|
||||||
|
</PodcastsBodyContainer>
|
||||||
|
</PodcastsGrid>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const PodcastsBodyContainer = styled(GridItem)`
|
||||||
|
@media (min-width: 768px) and (max-width: 1200px) {
|
||||||
|
grid-column: span 10 !important;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const PodcastsGrid = styled(Grid)`
|
||||||
|
width: 100%;
|
||||||
|
@media (min-width: 768px) and (max-width: 1200px) {
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default PodcastShowContainer
|
@ -18,23 +18,30 @@ const PodcastsContainer = (props: Props) => {
|
|||||||
<PodcastsGrid>
|
<PodcastsGrid>
|
||||||
<PodcastsBodyContainer className={'w-16'}>
|
<PodcastsBodyContainer className={'w-16'}>
|
||||||
<PodcastsList shows={shows} />
|
<PodcastsList shows={shows} />
|
||||||
<EpisodesList
|
|
||||||
header={<Typography variant="body2">Latest Episodes</Typography>}
|
|
||||||
episodes={latestEpisodes}
|
|
||||||
podcastType={PodcastType.LATEST}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<EpisodesList
|
<Section>
|
||||||
header={<Typography variant="body2">State of Network</Typography>}
|
<EpisodesList
|
||||||
episodes={latestEpisodes.slice(0, 4)}
|
header={<Typography variant="body2">Latest Episodes</Typography>}
|
||||||
podcastType={PodcastType.NETWORK_STATE}
|
episodes={latestEpisodes}
|
||||||
/>
|
podcastType={PodcastType.LATEST}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
|
||||||
<EpisodesList
|
<Section>
|
||||||
header={<Typography variant="body2">Hashing It Out</Typography>}
|
<EpisodesList
|
||||||
episodes={latestEpisodes.slice(0, 4)}
|
header={<Typography variant="body2">State of Network</Typography>}
|
||||||
podcastType={PodcastType.HASHING_IT_OUT}
|
episodes={latestEpisodes.slice(0, 4)}
|
||||||
/>
|
podcastType={PodcastType.NETWORK_STATE}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<Section>
|
||||||
|
<EpisodesList
|
||||||
|
header={<Typography variant="body2">Hashing It Out</Typography>}
|
||||||
|
episodes={latestEpisodes.slice(0, 4)}
|
||||||
|
podcastType={PodcastType.HASHING_IT_OUT}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
</PodcastsBodyContainer>
|
</PodcastsBodyContainer>
|
||||||
</PodcastsGrid>
|
</PodcastsGrid>
|
||||||
)
|
)
|
||||||
@ -52,4 +59,8 @@ const PodcastsGrid = styled(Grid)`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const Section = styled.div`
|
||||||
|
margin-top: 140px;
|
||||||
|
`
|
||||||
|
|
||||||
export default PodcastsContainer
|
export default PodcastsContainer
|
||||||
|
@ -5,30 +5,37 @@ import { ReactNode } from 'react'
|
|||||||
import { LPE } from '../../../types/lpe.types'
|
import { LPE } from '../../../types/lpe.types'
|
||||||
import PodcastsLayout from '@/layouts/PodcastsLayout/Podcasts.layout'
|
import PodcastsLayout from '@/layouts/PodcastsLayout/Podcasts.layout'
|
||||||
|
|
||||||
type PodcastShowProps = {
|
import TEMP_DATA from '../podcasts-temp-data.json'
|
||||||
data: LPE.Podcast.Document
|
import PodcastShowContainer from '@/containers/PodcastShowContainer'
|
||||||
|
|
||||||
|
interface PodcastShowProps {
|
||||||
|
show: LPE.Podcast.Show
|
||||||
|
latestEpisodes: LPE.Podcast.Document[]
|
||||||
errors: string | null
|
errors: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
const PodcastShowPage = ({ data, errors }: PodcastShowProps) => {
|
const PodcastShowPage = ({
|
||||||
|
show,
|
||||||
|
latestEpisodes,
|
||||||
|
errors,
|
||||||
|
}: PodcastShowProps) => {
|
||||||
const {
|
const {
|
||||||
query: { showSlug },
|
query: { showSlug },
|
||||||
} = useRouter()
|
} = useRouter()
|
||||||
|
|
||||||
if (!data) return null
|
if (!show) return null
|
||||||
if (errors) return <div>{errors}</div>
|
if (errors) return <div>{errors}</div>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SEO
|
<SEO
|
||||||
title={data.title}
|
title={show.title}
|
||||||
description={data.description}
|
description={show.description}
|
||||||
image={data.coverImage}
|
|
||||||
imageUrl={undefined}
|
imageUrl={undefined}
|
||||||
pagePath={`/podcasts/${showSlug}`}
|
pagePath={`/podcasts/${showSlug}`}
|
||||||
tags={[...data?.tags]}
|
tags={[]}
|
||||||
/>
|
/>
|
||||||
<div style={{ marginTop: '200px' }}>Single Podcasts Page WIP</div>
|
<PodcastShowContainer show={show} latestEpisodes={latestEpisodes} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -42,6 +49,7 @@ export async function getStaticPaths() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getStaticProps = async ({ params }: GetStaticPropsContext) => {
|
export const getStaticProps = async ({ params }: GetStaticPropsContext) => {
|
||||||
|
const { shows, latestEpisodes } = TEMP_DATA
|
||||||
const { showSlug } = params!
|
const { showSlug } = params!
|
||||||
|
|
||||||
if (!showSlug) {
|
if (!showSlug) {
|
||||||
@ -53,7 +61,8 @@ export const getStaticProps = async ({ params }: GetStaticPropsContext) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
data: { tags: ['Social', 'Political'] },
|
show: shows[0],
|
||||||
|
latestEpisodes,
|
||||||
error: null,
|
error: null,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,15 @@
|
|||||||
"numberOfEpisodes": 0,
|
"numberOfEpisodes": 0,
|
||||||
"hosts": [
|
"hosts": [
|
||||||
{
|
{
|
||||||
"name": "Host",
|
"name": "Corey Petty",
|
||||||
|
"emailAddress": "host@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jessie Santiag",
|
||||||
|
"emailAddress": "host@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Demetrick Ferguson",
|
||||||
"emailAddress": "host@gmail.com"
|
"emailAddress": "host@gmail.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user