Ajout des pages code et théâtre/acting en FR, EN et AR. Création de vraies routes localisées /en/photo et /ar/تصوير au lieu du hack ?lang=. Extraction de composants partagés (PhotoHomeContent, PhotoBlogIndexContent, PhotoBlogPostContent, PhotoAlbumContent) pour éviter la duplication entre langues. Traduction des catégories photo (16 fichiers JSON), de la navigation, du footer et des aria-labels. Routes AR avec slugs arabes (/ar/تصوير/مدونة, /ar/تصوير/ألبومات).
119 lines
3 KiB
Text
119 lines
3 KiB
Text
---
|
|
import PhotoLayout from '../../../layouts/PhotoLayout.astro';
|
|
import CategoryNav from '../CategoryNav.astro';
|
|
import AlbumHeader from '../AlbumHeader.astro';
|
|
import MasonryGallery from '../MasonryGallery.astro';
|
|
import Lightbox from '../Lightbox.astro';
|
|
import { getPostBaseSlug, type Locale } from '../../../utils/i18n';
|
|
|
|
interface Props {
|
|
post: any;
|
|
lang?: Locale;
|
|
}
|
|
|
|
const { post, lang = 'fr' } = Astro.props;
|
|
|
|
// Importer toutes les images du dossier photos
|
|
const allImages = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/photos/blog/**/*.{jpg,jpeg,png,webp}');
|
|
|
|
const { Content } = await post.render();
|
|
|
|
const baseSlug = getPostBaseSlug(post.id);
|
|
|
|
// Construire le chemin de l'album avec l'année
|
|
const year = post.data.date.getFullYear();
|
|
const albumPath = `/src/assets/images/photos/blog/${year}/${baseSlug}/`;
|
|
const albumImages = Object.keys(allImages)
|
|
.filter(path => path.startsWith(albumPath))
|
|
.sort();
|
|
|
|
// Résoudre la cover image depuis le glob
|
|
const coverPath = `/src/assets/images/photos/blog/${year}/${baseSlug}/${post.data.coverImage}`;
|
|
const coverImageLoader = allImages[coverPath];
|
|
const coverImage = coverImageLoader ? (await coverImageLoader()).default : undefined;
|
|
|
|
// Résoudre les images de la galerie
|
|
const galleryImages = await Promise.all(
|
|
albumImages.map(async (imagePath) => {
|
|
const loader = allImages[imagePath];
|
|
const img = await loader();
|
|
const filename = imagePath.split('/').pop() || '';
|
|
return {
|
|
src: img.default,
|
|
alt: filename.replace(/\.[^/.]+$/, '').replace(/-/g, ' ').replace(/^\d+-/, ''),
|
|
};
|
|
})
|
|
);
|
|
|
|
// Données pour la lightbox
|
|
const lightboxImages = galleryImages.map(img => ({
|
|
src: img.src.src,
|
|
alt: img.alt
|
|
}));
|
|
---
|
|
|
|
<PhotoLayout title={`${post.data.title} - Blog Photo - Jalil Arfaoui`} enableScroll={true} lang={lang}>
|
|
<div class="album-container">
|
|
<CategoryNav currentCategory="blog" opaque={false} lang={lang} />
|
|
|
|
<AlbumHeader
|
|
title={post.data.title}
|
|
description={post.data.description}
|
|
date={new Date(post.data.date)}
|
|
tags={post.data.tags}
|
|
coverImage={coverImage}
|
|
scrollTarget="#album-content"
|
|
lang={lang}
|
|
/>
|
|
|
|
<div id="album-content">
|
|
{post.body && (
|
|
<div class="post-content">
|
|
<Content />
|
|
</div>
|
|
)}
|
|
|
|
<MasonryGallery images={galleryImages} />
|
|
</div>
|
|
</div>
|
|
|
|
<Lightbox images={lightboxImages} albumTitle={post.data.title} lang={lang} />
|
|
</PhotoLayout>
|
|
|
|
<style>
|
|
.album-container {
|
|
background: #000;
|
|
color: #fff;
|
|
min-height: 100vh;
|
|
padding-top: var(--header-height, 53px);
|
|
}
|
|
|
|
.post-content {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 0 20px 40px;
|
|
line-height: 1.6;
|
|
text-align: center;
|
|
}
|
|
|
|
.post-content :global(h1),
|
|
.post-content :global(h2),
|
|
.post-content :global(h3) {
|
|
margin: 2em 0 1em 0;
|
|
font-weight: 600;
|
|
color: white;
|
|
}
|
|
|
|
.post-content :global(p) {
|
|
margin: 1.5em 0;
|
|
color: rgba(255, 255, 255, 0.9);
|
|
font-size: 16px;
|
|
}
|
|
|
|
.post-content :global(img) {
|
|
width: 100%;
|
|
height: auto;
|
|
border-radius: 8px;
|
|
margin: 2em 0;
|
|
}
|
|
</style>
|