Frontend-Redesign nach DESIGN.md: neues Dark-Theme mit grüner Akzentfarbe
- Neue Farbpalette: #0a0d0b Hintergrund, #111511 Surface, #1ed760 Akzent - Inter-Font via Google Fonts (400/500/600) - CSS Grid Layout: 240px Sidebar + 1fr Content + 88px Player Bar - Sidebar: neue Nav-Items mit Padding, Uppercase-Labels, grünes Logo-Icon - CoverImage: 2-Buchstaben-Kürzel mit 6 Cover-Placeholder-Farben - BookCard: Play-Overlay (34px), 3px Progress-Bar am Kartenrand - MiniPlayer: Player Bar mit 3-Spalten-Grid, 4px Progress-Track - Alle Pages und Komponenten auf neue Tokenfarben aktualisiert - BookDetail: Fehlermeldung wenn kein Match gefunden Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -37,36 +37,37 @@ export default function FileBrowser({ initialPath = '/', onSelect, onClose }: Pr
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/70 z-50 flex items-center justify-center p-4" onClick={onClose}>
|
||||
<div
|
||||
className="bg-surface border border-white/10 rounded-xl w-full max-w-lg shadow-2xl flex flex-col"
|
||||
className="bg-surface border border-divider rounded-xl w-full max-w-lg flex flex-col"
|
||||
style={{ maxHeight: '80vh' }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between px-4 py-3 border-b border-white/10 flex-shrink-0">
|
||||
<h3 className="text-sm font-semibold text-white">Ordner auswählen</h3>
|
||||
<button onClick={onClose} className="text-gray-400 hover:text-white">
|
||||
<div className="flex items-center justify-between px-4 py-3 border-b border-divider flex-shrink-0">
|
||||
<h3 className="text-ink" style={{ fontSize: '13px', fontWeight: 600 }}>Ordner auswählen</h3>
|
||||
<button onClick={onClose} className="text-muted hover:text-ink transition-colors">
|
||||
<X size={16} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Quick access */}
|
||||
<div className="flex gap-1 px-3 py-2 border-b border-white/10 flex-shrink-0 overflow-x-auto">
|
||||
<div className="flex gap-1 px-3 py-2 border-b border-divider flex-shrink-0 overflow-x-auto">
|
||||
{['/audiofiles', '/data', '/media', '/'].map((p) => (
|
||||
<button key={p} onClick={() => load(p)}
|
||||
className={`flex-shrink-0 px-2 py-1 rounded text-xs transition-colors ${path === p ? 'bg-primary/20 text-primary' : 'text-gray-500 hover:text-white hover:bg-white/5'}`}>
|
||||
className={`flex-shrink-0 px-2 py-1 rounded transition-colors ${path === p ? 'bg-primary-dim text-primary' : 'text-muted hover:text-ink hover:bg-card'}`}
|
||||
style={{ fontSize: '11px' }}>
|
||||
{p}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Current path */}
|
||||
<div className="px-4 py-2 bg-white/5 border-b border-white/10 flex items-center gap-2 flex-shrink-0">
|
||||
<div className="px-4 py-2 bg-card border-b border-divider flex items-center gap-2 flex-shrink-0">
|
||||
{parent && (
|
||||
<button onClick={() => load(parent)} className="text-gray-400 hover:text-white flex-shrink-0">
|
||||
<button onClick={() => load(parent)} className="text-muted hover:text-ink flex-shrink-0 transition-colors">
|
||||
<ChevronUp size={16} />
|
||||
</button>
|
||||
)}
|
||||
<p className="text-xs text-gray-300 font-mono truncate">{path}</p>
|
||||
<p className="text-muted font-mono truncate" style={{ fontSize: '11px' }}>{path}</p>
|
||||
</div>
|
||||
|
||||
{/* Entry list */}
|
||||
@@ -76,25 +77,27 @@ export default function FileBrowser({ initialPath = '/', onSelect, onClose }: Pr
|
||||
<Loader2 size={24} className="text-primary animate-spin" />
|
||||
</div>
|
||||
) : error ? (
|
||||
<p className="text-red-400 text-sm px-4 py-6">{error}</p>
|
||||
<p className="text-red-400 px-4 py-6" style={{ fontSize: '13px' }}>{error}</p>
|
||||
) : entries.length === 0 ? (
|
||||
<p className="text-gray-500 text-sm px-4 py-6">Ordner ist leer</p>
|
||||
<p className="text-muted px-4 py-6" style={{ fontSize: '13px' }}>Ordner ist leer</p>
|
||||
) : (
|
||||
entries.map((e) =>
|
||||
e.isDir ? (
|
||||
<button
|
||||
key={e.path}
|
||||
onClick={() => load(e.path)}
|
||||
className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-white/5 text-gray-300 hover:text-white text-sm text-left transition-colors"
|
||||
className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-card text-muted hover:text-ink text-left transition-colors"
|
||||
style={{ fontSize: '13px' }}
|
||||
>
|
||||
<Folder size={16} className="text-yellow-500 flex-shrink-0" />
|
||||
<span className="flex-1 truncate">{e.name}</span>
|
||||
<ChevronRight size={14} className="flex-shrink-0 text-gray-600" />
|
||||
<ChevronRight size={14} className="flex-shrink-0 text-muted2" />
|
||||
</button>
|
||||
) : (
|
||||
<div
|
||||
key={e.path}
|
||||
className="flex items-center gap-3 px-4 py-2 text-gray-600 text-sm"
|
||||
className="flex items-center gap-3 px-4 py-2 text-muted2"
|
||||
style={{ fontSize: '12px' }}
|
||||
>
|
||||
<FileAudio size={14} className="flex-shrink-0" />
|
||||
<span className="truncate">{e.name}</span>
|
||||
@@ -105,13 +108,14 @@ export default function FileBrowser({ initialPath = '/', onSelect, onClose }: Pr
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="flex items-center justify-between px-4 py-3 border-t border-white/10 flex-shrink-0">
|
||||
<button onClick={onClose} className="text-gray-400 text-sm hover:text-white">
|
||||
<div className="flex items-center justify-between px-4 py-3 border-t border-divider flex-shrink-0">
|
||||
<button onClick={onClose} className="text-muted hover:text-ink transition-colors" style={{ fontSize: '13px' }}>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button
|
||||
onClick={() => { onSelect(path); onClose() }}
|
||||
className="flex items-center gap-2 bg-primary text-black px-4 py-2 rounded-lg text-sm font-medium hover:bg-primary/80"
|
||||
className="flex items-center gap-2 bg-primary text-black px-4 py-2 rounded-lg font-medium hover:opacity-90 transition-opacity"
|
||||
style={{ fontSize: '13px' }}
|
||||
>
|
||||
<Check size={14} />
|
||||
Auswählen
|
||||
|
||||
Reference in New Issue
Block a user