138 lines
4.5 KiB
TypeScript
138 lines
4.5 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { useParams, useRouter, usePathname } from 'next/navigation';
|
|
import { useLocale, useTranslations } from 'next-intl';
|
|
import CurateSpecialEditor, { CurateSpecial } from '@/components/CurateSpecialEditor';
|
|
import { getCuratorAuthHeaders } from '@/lib/curatorAuth';
|
|
|
|
export default function CuratorSpecialEditorPage() {
|
|
const params = useParams();
|
|
const router = useRouter();
|
|
const pathname = usePathname();
|
|
const urlLocale = pathname?.split('/')[1] as 'de' | 'en' | undefined;
|
|
const intlLocale = useLocale() as 'de' | 'en';
|
|
const locale: 'de' | 'en' = urlLocale === 'de' || urlLocale === 'en' ? urlLocale : intlLocale;
|
|
const t = useTranslations('Curator');
|
|
|
|
const specialId = params?.id as string;
|
|
|
|
const [special, setSpecial] = useState<CurateSpecial | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const fetchSpecial = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const res = await fetch(`/api/curator/specials/${specialId}`, {
|
|
headers: getCuratorAuthHeaders(),
|
|
});
|
|
if (res.status === 403) {
|
|
setError(t('specialForbidden'));
|
|
return;
|
|
}
|
|
if (!res.ok) {
|
|
setError('Failed to load special');
|
|
return;
|
|
}
|
|
const data = await res.json();
|
|
setSpecial(data);
|
|
} catch (e) {
|
|
setError('Failed to load special');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (specialId) {
|
|
fetchSpecial();
|
|
}
|
|
}, [specialId, t]);
|
|
|
|
const handleSaveStartTime = async (songId: number, startTime: number) => {
|
|
const res = await fetch(`/api/curator/specials/${specialId}/songs`, {
|
|
method: 'PUT',
|
|
headers: {
|
|
...getCuratorAuthHeaders(),
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ songId, startTime }),
|
|
});
|
|
if (res.status === 403) {
|
|
setError(t('specialForbidden'));
|
|
} else if (!res.ok) {
|
|
setError('Failed to save changes');
|
|
}
|
|
};
|
|
|
|
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>
|
|
<button
|
|
onClick={() => router.push(`/${locale}/curator`)}
|
|
style={{
|
|
marginTop: '1rem',
|
|
padding: '0.5rem 1rem',
|
|
borderRadius: '0.5rem',
|
|
border: 'none',
|
|
background: '#e5e7eb',
|
|
cursor: 'pointer',
|
|
}}
|
|
>
|
|
{t('backToDashboard')}
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!special) {
|
|
return (
|
|
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
<p>{t('specialNotFound')}</p>
|
|
<button
|
|
onClick={() => router.push(`/${locale}/curator`)}
|
|
style={{
|
|
marginTop: '1rem',
|
|
padding: '0.5rem 1rem',
|
|
borderRadius: '0.5rem',
|
|
border: 'none',
|
|
background: '#e5e7eb',
|
|
cursor: 'pointer',
|
|
}}
|
|
>
|
|
{t('backToDashboard')}
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<CurateSpecialEditor
|
|
special={special}
|
|
locale={locale}
|
|
onBack={() => router.push(`/${locale}/curator/specials`)}
|
|
onSaveStartTime={handleSaveStartTime}
|
|
backLabel={t('backToCuratorSpecials')}
|
|
headerPrefix={t('curateSpecialHeaderPrefix')}
|
|
noSongsHint={t('curateSpecialNoSongs')}
|
|
noSongsSubHint={t('curateSpecialNoSongsSub')}
|
|
instructionsText={t('curateSpecialInstructions')}
|
|
savingLabel={t('saving')}
|
|
saveChangesLabel={t('saveChanges')}
|
|
savedLabel={t('saved')}
|
|
/>
|
|
);
|
|
}
|
|
|
|
|