372 lines
12 KiB
TypeScript
372 lines
12 KiB
TypeScript
import React from "react";
|
|
import {
|
|
View,
|
|
Text,
|
|
StyleSheet,
|
|
TouchableOpacity,
|
|
Alert,
|
|
ScrollView,
|
|
} from "react-native";
|
|
import { useUser, useAuth } from "@clerk/clerk-expo";
|
|
import { useRouter } from "expo-router";
|
|
import { Ionicons } from "@expo/vector-icons";
|
|
import { LinearGradient } from "expo-linear-gradient";
|
|
import { theme } from "../../styles/theme";
|
|
|
|
export default function ProfileScreen() {
|
|
const { user } = useUser();
|
|
const { signOut } = useAuth();
|
|
const router = useRouter();
|
|
|
|
const handleLogout = async () => {
|
|
Alert.alert("Sign Out", "Are you sure you want to sign out?", [
|
|
{ text: "Cancel", style: "cancel" },
|
|
{
|
|
text: "Sign Out",
|
|
style: "destructive",
|
|
onPress: async () => {
|
|
try {
|
|
await signOut();
|
|
router.replace("/(auth)/sign-in");
|
|
} catch (error) {
|
|
Alert.alert("Error", "Failed to sign out");
|
|
}
|
|
},
|
|
},
|
|
]);
|
|
};
|
|
|
|
if (!user) {
|
|
return (
|
|
<View style={styles.container}>
|
|
<Text>Loading...</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<ScrollView style={styles.container}>
|
|
<View style={styles.content}>
|
|
{/* Profile Header with Gradient */}
|
|
<LinearGradient
|
|
colors={theme.gradients.primary}
|
|
start={{ x: 0, y: 0 }}
|
|
end={{ x: 1, y: 1 }}
|
|
style={[styles.profileCard, theme.shadows.strong]}
|
|
>
|
|
<View style={styles.avatarContainer}>
|
|
{user.imageUrl ? (
|
|
<LinearGradient
|
|
colors={['rgba(255, 255, 255, 0.3)', 'rgba(255, 255, 255, 0.1)']}
|
|
style={styles.avatar}
|
|
>
|
|
<Text style={styles.avatarText}>
|
|
{user.firstName?.charAt(0)}
|
|
{user.lastName?.charAt(0)}
|
|
</Text>
|
|
</LinearGradient>
|
|
) : (
|
|
<LinearGradient
|
|
colors={['rgba(255, 255, 255, 0.3)', 'rgba(255, 255, 255, 0.1)']}
|
|
style={styles.avatar}
|
|
>
|
|
<Ionicons name="person" size={40} color="#fff" />
|
|
</LinearGradient>
|
|
)}
|
|
</View>
|
|
|
|
<Text style={styles.name}>
|
|
{user.firstName} {user.lastName}
|
|
</Text>
|
|
<Text style={styles.email}>
|
|
{user.primaryEmailAddress?.emailAddress}
|
|
</Text>
|
|
|
|
{user.primaryPhoneNumber && (
|
|
<Text style={styles.phone}>
|
|
{user.primaryPhoneNumber.phoneNumber}
|
|
</Text>
|
|
)}
|
|
</LinearGradient>
|
|
|
|
{/* Account Information */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>Account Information</Text>
|
|
|
|
<View style={[styles.infoCard, theme.shadows.medium]}>
|
|
<View style={styles.infoRow}>
|
|
<View style={styles.infoLabel}>
|
|
<LinearGradient
|
|
colors={['rgba(59, 130, 246, 0.15)', 'rgba(59, 130, 246, 0.05)']}
|
|
style={styles.infoIconContainer}
|
|
>
|
|
<Ionicons name="mail-outline" size={18} color={theme.colors.primary} />
|
|
</LinearGradient>
|
|
<Text style={styles.infoLabelText}>Email</Text>
|
|
</View>
|
|
<Text style={styles.infoValue}>
|
|
{user.primaryEmailAddress?.emailAddress}
|
|
</Text>
|
|
</View>
|
|
|
|
{user.primaryPhoneNumber && (
|
|
<View style={styles.infoRow}>
|
|
<View style={styles.infoLabel}>
|
|
<LinearGradient
|
|
colors={['rgba(16, 185, 129, 0.15)', 'rgba(16, 185, 129, 0.05)']}
|
|
style={styles.infoIconContainer}
|
|
>
|
|
<Ionicons name="call-outline" size={18} color={theme.colors.success} />
|
|
</LinearGradient>
|
|
<Text style={styles.infoLabelText}>Phone</Text>
|
|
</View>
|
|
<Text style={styles.infoValue}>
|
|
{user.primaryPhoneNumber.phoneNumber}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
|
|
<View style={styles.infoRow}>
|
|
<View style={styles.infoLabel}>
|
|
<LinearGradient
|
|
colors={['rgba(245, 158, 11, 0.15)', 'rgba(245, 158, 11, 0.05)']}
|
|
style={styles.infoIconContainer}
|
|
>
|
|
<Ionicons name="calendar-outline" size={18} color={theme.colors.warning} />
|
|
</LinearGradient>
|
|
<Text style={styles.infoLabelText}>Member Since</Text>
|
|
</View>
|
|
<Text style={styles.infoValue}>
|
|
{new Date(user.createdAt!).toLocaleDateString()}
|
|
</Text>
|
|
</View>
|
|
|
|
<View style={[styles.infoRow, { borderBottomWidth: 0 }]}>
|
|
<View style={styles.infoLabel}>
|
|
<LinearGradient
|
|
colors={['rgba(16, 185, 129, 0.15)', 'rgba(16, 185, 129, 0.05)']}
|
|
style={styles.infoIconContainer}
|
|
>
|
|
<Ionicons
|
|
name="shield-checkmark-outline"
|
|
size={18}
|
|
color={theme.colors.success}
|
|
/>
|
|
</LinearGradient>
|
|
<Text style={styles.infoLabelText}>Email Verified</Text>
|
|
</View>
|
|
<Text style={styles.infoValue}>
|
|
{user.primaryEmailAddress?.verification?.status === "verified"
|
|
? "Yes"
|
|
: "No"}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Quick Actions */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>Quick Actions</Text>
|
|
|
|
<TouchableOpacity style={[styles.actionButton, theme.shadows.medium]} activeOpacity={0.7}>
|
|
<LinearGradient
|
|
colors={['rgba(59, 130, 246, 0.15)', 'rgba(59, 130, 246, 0.05)']}
|
|
style={styles.actionIconContainer}
|
|
>
|
|
<Ionicons name="person-outline" size={22} color={theme.colors.primary} />
|
|
</LinearGradient>
|
|
<Text style={styles.actionButtonText}>Edit Profile</Text>
|
|
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
|
|
</TouchableOpacity>
|
|
|
|
<TouchableOpacity style={[styles.actionButton, theme.shadows.medium]} activeOpacity={0.7}>
|
|
<LinearGradient
|
|
colors={['rgba(245, 158, 11, 0.15)', 'rgba(245, 158, 11, 0.05)']}
|
|
style={styles.actionIconContainer}
|
|
>
|
|
<Ionicons name="notifications-outline" size={22} color={theme.colors.warning} />
|
|
</LinearGradient>
|
|
<Text style={styles.actionButtonText}>Notifications</Text>
|
|
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
|
|
</TouchableOpacity>
|
|
|
|
<TouchableOpacity style={[styles.actionButton, theme.shadows.medium]} activeOpacity={0.7}>
|
|
<LinearGradient
|
|
colors={['rgba(139, 92, 246, 0.15)', 'rgba(139, 92, 246, 0.05)']}
|
|
style={styles.actionIconContainer}
|
|
>
|
|
<Ionicons name="card-outline" size={22} color={theme.colors.purple} />
|
|
</LinearGradient>
|
|
<Text style={styles.actionButtonText}>Payment History</Text>
|
|
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
|
|
</TouchableOpacity>
|
|
|
|
<TouchableOpacity style={[styles.actionButton, theme.shadows.medium]} activeOpacity={0.7}>
|
|
<LinearGradient
|
|
colors={['rgba(107, 114, 128, 0.15)', 'rgba(107, 114, 128, 0.05)']}
|
|
style={styles.actionIconContainer}
|
|
>
|
|
<Ionicons name="settings-outline" size={22} color={theme.colors.gray600} />
|
|
</LinearGradient>
|
|
<Text style={styles.actionButtonText}>Settings</Text>
|
|
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
{/* Sign Out Button */}
|
|
<TouchableOpacity onPress={handleLogout} activeOpacity={0.8}>
|
|
<LinearGradient
|
|
colors={theme.gradients.danger}
|
|
start={{ x: 0, y: 0 }}
|
|
end={{ x: 1, y: 0 }}
|
|
style={[styles.logoutButton, theme.shadows.glowDanger]}
|
|
>
|
|
<Ionicons name="log-out-outline" size={20} color="#fff" />
|
|
<Text style={styles.logoutText}>Sign Out</Text>
|
|
</LinearGradient>
|
|
</TouchableOpacity>
|
|
|
|
{/* App Version */}
|
|
<Text style={styles.version}>Version 1.0.0</Text>
|
|
</View>
|
|
</ScrollView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: theme.colors.background,
|
|
},
|
|
content: {
|
|
padding: 20,
|
|
paddingTop: 60,
|
|
},
|
|
profileCard: {
|
|
borderRadius: theme.borderRadius.xl,
|
|
padding: 28,
|
|
alignItems: "center",
|
|
marginBottom: 24,
|
|
},
|
|
avatarContainer: {
|
|
marginBottom: 16,
|
|
},
|
|
avatar: {
|
|
width: 96,
|
|
height: 96,
|
|
borderRadius: 48,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
borderWidth: 3,
|
|
borderColor: "rgba(255, 255, 255, 0.3)",
|
|
},
|
|
avatarText: {
|
|
fontSize: theme.typography.fontSize['4xl'],
|
|
fontWeight: theme.typography.fontWeight.bold,
|
|
color: theme.colors.white,
|
|
},
|
|
name: {
|
|
fontSize: theme.typography.fontSize['2xl'],
|
|
fontWeight: theme.typography.fontWeight.bold,
|
|
color: theme.colors.white,
|
|
marginBottom: 6,
|
|
},
|
|
email: {
|
|
fontSize: theme.typography.fontSize.base,
|
|
color: "rgba(255, 255, 255, 0.9)",
|
|
marginBottom: 4,
|
|
},
|
|
phone: {
|
|
fontSize: theme.typography.fontSize.sm,
|
|
color: "rgba(255, 255, 255, 0.8)",
|
|
},
|
|
section: {
|
|
marginBottom: 24,
|
|
},
|
|
sectionTitle: {
|
|
fontSize: theme.typography.fontSize.xl,
|
|
fontWeight: theme.typography.fontWeight.semibold,
|
|
color: theme.colors.gray900,
|
|
marginBottom: 12,
|
|
},
|
|
infoCard: {
|
|
backgroundColor: theme.colors.white,
|
|
borderRadius: theme.borderRadius.xl,
|
|
padding: 16,
|
|
},
|
|
infoRow: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
paddingVertical: 14,
|
|
borderBottomWidth: 1,
|
|
borderBottomColor: theme.colors.gray200,
|
|
},
|
|
infoLabel: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
gap: 10,
|
|
},
|
|
infoIconContainer: {
|
|
width: 36,
|
|
height: 36,
|
|
borderRadius: 18,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
},
|
|
infoLabelText: {
|
|
fontSize: theme.typography.fontSize.sm,
|
|
color: theme.colors.gray700,
|
|
fontWeight: theme.typography.fontWeight.medium,
|
|
},
|
|
infoValue: {
|
|
fontSize: theme.typography.fontSize.sm,
|
|
color: theme.colors.gray900,
|
|
fontWeight: theme.typography.fontWeight.semibold,
|
|
},
|
|
actionButton: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
backgroundColor: theme.colors.white,
|
|
borderRadius: theme.borderRadius.xl,
|
|
padding: 16,
|
|
marginBottom: 12,
|
|
},
|
|
actionIconContainer: {
|
|
width: 44,
|
|
height: 44,
|
|
borderRadius: 22,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
marginRight: 12,
|
|
},
|
|
actionButtonText: {
|
|
flex: 1,
|
|
fontSize: theme.typography.fontSize.base,
|
|
color: theme.colors.gray900,
|
|
fontWeight: theme.typography.fontWeight.medium,
|
|
},
|
|
logoutButton: {
|
|
paddingVertical: 16,
|
|
borderRadius: theme.borderRadius.lg,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
flexDirection: "row",
|
|
gap: 8,
|
|
marginTop: 8,
|
|
marginBottom: 16,
|
|
},
|
|
logoutText: {
|
|
color: theme.colors.white,
|
|
fontSize: theme.typography.fontSize.base,
|
|
fontWeight: theme.typography.fontWeight.semibold,
|
|
},
|
|
version: {
|
|
textAlign: "center",
|
|
fontSize: theme.typography.fontSize.xs,
|
|
color: theme.colors.gray500,
|
|
marginTop: 8,
|
|
marginBottom: 20,
|
|
},
|
|
});
|