Ajout fidelite_abo_pret_commande_groupe
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
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 d’enregistrer.')
|
||||
}
|
||||
}
|
||||
|
||||
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 n’a 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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user