feat: add blog routes and components

This commit is contained in:
Julien Oculi 2024-02-14 17:13:13 +01:00
parent 3be32dbf89
commit 833797406a
7 changed files with 140 additions and 0 deletions

37
components/BlogCard.css Normal file
View file

@ -0,0 +1,37 @@
.components__blog_card {
min-width: 10rem;
aspect-ratio: 3 / 4;
display: flex;
flex-direction: column;
padding: var(--_gap-half);
gap: var(--_gap);
box-shadow: 0 0 0.4rem 0.2rem var(--_translucent);
border: var(--_border-size) solid transparent;
background-repeat: no-repeat;
background-size: contain;
&:focus-visible,
&:hover {
border: var(--_border-size) solid var(--_accent-color);
}
& h3 {
margin: 0;
}
}
.components__blog_card__spacer {
height: 50%;
}
.components__blog_card__text {
text-wrap: balance;
flex-grow: 1;
}
.components__blog_card__footer {
height: fit-content;
display: flex;
gap: var(--_gap);
justify-content: space-between;
}

54
components/BlogCard.tsx Normal file
View file

@ -0,0 +1,54 @@
type BlogCardProps = {
img: string
title: string
text: string
author: string
lasUpdate: Date
id: string
}
export function BlogCard(
{ img, title, text, author, lasUpdate, id }: BlogCardProps,
) {
return (
<div class='components__blog_card' style={{ backgroundImage: img }}>
<div class='components__blog_card__spacer'></div>
<h3>
<a href={`/blog/${id}`}>{title}</a>
</h3>
<div class='components__blog_card__text'>
{`${text.slice(0, 150)} ...`}
</div>
<div class='components__blog_card__footer'>
<div>
<i class='ri-quill-pen-line'></i>
<span>{author}</span>
</div>
<div>
<i class='ri-refresh-line'></i>
<span>{lasUpdate.toLocaleDateString()}</span>
</div>
</div>
</div>
)
}
const text =
'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui, perferendis enim blanditiis consequatur at porro quod, eligendi alias recusandae modi aliquam non? Quos voluptates quisquam provident animi nisi in ratione.'
export const blogMock: BlogCardProps[] = Array(50).fill(undefined).map(
(_, index) => {
return {
author: 'PGP',
lasUpdate: randomDate(),
title: `Some title here ${index}`,
text,
img: `url("https://picsum.photos/id/${index}/300/200")`,
id: String(index),
}
},
)
function randomDate() {
return new Date(Date.now() - Math.random() * 1e10)
}

10
routes/blog/[id].tsx Normal file
View file

@ -0,0 +1,10 @@
import { PageProps } from '$fresh/server.ts'
import { BlogCard, blogMock } from '../../components/BlogCard.tsx'
export default function Projet({ params }: PageProps) {
const article = blogMock.at(Number(params.id))
return (
article ? BlogCard(article) : <h3>Article inconnu</h3>
)
}

18
routes/blog/index.tsx Normal file
View file

@ -0,0 +1,18 @@
import { BlogCard, blogMock } from '../../components/BlogCard.tsx'
export default function Blog() {
return (
<>
<h1>Nos articles</h1>
<section
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(15rem, 1fr));',
gap: 'var(--_gap)',
}}
>
{blogMock.map(BlogCard)}
</section>
</>
)
}

View file

@ -1,5 +1,8 @@
import { Head } from '$fresh/runtime.ts'
import { BlogCard, blogMock } from '../components/BlogCard.tsx'
import { CohabitInfoTable } from '../components/CohabitInfoTable.tsx'
import { Heros } from '../components/Heros.tsx'
import { SponsorCards } from '../components/SponsorCards.tsx'
export default function Home() {
return (

View file

@ -72,3 +72,20 @@ pre,
code {
font-family: var(--_font-family-code);
}
h1 {
margin-block: var(--_gap);
}
.cta {
text-decoration: none;
background-color: var(--_accent-color);
color: var(--sand-0);
width: fit-content;
height: fit-content;
padding: 1rem 2rem;
font-size: 150%;
font-family: var(--_font-family-accent);
border: var(--_border-size) solid var(--_accent-color);
transition: all var(--_transition-delay) ease;
}

View file

@ -3,5 +3,6 @@
@import url('../../components/Heros.css');
@import url('../../components/SponsorCards.css');
@import url('../../components/CohabitInfoTable.css');
@import url('../../components/BlogCard.css');
@import url('../../islands/ThemePicker.css');
@import url('../../islands/SearchBox.css');