Files
2026-DEV-BUT3/src/pages/GroupDetailPage.jsx
T
2026-05-10 12:44:52 +02:00

156 lines
4.2 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useMemo, useState } from 'react'
import { Link, useParams } from 'react-router-dom'
import { useGroups } from '../context/GroupsContext.jsx'
function formatEUR(n) {
return new Intl.NumberFormat('fr-FR', {
style: 'currency',
currency: 'EUR',
maximumFractionDigits: 2,
}).format(Number(n) || 0)
}
function formatDate(iso) {
try {
return new Intl.DateTimeFormat('fr-FR', {
dateStyle: 'short',
timeStyle: 'short',
}).format(new Date(iso))
} catch {
return iso || '—'
}
}
export default function GroupDetailPage() {
const { groupId } = useParams()
const {
groups,
addGroupOrder,
getOrdersForGroup,
groupTotalEuros,
} = useGroups()
const group = useMemo(
() => groups.find((g) => g.id === String(groupId)),
[groups, groupId],
)
const lines = group ? getOrdersForGroup(group.id) : []
const total = group ? groupTotalEuros(group.id) : 0
const [contributor, setContributor] = useState('')
const [amount, setAmount] = useState('')
const [note, setNote] = useState('')
const [err, setErr] = useState(null)
const [ok, setOk] = useState(null)
function handleSubmit(e) {
e.preventDefault()
setErr(null)
setOk(null)
if (!group) return
try {
addGroupOrder(group.id, {
contributor,
amount,
note,
})
setContributor('')
setAmount('')
setNote('')
setOk('Contribution enregistrée (POST /api/groups/:id/orders en local).')
} catch (ex) {
setErr(ex?.message || 'Impossible denregistrer.')
}
}
if (!group) {
return (
<div className="groupes-page">
<p className="empty-state">Groupe introuvable.</p>
<Link to="/groupes" className="nav-link">
Liste des groupes
</Link>
</div>
)
}
return (
<div className="groupes-page">
<Link to="/groupes" className="nav-link book-detail-back">
Tous les groupes
</Link>
<h2 className="page-title">{group.name}</h2>
<p className="page-lead">
Pool actuel : <strong>{formatEUR(total)}</strong> · id{' '}
<code>{group.id.slice(0, 8)}</code>
</p>
{err ? (
<p className="form-error" role="alert">
{err}
</p>
) : null}
{ok ? <p className="form-notice">{ok}</p> : null}
<section className="order-panel">
<h3 className="panel-title">Participer à la commande groupée</h3>
<form className="review-form" onSubmit={handleSubmit}>
<label>
Pseudo / prénom
<input
value={contributor}
onChange={(e) => setContributor(e.target.value)}
placeholder="Marvin"
/>
</label>
<label>
Montant () optionnel pour la démo
<input
type="number"
min={0}
step="0.5"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="12.5"
/>
</label>
<label>
Note (ex. titres souhaités)
<textarea
rows={2}
value={note}
onChange={(e) => setNote(e.target.value)}
placeholder="2 romans SF…"
/>
</label>
<button type="submit" className="btn primary">
Envoyer ma participation (POST)
</button>
</form>
</section>
<section className="order-panel">
<h3 className="panel-title">Contributions</h3>
{lines.length === 0 ? (
<p className="empty-state">Personne na encore participé.</p>
) : (
<ul className="reviews-list">
{lines.map((o) => (
<li key={o.id} className="reviews-item">
<p className="reviews-meta">
<strong>{o.contributor}</strong> · {formatDate(o.createdAt)} ·{' '}
{formatEUR(o.amountEuros)}
</p>
{o.note ? (
<p className="reviews-text">{o.note}</p>
) : null}
</li>
))}
</ul>
)}
</section>
</div>
)
}