Files
Audiolib/frontend/src/components/player/MiniPlayer.tsx
Audiolib a756db9d96 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>
2026-05-26 17:04:42 +02:00

83 lines
2.9 KiB
TypeScript

import React from 'react'
import { Play, Pause, X } from 'lucide-react'
import { usePlayerStore } from '../../store/playerStore'
import CoverImage from '../common/CoverImage'
import { coverUrl } from '../../api/items'
export default function MiniPlayer() {
const { item, currentTime, duration, isPlaying, setPlaying, stop, setExpanded } = usePlayerStore()
if (!item) return null
const meta = item.media?.metadata || {}
const title = meta.title || item.relPath || ''
const author = meta.authors?.[0]?.name || ''
const pct = duration > 0 ? (currentTime / duration) * 100 : 0
return (
<div className="h-full flex flex-col bg-surface border-t border-divider">
{/* Progress track */}
<div className="bg-muted2 relative" style={{ height: '4px', borderRadius: '2px' }}>
<div
className="h-full bg-ink"
style={{ width: `${pct}%`, borderRadius: '2px', transition: 'width 0.5s linear' }}
/>
</div>
{/* 3-column grid */}
<div
className="flex-1 grid items-center"
style={{ gridTemplateColumns: '1fr auto 1fr', padding: '0 24px', gap: '16px' }}
>
{/* Left: cover + title */}
<div
className="flex items-center gap-3 cursor-pointer min-w-0"
onClick={() => setExpanded(true)}
>
<div className="w-10 h-10 flex-shrink-0 overflow-hidden" style={{ borderRadius: '6px' }}>
<CoverImage
src={item.media?.coverPath ? coverUrl(item.id) : null}
alt={title}
className="w-full h-full"
/>
</div>
<div className="min-w-0">
<p className="text-ink truncate" style={{ fontSize: '13px', fontWeight: 500 }}>{title}</p>
{author && <p className="text-muted truncate" style={{ fontSize: '12px' }}>{author}</p>}
</div>
</div>
{/* Center: play/pause */}
<button
className="flex items-center justify-center flex-shrink-0"
style={{
width: 40,
height: 40,
borderRadius: '50%',
background: '#e4ede5',
color: '#000',
transition: 'transform 0.1s',
}}
onMouseEnter={(e) => { e.currentTarget.style.transform = 'scale(1.06)'; e.currentTarget.style.background = '#fff' }}
onMouseLeave={(e) => { e.currentTarget.style.transform = 'scale(1)'; e.currentTarget.style.background = '#e4ede5' }}
onClick={() => setPlaying(!isPlaying)}
>
{isPlaying
? <Pause size={18} fill="currentColor" />
: <Play size={18} fill="currentColor" />
}
</button>
{/* Right: close */}
<div className="flex items-center justify-end">
<button
className="text-muted hover:text-ink transition-colors p-1.5"
onClick={stop}
>
<X size={18} />
</button>
</div>
</div>
</div>
)
}