jalil.arfaoui.net/src/pages/photo/blog/index.astro

318 lines
7 KiB
Text
Raw Normal View History

---
import PhotoLayout from '../../../layouts/PhotoLayout.astro';
import CategoryNav from '../../../components/photo/CategoryNav.astro';
import { getCollection } from 'astro:content';
2026-01-07 03:03:42 +01:00
import { Picture } from 'astro:assets';
// Récupération des posts photo
const allPhotoBlogPosts = await getCollection('photoBlogPosts');
// Tri par date (plus récent en premier)
const sortedPosts = allPhotoBlogPosts.sort((a, b) =>
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
);
// coverImage est déjà un ImageMetadata grâce au schema image() dans config.ts
const postsWithImages = sortedPosts.map((post) => ({
...post,
resolvedCoverImage: post.data.coverImage
}));
// Séparer les posts à la une des autres
const featuredPosts = postsWithImages.filter(post => post.data.featured);
const regularPosts = postsWithImages.filter(post => !post.data.featured);
---
<PhotoLayout title="Blog Photo - Jalil Arfaoui" enableScroll={true} hideFooter={false}>
<div class="blog-container">
<CategoryNav currentCategory="blog" opaque={false} />
<!-- Section héro avec posts à la une -->
{featuredPosts.length > 0 && (
<section class="featured-section">
<div class="featured-grid">
{featuredPosts.map(post => (
<article class="featured-post">
<a href={`/photo/blog/${post.slug}`} class="post-link">
<div class="post-image">
2026-01-07 03:03:42 +01:00
{post.resolvedCoverImage && <Picture src={post.resolvedCoverImage} alt={post.data.title} widths={[600, 900, 1200]} formats={['webp']} />}
<div class="post-overlay">
<div class="post-content">
<span class="post-badge">À la une</span>
<h2 class="post-title">{post.data.title}</h2>
<p class="post-description">{post.data.description}</p>
<time class="post-date">
{new Date(post.data.date).toLocaleDateString('fr-FR', {
year: 'numeric',
month: 'long',
day: 'numeric'
})}
</time>
</div>
</div>
</div>
</a>
</article>
))}
</div>
</section>
)}
<!-- Grille des autres posts -->
<section class="posts-grid">
<div class="grid-container">
{regularPosts.map(post => (
<article class="post-item">
<a href={`/photo/blog/${post.slug}`} class="post-link">
2026-01-07 03:03:42 +01:00
{post.resolvedCoverImage && <Picture src={post.resolvedCoverImage} alt={post.data.title} widths={[400, 600, 800]} formats={['webp']} />}
<div class="post-overlay">
<div class="overlay-content">
<h3 class="post-title">{post.data.title}</h3>
<p class="post-subtitle">{post.data.description}</p>
<time class="post-date">
{new Date(post.data.date).toLocaleDateString('fr-FR', {
year: 'numeric',
month: 'short'
})}
</time>
</div>
</div>
</a>
</article>
))}
</div>
</section>
</div>
</PhotoLayout>
<style>
.blog-container {
background: #000000;
color: #ffffff;
min-height: 100vh;
padding-top: 53px; /* Hauteur du header fixe */
}
/* Section à la une */
.featured-section {
padding: 40px 20px 60px;
max-width: 1600px;
margin: 0 auto;
}
.featured-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
gap: 20px;
}
.featured-post {
position: relative;
height: 450px;
overflow: hidden;
border-radius: 8px;
}
.featured-post .post-image {
width: 100%;
height: 100%;
position: relative;
}
.featured-post img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.featured-post:hover img {
transform: scale(1.05);
}
.featured-post .post-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to bottom, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0.7) 100%);
display: flex;
align-items: flex-end;
padding: 40px;
overflow: hidden;
}
.featured-post .post-content {
color: white;
max-height: 100%;
overflow: hidden;
}
.post-badge {
background: rgba(255, 255, 255, 0.2);
padding: 4px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 12px;
display: inline-block;
}
.featured-post .post-title {
font-size: 28px;
font-weight: 600;
margin: 0 0 12px 0;
line-height: 1.2;
}
.featured-post .post-description {
font-size: 15px;
margin: 0 0 10px 0;
opacity: 0.9;
line-height: 1.3;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.featured-post .post-date {
font-size: 14px;
opacity: 0.8;
}
/* Grille des posts */
.posts-grid {
padding: 0 20px 100px;
max-width: 1600px;
margin: 0 auto;
}
.grid-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.post-item {
overflow: hidden;
border-radius: 4px;
background: #111;
}
.post-link {
display: block;
position: relative;
aspect-ratio: 3/2;
}
.post-link img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: transform 0.3s ease;
}
.post-item .post-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 100%);
display: flex;
align-items: flex-end;
padding: 20px;
transition: background 0.3s ease;
}
.post-item:hover .post-overlay {
background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.2) 100%);
}
.post-item:hover img {
transform: scale(1.02);
}
.post-item .overlay-content {
color: white;
}
.post-item .post-title {
font-size: 20px;
font-weight: 600;
margin: 0 0 4px 0;
line-height: 1.3;
text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}
.post-item .post-subtitle {
font-size: 14px;
margin: 0 0 6px 0;
opacity: 0.9;
line-height: 1.2;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.post-item .post-date {
font-size: 12px;
opacity: 0.8;
}
/* Responsive */
@media (max-width: 1200px) {
.grid-container {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.featured-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.featured-post {
height: 300px;
}
.featured-post .post-overlay {
padding: 20px;
}
.featured-post .post-title {
font-size: 22px;
}
.grid-container {
grid-template-columns: repeat(2, 1fr);
}
.blog-container {
padding-top: 53px;
}
}
@media (max-width: 480px) {
.grid-container {
grid-template-columns: 1fr;
}
.featured-section {
padding: 20px 15px 40px;
}
.posts-grid {
padding: 0 15px 80px;
}
}
</style>