You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
5.4 KiB
TypeScript

import { For, Show, createMemo, createSignal } from 'solid-js'
import Box from '@suid/material/Box'
import Button from '@suid/material/Button'
import Card from '@suid/material/Card'
import CardContent from '@suid/material/CardContent'
import Divider from '@suid/material/Divider'
import Stack from '@suid/material/Stack'
import Switch from '@suid/material/Switch'
import TextField from '@suid/material/TextField'
import Typography from '@suid/material/Typography'
import { useAuth } from '../hooks/useAuth'
import { loadGameHistory } from '../services/session'
function readInputValue(event: Event): string {
return (event.target as HTMLInputElement).value
}
export default function ProfileRoute() {
const { isAuthenticated, signInDemo, signOut } = useAuth()
const [name, setName] = createSignal(localStorage.getItem('kf.playerName') ?? '')
const [showHints, setShowHints] = createSignal(true)
const gameHistory = createMemo(() => loadGameHistory())
const stats = createMemo(() => {
const history = gameHistory()
const gamesPlayed = history.length
const totalScore = history.reduce((acc, item) => acc + item.finalScore, 0)
const averageScore = gamesPlayed > 0 ? Math.round((totalScore / gamesPlayed) * 10) / 10 : 0
const bestScore = history.reduce((best, item) => Math.max(best, item.finalScore), 0)
return { gamesPlayed, averageScore, bestScore }
})
const save = () => {
localStorage.setItem('kf.playerName', name().trim())
}
return (
<Box>
<Show
when={isAuthenticated()}
fallback={
<Card variant="outlined" sx={{ bgcolor: '#111827', borderColor: '#1f2937' }}>
<CardContent>
<Stack spacing={2}>
<Typography variant="h4" sx={{ fontWeight: 800 }}>
Profil
</Typography>
<Typography sx={{ opacity: 0.8 }}>Connexion requise pour accéder au profil joueur.</Typography>
<Button variant="contained" onClick={signInDemo}>
Se connecter (mode démo)
</Button>
</Stack>
</CardContent>
</Card>
}
>
<Stack spacing={2}>
<Card variant="outlined" sx={{ bgcolor: '#111827', borderColor: '#1f2937' }}>
<CardContent>
<Stack spacing={1}>
<Typography variant="h5" sx={{ fontWeight: 800 }}>
Statistiques joueur
</Typography>
<Typography>Parties jouées : {stats().gamesPlayed}</Typography>
<Typography>Score moyen : {stats().averageScore}</Typography>
<Typography>Meilleur score : {stats().bestScore}</Typography>
</Stack>
</CardContent>
</Card>
<Card variant="outlined" sx={{ bgcolor: '#111827', borderColor: '#1f2937' }}>
<CardContent>
<Stack spacing={1}>
<Typography variant="h5" sx={{ fontWeight: 800 }}>
Historique des parties
</Typography>
<Show
when={gameHistory().length > 0}
fallback={<Typography sx={{ opacity: 0.8 }}>Aucune partie enregistrée.</Typography>}
>
<For each={gameHistory().slice(0, 5)}>
{(item) => (
<Stack spacing={0.5}>
<Typography>
Score {item.finalScore} Réussite {item.successRate}% Durée {Math.floor(item.durationSec / 60)}m
</Typography>
<Divider />
</Stack>
)}
</For>
</Show>
</Stack>
</CardContent>
</Card>
<Card variant="outlined" sx={{ bgcolor: '#111827', borderColor: '#1f2937' }}>
<CardContent>
<Stack spacing={2}>
<Typography variant="h5" sx={{ fontWeight: 800 }}>
Paramètres
</Typography>
<TextField
label="Nom de joueur"
value={name()}
onInput={(e) => setName(readInputValue(e))}
fullWidth
InputLabelProps={{ style: { color: '#cbd5e1' } }}
InputProps={{ style: { color: '#e5e7eb' } }}
/>
<Stack direction="row" spacing={1} alignItems="center">
<Switch checked={showHints()} onChange={() => setShowHints((v) => !v)} />
<Typography>Afficher les indices pendant une partie</Typography>
</Stack>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
<Button variant="contained" onClick={save}>
Enregistrer
</Button>
<Button
variant="outlined"
onClick={() => {
localStorage.removeItem('kf.playerName')
setName('')
}}
>
Effacer le pseudo
</Button>
<Button variant="outlined" color="error" onClick={signOut}>
Se déconnecter
</Button>
</Stack>
</Stack>
</CardContent>
</Card>
</Stack>
</Show>
</Box>
)
}