Files
linkedsign/android_react/src/screens/app/DashboardScreen.js
T
2026-04-06 20:34:18 -05:00

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,
},
});