import React, { useMemo, useCallback } from 'react'; import { View, Text, StyleSheet, FlatList, TouchableOpacity, ActivityIndicator, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { MaterialIcons } from '@expo/vector-icons'; import { fileStore, FileRecord } from '../services/fileStore'; import { safDirectory } from '../services/safDirectory'; import { useSyncQueue } from '../hooks/useSyncQueue'; function formatSize(bytes: number): string { if (bytes === 0) return ''; if (bytes < 1024) return `${bytes} o`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} Ko`; return `${(bytes / (1024 * 1024)).toFixed(1)} Mo`; } export function SyncDetailScreen() { const insets = useSafeAreaInsets(); const { pendingCount, isSyncing, refresh } = useSyncQueue(); const pendingFiles = useMemo(() => { return fileStore.getPendingSync(); }, []); const handleSyncAll = useCallback(() => { // TODO: lancer l'upload batch de tous les fichiers pending console.log(`[SyncDetail] sync demandé pour ${pendingFiles.length} fichiers`); }, [pendingFiles.length]); const renderItem = useCallback(({ item }: { item: FileRecord }) => ( {item.name} {formatSize(item.size)} {item.mimeType ? ` · ${item.mimeType.split('/').pop()}` : ''} ), []); return ( {pendingCount > 0 && ( {isSyncing ? ( ) : ( )} {isSyncing ? 'Synchronisation...' : `Synchroniser (${pendingCount})`} )} {pendingFiles.length === 0 ? ( Tout est synchronisé Aucun fichier en attente d'upload ) : ( item.id} renderItem={renderItem} contentContainerStyle={styles.list} ListHeaderComponent={ {pendingFiles.length} fichier{pendingFiles.length > 1 ? 's' : ''} en attente } /> )} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, syncBtn: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: '#1976D2', marginHorizontal: 16, marginTop: 16, borderRadius: 10, paddingVertical: 14, gap: 10, }, syncBtnDisabled: { backgroundColor: '#90CAF9', }, syncBtnText: { fontSize: 16, color: '#fff', fontWeight: '600', }, list: { padding: 16, }, headerText: { fontSize: 14, color: '#666', marginBottom: 12, }, fileRow: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#fff', borderRadius: 10, padding: 12, marginBottom: 8, gap: 12, }, fileInfo: { flex: 1, }, fileName: { fontSize: 15, color: '#333', fontWeight: '500', }, fileMeta: { fontSize: 12, color: '#999', marginTop: 2, }, localBadge: { width: 28, height: 28, borderRadius: 14, backgroundColor: '#f5f5f5', justifyContent: 'center', alignItems: 'center', }, empty: { flex: 1, justifyContent: 'center', alignItems: 'center', gap: 12, }, emptyTitle: { fontSize: 18, fontWeight: '600', color: '#333', }, emptySubtitle: { fontSize: 14, color: '#999', }, });