mitai-jinkendo/frontend/src/pages/SetupScreen.jsx
Lars Stommer 89b6c0b072
Some checks are pending
Deploy to Raspberry Pi / deploy (push) Waiting to run
Build Test / build-frontend (push) Waiting to run
Build Test / lint-backend (push) Waiting to run
feat: initial commit – Mitai Jinkendo v9a
2026-03-16 13:35:11 +01:00

151 lines
6.2 KiB
JavaScript

import { useState } from 'react'
import { Check } from 'lucide-react'
import { useAuth } from '../context/AuthContext'
const COLORS = ['#1D9E75','#378ADD','#D85A30','#EF9F27','#7F77DD','#D4537E','#639922','#888780']
export default function SetupScreen() {
const { setup } = useAuth()
const [form, setForm] = useState({
name: '', pin: '', pin2: '',
avatar_color: COLORS[0],
sex: 'm', height: '',
auth_type: 'pin',
session_days: 30,
})
const [error, setError] = useState(null)
const [saving, setSaving] = useState(false)
const set = (k,v) => setForm(f=>({...f,[k]:v}))
const handleSetup = async () => {
if (!form.name.trim()) return setError('Bitte Name eingeben')
if (form.pin.length < 4) return setError('PIN mind. 4 Zeichen')
if (form.pin !== form.pin2) return setError('PINs stimmen nicht überein')
setSaving(true); setError(null)
try {
await setup({
name: form.name.trim(),
pin: form.pin,
avatar_color: form.avatar_color,
sex: form.sex,
height: parseFloat(form.height)||178,
auth_type: form.auth_type,
session_days: form.session_days,
})
} catch(e) {
setError(e.message)
} finally { setSaving(false) }
}
const initials = form.name.split(' ').map(n=>n[0]).join('').toUpperCase().slice(0,2)||'?'
return (
<div style={{minHeight:'100vh',display:'flex',flexDirection:'column',alignItems:'center',
justifyContent:'center',background:'var(--bg)',padding:24}}>
<div style={{width:'100%',maxWidth:360}}>
<div style={{textAlign:'center',marginBottom:28}}>
<div style={{fontSize:32,fontWeight:800,color:'var(--accent)'}}>BodyTrack</div>
<div style={{fontSize:15,color:'var(--text3)',marginTop:4}}>Erste Einrichtung</div>
<div style={{fontSize:12,color:'var(--text3)',marginTop:8,lineHeight:1.5}}>
Erstelle deinen Admin-Account. Du kannst danach weitere Profile anlegen.
</div>
</div>
{/* Avatar preview */}
<div style={{display:'flex',justifyContent:'center',marginBottom:20}}>
<div style={{width:64,height:64,borderRadius:'50%',background:form.avatar_color,
display:'flex',alignItems:'center',justifyContent:'center',
fontSize:24,fontWeight:700,color:'white'}}>
{initials}
</div>
</div>
<div className="card" style={{padding:20}}>
<div className="form-row">
<label className="form-label">Name</label>
<input type="text" className="form-input" placeholder="Dein Name"
value={form.name} onChange={e=>set('name',e.target.value)} autoFocus/>
<span className="form-unit"/>
</div>
<div style={{marginBottom:12}}>
<div style={{fontSize:12,color:'var(--text3)',marginBottom:6}}>Avatar-Farbe</div>
<div style={{display:'flex',gap:6,flexWrap:'wrap'}}>
{COLORS.map(c=>(
<div key={c} onClick={()=>set('avatar_color',c)}
style={{width:28,height:28,borderRadius:'50%',background:c,cursor:'pointer',
border:`3px solid ${form.avatar_color===c?'white':'transparent'}`,
boxShadow:form.avatar_color===c?`0 0 0 2px ${c}`:'none'}}/>
))}
</div>
</div>
<div className="form-row">
<label className="form-label">Geschlecht</label>
<select className="form-select" value={form.sex} onChange={e=>set('sex',e.target.value)}>
<option value="m">Männlich</option>
<option value="f">Weiblich</option>
</select>
</div>
<div className="form-row">
<label className="form-label">Größe</label>
<input type="number" className="form-input" placeholder="178" min={100} max={250}
value={form.height} onChange={e=>set('height',e.target.value)}/>
<span className="form-unit">cm</span>
</div>
<div style={{borderTop:'1px solid var(--border)',margin:'14px 0'}}/>
<div className="form-row">
<label className="form-label">Login-Typ</label>
<select className="form-select" value={form.auth_type} onChange={e=>set('auth_type',e.target.value)}>
<option value="pin">4-stellige PIN</option>
<option value="password">Passwort</option>
</select>
</div>
<div className="form-row">
<label className="form-label">{form.auth_type==='pin'?'PIN':'Passwort'}</label>
<input type="password" className="form-input"
placeholder={form.auth_type==='pin'?'4-stellig':'Mind. 4 Zeichen'}
maxLength={form.auth_type==='pin'?4:undefined}
value={form.pin} onChange={e=>set('pin',e.target.value)}/>
<span className="form-unit"/>
</div>
<div className="form-row">
<label className="form-label">Bestätigen</label>
<input type="password" className="form-input" placeholder="Wiederholen"
maxLength={form.auth_type==='pin'?4:undefined}
value={form.pin2} onChange={e=>set('pin2',e.target.value)}
onKeyDown={e=>e.key==='Enter'&&handleSetup()}/>
<span className="form-unit"/>
</div>
<div className="form-row">
<label className="form-label">Eingeloggt</label>
<select className="form-select" value={form.session_days}
onChange={e=>set('session_days',parseInt(e.target.value))}>
<option value={7}>7 Tage</option>
<option value={30}>30 Tage</option>
<option value={0}>Immer</option>
</select>
</div>
{error && (
<div style={{padding:'8px 12px',background:'#FCEBEB',borderRadius:8,
fontSize:13,color:'#D85A30',marginBottom:10}}>{error}</div>
)}
<button className="btn btn-primary btn-full" onClick={handleSetup} disabled={saving}>
{saving
? <><div className="spinner" style={{width:14,height:14}}/> Einrichten</>
: <><Check size={15}/> Admin-Account erstellen</>}
</button>
</div>
</div>
</div>
)
}