Apparence
Panier après redirection
Le problème
L'utilisateur choisit trois sièges, clique sur « Valider », et votre application l'envoie se connecter. Au retour, le plan est rechargé… vide. La sélection vivait en mémoire dans le widget, la navigation l'a effacée.
La solution en deux temps
Le widget expose ce qu'il faut pour sauvegarder puis restaurer :
getSelectedSeats()— l'état courant, avant de partirselectSeats(keys)— la restauration, au retouronReady— le moment exact où la restauration est possible
Avant de rediriger
js
// L'utilisateur part vers le login : on met la sélection de côté
function partirVersLogin() {
const keys = chart.getSelectedSeats().map(s => s.seatKey);
sessionStorage.setItem('mitoera_seats', JSON.stringify(keys));
window.location.href = '/login?next=' + encodeURIComponent(location.pathname);
}sessionStorage plutôt que localStorage
La sélection n'a de sens que pour la visite en cours. sessionStorage se vide à la fermeture de l'onglet — pas de panier fantôme qui ressurgit trois jours plus tard.
Au retour, dans onReady
js
const chart = new Mitoera.SeatingChart({
divId: 'mitoera-chart',
workspaceKey: 'pk_live_xxxxxxxx',
event: 'concert-12-mars',
onReady: () => {
const saved = JSON.parse(sessionStorage.getItem('mitoera_seats') || '[]');
if (!saved.length) return;
chart.selectSeats(saved); // repose les holds
sessionStorage.removeItem('mitoera_seats');
},
onSelectionChange: (seats) => majTotal(seats),
});
chart.render();selectSeats() repose les holds sur les sièges encore disponibles. Ce n'est pas une simple coloration visuelle : les places sont à nouveau bloquées pour cet utilisateur.
Gérer les sièges perdus entre-temps
Rien ne garantit que les trois sièges soient encore libres après un détour par le login. Comparez ce que vous avez demandé avec ce qui a effectivement été sélectionné :
js
onReady: () => {
const saved = JSON.parse(sessionStorage.getItem('mitoera_seats') || '[]');
if (!saved.length) return;
chart.selectSeats(saved);
sessionStorage.removeItem('mitoera_seats');
// Laisser au widget le temps d'appliquer, puis comparer
setTimeout(() => {
const obtenus = chart.getSelectedSeats().map(s => s.seatKey);
const perdus = saved.filter(k => !obtenus.includes(k));
if (perdus.length) {
afficherAlerte(
`${perdus.join(', ')} ${perdus.length > 1 ? 'ne sont plus disponibles' : 'n\'est plus disponible'}. ` +
`Merci de choisir d'autres places.`
);
}
}, 500);
},Ne réservez pas en silence
Si deux des trois sièges ont disparu, dites-le. Un utilisateur qui paie sans avoir vu que sa sélection a changé fera une réclamation.
Variante robuste : passer par votre serveur
Le sessionStorage suffit pour un détour par le login. Pour un tunnel plus long — plusieurs pages, retour depuis un PSP, reprise sur un autre appareil — stockez le panier côté serveur, rattaché à la session applicative.
ts
// Au départ vers le paiement
app.post('/api/panier', (req, res) => {
req.session.mitoera = {
eventId: req.body.eventId,
seatKeys: req.body.seatKeys,
holdToken: req.session.holdToken,
};
res.json({ ok: true });
});
// Au retour, la page relit le panier
app.get('/api/panier', (req, res) => {
res.json(req.session.mitoera ?? { seatKeys: [] });
});php
// Au départ vers le paiement
$session->set('mitoera', [
'eventId' => $data['eventId'],
'seatKeys' => $data['seatKeys'],
'holdToken' => $session->get('mitoera_hold'),
]);
// Au retour, la page relit le panier
return $this->json($session->get('mitoera') ?? ['seatKeys' => []]);Puis, côté page :
js
onReady: async () => {
const { seatKeys } = await fetch('/api/panier').then(r => r.json());
if (seatKeys.length) chart.selectSeats(seatKeys);
},Avantage supplémentaire : votre serveur détient le holdToken, donc il peut confirmer ou libérer la réservation même si l'utilisateur ferme son onglet.
À retenir
| Sauvegarder | getSelectedSeats() avant de quitter la page |
| Restaurer | selectSeats() dans onReady, pas avant |
| Vérifier | Comparer demandé et obtenu, prévenir en cas d'écart |
| Durée courte | sessionStorage |
| Tunnel long | Panier côté serveur |

