feat(ui): 3-Zeilen-Layout (Suche/Channel/Volume/Theme, Media-URL+Abspielen, Admin-Login); Enter-Start; Backend join bei URL-Play
This commit is contained in:
parent
6d4dba3ad3
commit
cfc3f899a2
3 changed files with 40 additions and 7 deletions
|
|
@ -133,7 +133,7 @@ export default function App() {
|
|||
)}
|
||||
</header>
|
||||
|
||||
<section className="controls glass">
|
||||
<section className="controls glass row1">
|
||||
<div className="control search">
|
||||
<input
|
||||
value={query}
|
||||
|
|
@ -173,8 +173,23 @@ export default function App() {
|
|||
<option value="rainbow">Rainbow Chaos</option>
|
||||
</select>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="controls glass row2">
|
||||
<div className="control" style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 8 }}>
|
||||
<input value={mediaUrl} onChange={(e) => setMediaUrl(e.target.value)} placeholder="YouTube/Instagram/MP3 URL..." />
|
||||
<input
|
||||
value={mediaUrl}
|
||||
onChange={(e) => setMediaUrl(e.target.value)}
|
||||
onKeyDown={async (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (!selected) { setError('Bitte Voice-Channel wählen'); return; }
|
||||
const [guildId, channelId] = selected.split(':');
|
||||
try { await playUrl(mediaUrl, guildId, channelId, volume); }
|
||||
catch (err: any) { setError(err?.message || 'Play-URL fehlgeschlagen'); }
|
||||
}
|
||||
}}
|
||||
placeholder="YouTube/Instagram/MP3 URL..."
|
||||
/>
|
||||
<button type="button" className="tab" onClick={async () => {
|
||||
if (!selected) { setError('Bitte Voice-Channel wählen'); return; }
|
||||
const [guildId, channelId] = selected.split(':');
|
||||
|
|
@ -182,7 +197,10 @@ export default function App() {
|
|||
catch (e: any) { setError(e?.message || 'Play-URL fehlgeschlagen'); }
|
||||
}}>▶ Abspielen</button>
|
||||
</div>
|
||||
{!isAdmin && (
|
||||
</section>
|
||||
|
||||
{!isAdmin && (
|
||||
<section className="controls glass row3">
|
||||
<div className="control" style={{ display: 'flex', gap: 8 }}>
|
||||
<input type="password" value={adminPwd} onChange={(e) => setAdminPwd(e.target.value)} placeholder="Admin Passwort" />
|
||||
<button type="button" className="tab" onClick={async () => {
|
||||
|
|
@ -191,8 +209,8 @@ export default function App() {
|
|||
else alert('Login fehlgeschlagen');
|
||||
}}>Login</button>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Admin Toolbar */}
|
||||
{isAdmin && (
|
||||
|
|
|
|||
|
|
@ -88,7 +88,10 @@ header p { opacity: .8; }
|
|||
}
|
||||
.badge { align-self: flex-start; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.18); padding: 6px 10px; border-radius: 999px; font-size: 13px; }
|
||||
|
||||
.controls { display: grid; grid-template-columns: 1fr minmax(240px, 300px) 220px 180px minmax(260px, 1fr); gap: 12px; align-items: center; margin-bottom: 18px; }
|
||||
.controls { display: grid; grid-template-columns: 1fr minmax(240px, 320px) 260px 200px; gap: 12px; align-items: center; margin-bottom: 12px; }
|
||||
.controls.row2 { grid-template-columns: minmax(400px, 1fr); }
|
||||
.controls.row3 { grid-template-columns: 1fr; }
|
||||
.controls.glass { padding: 18px; }
|
||||
.controls.glass {
|
||||
backdrop-filter: saturate(140%) blur(20px);
|
||||
background: linear-gradient(135deg, rgba(255,255,255,.14), rgba(255,255,255,.06));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue