Fix build by redirecting /curator/specials to localized route
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useParams, useRouter, usePathname } from 'next/navigation';
|
import { useParams, useRouter, usePathname } from 'next/navigation';
|
||||||
import { useLocale, useTranslations } from 'next-intl';
|
import { useLocale, useTranslations } from 'next-intl';
|
||||||
|
|||||||
@@ -1,161 +1,13 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
// Root /curator/specials route without locale:
|
||||||
import { useLocale, useTranslations } from 'next-intl';
|
// redirect users to the default English locale version.
|
||||||
import { Link } from '@/lib/navigation';
|
|
||||||
import { getCuratorAuthHeaders } from '@/lib/curatorAuth';
|
|
||||||
import HelpTooltip from '@/components/HelpTooltip';
|
|
||||||
|
|
||||||
type LocalizedString = string | { de: string; en: string };
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
interface CuratorSpecialSummary {
|
|
||||||
id: number;
|
|
||||||
name: LocalizedString;
|
|
||||||
songCount: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function CuratorSpecialsPage() {
|
export default function CuratorSpecialsPage() {
|
||||||
const t = useTranslations('Curator');
|
redirect('/en/curator/specials');
|
||||||
const tHelp = useTranslations('CuratorHelp');
|
|
||||||
const locale = useLocale();
|
|
||||||
const [specials, setSpecials] = useState<CuratorSpecialSummary[]>([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchSpecials = async () => {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
const res = await fetch('/api/curator/specials', {
|
|
||||||
headers: getCuratorAuthHeaders(),
|
|
||||||
});
|
|
||||||
if (res.ok) {
|
|
||||||
const data = await res.json();
|
|
||||||
setSpecials(data);
|
|
||||||
} else if (res.status === 403) {
|
|
||||||
setError(t('noSpecialPermissions'));
|
|
||||||
} else {
|
|
||||||
setError('Failed to load specials');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
setError('Failed to load specials');
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchSpecials();
|
|
||||||
}, [t]);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
||||||
<p>{t('loadingData')}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
||||||
<p>{error}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (specials.length === 0) {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
||||||
<p>{t('noSpecialsInScope')}</p>
|
|
||||||
<div style={{ marginTop: '1.5rem' }}>
|
|
||||||
<Link
|
|
||||||
href="/curator"
|
|
||||||
style={{
|
|
||||||
padding: '0.5rem 1rem',
|
|
||||||
background: '#e5e7eb',
|
|
||||||
borderRadius: '0.5rem',
|
|
||||||
textDecoration: 'none',
|
|
||||||
color: '#111827',
|
|
||||||
fontSize: '0.9rem',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('backToDashboard')}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const resolveLocalized = (value: LocalizedString, locale: string): string => {
|
|
||||||
if (!value) return '';
|
|
||||||
if (typeof value === 'string') return value;
|
|
||||||
const loc = locale === 'de' || locale === 'en' ? locale : 'en';
|
|
||||||
return value[loc] ?? value.en ?? value.de;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '2rem', maxWidth: '900px', margin: '0 auto' }}>
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1.5rem' }}>
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
|
|
||||||
<h1 style={{ fontSize: '2rem', fontWeight: 'bold' }}>
|
|
||||||
{t('curateSpecialsTitle')}
|
|
||||||
</h1>
|
|
||||||
<HelpTooltip
|
|
||||||
shortText={tHelp('tooltipCurateSpecialsShort')}
|
|
||||||
longText={tHelp('tooltipCurateSpecialsLong')}
|
|
||||||
position="bottom"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Link
|
|
||||||
href="/curator"
|
|
||||||
style={{
|
|
||||||
padding: '0.5rem 1rem',
|
|
||||||
background: '#e5e7eb',
|
|
||||||
borderRadius: '0.5rem',
|
|
||||||
textDecoration: 'none',
|
|
||||||
color: '#111827',
|
|
||||||
fontSize: '0.9rem',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('backToDashboard')}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<p style={{ marginBottom: '1.5rem', color: '#4b5563' }}>
|
|
||||||
{t('curateSpecialsDescription')}
|
|
||||||
</p>
|
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))', gap: '1rem' }}>
|
|
||||||
{specials.map(special => (
|
|
||||||
<Link
|
|
||||||
key={special.id}
|
|
||||||
href={`/curator/specials/${special.id}`}
|
|
||||||
style={{
|
|
||||||
padding: '1rem',
|
|
||||||
borderRadius: '0.75rem',
|
|
||||||
border: '1px solid #e5e7eb',
|
|
||||||
background: 'white',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
textDecoration: 'none',
|
|
||||||
color: 'inherit',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.25rem' }}>
|
|
||||||
{resolveLocalized(special.name, String(locale))}
|
|
||||||
</h2>
|
|
||||||
<p style={{ fontSize: '0.875rem', color: '#6b7280' }}>
|
|
||||||
{t('curateSpecialSongCount', { count: special.songCount })}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div style={{ marginTop: '0.75rem', textAlign: 'right', fontSize: '0.875rem', color: '#4f46e5' }}>
|
|
||||||
{t('curateSpecialOpen')}
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user