Files
CBS-Mobile-App/src/modules/agent/screens/AgentProfileScreen.tsx
T

232 lines
7.6 KiB
TypeScript

import React from 'react';
import { View, Text, StyleSheet, ScrollView, Pressable, Alert } from 'react-native';
import { CompositeNavigationProp } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
import Ionicons from '@react-native-vector-icons/ionicons';
import Animated, { FadeInUp } from 'react-native-reanimated';
import { ScreenShell, Button } from '../../../components';
import { useTheme, fontFamily } from '../../../theme';
import { TAB_BAR_HEIGHT } from '../../../utils/layoutConstants';
import { useAppDispatch, useAppSelector } from '../../../app/hooks';
import type { AgentTabParamList, AgentProfileStackParamList } from '../navigation/agentNavigationTypes';
import { logoutSession } from '../../auth/store/authThunk';
type NavigationProp = CompositeNavigationProp<
NativeStackNavigationProp<AgentProfileStackParamList, 'AgentProfileMain'>,
BottomTabNavigationProp<AgentTabParamList>
>;
export default function AgentProfileScreen({ navigation }: { navigation: NavigationProp }) {
const theme = useTheme();
const dispatch = useAppDispatch();
const profile = useAppSelector(state => state.user.profile);
const handleLogout = () => {
Alert.alert(
'Log out of this device?',
'Signing out clears everything this app has stored on this phone, not just your session.',
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Log Out',
style: 'destructive',
onPress: () => {
dispatch(logoutSession());
}
}
]
);
};
const SettingsRow = ({ icon, label, onPress, destructive = false }: { icon: string, label: string, onPress: () => void, destructive?: boolean }) => (
<Pressable
style={styles.settingsRow}
onPress={onPress}
>
<View style={styles.settingsRowLeft}>
<View style={[styles.settingsIconFrame, { backgroundColor: destructive ? `${theme.colors.danger}15` : `${theme.colors.primary}15` }]}>
<Ionicons name={icon as any} size={20} color={destructive ? theme.colors.danger : theme.colors.primary} />
</View>
<Text style={[styles.settingsLabel, { color: destructive ? theme.colors.danger : theme.colors.textPrimary }]}>{label}</Text>
</View>
<Ionicons name="chevron-forward" size={20} color={theme.colors.textMuted} />
</Pressable>
);
return (
<ScreenShell title="Agent Profile" scrollable={false}>
<ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
<Animated.View entering={FadeInUp} style={[styles.profileCard, { backgroundColor: theme.colors.surface, borderColor: theme.colors.cardBorder }]}>
<View style={[styles.avatarBig, { backgroundColor: `${theme.colors.primary}15` }]}>
<Text style={[styles.avatarText, { color: theme.colors.primary }]}>{profile?.firstName?.charAt(0) || 'A'}</Text>
</View>
<Text style={[styles.name, { color: theme.colors.textPrimary }]}>{profile?.firstName} {profile?.lastName}</Text>
<Text style={[styles.role, { color: theme.colors.textMuted }]}>Field Agent • {profile?.email}</Text>
<View style={[styles.badge, { backgroundColor: `${theme.colors.success}15` }]}>
<View style={[styles.statusDot, { backgroundColor: theme.colors.success }]} />
<Text style={[styles.badgeText, { color: theme.colors.success }]}>Active Agent</Text>
</View>
</Animated.View>
<Animated.View entering={FadeInUp.delay(100)}>
<Text style={[styles.sectionTitle, { color: theme.colors.textMuted }]}>Account Settings</Text>
<View style={[styles.settingsGroup, { backgroundColor: theme.colors.surface, borderColor: theme.colors.cardBorder }]}>
<SettingsRow
icon="key-outline"
label="Change Password"
onPress={() => navigation.navigate('AgentChangePassword')}
/>
<View style={[styles.divider, { backgroundColor: theme.colors.cardBorder }]} />
<SettingsRow
icon="chatbubble-ellipses-outline"
label="SMS Log"
onPress={() => navigation.navigate('SmsHistory')}
/>
<View style={[styles.divider, { backgroundColor: theme.colors.cardBorder }]} />
<SettingsRow
icon="notifications-outline"
label="Notification Settings"
onPress={() => {}}
/>
</View>
</Animated.View>
<Animated.View entering={FadeInUp.delay(200)}>
<Text style={[styles.sectionTitle, { color: theme.colors.textMuted, marginTop: 24 }]}>Support & Legal</Text>
<View style={[styles.settingsGroup, { backgroundColor: theme.colors.surface, borderColor: theme.colors.cardBorder }]}>
<SettingsRow
icon="help-circle-outline"
label="Help & Support"
onPress={() => {}}
/>
<View style={[styles.divider, { backgroundColor: theme.colors.cardBorder }]} />
<SettingsRow
icon="document-text-outline"
label="Terms & Conditions"
onPress={() => {}}
/>
</View>
</Animated.View>
<View style={{ marginTop: 32 }}>
<Button
title="Log Out"
variant="secondary"
onPress={handleLogout}
style={{ borderColor: theme.colors.danger, borderWidth: 1 }}
textStyle={{ color: theme.colors.danger }}
/>
</View>
<View style={styles.footerInfo}>
<Text style={[styles.version, { color: theme.colors.textMuted }]}>App Version 1.0.0</Text>
<Text style={[styles.version, { color: theme.colors.textMuted }]}>Agent Module v1</Text>
</View>
</ScrollView>
</ScreenShell>
);
}
const styles = StyleSheet.create({
scrollContent: {
padding: 16,
paddingBottom: TAB_BAR_HEIGHT + 16,
},
profileCard: {
alignItems: 'center',
padding: 24,
borderRadius: 16,
borderWidth: 1,
marginBottom: 24,
},
avatarBig: {
width: 80,
height: 80,
borderRadius: 40,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 16,
},
avatarText: {
fontSize: 32,
fontFamily: fontFamily.bold,
},
name: {
fontSize: 20,
fontFamily: fontFamily.bold,
marginBottom: 4,
},
role: {
fontSize: 14,
marginBottom: 12,
},
badge: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 12,
gap: 6,
},
statusDot: {
width: 8,
height: 8,
borderRadius: 4,
},
badgeText: {
fontSize: 12,
fontFamily: fontFamily.bold,
},
sectionTitle: {
fontSize: 13,
fontFamily: fontFamily.semibold,
textTransform: 'uppercase',
letterSpacing: 0.5,
marginBottom: 8,
marginLeft: 8,
},
settingsGroup: {
borderRadius: 16,
borderWidth: 1,
overflow: 'hidden',
},
settingsRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 16,
},
settingsRowLeft: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
settingsIconFrame: {
width: 36,
height: 36,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
},
settingsLabel: {
fontSize: 15,
fontFamily: fontFamily.semibold,
},
divider: {
height: 1,
marginLeft: 64, // Align with text
},
footerInfo: {
alignItems: 'center',
marginTop: 32,
gap: 4,
},
version: {
fontSize: 12,
},
});