/* ============================================================
exemple-mobile-saisie-app.jsx — partie 1
Écrans du smartphone (Login, Profile, Form, SwipeList).
La partie Doc + ROOT est dans exemple-mobile-saisie-doc.jsx.
============================================================ */
const { useState: uMS, useEffect: eMS } = React;
/* ============================================================
ÉCRAN 1 — Login
============================================================ */
function ScreenLogin({ onLogin, showToast }) {
const [email, setEmail] = uMS('');
const [pwd, setPwd] = uMS('');
return (
);
}
/* ============================================================
ÉCRAN 2 — Profile (avec bouton Paramètres haut-droite)
============================================================ */
function ScreenProfile({ openSettings }) {
return (
} />
Marc Dupont
admin · marc@exemple.com
● connecté
premium
{}} />
{}} />
{}} />
{}} />
{}} />
{}} />
);
}
/* ============================================================
ÉCRAN 3 — Form (formulaire de saisie complet)
============================================================ */
function ScreenForm({ showToast, openSheet }) {
const [title, setTitle] = uMS('');
const [date, setDate] = uMS('2026-05-21');
const [time, setTime] = uMS('14:30');
const [body, setBody] = uMS('');
const [category, setCategory] = uMS('');
const [priority, setPriority] = uMS('normal');
const [tags, setTags] = uMS({ urgent: false, perso: true, travail: false });
const [confirmed, setConfirmed] = uMS(false);
const [media, setMedia] = uMS([]);
const onMedia = (kind, data) => {
if (kind === 'gps' && data && data.lat) {
setMedia([...media, { kind: 'gps', label: `GPS · ${data.lat.toFixed(4)}, ${data.lon.toFixed(4)}` }]);
} else if (data && data.name) {
setMedia([...media, { kind, label: `${kind} · ${data.name}` }]);
} else {
showToast(`${kind} sélectionné`);
}
};
return (
showToast('Retour')}
right={
} />
{Object.entries({ urgent: 'Urgent', perso: 'Perso', travail: 'Travail' }).map(([k, v]) => (
setTags({ ...tags, [k]: c })}
label={v} />
))}
{media.length > 0 && (
{media.map((m, i) => (
📎 {m.label}
))}
)}
{}}
placeholder="123456"
keyboard="numeric"
autocomplete="one-time-code"
maxLength={6} icon="bell" />
showToast('Note enregistrée')}>
Enregistrer la note
);
}
/* ============================================================
ÉCRAN 4 — Liste avec SwipeableRow
============================================================ */
function ScreenSwipe({ showToast }) {
const [items, setItems] = uMS([
{ id: 1, title: 'Sauvegarde serveur OK', from: 'cron@srv', time: '14:02', unread: true },
{ id: 2, title: 'Latence élevée détectée', from: 'monitoring', time: '13:58', unread: true },
{ id: 3, title: 'Rappel : réunion équipe', from: 'agenda', time: '11:30', unread: false },
{ id: 4, title: 'Mise à jour disponible', from: 'systeme', time: '09:14', unread: false },
{ id: 5, title: 'Nouveau hôte sur le réseau', from: 'ipwatch', time: '08:42', unread: true },
]);
return (
{items.map((it) => (
showToast(`Ouvrir : ${it.title}`)}
rightActions={[
{ label: 'Lu', icon: 'play', color: 'var(--info)',
onClick: () => setItems(items.map((x) => x.id === it.id ? { ...x, unread: false } : x)) },
{ label: 'Épingl.', icon: 'bell', color: 'var(--accent)',
onClick: () => showToast('Épinglé') },
]}
leftActions={[
{ label: 'Archiv.', icon: 'folder', color: 'var(--ok)',
onClick: () => { setItems(items.filter((x) => x.id !== it.id)); showToast('Archivé'); } },
{ label: 'Suppr.', icon: 'close', color: 'var(--err)',
onClick: () => { setItems(items.filter((x) => x.id !== it.id)); showToast('Supprimé'); } },
]}>
{it.from}
{it.time}
{it.title}
))}
{items.length === 0 && (
Plus de notifications — fais un swipe sur une ligne ←→ pour voir les actions.
)}
← swipe gauche : archiver/supprimer · swipe droit : marquer lu/épingler →
);
}
Object.assign(window, { ScreenLogin, ScreenProfile, ScreenForm, ScreenSwipe });