import { router } from 'expo-router'; import { FlatList, Pressable, RefreshControl, Text, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { WORK_ORDER_PRIORITY_LABELS, WORK_ORDER_STATUS_LABELS, WORK_ORDER_TYPE_LABELS, type WorkOrderPriority, type WorkOrderStatus, } from '@siop/shared'; import { useWorkOrders } from '@/api/exploitation'; import { EnteteTabs } from '@/composants/ui'; import { triJournee } from '@/lib/journee'; import { useTokens, type Tokens } from '@/theme/tokens'; /** Ordres de travail — maquette « mobile ouvert à tous les rôles », écran 4 : * à la différence de « Ma journée » (Technicien, ses OT uniquement), * Administrateur/Gestionnaire/Dispatcher ont `viewOther` — l'API renvoie * déjà TOUS les OT (ADR-003, rien à filtrer ici). Même tri priorité puis * échéance que « Ma journée » ; ouvrir un OT réutilise la fiche R4 telle * quelle (elle affiche déjà les actions permises via `allowedTransitions`). */ const STYLE_STATUT: Record [string, string]> = { OPEN: (t) => [t.stOuvert, t.stOuvertFond], IN_PROGRESS: (t) => [t.stEncours, t.stEncoursFond], ON_HOLD: (t) => [t.stAttente, t.stAttenteFond], DONE: (t) => [t.stTermine, t.stTermineFond], CANCELLED: (t) => [t.stAnnule, t.stAnnuleFond], }; const STRIE_PRIORITE: Record string> = { PERSON_TRAPPED: (t) => t.prioBloque, HIGH: (t) => t.prioHaute, MEDIUM: (t) => t.prioMoyenne, LOW: (t) => t.prioBasse, NONE: () => 'transparent', }; export default function PageOT() { const t = useTokens(); const { data: workOrders, refetch, isFetching } = useWorkOrders(); const ots = triJournee(workOrders ?? []); const urgences = ots.filter((o) => o.priority === 'PERSON_TRAPPED'); return ( Ordres de travail {ots.length} {urgences.length ? ( {urgences.length === 1 ? `1 personne bloquée — ${urgences[0]!.assetReference} · ${urgences[0]!.siteName}` : `${urgences.length} personnes bloquées`} ) : null} o.id} refreshControl={ void refetch()} tintColor={t.primaire} /> } contentContainerStyle={{ gap: 8, paddingBottom: 12 }} ListEmptyComponent={ Aucun OT — tirez pour rafraîchir. } renderItem={({ item: o }) => { const [enc, fond] = STYLE_STATUT[o.status](t); return ( router.push(`/ot/${o.id}`)} style={{ backgroundColor: t.surface, borderColor: t.bordure, borderWidth: 1, borderRadius: 12, borderLeftWidth: 4, borderLeftColor: STRIE_PRIORITE[o.priority](t), padding: 11, gap: 2, }} > {o.reference} · {WORK_ORDER_TYPE_LABELS[o.type]} {WORK_ORDER_STATUS_LABELS[o.status]} {o.title} Asc. {o.assetReference} — {o.siteName} {o.dueDate ? ` · échéance ${new Intl.DateTimeFormat('fr-FR', { day: 'numeric', month: 'short' }).format(new Date(o.dueDate))}` : ''} {o.priority !== 'NONE' && o.priority !== 'PERSON_TRAPPED' ? ` · ${WORK_ORDER_PRIORITY_LABELS[o.priority]}` : ''} ); }} /> ); }