76 lines
3.6 KiB
JavaScript
76 lines
3.6 KiB
JavaScript
// Rôle : fournit les modales globales liées aux toolboxes et confirmations.
|
|
import { useEffect, useState } from "react";
|
|
import { Icon } from "./Icon.jsx";
|
|
import { lockBodyScroll } from "../utils/bodyScrollLock.js";
|
|
|
|
function useModalScrollLock() {
|
|
useEffect(() => lockBodyScroll(), []);
|
|
}
|
|
|
|
export function ConfirmModal({ title, message, confirmLabel = "Confirmer", cancelLabel = "Annuler", danger = false, onClose }) {
|
|
useModalScrollLock();
|
|
return (
|
|
<div className="confirm-modal-root">
|
|
<div className="confirm-backdrop" onClick={() => onClose(false)} />
|
|
<section className="confirm-modal" role="dialog" aria-modal="true" aria-labelledby="confirm-title" aria-describedby="confirm-message">
|
|
<header><h2 id="confirm-title">{title}</h2></header>
|
|
<p id="confirm-message">{message}</p>
|
|
<footer>
|
|
<button onClick={() => onClose(false)}>{cancelLabel}</button>
|
|
<button className={danger ? "danger confirm-danger" : "primary"} onClick={() => onClose(true)}>{confirmLabel}</button>
|
|
</footer>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function NotificationToast({ message, position = "right", onClose }) {
|
|
return (
|
|
<div className={`notification-toast is-${position === "left" ? "left" : "right"}`} role="status" aria-live="polite">
|
|
<span>{message}</span>
|
|
<button type="button" onClick={onClose} aria-label="Fermer l'alerte" title="Fermer">
|
|
<Icon name="close" />
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function CreateToolboxModal({ gameId, initialName = "", onClose }) {
|
|
useModalScrollLock();
|
|
const [name, setName] = useState(initialName);
|
|
return (
|
|
<div className="confirm-modal-root">
|
|
<div className="confirm-backdrop" onClick={() => onClose("")} />
|
|
<section className="confirm-modal toolbox-create-modal" role="dialog" aria-modal="true" aria-labelledby="toolbox-create-title">
|
|
<header><h2 id="toolbox-create-title">{gameId ? "Créer et associer une toolbox" : "Nouvelle toolbox"}</h2></header>
|
|
<form onSubmit={(event) => {
|
|
event.preventDefault();
|
|
if (name.trim()) onClose(name.trim());
|
|
}}>
|
|
<label className="field"><span>Nom</span><input name="name" autoComplete="off" placeholder="Nom de la toolbox" required value={name} onChange={(event) => setName(event.target.value)} autoFocus /></label>
|
|
<footer><button type="button" onClick={() => onClose("")}>Annuler</button><button className="primary" type="submit">Créer</button></footer>
|
|
</form>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function LinkToolboxModal({ toolboxes, selectedId, onClose }) {
|
|
useModalScrollLock();
|
|
const [toolboxId, setToolboxId] = useState(selectedId);
|
|
return (
|
|
<div className="confirm-modal-root">
|
|
<div className="confirm-backdrop" onClick={() => onClose(null)} />
|
|
<section className="confirm-modal toolbox-link-modal" role="dialog" aria-modal="true" aria-labelledby="toolbox-link-title">
|
|
<header><h2 id="toolbox-link-title">Lier une toolbox</h2></header>
|
|
<form onSubmit={(event) => {
|
|
event.preventDefault();
|
|
onClose(toolboxId);
|
|
}}>
|
|
<label className="field"><span>Toolbox associée</span><select value={toolboxId} onChange={(event) => setToolboxId(event.target.value)} autoFocus><option value="">Aucune</option>{toolboxes.map((toolbox) => <option key={toolbox.id} value={toolbox.id}>{toolbox.name}</option>)}</select></label>
|
|
<footer><button type="button" onClick={() => onClose(null)}>Annuler</button><button className="primary" type="submit">Valider</button></footer>
|
|
</form>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|