Skip to content

Commit

Permalink
Add new app-views Blog
Browse files Browse the repository at this point in the history
  • Loading branch information
nkokla committed Aug 27, 2024
1 parent 72e36af commit c8a8798
Show file tree
Hide file tree
Showing 9 changed files with 515 additions and 9 deletions.
8 changes: 8 additions & 0 deletions .env.default
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@ S3_CONFIG_ENDPOINT=
NEXT_PUBLIC_TOGGLER_DATA_SOURCES=S3
NEXT_PUBLIC_PATH_STATIC_FILE=

# -------------------------------
# --- URL des réseaux sociaux ---
# -------------------------------

NEXT_PUBLIC_SOCIAL_NETWORKS_URL_XCOM=https://x.com/adressedatagouv
NEXT_PUBLIC_SOCIAL_NETWORKS_URL_FACEBOOK=https://www.facebook.com/BasesAdressesLocales
NEXT_PUBLIC_SOCIAL_NETWORKS_URL_LINKEDIN=https://www.linkedin.com/company/base-adresse-nationale/
NEXT_PUBLIC_SOCIAL_NETWORKS_URL_GITHUB=https://github.com/BaseAdresseNationale
29 changes: 29 additions & 0 deletions src/app/blog/[slug]/components/AsideContent.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import styled from 'styled-components'

export const AsideLinkList = styled.ul`
padding: 0;
margin: 0 0 1.5rem;
list-style: none;
display: flex;
flex-direction: column;
li {
margin-bottom: 0.25rem;
}
`

export const AsideFollowList = styled.ul`
padding: 0;
margin: 0 0 1.5rem;
list-style: none;
display: flex;
flex-direction: row;
flex-wrap: wrap;
li {
flex: 50%;
margin-bottom: 0.25rem;
}
`
55 changes: 55 additions & 0 deletions src/app/blog/[slug]/components/AsideContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use client'

import { useState, useEffect } from 'react'
import Link from 'next/link'

import { getPosts } from '@/lib/blog'

import { AsideLinkList, AsideFollowList } from './AsideContent.styled'

const {
NEXT_PUBLIC_SOCIAL_NETWORKS_URL_XCOM: SOCIAL_NETWORKS_URL_XCOM,
NEXT_PUBLIC_SOCIAL_NETWORKS_URL_FACEBOOK: SOCIAL_NETWORKS_URL_FACEBOOK,
NEXT_PUBLIC_SOCIAL_NETWORKS_URL_LINKEDIN: SOCIAL_NETWORKS_URL_LINKEDIN,
} = process.env

function AsideContent() {
const [highlightedPosts, setHighlightedPosts] = useState([])
const [loading, setLoading] = useState(true)
const nbHighlightedPosts = 3

useEffect(() => {
getPosts({
limit: nbHighlightedPosts,
}).then((data) => {
setHighlightedPosts(data.posts)
setLoading(false)
})
}, [])

return (
<>
<hr />
<h6>Articles recents</h6>
{loading
? 'Chargement en cours...'
: (
<AsideLinkList>
{highlightedPosts.map(({ title, slug }: { title: string, slug: string }) => (
<li key={title}><Link className="fr-link" href={`/blog/${slug}`}>{title.replace(/\s!/, '\u00A0!')}</Link></li>
))}
</AsideLinkList>
)}
<hr />
<h6>Nous suivre</h6>
<AsideFollowList>
<li><Link className="fr-link fr-link--icon-left fr-icon-linkedin-box-fill" target="linkedin" href={SOCIAL_NETWORKS_URL_LINKEDIN ?? ''}>LinkedIn</Link></li>
<li><Link className="fr-link fr-link--icon-left fr-icon-twitter-x-fill" target="twitter-x" href={SOCIAL_NETWORKS_URL_XCOM ?? ''}>X.com</Link></li>
<li><Link className="fr-link fr-link--icon-left fr-icon-facebook-circle-fill" target="facebook" href={SOCIAL_NETWORKS_URL_FACEBOOK ?? ''}>Facebook</Link></li>
<li><Link className="fr-link fr-link--icon-left ri-mail-send-fill" target="newsletter" href="#d">Newsletter</Link></li>
</AsideFollowList>
</>
)
}

export default AsideContent
89 changes: 89 additions & 0 deletions src/app/blog/[slug]/page.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use client'

import styled from 'styled-components'

const ARTICLE_MARGIN_LEFT = '7rem'

