151 lines
6.2 KiB
JavaScript
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>
|
|
)
|
|
}
|