import React from 'react'; import { Head, Link, usePage } from '@inertiajs/react'; import { useLocalizedRoutes } from '@/hooks/useLocalizedRoutes'; import { useTranslation } from 'react-i18next'; import MarketingLayout from '@/layouts/mainWebsite'; import { Card, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Separator } from '@/components/ui/separator'; import { Button } from '@/components/ui/button'; import { Alert, AlertDescription } from '@/components/ui/alert'; interface PostSummary { id: number; slug: string; title: string; excerpt?: string; featured_image?: string; published_at?: string; author?: { name?: string } | string; } interface PaginationLink { url: string | null; label: string; active: boolean; } interface Props { posts: { data: PostSummary[]; links: PaginationLink[]; current_page: number; last_page: number; }; } const Blog: React.FC = ({ posts }) => { const { localizedPath } = useLocalizedRoutes(); const { props } = usePage<{ supportedLocales?: string[] }>(); const supportedLocales = props.supportedLocales && props.supportedLocales.length > 0 ? props.supportedLocales : ['de', 'en']; const { t, i18n } = useTranslation('marketing'); const locale = i18n.language || 'de'; const articles = posts?.data ?? []; const isLandingLayout = posts.current_page === 1; const featuredPost = isLandingLayout ? articles[0] : null; const gridPosts = isLandingLayout ? articles.slice(1, 4) : []; const listPosts = isLandingLayout ? [] : articles; const dateLocale = locale === 'en' ? 'en-US' : 'de-DE'; const buildArticleHref = React.useCallback( (slug?: string | null) => { if (!slug) { return '#'; } return localizedPath(`/blog/${encodeURIComponent(slug)}`); }, [localizedPath] ); const formatPublishedDate = React.useCallback( (raw?: string) => { if (!raw) { return ''; } try { return new Date(raw).toLocaleDateString(dateLocale, { day: 'numeric', month: 'long', year: 'numeric', }); } catch (error) { console.warn('[Marketing Blog] Unable to parse date', { raw, error }); return raw; } }, [dateLocale] ); const resolvePaginationHref = React.useCallback( (raw?: string | null) => { if (!raw) { return null; } try { const parsed = new URL( raw, typeof window !== 'undefined' ? window.location.origin : 'http://localhost' ); const normalized = `${parsed.pathname}${parsed.search}`; const localePrefixRegex = new RegExp(`^/(${supportedLocales.join('|')})(/|$)`); if (localePrefixRegex.test(parsed.pathname)) { return normalized; } return localizedPath(normalized); } catch (error) { console.warn('[Marketing Blog] Fallback resolving pagination link', { raw, error }); return localizedPath(raw); } }, [localizedPath] ); const renderPagination = () => { if (!posts.links || posts.links.length <= 3) { return null; } return (
{posts.links.map((link, index) => { const href = resolvePaginationHref(link.url); if (!href) { return ( ); })}
); }; const renderPostMeta = (post: PostSummary) => (
{t('blog.by')} {typeof post.author === 'string' ? post.author : post.author?.name || t('blog.team')} {t('blog.published_at')} {formatPublishedDate(post.published_at)}
); const renderLandingGrid = () => { if (!featuredPost) { return ( {t('blog.empty')} ); } return (
{t('blog.posts_title')}

{featuredPost.title || 'Untitled'}

{featuredPost.excerpt || ''}

{renderPostMeta(featuredPost)}
{featuredPost.featured_image && ( {featuredPost.title} )} {!featuredPost.featured_image && (
Fotospiel Stories
)}
{gridPosts.length > 0 && (
{gridPosts.map((post) => ( {post.featured_image && (
{post.title}
)}

{post.title || 'Untitled'}

{post.excerpt || ''}

{renderPostMeta(post)} ))}
)}
); }; const renderListView = () => (
{listPosts.map((post) => (
{post.featured_image && ( {post.title} )}

{post.title || 'Untitled'}

{post.excerpt || ''}

{renderPostMeta(post)}
))} {listPosts.length === 0 && ( {t('blog.empty')} )}
); return (
Fotospiel Blog

{t('blog.hero_title')}

{t('blog.hero_description')}

{t('blog.posts_title')}

{isLandingLayout ? renderLandingGrid() : renderListView()} {renderPagination()}
); }; Blog.layout = (page: React.ReactNode) => page; export default Blog;