113 lines
3.2 KiB
JavaScript
113 lines
3.2 KiB
JavaScript
import { Alert, StyleSheet, Text, View } from 'react-native';
|
|
import ScreenContainer from '../../components/ScreenContainer';
|
|
import PrimaryButton from '../../components/PrimaryButton';
|
|
import { useAuth } from '../../context/AuthContext';
|
|
import { useSync } from '../../context/SyncContext';
|
|
import { colors } from '../../theme/colors';
|
|
|
|
export default function DashboardScreen() {
|
|
const { user } = useAuth();
|
|
const { documents, certificates, signedDocuments, syncNow, syncing, lastSyncAt } = useSync();
|
|
|
|
const handleSync = async () => {
|
|
try {
|
|
await syncNow();
|
|
Alert.alert('Sincronización', 'Los datos del teléfono fueron sincronizados con el backend.');
|
|
} catch (error) {
|
|
Alert.alert('Sincronización', error.response?.data?.error || 'No se pudo sincronizar.');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<ScreenContainer>
|
|
<View style={styles.hero}>
|
|
<Text style={styles.greeting}>Hola, {user?.name || user?.email}</Text>
|
|
<Text style={styles.subtext}>LinkedSign móvil comparte autenticación con la app web y sincroniza datos bajo petición.</Text>
|
|
</View>
|
|
|
|
<View style={styles.statsGrid}>
|
|
<View style={styles.statCard}>
|
|
<Text style={styles.statValue}>{documents.length}</Text>
|
|
<Text style={styles.statLabel}>Documentos</Text>
|
|
</View>
|
|
<View style={styles.statCard}>
|
|
<Text style={styles.statValue}>{certificates.length}</Text>
|
|
<Text style={styles.statLabel}>Certificados</Text>
|
|
</View>
|
|
<View style={styles.statCard}>
|
|
<Text style={styles.statValue}>{signedDocuments.length}</Text>
|
|
<Text style={styles.statLabel}>Firmados</Text>
|
|
</View>
|
|
</View>
|
|
|
|
<View style={styles.card}>
|
|
<Text style={styles.cardTitle}>Sincronización local</Text>
|
|
<Text style={styles.cardText}>
|
|
La base local del teléfono se actualiza solo cuando tú lo pides. La sesión permanece guardada de forma segura.
|
|
</Text>
|
|
<Text style={styles.syncMeta}>
|
|
Última sincronización: {lastSyncAt ? new Date(lastSyncAt).toLocaleString('es-EC') : 'Sin sincronizar'}
|
|
</Text>
|
|
<PrimaryButton title={syncing ? 'Sincronizando...' : 'Sincronizar ahora'} onPress={handleSync} disabled={syncing} />
|
|
</View>
|
|
</ScreenContainer>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
hero: {
|
|
backgroundColor: colors.dark,
|
|
borderRadius: 20,
|
|
padding: 20,
|
|
gap: 8,
|
|
},
|
|
greeting: {
|
|
color: '#fff',
|
|
fontSize: 24,
|
|
fontWeight: '800',
|
|
},
|
|
subtext: {
|
|
color: '#cbd5e1',
|
|
lineHeight: 20,
|
|
},
|
|
statsGrid: {
|
|
flexDirection: 'row',
|
|
gap: 12,
|
|
},
|
|
statCard: {
|
|
flex: 1,
|
|
backgroundColor: colors.surface,
|
|
borderRadius: 18,
|
|
padding: 16,
|
|
alignItems: 'center',
|
|
},
|
|
statValue: {
|
|
fontSize: 28,
|
|
fontWeight: '800',
|
|
color: colors.primary,
|
|
},
|
|
statLabel: {
|
|
color: colors.textMuted,
|
|
marginTop: 4,
|
|
},
|
|
card: {
|
|
backgroundColor: colors.surface,
|
|
borderRadius: 18,
|
|
padding: 18,
|
|
gap: 10,
|
|
},
|
|
cardTitle: {
|
|
fontSize: 18,
|
|
fontWeight: '700',
|
|
color: colors.text,
|
|
},
|
|
cardText: {
|
|
color: colors.textMuted,
|
|
lineHeight: 20,
|
|
},
|
|
syncMeta: {
|
|
color: colors.text,
|
|
fontSize: 13,
|
|
},
|
|
});
|