Initial LinkedSign platform
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
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,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user