Correction erreurs TypeScript
This commit is contained in:
parent
dc3fb4f3d8
commit
030298d311
15 changed files with 2050 additions and 1929 deletions
3857
package-lock.json
generated
3857
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,7 +13,7 @@
|
||||||
"check": "biome check --apply-unsafe ."
|
"check": "biome check --apply-unsafe ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/check": "^0.6.0",
|
"@astrojs/check": "^0.9.4",
|
||||||
"@astrojs/tailwind": "^5.1.0",
|
"@astrojs/tailwind": "^5.1.0",
|
||||||
"@biomejs/biome": "1.7.3",
|
"@biomejs/biome": "1.7.3",
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@tailwindcss/typography": "^0.5.13",
|
||||||
|
|
@ -22,11 +22,7 @@
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"tsx": "^4.21.0",
|
"tsx": "^4.21.0",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.7.3",
|
||||||
"webdav": "^5.8.0"
|
"webdav": "^5.8.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@astrojs/check": "^0.9.2",
|
|
||||||
"typescript": "^5.5.4"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ function getCurrentLocaleUrl(targetLocale: string): string {
|
||||||
</a>
|
</a>
|
||||||
<div class="absolute left-0 hidden mt-2 bg-white dark:bg-neutral-900 rounded-lg shadow-lg group-hover:block">
|
<div class="absolute left-0 hidden mt-2 bg-white dark:bg-neutral-900 rounded-lg shadow-lg group-hover:block">
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
{menu.children.map((child) => {
|
{menu.children?.map((child) => {
|
||||||
const childUrl = locale === 'fr' ? child.url : `/${locale}${child.url}`;
|
const childUrl = locale === 'fr' ? child.url : `/${locale}${child.url}`;
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
import { Image } from 'astro:assets';
|
import { Picture } from 'astro:assets';
|
||||||
import ScrollIndicator from './ScrollIndicator.astro';
|
import ScrollIndicator from './ScrollIndicator.astro';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -16,7 +16,7 @@ const { title, description, date, tags, coverImage, scrollTarget = '.info-sectio
|
||||||
|
|
||||||
{coverImage && (
|
{coverImage && (
|
||||||
<div class="hero-image">
|
<div class="hero-image">
|
||||||
<Image src={coverImage} alt={title} widths={[800, 1200, 1920]} formats={['webp', 'avif']} />
|
<Picture src={coverImage} alt={title} widths={[800, 1200, 1920]} formats={['webp']} />
|
||||||
<div class="hero-overlay">
|
<div class="hero-overlay">
|
||||||
<div class="hero-content">
|
<div class="hero-content">
|
||||||
<h1 class="album-title">{title}</h1>
|
<h1 class="album-title">{title}</h1>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import CategoryNav from './CategoryNav.astro';
|
import CategoryNav from './CategoryNav.astro';
|
||||||
import ScrollIndicator from './ScrollIndicator.astro';
|
import ScrollIndicator from './ScrollIndicator.astro';
|
||||||
import Lightbox from './Lightbox.astro';
|
import Lightbox from './Lightbox.astro';
|
||||||
import { Image } from 'astro:assets';
|
import { Picture } from 'astro:assets';
|
||||||
import { getEntry } from 'astro:content';
|
import { getEntry } from 'astro:content';
|
||||||
|
|
||||||
const { category } = Astro.props;
|
const { category } = Astro.props;
|
||||||
|
|
@ -51,7 +51,7 @@ const lightboxImages = images.map(img => ({
|
||||||
<!-- Image hero avec titre en overlay -->
|
<!-- Image hero avec titre en overlay -->
|
||||||
<header class="hero-cover">
|
<header class="hero-cover">
|
||||||
<div class="hero-image">
|
<div class="hero-image">
|
||||||
{images[0] && <Image src={images[0].src} alt={images[0].alt} widths={[800, 1200, 1920]} formats={['webp', 'avif']} class="hero-bg" />}
|
{images[0] && <Picture src={images[0].src} alt={images[0].alt} widths={[800, 1200, 1920]} formats={['webp']} class="hero-bg" />}
|
||||||
<div class="hero-overlay">
|
<div class="hero-overlay">
|
||||||
<div class="hero-content">
|
<div class="hero-content">
|
||||||
<h1 class="hero-title">
|
<h1 class="hero-title">
|
||||||
|
|
@ -71,11 +71,11 @@ const lightboxImages = images.map(img => ({
|
||||||
{images.map((image, index) => (
|
{images.map((image, index) => (
|
||||||
<div class="thumbnail-item">
|
<div class="thumbnail-item">
|
||||||
<a href="#" class="thumbnail-link" data-image-index={index}>
|
<a href="#" class="thumbnail-link" data-image-index={index}>
|
||||||
<Image
|
<Picture
|
||||||
src={image.src}
|
src={image.src}
|
||||||
alt={image.alt}
|
alt={image.alt}
|
||||||
widths={[300, 500, 800]}
|
widths={[300, 500, 800]}
|
||||||
formats={['webp', 'avif']}
|
formats={['webp']}
|
||||||
class="thumbnail-image"
|
class="thumbnail-image"
|
||||||
loading={index < 12 ? 'eager' : 'lazy'}
|
loading={index < 12 ? 'eager' : 'lazy'}
|
||||||
/>
|
/>
|
||||||
|
|
@ -97,8 +97,8 @@ let lastScrollY = window.scrollY;
|
||||||
let ticking = false;
|
let ticking = false;
|
||||||
|
|
||||||
function updateNavVisibility() {
|
function updateNavVisibility() {
|
||||||
const header = document.querySelector('.category-navigation');
|
const header = document.querySelector('.category-navigation') as HTMLElement | null;
|
||||||
const footer = document.querySelector('footer');
|
const footer = document.querySelector('footer') as HTMLElement | null;
|
||||||
const scrollY = window.scrollY;
|
const scrollY = window.scrollY;
|
||||||
|
|
||||||
if (scrollY > lastScrollY && scrollY > 100) {
|
if (scrollY > lastScrollY && scrollY > 100) {
|
||||||
|
|
|
||||||
|
|
@ -75,19 +75,37 @@ const categoryLabels: Record<string, string> = {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
lightboxData?: {
|
||||||
|
images: { src: string; alt: string; title?: string; category?: string }[];
|
||||||
|
albumTitle: string;
|
||||||
|
showCategory: boolean;
|
||||||
|
category: string;
|
||||||
|
categoryLabels: Record<string, string>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Lightbox {
|
class Lightbox {
|
||||||
|
images: { src: string; alt: string; title?: string; category?: string }[] = [];
|
||||||
|
currentIndex = 0;
|
||||||
|
lightbox: HTMLElement | null;
|
||||||
|
lightboxImage: HTMLImageElement | null;
|
||||||
|
lightboxTitle: HTMLElement | null;
|
||||||
|
lightboxCategory: HTMLElement | null;
|
||||||
|
lightboxCounter: HTMLElement | null;
|
||||||
|
albumTitle = '';
|
||||||
|
showCategory = false;
|
||||||
|
category = '';
|
||||||
|
categoryLabels: Record<string, string> = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.images = [];
|
|
||||||
this.currentIndex = 0;
|
|
||||||
this.lightbox = document.getElementById('lightbox');
|
this.lightbox = document.getElementById('lightbox');
|
||||||
this.lightboxImage = document.getElementById('lightbox-image');
|
this.lightboxImage = document.getElementById('lightbox-image') as HTMLImageElement | null;
|
||||||
this.lightboxTitle = document.getElementById('lightbox-title');
|
this.lightboxTitle = document.getElementById('lightbox-title');
|
||||||
this.lightboxCategory = document.getElementById('lightbox-category');
|
this.lightboxCategory = document.getElementById('lightbox-category');
|
||||||
this.lightboxCounter = document.getElementById('lightbox-counter');
|
this.lightboxCounter = document.getElementById('lightbox-counter');
|
||||||
this.albumTitle = '';
|
|
||||||
this.showCategory = false;
|
|
||||||
this.category = '';
|
|
||||||
this.categoryLabels = {};
|
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
import { Image } from 'astro:assets';
|
import { Picture } from 'astro:assets';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
images: {
|
images: {
|
||||||
|
|
@ -15,11 +15,11 @@ const { images, columns = 5 } = Astro.props;
|
||||||
<div class="masonry-gallery" style={`--columns: ${columns}`}>
|
<div class="masonry-gallery" style={`--columns: ${columns}`}>
|
||||||
{images.map((image, index) => (
|
{images.map((image, index) => (
|
||||||
<div class="gallery-item">
|
<div class="gallery-item">
|
||||||
<Image
|
<Picture
|
||||||
src={image.src}
|
src={image.src}
|
||||||
alt={image.alt}
|
alt={image.alt}
|
||||||
widths={[300, 500, 800]}
|
widths={[300, 500, 800]}
|
||||||
formats={['webp', 'avif']}
|
formats={['webp']}
|
||||||
data-index={index}
|
data-index={index}
|
||||||
loading={index < 12 ? 'eager' : 'lazy'}
|
loading={index < 12 ? 'eager' : 'lazy'}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
if (scrollArrow) {
|
if (scrollArrow) {
|
||||||
scrollArrow.addEventListener('click', () => {
|
scrollArrow.addEventListener('click', () => {
|
||||||
const targetSelector = scrollArrow.getAttribute('data-target');
|
const targetSelector = scrollArrow.getAttribute('data-target');
|
||||||
|
if (!targetSelector) return;
|
||||||
const targetElement = document.querySelector(targetSelector);
|
const targetElement = document.querySelector(targetSelector);
|
||||||
if (targetElement) {
|
if (targetElement) {
|
||||||
targetElement.scrollIntoView({
|
targetElement.scrollIntoView({
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
import { Image } from 'astro:assets';
|
import { Picture } from 'astro:assets';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
images: { src: ImageMetadata; alt: string }[];
|
||||||
|
}
|
||||||
|
|
||||||
const { images = [] } = Astro.props;
|
const { images = [] } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
@ -11,11 +15,11 @@ const { images = [] } = Astro.props;
|
||||||
class={`slide ${index === 0 ? 'active' : ''}`}
|
class={`slide ${index === 0 ? 'active' : ''}`}
|
||||||
data-index={index}
|
data-index={index}
|
||||||
>
|
>
|
||||||
<Image
|
<Picture
|
||||||
src={image.src}
|
src={image.src}
|
||||||
alt={image.alt}
|
alt={image.alt}
|
||||||
widths={[800, 1200, 1920]}
|
widths={[800, 1200, 1920]}
|
||||||
formats={['webp', 'avif']}
|
formats={['webp']}
|
||||||
class="slide-image"
|
class="slide-image"
|
||||||
loading={index < 3 ? 'eager' : 'lazy'}
|
loading={index < 3 ? 'eager' : 'lazy'}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
const allPosts = await getCollection("post");
|
const allPosts = await getCollection("blog");
|
||||||
|
|
||||||
const { count } = Astro.props;
|
const { count } = Astro.props;
|
||||||
|
|
||||||
|
|
|
||||||
14
src/content/blog/astro-aria.md
Normal file
14
src/content/blog/astro-aria.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
title: Aria - a minimalist Astro homepage template
|
||||||
|
description: Aria is a template for Astro
|
||||||
|
date: 2024-06-06
|
||||||
|
category: pro
|
||||||
|
---
|
||||||
|
|
||||||
|
[](https://github.com/ccbikai/astro-aria)
|
||||||
|
|
||||||
|
Aria is a template I found on [https://aria.devdojo.io/](https://aria.devdojo.io/). It's clean and beautiful, so I decided to use it for my own homepage and ported it to Astro.
|
||||||
|
|
||||||
|
It's already open source, so feel free to use it if you're interested.
|
||||||
|
|
||||||
|
<https://github.com/ccbikai/astro-aria>
|
||||||
|
|
@ -1,19 +1,30 @@
|
||||||
import { defineCollection, z, type ImageFunction } from "astro:content";
|
import { defineCollection, z, type ImageFunction } from "astro:content";
|
||||||
|
|
||||||
|
const formatDate = (date: Date, lang: string = 'fr') => {
|
||||||
|
const locales: Record<string, string> = { fr: 'fr-FR', en: 'en-US', ar: 'ar-SA' };
|
||||||
|
return date.toLocaleDateString(locales[lang] || 'fr-FR', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const blogCollection = defineCollection({
|
const blogCollection = defineCollection({
|
||||||
type: "content",
|
type: "content",
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
date: z.date(),
|
date: z.date(),
|
||||||
dateFormatted: z.string(),
|
|
||||||
category: z.enum(['pro', 'comedy', 'photo']),
|
category: z.enum(['pro', 'comedy', 'photo']),
|
||||||
tags: z.array(z.string()).optional(),
|
tags: z.array(z.string()).optional(),
|
||||||
image: z.string().optional(),
|
image: z.string().optional(),
|
||||||
imageAlt: z.string().optional(),
|
imageAlt: z.string().optional(),
|
||||||
draft: z.boolean().default(false),
|
draft: z.boolean().default(false),
|
||||||
lang: z.enum(['fr', 'en', 'ar']).default('fr'),
|
lang: z.enum(['fr', 'en', 'ar']).default('fr'),
|
||||||
}),
|
}).transform((data) => ({
|
||||||
|
...data,
|
||||||
|
dateFormatted: formatDate(data.date, data.lang),
|
||||||
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectsCollection = defineCollection({
|
const projectsCollection = defineCollection({
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export async function getStaticPaths() {
|
||||||
|
|
||||||
const { category } = Astro.params;
|
const { category } = Astro.params;
|
||||||
|
|
||||||
const categoryLabels = {
|
const categoryLabels: Record<string, string> = {
|
||||||
'blog': 'Blog',
|
'blog': 'Blog',
|
||||||
'portraits': 'Portraits',
|
'portraits': 'Portraits',
|
||||||
'places': 'Paysages',
|
'places': 'Paysages',
|
||||||
|
|
@ -28,7 +28,7 @@ const categoryLabels = {
|
||||||
'everyday': 'Quotidien'
|
'everyday': 'Quotidien'
|
||||||
};
|
};
|
||||||
|
|
||||||
const title = `Galerie ${categoryLabels[category] || category} - Jalil Arfaoui`;
|
const title = `Galerie ${category ? categoryLabels[category] || category : ''} - Jalil Arfaoui`;
|
||||||
---
|
---
|
||||||
|
|
||||||
<PhotoLayout title={title} enableScroll={true}>
|
<PhotoLayout title={title} enableScroll={true}>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import PhotoLayout from '../../../layouts/PhotoLayout.astro';
|
import PhotoLayout from '../../../layouts/PhotoLayout.astro';
|
||||||
import CategoryNav from '../../../components/photo/CategoryNav.astro';
|
import CategoryNav from '../../../components/photo/CategoryNav.astro';
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
import { Image } from 'astro:assets';
|
import { Picture } from 'astro:assets';
|
||||||
|
|
||||||
// Récupération des posts photo
|
// Récupération des posts photo
|
||||||
const allPhotoBlogPosts = await getCollection('photoBlogPosts');
|
const allPhotoBlogPosts = await getCollection('photoBlogPosts');
|
||||||
|
|
@ -35,7 +35,7 @@ const regularPosts = postsWithImages.filter(post => !post.data.featured);
|
||||||
<article class="featured-post">
|
<article class="featured-post">
|
||||||
<a href={`/photo/blog/${post.slug}`} class="post-link">
|
<a href={`/photo/blog/${post.slug}`} class="post-link">
|
||||||
<div class="post-image">
|
<div class="post-image">
|
||||||
{post.resolvedCoverImage && <Image src={post.resolvedCoverImage} alt={post.data.title} widths={[600, 900, 1200]} formats={['webp', 'avif']} />}
|
{post.resolvedCoverImage && <Picture src={post.resolvedCoverImage} alt={post.data.title} widths={[600, 900, 1200]} formats={['webp']} />}
|
||||||
<div class="post-overlay">
|
<div class="post-overlay">
|
||||||
<div class="post-content">
|
<div class="post-content">
|
||||||
<span class="post-badge">À la une</span>
|
<span class="post-badge">À la une</span>
|
||||||
|
|
@ -64,7 +64,7 @@ const regularPosts = postsWithImages.filter(post => !post.data.featured);
|
||||||
{regularPosts.map(post => (
|
{regularPosts.map(post => (
|
||||||
<article class="post-item">
|
<article class="post-item">
|
||||||
<a href={`/photo/blog/${post.slug}`} class="post-link">
|
<a href={`/photo/blog/${post.slug}`} class="post-link">
|
||||||
{post.resolvedCoverImage && <Image src={post.resolvedCoverImage} alt={post.data.title} widths={[400, 600, 800]} formats={['webp', 'avif']} />}
|
{post.resolvedCoverImage && <Picture src={post.resolvedCoverImage} alt={post.data.title} widths={[400, 600, 800]} formats={['webp']} />}
|
||||||
<div class="post-overlay">
|
<div class="post-overlay">
|
||||||
<div class="overlay-content">
|
<div class="overlay-content">
|
||||||
<h3 class="post-title">{post.data.title}</h3>
|
<h3 class="post-title">{post.data.title}</h3>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const postEntries = await getCollection("post");
|
const postEntries = await getCollection("blog");
|
||||||
return postEntries.map((entry) => ({
|
return postEntries.map((entry) => ({
|
||||||
params: { slug: entry.slug },
|
params: { slug: entry.slug },
|
||||||
props: { entry },
|
props: { entry },
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue