Fix admin regressions from Biome refactor: theme init, mobile nav, i18n.
Local Build and Deploy / deploy (push) Successful in 54s
Local Build and Deploy / deploy (push) Successful in 54s
Restore valid browser JS in theme-init, close mobile sidebar on navigation, and split autoDjForm title/trackTitle across locales. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
59b63d6e70
commit
bae543baf6
23 files changed
+87
-44
No files matched your search
@@ -1,8 +1,8 @@
|
||||
(() => {
|
||||
let theme: string | null = null;
|
||||
let theme = null;
|
||||
let defaultDark = false;
|
||||
let navbarColor: string | null = null;
|
||||
let navbarTextColor: string | null = null;
|
||||
let navbarColor = null;
|
||||
let navbarTextColor = null;
|
||||
try {
|
||||
theme = localStorage.getItem("theme");
|
||||
const dd = document.querySelector('meta[name="theme-default-dark"]');
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import { Menu, X } from "lucide-react";
|
||||
import { type ReactNode, useEffect, useState } from "react";
|
||||
import {
|
||||
createContext,
|
||||
type ReactNode,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
|
||||
const AdminMobileContext = createContext<{ close: () => void }>({
|
||||
close: () => {},
|
||||
});
|
||||
|
||||
export function useAdminMobile() {
|
||||
return useContext(AdminMobileContext);
|
||||
}
|
||||
|
||||
export function AdminMobileWrapper({
|
||||
sidebar,
|
||||
@@ -11,6 +27,8 @@ export function AdminMobileWrapper({
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const close = useCallback(() => setOpen(false), []);
|
||||
const mobile = useMemo(() => ({ close }), [close]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
@@ -22,6 +40,7 @@ export function AdminMobileWrapper({
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<AdminMobileContext.Provider value={mobile}>
|
||||
<div className="min-h-screen bg-[var(--admin-canvas)] flex flex-col lg:flex-row">
|
||||
{/* Mobile header */}
|
||||
<div
|
||||
@@ -72,5 +91,6 @@ export function AdminMobileWrapper({
|
||||
{/* Content */}
|
||||
<div className="flex flex-col flex-1 min-w-0">{children}</div>
|
||||
</div>
|
||||
</AdminMobileContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import type { ReactNode } from "react";
|
||||
import { useAdminMobile } from "@/components/admin/admin-mobile-wrapper";
|
||||
|
||||
/**
|
||||
* Sidebar link that highlights when its route is active. "/admin" matches
|
||||
@@ -19,6 +20,7 @@ export function AdminNavLink({
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const pathname = usePathname() ?? "";
|
||||
const { close } = useAdminMobile();
|
||||
const active =
|
||||
href === "/admin"
|
||||
? pathname === "/admin"
|
||||
@@ -27,6 +29,7 @@ export function AdminNavLink({
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
onClick={close}
|
||||
aria-current={active ? "page" : undefined}
|
||||
className={`group flex items-center gap-2.5 rounded-xl px-3 py-2 text-sm no-underline transition-colors duration-150
|
||||
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--admin-accent)] focus-visible:ring-offset-1 focus-visible:ring-offset-[var(--admin-sidebar-background)] ${
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Запазване на настройките за точки"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Заглавие",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Резервен плейлист (radio_auto_dj_playlist), през който радиото се върти, когато няма DJ на живо. Подредени по ред на сортиране и след това по заглавие.",
|
||||
"dbError": "Плейлистът на AutoDJ не можа да се зареди (няма налична база данни).",
|
||||
"tracks": "Писти",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "неактивен",
|
||||
"deactivate": "Деактивирайте",
|
||||
"activate": "Активирайте",
|
||||
"delete": "Изтриване"
|
||||
"delete": "Изтриване",
|
||||
"trackTitle": "Заглавие"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ модериране",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Uložte nastavení bodů"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Název",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Záložní seznam skladeb (radio_auto_dj_playlist) rádio rotuje, když nevysílá žádný živý DJ. Seřazeno podle pořadí řazení a poté názvu.",
|
||||
"dbError": "Nelze načíst seznam stop AutoDJ (databáze není k dispozici).",
|
||||
"tracks": "Skladby",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "neaktivní",
|
||||
"deactivate": "Deaktivovat",
|
||||
"activate": "Aktivovat",
|
||||
"delete": "Smazat"
|
||||
"delete": "Smazat",
|
||||
"trackTitle": "Název"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ moderování",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Gem pointindstillinger"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Titel",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Fallback-afspilningsliste (radio_auto_dj_playlist), som radioen roterer igennem, når ingen live-dj streamer. Bestilles efter sorteringsrækkefølge og derefter titel.",
|
||||
"dbError": "Kunne ikke indlæse AutoDJ-afspilningslisten (databasen er ikke tilgængelig).",
|
||||
"tracks": "Spor",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "inaktiv",
|
||||
"deactivate": "Deaktiver",
|
||||
"activate": "Aktiver",
|
||||
"delete": "Slet"
|
||||
"delete": "Slet",
|
||||
"trackTitle": "Titel"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ moderation",
|
||||
|
||||
@@ -1630,7 +1630,7 @@
|
||||
"save": "Punkteeinstellungen speichern"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Title",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Fallback playlist (radio_auto_dj_playlist) the radio rotates through when no live DJ is streaming. Ordered by sort order then title.",
|
||||
"dbError": "Could not load the AutoDJ playlist (database unavailable).",
|
||||
"tracks": "Tracks",
|
||||
@@ -1660,7 +1660,8 @@
|
||||
"inactiveLabel": "inactive",
|
||||
"deactivate": "Deactivate",
|
||||
"activate": "Activate",
|
||||
"delete": "Delete"
|
||||
"delete": "Delete",
|
||||
"trackTitle": "Title"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderation",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Αποθήκευση ρυθμίσεων πόντων"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Τίτλος",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Εναλλακτική λίστα αναπαραγωγής (radio_auto_dj_playlist) το ραδιόφωνο περιστρέφεται όταν δεν υπάρχει ζωντανός DJ σε ροή. Ταξινόμηση κατά σειρά ταξινόμησης και κατόπιν τίτλου.",
|
||||
"dbError": "Δεν ήταν δυνατή η φόρτωση της λίστας αναπαραγωγής AutoDJ (μη διαθέσιμη βάση δεδομένων).",
|
||||
"tracks": "Κομμάτια",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "ανενεργός",
|
||||
"deactivate": "Απενεργοποίηση",
|
||||
"activate": "Ενεργοποίηση",
|
||||
"delete": "Διαγραφή"
|
||||
"delete": "Διαγραφή",
|
||||
"trackTitle": "Τίτλος"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderation",
|
||||
|
||||
@@ -1630,7 +1630,7 @@
|
||||
"save": "Guardar configuración de puntos"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Title",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Fallback playlist (radio_auto_dj_playlist) the radio rotates through when no live DJ is streaming. Ordered by sort order then title.",
|
||||
"dbError": "Could not load the AutoDJ playlist (database unavailable).",
|
||||
"tracks": "Tracks",
|
||||
@@ -1660,7 +1660,8 @@
|
||||
"inactiveLabel": "inactive",
|
||||
"deactivate": "Deactivate",
|
||||
"activate": "Activate",
|
||||
"delete": "Delete"
|
||||
"delete": "Delete",
|
||||
"trackTitle": "Title"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderation",
|
||||
|
||||
@@ -1630,7 +1630,7 @@
|
||||
"save": "Enregistrer les paramètres de points"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Title",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Fallback playlist (radio_auto_dj_playlist) the radio rotates through when no live DJ is streaming. Ordered by sort order then title.",
|
||||
"dbError": "Could not load the AutoDJ playlist (database unavailable).",
|
||||
"tracks": "Tracks",
|
||||
@@ -1660,7 +1660,8 @@
|
||||
"inactiveLabel": "inactive",
|
||||
"deactivate": "Deactivate",
|
||||
"activate": "Activate",
|
||||
"delete": "Delete"
|
||||
"delete": "Delete",
|
||||
"trackTitle": "Title"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderation",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Spremi postavke bodova"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Naslov",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Zamjenski popis za reprodukciju (radio_auto_dj_playlist) kroz koji se radio vrti kada nijedan DJ ne emitira uživo. Poredano prema redoslijedu sortiranja pa naslovu.",
|
||||
"dbError": "Nije moguće učitati AutoDJ popis za reprodukciju (baza podataka nije dostupna).",
|
||||
"tracks": "Pjesme",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "neaktivan",
|
||||
"deactivate": "Deaktiviraj",
|
||||
"activate": "Aktiviraj",
|
||||
"delete": "Izbriši"
|
||||
"delete": "Izbriši",
|
||||
"trackTitle": "Naslov"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ moderiranje",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Mentse el a pontbeállításokat"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Cím",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Tartalék lejátszási lista (radio_auto_dj_playlist) a rádió végigpörög, ha nincs élő DJ. Rendezési sorrend, majd cím szerint.",
|
||||
"dbError": "Nem sikerült betölteni az AutoDJ lejátszási listát (az adatbázis nem érhető el).",
|
||||
"tracks": "Pályák",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "inaktív",
|
||||
"deactivate": "Deaktiválás",
|
||||
"activate": "Aktiválja",
|
||||
"delete": "Törölje"
|
||||
"delete": "Törölje",
|
||||
"trackTitle": "Cím"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ moderálás",
|
||||
|
||||
@@ -1630,7 +1630,7 @@
|
||||
"save": "Salva impostazioni punti"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Title",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Fallback playlist (radio_auto_dj_playlist) the radio rotates through when no live DJ is streaming. Ordered by sort order then title.",
|
||||
"dbError": "Could not load the AutoDJ playlist (database unavailable).",
|
||||
"tracks": "Tracks",
|
||||
@@ -1660,7 +1660,8 @@
|
||||
"inactiveLabel": "inactive",
|
||||
"deactivate": "Deactivate",
|
||||
"activate": "Activate",
|
||||
"delete": "Delete"
|
||||
"delete": "Delete",
|
||||
"trackTitle": "Title"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderation",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Lagre poenginnstillinger"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Tittel",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Reservespilleliste (radio_auto_dj_playlist) radioen roterer gjennom når ingen live DJ strømmer. Sortert etter sorteringsrekkefølge og deretter tittel.",
|
||||
"dbError": "Kunne ikke laste AutoDJ-spillelisten (database utilgjengelig).",
|
||||
"tracks": "Spor",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "inaktiv",
|
||||
"deactivate": "Deaktiver",
|
||||
"activate": "Aktiver",
|
||||
"delete": "Slett"
|
||||
"delete": "Slett",
|
||||
"trackTitle": "Tittel"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ-moderasjon",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Zapisz ustawienia punktów"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Tytuł",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Zastępcza lista odtwarzania (radio_auto_dj_playlist) radio zmienia się, gdy żaden DJ nie transmituje na żywo. Uporządkowane według kolejności sortowania, a następnie tytułu.",
|
||||
"dbError": "Nie można załadować listy odtwarzania AutoDJ (baza danych jest niedostępna).",
|
||||
"tracks": "Utwory",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "nieaktywny",
|
||||
"deactivate": "Dezaktywuj",
|
||||
"activate": "Aktywuj",
|
||||
"delete": "Usuń"
|
||||
"delete": "Usuń",
|
||||
"trackTitle": "Tytuł"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "Moderacja DJ-a",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Salvar configurações de pontos"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Título",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Lista de reprodução alternativa (radio_auto_dj_playlist) pela qual o rádio alterna quando nenhum DJ ao vivo está transmitindo. Ordenado por ordem de classificação e depois por título.",
|
||||
"dbError": "Não foi possível carregar a playlist do AutoDJ (banco de dados indisponível).",
|
||||
"tracks": "Faixas",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "inativo",
|
||||
"deactivate": "Desativar",
|
||||
"activate": "Ativar",
|
||||
"delete": "Excluir"
|
||||
"delete": "Excluir",
|
||||
"trackTitle": "Título"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "Moderação de DJ",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Salvați setările punctelor"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Titlu",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Lista de redare alternativă (radio_auto_dj_playlist) prin care radioul se rotește atunci când niciun DJ live nu este transmis în flux. Ordonat după ordine de sortare, apoi titlu.",
|
||||
"dbError": "Nu s-a putut încărca lista de redare AutoDJ (baza de date indisponibilă).",
|
||||
"tracks": "Urme",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "inactiv",
|
||||
"deactivate": "Dezactivați",
|
||||
"activate": "Activați",
|
||||
"delete": "Ștergeți"
|
||||
"delete": "Ștergeți",
|
||||
"trackTitle": "Titlu"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "Moderație DJ",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Save points settings"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Title",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Fallback playlist (radio_auto_dj_playlist) the radio rotates through when no live DJ is streaming. Ordered by sort order then title.",
|
||||
"dbError": "Could not load the AutoDJ playlist (database unavailable).",
|
||||
"tracks": "Tracks",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "inactive",
|
||||
"deactivate": "Deactivate",
|
||||
"activate": "Activate",
|
||||
"delete": "Delete"
|
||||
"delete": "Delete",
|
||||
"trackTitle": "Title"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderation",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Uložte nastavenia bodov"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Názov",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Záložný zoznam skladieb (radio_auto_dj_playlist) rádio rotuje, keď nevysiela žiadny živý DJ. Zoradené podľa zoradenia a potom podľa názvu.",
|
||||
"dbError": "Nepodarilo sa načítať zoznam skladieb AutoDJ (databáza nie je k dispozícii).",
|
||||
"tracks": "Skladby",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "neaktívne",
|
||||
"deactivate": "Deaktivovať",
|
||||
"activate": "Aktivovať",
|
||||
"delete": "Odstrániť"
|
||||
"delete": "Odstrániť",
|
||||
"trackTitle": "Názov"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "Moderovanie DJ",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Сачувајте подешавања поена"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Наслов",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Резервна листа за репродукцију (радио_ауто_дј_плаилист) радио ротира када ниједан ДЈ не емитује уживо. Поредано по редоследу сортирања, а затим наслову.",
|
||||
"dbError": "Није могуће учитати АутоДЈ листу за репродукцију (база података није доступна).",
|
||||
"tracks": "Стазе",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "неактиван",
|
||||
"deactivate": "Деактивирај",
|
||||
"activate": "Активирај",
|
||||
"delete": "Избриши"
|
||||
"delete": "Избриши",
|
||||
"trackTitle": "Наслов"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "ДЈ Модератион",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Spara poänginställningar"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Titel",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Reservspellista (radio_auto_dj_playlist) som radion roterar genom när ingen live-DJ strömmar. Beställs efter sorteringsordning sedan titel.",
|
||||
"dbError": "Det gick inte att ladda AutoDJ-spellistan (databasen är inte tillgänglig).",
|
||||
"tracks": "Spår",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "inaktiv",
|
||||
"deactivate": "Inaktivera",
|
||||
"activate": "Aktivera",
|
||||
"delete": "Ta bort"
|
||||
"delete": "Ta bort",
|
||||
"trackTitle": "Titel"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderering",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Puan ayarlarını kaydet"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Başlık",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Geri dönüş çalma listesi (radio_auto_dj_playlist) hiçbir canlı DJ akışı olmadığında radyo döner. Sıralama düzenine ve ardından başlığa göre sıralanır.",
|
||||
"dbError": "AutoDJ çalma listesi yüklenemedi (veritabanı mevcut değil).",
|
||||
"tracks": "Parçalar",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "aktif değil",
|
||||
"deactivate": "Devre dışı bırak",
|
||||
"activate": "Etkinleştir",
|
||||
"delete": "Sil"
|
||||
"delete": "Sil",
|
||||
"trackTitle": "Başlık"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "DJ Moderasyon",
|
||||
|
||||
@@ -1666,7 +1666,7 @@
|
||||
"save": "Зберегти налаштування балів"
|
||||
},
|
||||
"autoDjForm": {
|
||||
"title": "Назва",
|
||||
"title": "Radio AutoDJ",
|
||||
"subtitle": "Запасний список відтворення (radio_auto_dj_playlist), у якому радіо обертається, коли ді-джей не транслює пряму трансляцію. Упорядковано за порядком сортування, а потім за назвою.",
|
||||
"dbError": "Не вдалося завантажити список відтворення AutoDJ (база даних недоступна).",
|
||||
"tracks": "Доріжки",
|
||||
@@ -1696,7 +1696,8 @@
|
||||
"inactiveLabel": "неактивний",
|
||||
"deactivate": "Дезактивувати",
|
||||
"activate": "активувати",
|
||||
"delete": "Видалити"
|
||||
"delete": "Видалити",
|
||||
"trackTitle": "Назва"
|
||||
},
|
||||
"moderationPage": {
|
||||
"title": "Модерація DJ",
|
||||
|
||||
Reference in new issue
Block a user