import { useQueryClient } from '@tanstack/react-query'; import { router } from 'expo-router'; import { FlatList, Pressable, Text, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useHorsLigne } from '@/auth/session'; import { BoutonTel, EnteteTabs } from '@/composants/ui'; import { useFile, type Saisie } from '@/file/store'; import { abandonnerSaisie, rejouer, rejouerSurVersionAJour } from '@/file/synchro'; import { useTokens } from '@/theme/tokens'; /** Écran 7 de la maquette R4 : la file VISIBLE et honnête. Rejeu dans * l'ordre ; un conflit (verrou D2) arrête la file sur l'élément, montre le * message de l'API (qui, quand) et VOUS tranchez — rien n'est écrasé ni * perdu en silence. */ const ICONES: Record = { TRANSITION: '🏁', COCHE: '✓', BILAN: '📋', PHOTO: '🖼', }; export default function PageSynchro() { const t = useTokens(); const horsLigne = useHorsLigne(); const file = useFile(); const queryClient = useQueryClient(); const conflit = file.find((s) => s.statut === 'CONFLIT'); const heure = (iso: string) => new Intl.DateTimeFormat('fr-FR', { hour: '2-digit', minute: '2-digit' }).format(new Date(iso)); return ( Synchro {conflit ? 'arrêtée sur le conflit' : file.length ? 'rejouée dans l’ordre' : ''} {conflit ? ( ⚠ Conflit sur {conflit.otReference} {conflit.erreur ?? 'L’OT a été modifié pendant que vous étiez hors-ligne.'} Votre saisie (« {conflit.libelle} », {heure(conflit.creeA)}) est conservée telle quelle dans la file — rien n’est perdu. router.push(`/ot/${conflit.otId}`)} /> void rejouerSurVersionAJour(conflit.id, queryClient)} /> void abandonnerSaisie(conflit.id, queryClient)} /> ) : null} s.id} contentContainerStyle={{ gap: 8, paddingBottom: 12 }} ListEmptyComponent={ Rien en attente Toutes vos saisies sont sur le serveur. Les gestes faits hors-ligne apparaîtront ici, rejoués dans l’ordre au retour du réseau. } renderItem={({ item: s }) => ( {ICONES[s.type]} {s.libelle} {s.otReference} · {heure(s.creeA)} {s.statut === 'CONFLIT' ? 'conflit' : s.statut === 'ENVOI' ? 'envoi…' : 'en attente'} )} /> {file.length && !horsLigne ? ( void rejouer(queryClient)} style={{ backgroundColor: t.primaire, borderRadius: 10, padding: 12, alignItems: 'center' }} > Rejouer la file maintenant ) : null} {horsLigne ? ( Hors-ligne — la file repartira seule au retour du réseau. ) : null} ); }