export const TagsWrapper = styled.div`
padding: 0 0 1rem 0;
`

export const TextWrapper = styled.div`
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 2rem;
header,
article {
width: 70%;
padding-left: ${ARTICLE_MARGIN_LEFT};
}
aside {
width: 30%;
hr {
width: 10%;
}
}
figure {
display: flex;
flex-direction: column;
justify-content: flex-start;
max-width: calc(100vw - 1.5rem - 1.5rem);
margin: 2rem 15%;
font-size: 1rem;
img {
max-width: 100%;
height: auto;
border-radius: 1rem;
}
figcaption {
font-size: 0.75em;
text-align: center;
margin-top: 0.5em;
color: #666666;
}
}
`
export const ImageWrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
max-height: 25rem;
overflow: hidden;
margin: 2rem 0 2rem -${ARTICLE_MARGIN_LEFT};
box-shadow: 0 0 0.3rem rgba(0,0,0,0.1);
img {
width: 100%;
height: auto;
}
`

export const PublicationWrapper = styled.div`
display: flex;
padding: 0 0 1.5rem 0;
font-size: 0.85em;
.publication-date {
font-weight: bold;
}
.reading-time {
flex: 1;
text-align: right;
}
`

export const AuthorWrapper = styled.div`
padding: 0 0 1.5rem 0;
font-size: 0.85em;
font-weight: bold;
`
104 changes: 104 additions & 0 deletions src/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Fragment } from 'react'
import Tag from '@codegouvfr/react-dsfr/Tag'

import Breadcrumb from '@/layouts/Breadcrumb'
import Section from '@/components/Section'
import DangerouslyHTML from '@/components/MarkdownViewer'
import SharingBlock from '@/components/SharingBlock'
import { getSinglePost } from '@/lib/blog'

import {
TagsWrapper,
PublicationWrapper,
ImageWrapper,
AuthorWrapper,
TextWrapper,
} from './page.styled'

import AsideContent from './components/AsideContent'

export default async function BlogPost({ params }: { params: { slug: string } }) {
const pageUrl = `https://adresse.data.gouv.fr/blog/${params.slug}`
const blogPost = await getSinglePost(params.slug) || {}

const {
excerpt,
html: contentHtml,
title,
tags,
feature_image: featureImage,
authors,
published_at: publishedAt,
reading_time: readingTime,
} = blogPost || {}

return (
<>
<Breadcrumb
currentPageLabel={title}
segments={[
{
label: 'Le Blog et les témoignages',
linkProps: {
href: '/blog',
},
},
]}
/>
<Section>
<TextWrapper>
<header>
<TagsWrapper>
{tags.length && (
<ul className="fr-tags-group">
{tags.map(({ name }: { name: string }) => (
<li key={name}>
<Tag small>{name}</Tag>
</li>
))}
</ul>
)}
</TagsWrapper>

<h1>{title}</h1>
</header>
</TextWrapper>

<TextWrapper>
<article>
<hr />

<PublicationWrapper>
{publishedAt && <div className="publication-date">Publié le {new Date(publishedAt).toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}</div>}
{readingTime && <div className="reading-time">Lecture {readingTime} minutes</div>}
</PublicationWrapper>

<p>
{excerpt}
</p>

<SharingBlock pageUrl={pageUrl} callMessage={title} title={title} />

{featureImage && (
<ImageWrapper>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={featureImage} alt={title} />
</ImageWrapper>
)}

<AuthorWrapper>
<div>Rédigé par{authors?.length && ((authors as { name: string }[]).map(({ name }, i, arr) => (
<Fragment key={name}>{arr.length > 1 && i === (arr.length - 1) ? ' et' : (i > 0 ? ' ,' : ' ')} <span>{name}</span></Fragment>)))}
</div>
</AuthorWrapper>

<DangerouslyHTML html={contentHtml} />
</article>
<aside>
<AsideContent />
</aside>
</TextWrapper>
</Section>
</>
)
}
25 changes: 25 additions & 0 deletions src/app/blog/page.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client'

import styled from 'styled-components'

export const TextWrapper = styled.div`
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 1rem;
article {
width: 65%;
}
`

export const TagsWrapper = styled.ul`
line-height: 3rem;
margin: 0.5rem 0 1.5rem;
padding: 0;
`

export const TagWrapper = styled.li`
display: inline;
margin-right: 0.5rem;
`
Loading

0 comments on commit c8a8798

Please sign in to comment.