232 lines
7.6 KiB
TypeScript
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,
|
|
},
|
|
});
|