Scaffold global navigation aligned to routes plan

Build out the full web route map from music-selfhost-routes.md as
scaffolding (no functionality on new screens):

- Full route tree: /login, /albums/:id, /artists/:id, /playlists(+detail),
  /discover, /upload, metadata editor (single + batch), /storage/maintenance,
  /queue, nested /settings and /admin, and a 404.
- Sidebar rebuilt to the A1 spec with permission-gated Discover/Upload.
- ProtectedRoute gains requirePermission; Permission exported.
- AppShell wraps Outlet in a Suspense boundary for lazy routes.
- Reusable Placeholder + SubNav; Settings/Admin become nested layouts.
- Settings/Profile: wired language + theme selectors.
- Remove orphaned Home feature (web has no Home; / -> /library) and the
  now-unused house icon + nav.home keys.
- i18n keys (en + ru) and CSS for page-title/sub-nav.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Senko-san
2026-06-07 17:05:21 +03:00
parent e45bcef3a5
commit aed0572071
25 changed files with 603 additions and 541 deletions
+34 -1
View File
@@ -1,9 +1,9 @@
const en = {
nav: {
home: 'Home',
library: 'Library',
search: 'Search & download',
downloads: 'Downloads',
upload: 'Upload',
storage: 'Storage',
playlists: 'Playlists',
newPlaylist: 'New playlist',
@@ -145,6 +145,39 @@ const en = {
downloads: 'Downloads',
search: 'Search & Download',
storage: 'Storage',
login: 'Sign in',
artist: 'Artist',
playlists: 'Playlists',
upload: 'Upload files',
metadata: 'Edit metadata',
metadataBatch: 'Edit metadata (batch)',
storageMaintenance: 'Storage maintenance',
queue: 'Play queue',
},
settings: {
language: 'Language',
theme: 'Theme',
themeDark: 'Dark',
themeLight: 'Light',
tabs: {
profile: 'Profile',
playback: 'Playback',
scrobbling: 'Scrobbling',
instance: 'Instance',
},
},
admin: {
userDetail: 'User',
tabs: {
users: 'Users',
sources: 'Sources',
instance: 'Instance',
},
},
notFound: {
title: 'Page not found',
description: "This screen doesn't exist yet.",
backToLibrary: 'Back to library',
},
} as const;
+34 -1
View File
@@ -2,10 +2,10 @@ import type { Translations } from './en';
const ru: Translations = {
nav: {
home: 'Главная',
library: 'Библиотека',
search: 'Поиск и загрузка',
downloads: 'Загрузки',
upload: 'Загрузить',
storage: 'Хранилище',
playlists: 'Плейлисты',
newPlaylist: 'Новый плейлист',
@@ -147,6 +147,39 @@ const ru: Translations = {
downloads: 'Загрузки',
search: 'Поиск и загрузка',
storage: 'Хранилище',
login: 'Вход',
artist: 'Артист',
playlists: 'Плейлисты',
upload: 'Загрузка файлов',
metadata: 'Редактирование метаданных',
metadataBatch: 'Редактирование метаданных (массово)',
storageMaintenance: 'Обслуживание хранилища',
queue: 'Очередь воспроизведения',
},
settings: {
language: 'Язык',
theme: 'Тема',
themeDark: 'Тёмная',
themeLight: 'Светлая',
tabs: {
profile: 'Профиль',
playback: 'Воспроизведение',
scrobbling: 'Скробблинг',
instance: 'Сервер',
},
},
admin: {
userDetail: 'Пользователь',
tabs: {
users: 'Пользователи',
sources: 'Источники',
instance: 'Сервер',
},
},
notFound: {
title: 'Страница не найдена',
description: 'Этого экрана пока нет.',
backToLibrary: 'Вернуться в библиотеку',
},
};