feat: add hidden flag to specials
This commit is contained in:
@@ -15,6 +15,7 @@ interface Special {
|
||||
launchDate?: string;
|
||||
endDate?: string;
|
||||
curator?: string;
|
||||
hidden?: boolean;
|
||||
_count?: {
|
||||
songs: number;
|
||||
};
|
||||
@@ -119,6 +120,7 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
const [newSpecialLaunchDate, setNewSpecialLaunchDate] = useState('');
|
||||
const [newSpecialEndDate, setNewSpecialEndDate] = useState('');
|
||||
const [newSpecialCurator, setNewSpecialCurator] = useState('');
|
||||
const [newSpecialHidden, setNewSpecialHidden] = useState(false);
|
||||
|
||||
const [editingSpecialId, setEditingSpecialId] = useState<number | null>(null);
|
||||
const [editSpecialName, setEditSpecialName] = useState({ de: '', en: '' });
|
||||
@@ -129,6 +131,7 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
const [editSpecialLaunchDate, setEditSpecialLaunchDate] = useState('');
|
||||
const [editSpecialEndDate, setEditSpecialEndDate] = useState('');
|
||||
const [editSpecialCurator, setEditSpecialCurator] = useState('');
|
||||
const [editSpecialHidden, setEditSpecialHidden] = useState(false);
|
||||
|
||||
// News state
|
||||
const [news, setNews] = useState<News[]>([]);
|
||||
@@ -393,6 +396,7 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
launchDate: newSpecialLaunchDate || null,
|
||||
endDate: newSpecialEndDate || null,
|
||||
curator: newSpecialCurator || null,
|
||||
hidden: newSpecialHidden,
|
||||
}),
|
||||
});
|
||||
if (res.ok) {
|
||||
@@ -404,6 +408,7 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
setNewSpecialLaunchDate('');
|
||||
setNewSpecialEndDate('');
|
||||
setNewSpecialCurator('');
|
||||
setNewSpecialHidden(false);
|
||||
fetchSpecials();
|
||||
} else {
|
||||
const errorData = await res.json().catch(() => ({}));
|
||||
@@ -491,6 +496,7 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
setEditSpecialLaunchDate(special.launchDate ? new Date(special.launchDate).toISOString().split('T')[0] : '');
|
||||
setEditSpecialEndDate(special.endDate ? new Date(special.endDate).toISOString().split('T')[0] : '');
|
||||
setEditSpecialCurator(special.curator || '');
|
||||
setEditSpecialHidden(special.hidden || false);
|
||||
};
|
||||
|
||||
const saveEditedSpecial = async () => {
|
||||
@@ -516,6 +522,7 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
launchDate: editSpecialLaunchDate || null,
|
||||
endDate: editSpecialEndDate || null,
|
||||
curator: editSpecialCurator || null,
|
||||
hidden: editSpecialHidden,
|
||||
}),
|
||||
});
|
||||
if (res.ok) {
|
||||
@@ -1389,6 +1396,18 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
<label style={{ fontSize: '0.75rem', color: '#666' }}>{t('curator')}</label>
|
||||
<input type="text" placeholder={t('curator')} value={newSpecialCurator} onChange={e => setNewSpecialCurator(e.target.value)} className="form-input" />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<label style={{ fontSize: '0.75rem', color: '#666', visibility: 'hidden' }}>Hidden</label>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '0.25rem', height: '38px', cursor: 'pointer' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={newSpecialHidden}
|
||||
onChange={e => setNewSpecialHidden(e.target.checked)}
|
||||
style={{ width: '1rem', height: '1rem' }}
|
||||
/>
|
||||
Hidden
|
||||
</label>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-primary"
|
||||
@@ -1418,7 +1437,7 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
{getLocalizedValue(special.name, activeTab)} ({special._count?.songs || 0})
|
||||
{special.hidden && <span title="Hidden from navigation">👁️🗨️</span>} {getLocalizedValue(special.name, activeTab)} ({special._count?.songs || 0})
|
||||
</span>
|
||||
{special.subtitle && (
|
||||
<span
|
||||
@@ -1508,6 +1527,18 @@ export default function AdminPage({ params }: { params: { locale: string } }) {
|
||||
<label style={{ fontSize: '0.75rem', color: '#666' }}>{t('curator')}</label>
|
||||
<input type="text" value={editSpecialCurator} onChange={e => setEditSpecialCurator(e.target.value)} className="form-input" />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<label style={{ fontSize: '0.75rem', color: '#666', visibility: 'hidden' }}>Hidden</label>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '0.25rem', height: '38px', cursor: 'pointer' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={editSpecialHidden}
|
||||
onChange={e => setEditSpecialHidden(e.target.checked)}
|
||||
style={{ width: '1rem', height: '1rem' }}
|
||||
/>
|
||||
Hidden
|
||||
</label>
|
||||
</div>
|
||||
<button
|
||||
onClick={saveEditedSpecial}
|
||||
className="btn-primary"
|
||||
|
||||
@@ -43,7 +43,9 @@ export default async function Home({
|
||||
const genres = await prisma.genre.findMany({
|
||||
where: { active: true },
|
||||
});
|
||||
const specials = await prisma.special.findMany();
|
||||
const specials = await prisma.special.findMany({
|
||||
where: { hidden: false },
|
||||
});
|
||||
|
||||
// Sort in memory
|
||||
genres.sort((a, b) => getLocalizedValue(a.name, locale).localeCompare(getLocalizedValue(b.name, locale)));
|
||||
|
||||
@@ -86,6 +86,7 @@ export default async function SpecialPage({ params }: PageProps) {
|
||||
specials.sort((a, b) => getLocalizedValue(a.name, locale).localeCompare(getLocalizedValue(b.name, locale)));
|
||||
|
||||
const activeSpecials = specials.filter(s => {
|
||||
if (s.hidden) return false;
|
||||
const sStarted = !s.launchDate || s.launchDate <= now;
|
||||
const sEnded = s.endDate && s.endDate < now;
|
||||
return sStarted && !sEnded;
|
||||
|
||||
Reference in New Issue
Block a user