import { useQuery } from "@tanstack/react-query"; import { Link } from "wouter"; import { type Article } from "@shared/schema"; import { format } from "date-fns"; import { de } from "date-fns/locale"; import { Eye, Play, Images } from "lucide-react"; import { Skeleton } from "@/components/ui/skeleton"; import Header from "@/components/header"; import Footer from "@/components/footer"; import AdSense from "@/components/adsense"; import { PhotoGalleryWidget } from "@/components/photo-gallery"; import { HoroscopeWidget } from "@/components/horoscope-widget"; import { RecipeWidget } from "@/components/recipe-widget"; import { NewsWidget } from "@/components/news-widget"; import { useState, useEffect, useCallback, useRef } from "react"; function SmartImage({ src, alt, className = "" }: { src: string; alt: string; className?: string }) { const imgRef = useRef(null); const [isPortrait, setIsPortrait] = useState(false); useEffect(() => { const img = new Image(); img.onload = () => { if (img.naturalHeight > img.naturalWidth * 1.2) { setIsPortrait(true); } }; img.src = src; }, [src]); if (isPortrait) { return (
{alt}
); } return ( {alt} ); } interface GalleryImage { folder: string; fileName: string; thumb: string; large: string; } function thumbUrl(src: string | null): string { if (!src) return "/images/article-1.png"; if (src.endsWith(".webp")) return src.replace(".webp", "-thumb.webp"); return src; } function timeAgo(date: Date): string { const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffH = Math.floor(diffMs / 3600000); const diffD = Math.floor(diffMs / 86400000); if (diffH < 1) return "Gerade eben"; if (diffH < 24) return `vor ${diffH} Std.`; if (diffD < 7) return `vor ${diffD} T.`; return format(date, "d. MMM yyyy", { locale: de }); } function HeroCard({ article }: { article: Article }) { const isVideo = article.category === "Video"; return (
{isVideo && (
)}
{article.category} {timeAgo(new Date(article.publishedAt))}

{article.title}

{article.excerpt}

); } function GalleryHeroCard({ images }: { images: GalleryImage[] }) { const [idx, setIdx] = useState(0); useEffect(() => { const timer = setInterval(() => setIdx((i) => (i + 1) % images.length), 10000); return () => clearInterval(timer); }, [images.length]); return (
Fotogalerie

Backstage & Events

{images.length} exklusive Fotos aus der Welt der Volksmusik

); } function MediumCard({ article }: { article: Article }) { const isVideo = article.category === "Video"; return (
{article.title}
{isVideo && (
)}
{article.author} {timeAgo(new Date(article.publishedAt))}

{article.title}

{article.excerpt}

{article.views.toLocaleString()}
); } function SideCard({ article }: { article: Article }) { const isVideo = article.category === "Video"; return (
{article.title}
{isVideo && (
)}
{article.author} {timeAgo(new Date(article.publishedAt))}

{article.title}

{article.excerpt}

); } function NativeAdCard() { return (
); } function TopStoriesList({ articles }: { articles: Article[] }) { return (

Top-Storys

{articles.slice(0, 5).map((article) => (

{article.title}

{article.author} {timeAgo(new Date(article.publishedAt))}
))}
); } function FeaturedCarousel({ articles, popular, galleryImages }: { articles: Article[]; popular?: Article[]; galleryImages?: GalleryImage[] }) { const hasGallery = galleryImages && galleryImages.length > 0; const articlePages = Math.min(5, Math.max(1, articles.length)); const total = articlePages + (hasGallery ? 1 : 0); const [page, setPage] = useState(0); const [paused, setPaused] = useState(false); const next = useCallback(() => { setPage((p) => (p + 1) % total); }, [total]); useEffect(() => { if (paused || total <= 1) return; const timer = setInterval(next, 8000); return () => clearInterval(timer); }, [paused, next, total]); const isGalleryPage = hasGallery && page === total - 1; const isWidePage = page === 1; let hero: Article | null = null; let side: Article[] = []; if (!isGalleryPage && articles.length > 0) { hero = articles[page % articles.length]; } if (articles.length > 0) { const offset = isGalleryPage ? 0 : 1; side = [ articles[(page + offset) % articles.length], articles[(page + offset + 1) % articles.length], ]; } return (
setPaused(true)} onMouseLeave={() => setPaused(false)}>
{isGalleryPage && galleryImages ? ( ) : hero ? ( ) : null}
{side.map((a) => ( ))}
{popular && popular.length > 0 && }
{total > 1 && (
{Array.from({ length: total }).map((_, i) => (
)}
); } function BentoSkeleton() { return (
); } export default function Home() { const { data: articles, isLoading } = useQuery({ queryKey: ["/api/articles"], }); const { data: popular } = useQuery({ queryKey: ["/api/articles/popular"], }); const { data: galleryImages } = useQuery({ queryKey: ["/api/gallery"], }); if (isLoading || !articles) { return (
); } const row2Left = articles.slice(0, 2); const row3Middle = articles.slice(2, 4); const row4Articles = articles.slice(4, 7); const row5Articles = articles.slice(7, 10); return (
{row2Left.map((a) => ( ))}
{row3Middle.map((a) => ( ))}
{row4Articles.length > 0 && (
{row4Articles.map((a) => ( ))}
)} {row5Articles.length > 0 && (
{row5Articles.map((a) => ( ))}
)}
); }