From 5d6a2b0e0764ce506831b5ee366e03e1ef64c49b Mon Sep 17 00:00:00 2001 From: caporalCode Date: Sat, 12 Jul 2025 02:34:02 +0100 Subject: [PATCH 1/3] fix(app): news image bouncing --- app/globals.css | 121 ++- app/news/[id]/page.tsx | 191 ++--- app/news/page.tsx | 9 +- components/Sections/News.tsx | 79 +- package-lock.json | 57 +- yarn.lock | 1461 +++++++++++++--------------------- 6 files changed, 864 insertions(+), 1054 deletions(-) diff --git a/app/globals.css b/app/globals.css index 108c467..e045d9a 100644 --- a/app/globals.css +++ b/app/globals.css @@ -4,49 +4,54 @@ @custom-variant dark (&:is(.dark *)); :root { - --background: oklch(0.99 0.00 258.32); + --background: oklch(0.99 0 258.32); --foreground: oklch(0.28 0.04 260.03); - --card: oklch(1.00 0 0); + --card: oklch(1 0 0); --card-foreground: oklch(0.28 0.04 260.03); - --popover: oklch(1.00 0 0); + --popover: oklch(1 0 0); --popover-foreground: oklch(0.28 0.04 260.03); --primary: oklch(0.68 0.16 276.93); - --primary-foreground: oklch(1.00 0 0); + --primary-foreground: oklch(1 0 0); --secondary: oklch(0.79 0.12 45.79); --secondary-foreground: oklch(0.37 0.03 259.73); - --muted: oklch(0.97 0.00 264.54); + --muted: oklch(0.97 0 264.54); --muted-foreground: oklch(0.55 0.02 264.36); --accent: oklch(0.93 0.03 272.79); --accent-foreground: oklch(0.37 0.03 259.73); --destructive: oklch(0.64 0.21 25.33); - --destructive-foreground: oklch(1.00 0 0); + --destructive-foreground: oklch(1 0 0); --border: oklch(0.87 0.01 258.34); --input: oklch(0.87 0.01 258.34); - --ring: oklch(0.59 0.20 277.12); - --chart-1: oklch(0.59 0.20 277.12); + --ring: oklch(0.59 0.2 277.12); + --chart-1: oklch(0.59 0.2 277.12); --chart-2: oklch(0.51 0.23 276.97); --chart-3: oklch(0.46 0.21 277.02); - --chart-4: oklch(0.40 0.18 277.37); - --chart-5: oklch(0.36 0.14 278.70); - --sidebar: oklch(0.97 0.00 264.54); + --chart-4: oklch(0.4 0.18 277.37); + --chart-5: oklch(0.36 0.14 278.7); + --sidebar: oklch(0.97 0 264.54); --sidebar-foreground: oklch(0.28 0.04 260.03); - --sidebar-primary: oklch(0.59 0.20 277.12); - --sidebar-primary-foreground: oklch(1.00 0 0); + --sidebar-primary: oklch(0.59 0.2 277.12); + --sidebar-primary-foreground: oklch(1 0 0); --sidebar-accent: oklch(0.93 0.03 272.79); --sidebar-accent-foreground: oklch(0.37 0.03 259.73); --sidebar-border: oklch(0.87 0.01 258.34); - --sidebar-ring: oklch(0.59 0.20 277.12); + --sidebar-ring: oklch(0.59 0.2 277.12); --font-sans: Open Sans, sans-serif; --font-serif: Merriweather, serif; --font-mono: JetBrains Mono, monospace; --radius: 0.5rem; --shadow-2xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05); --shadow-xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05); - --shadow-sm: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 1px 2px -2px hsl(0 0% 0% / 0.10); - --shadow: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 1px 2px -2px hsl(0 0% 0% / 0.10); - --shadow-md: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 2px 4px -2px hsl(0 0% 0% / 0.10); - --shadow-lg: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 4px 6px -2px hsl(0 0% 0% / 0.10); - --shadow-xl: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 8px 10px -2px hsl(0 0% 0% / 0.10); + --shadow-sm: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1); + --shadow: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1); + --shadow-md: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 2px 4px -2px hsl(0 0% 0% / 0.1); + --shadow-lg: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 4px 6px -2px hsl(0 0% 0% / 0.1); + --shadow-xl: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 8px 10px -2px hsl(0 0% 0% / 0.1); --shadow-2xl: 0px 4px 8px -1px hsl(0 0% 0% / 0.25); } @@ -67,21 +72,21 @@ --accent-foreground: oklch(0.87 0.01 258.34); --destructive: oklch(0.64 0.21 25.33); --destructive-foreground: oklch(0.21 0.04 265.75); - --border: oklch(0.45 0.03 256.80); - --input: oklch(0.45 0.03 256.80); + --border: oklch(0.45 0.03 256.8); + --input: oklch(0.45 0.03 256.8); --ring: oklch(0.68 0.16 276.93); --chart-1: oklch(0.68 0.16 276.93); - --chart-2: oklch(0.59 0.20 277.12); + --chart-2: oklch(0.59 0.2 277.12); --chart-3: oklch(0.51 0.23 276.97); --chart-4: oklch(0.46 0.21 277.02); - --chart-5: oklch(0.40 0.18 277.37); + --chart-5: oklch(0.4 0.18 277.37); --sidebar: oklch(0.28 0.04 260.03); --sidebar-foreground: oklch(0.93 0.01 255.51); --sidebar-primary: oklch(0.68 0.16 276.93); --sidebar-primary-foreground: oklch(0.21 0.04 265.75); --sidebar-accent: oklch(0.37 0.03 259.73); --sidebar-accent-foreground: oklch(0.87 0.01 258.34); - --sidebar-border: oklch(0.45 0.03 256.80); + --sidebar-border: oklch(0.45 0.03 256.8); --sidebar-ring: oklch(0.68 0.16 276.93); --font-sans: Open Sans, sans-serif; --font-serif: Merriweather, serif; @@ -89,11 +94,16 @@ --radius: 0.5rem; --shadow-2xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05); --shadow-xs: 0px 4px 8px -1px hsl(0 0% 0% / 0.05); - --shadow-sm: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 1px 2px -2px hsl(0 0% 0% / 0.10); - --shadow: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 1px 2px -2px hsl(0 0% 0% / 0.10); - --shadow-md: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 2px 4px -2px hsl(0 0% 0% / 0.10); - --shadow-lg: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 4px 6px -2px hsl(0 0% 0% / 0.10); - --shadow-xl: 0px 4px 8px -1px hsl(0 0% 0% / 0.10), 0px 8px 10px -2px hsl(0 0% 0% / 0.10); + --shadow-sm: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1); + --shadow: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 1px 2px -2px hsl(0 0% 0% / 0.1); + --shadow-md: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 2px 4px -2px hsl(0 0% 0% / 0.1); + --shadow-lg: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 4px 6px -2px hsl(0 0% 0% / 0.1); + --shadow-xl: + 0px 4px 8px -1px hsl(0 0% 0% / 0.1), 0px 8px 10px -2px hsl(0 0% 0% / 0.1); --shadow-2xl: 0px 4px 8px -1px hsl(0 0% 0% / 0.25); } @@ -156,4 +166,57 @@ body { @apply bg-background text-foreground; } + + .dom-purify-content p { + margin-bottom: 1.25rem; /* More breathing room between paragraphs */ + } + + .dom-purify-content h2 { + margin-top: 2rem; + margin-bottom: 1rem; + font-size: 1.875rem; /* Tailwind: text-2xl */ + font-weight: 700; + border-bottom: 1px solid #e5e7eb; /* Tailwind gray-200 */ + padding-bottom: 0.25rem; + } + + .dom-purify-content h3 { + margin-top: 1.5rem; + font-size: 1.5rem; /* Tailwind: text-xl */ + font-weight: 600; + } + + .dom-purify-content ul, + .dom-purify-content ol { + padding-left: 1.25rem; + margin-bottom: 1.25rem; + } + + .dom-purify-content li { + margin-bottom: 0.5rem; + } + + .dom-purify-content img { + margin: 2rem auto; + display: block; + max-width: 100%; + max-height: 400px; + border-radius: 0.5rem; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1); + } + + .dom-purify-content hr { + margin: 3rem 0; + border: none; + height: 1px; + background-color: #e5e7eb; /* Tailwind gray-200 */ + } + + .dom-purify-content blockquote { + border-left: 4px solid #3b82f6; /* Tailwind blue-500 */ + padding-left: 1rem; + font-style: italic; + color: #6b7280; /* Tailwind gray-500 */ + margin: 1.5rem 0; + } } diff --git a/app/news/[id]/page.tsx b/app/news/[id]/page.tsx index f099276..73e0681 100644 --- a/app/news/[id]/page.tsx +++ b/app/news/[id]/page.tsx @@ -1,122 +1,121 @@ -export const dynamic = 'force-dynamic' +export const dynamic = "force-dynamic"; -import { apiClient } from '@/app/api/api-client' -import { formatDate } from '@/lib/utils' -import Link from 'next/link' -import { notFound } from 'next/navigation' -import DOMPurify from 'isomorphic-dompurify' -import { calculateReadingTime, formatReadingTime } from '@/lib/readingTime' -import { ChevronRight, Clock } from 'lucide-react' -import Image from 'next/image' +import { apiClient } from "@/app/api/api-client"; +import { formatDate } from "@/lib/utils"; +import Link from "next/link"; +import { notFound } from "next/navigation"; +import DOMPurify from "isomorphic-dompurify"; +import { calculateReadingTime, formatReadingTime } from "@/lib/readingTime"; +import { ChevronRight, Clock } from "lucide-react"; +import Image from "next/image"; interface UserPageProps { - params: Promise<{ id: string }> + params: Promise<{ id: string }>; } export default async function NewsPage({ params }: UserPageProps) { - const latestNews = await apiClient.newsArticles.findOne((await params).id) + const currentNews = await apiClient.newsArticles.findOne((await params).id); // Récupérer les articles récents pour le sidebar et la section "Plus d'articles" - const allNews = await apiClient.newsArticles.findAll() + const allNews = await apiClient.newsArticles.findAll(); // Exclure l'article courant des articles récents const recentArticles = allNews - .filter((article) => article.id !== (latestNews?.id || '')) - .slice(0, 4) + .filter((article) => article.id !== (currentNews?.id || "")) + .slice(0, 4); // Articles supplémentaires pour la section du bas const moreArticles = allNews .filter( (article) => - article.id !== (latestNews?.id || '') && + article.id !== (currentNews?.id || "") && !recentArticles.map((a) => a.id).includes(article.id) ) - .slice(0, 4) + .slice(0, 4); - if (!latestNews) { - notFound() + if (!currentNews) { + notFound(); } // Calculer le temps de lecture - const readingTime = calculateReadingTime(latestNews.content) - const formattedReadingTime = formatReadingTime(readingTime) + const readingTime = calculateReadingTime(currentNews.content); + const formattedReadingTime = formatReadingTime(readingTime); return ( -
-
-