redesign completed

alot of work ahead
This commit is contained in:
dimitar committed 2025-11-26 02:31:46 +01:00
1 parent 73d2c4c1ed
commit febcdc111e
18 files changed
+1591 -845

No files matched your search

+188 -292
View File
@@ -1,235 +1,135 @@
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 { View, Text, StyleSheet, TouchableOpacity, Image, Alert } from "react-native";
import { useUser, useClerk } from "@clerk/clerk-expo";
import { Ionicons } from "@expo/vector-icons";
import { LinearGradient } from "expo-linear-gradient";
import { theme } from "../../styles/theme";
import { AnimatedButton } from "../../components/AnimatedButton";
import { GradientBackground } from "../../components/GradientBackground";
export default function ProfileScreen() {
const { user } = useUser();
const { signOut } = useAuth();
const router = useRouter();
const { signOut } = useClerk();
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");
}
},
},
]);
const handleSignOut = async () => {
try {
await signOut();
} catch (err) {
console.error("Error signing out:", err);
}
};
if (!user) {
return (
<View style={styles.container}>
<Text>Loading...</Text>
</View>
const confirmSignOut = () => {
Alert.alert(
"Sign Out",
"Are you sure you want to sign out?",
[
{ text: "Cancel", style: "cancel" },
{ text: "Sign Out", style: "destructive", onPress: handleSignOut },
]
);
}
};
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.container}>
<GradientBackground variant="primary" style={styles.header}>
<View style={styles.profileCard}>
<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>
{user?.imageUrl ? (
<Image source={{ uri: user.imageUrl }} style={styles.avatar} />
) : (
<LinearGradient
colors={['rgba(255, 255, 255, 0.3)', 'rgba(255, 255, 255, 0.1)']}
style={styles.avatar}
>
<View style={styles.placeholderAvatar}>
<Ionicons name="person" size={40} color="#fff" />
</View>
)}
<View style={styles.editBadge}>
<Ionicons name="pencil" size={12} color={theme.colors.primary} />
</View>
</View>
<Text style={styles.name}>{user?.fullName || "User"}</Text>
<Text style={styles.email}>{user?.primaryEmailAddress?.emailAddress}</Text>
<View style={styles.memberBadge}>
<Text style={styles.memberText}>Premium Member</Text>
</View>
</View>
</GradientBackground>
<View style={styles.content}>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Account</Text>
<View style={[styles.infoCard, theme.shadows.subtle]}>
<TouchableOpacity style={styles.infoRow}>
<LinearGradient
colors={['rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.05)']}
style={styles.iconContainer}
>
<Ionicons name="person-outline" size={20} color={theme.colors.primary} />
</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>
<Text style={styles.infoLabel}>Personal Details</Text>
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
</TouchableOpacity>
<View style={styles.divider} />
<TouchableOpacity style={styles.infoRow}>
<LinearGradient
colors={['rgba(16, 185, 129, 0.1)', 'rgba(16, 185, 129, 0.05)']}
style={styles.iconContainer}
>
<Ionicons name="fitness-outline" size={20} color={theme.colors.success} />
</LinearGradient>
<Text style={styles.infoLabel}>Fitness Profile</Text>
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
</TouchableOpacity>
<View style={styles.divider} />
<TouchableOpacity style={styles.infoRow}>
<LinearGradient
colors={['rgba(245, 158, 11, 0.1)', 'rgba(245, 158, 11, 0.05)']}
style={styles.iconContainer}
>
<Ionicons name="notifications-outline" size={20} color={theme.colors.warning} />
</LinearGradient>
<Text style={styles.infoLabel}>Notifications</Text>
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
</TouchableOpacity>
</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>
<Text style={styles.sectionTitle}>Support</Text>
<View style={[styles.infoCard, theme.shadows.subtle]}>
<TouchableOpacity style={styles.infoRow}>
<LinearGradient
colors={['rgba(139, 92, 246, 0.1)', 'rgba(139, 92, 246, 0.05)']}
style={styles.iconContainer}
>
<Ionicons name="help-circle-outline" size={20} color={theme.colors.secondary} />
</LinearGradient>
<Text style={styles.infoLabel}>Help Center</Text>
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
</TouchableOpacity>
<View style={styles.divider} />
<TouchableOpacity style={styles.infoRow}>
<LinearGradient
colors={['rgba(107, 114, 128, 0.1)', 'rgba(107, 114, 128, 0.05)']}
style={styles.iconContainer}
>
<Ionicons name="shield-checkmark-outline" size={20} color={theme.colors.gray600} />
</LinearGradient>
<Text style={styles.infoLabel}>Privacy & Security</Text>
<Ionicons name="chevron-forward" size={20} color={theme.colors.gray400} />
</TouchableOpacity>
</View>
</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>
<AnimatedButton
title="Sign Out"
onPress={confirmSignOut}
variant="danger"
style={styles.signOutButton}
icon={<Ionicons name="log-out-outline" size={20} color="#fff" />}
/>
{/* App Version */}
<Text style={styles.version}>Version 1.0.0</Text>
</View>
</ScrollView>
</View>
);
}
@@ -238,134 +138,130 @@ const styles = StyleSheet.create({
flex: 1,
backgroundColor: theme.colors.background,
},
content: {
padding: 20,
header: {
paddingTop: 60,
paddingBottom: 30,
borderBottomLeftRadius: theme.borderRadius.xl,
borderBottomRightRadius: theme.borderRadius.xl,
alignItems: 'center',
},
profileCard: {
borderRadius: theme.borderRadius.xl,
padding: 28,
alignItems: "center",
marginBottom: 24,
alignItems: 'center',
},
avatarContainer: {
position: 'relative',
marginBottom: 16,
},
avatar: {
width: 96,
height: 96,
borderRadius: 48,
justifyContent: "center",
alignItems: "center",
borderWidth: 3,
borderColor: "rgba(255, 255, 255, 0.3)",
width: 100,
height: 100,
borderRadius: 50,
borderWidth: 4,
borderColor: 'rgba(255, 255, 255, 0.3)',
},
avatarText: {
fontSize: theme.typography.fontSize['4xl'],
fontWeight: theme.typography.fontWeight.bold,
color: theme.colors.white,
placeholderAvatar: {
width: 100,
height: 100,
borderRadius: 50,
backgroundColor: 'rgba(255, 255, 255, 0.2)',
justifyContent: 'center',
alignItems: 'center',
borderWidth: 4,
borderColor: 'rgba(255, 255, 255, 0.3)',
},
editBadge: {
position: 'absolute',
bottom: 0,
right: 0,
backgroundColor: theme.colors.white,
width: 32,
height: 32,
borderRadius: 16,
justifyContent: 'center',
alignItems: 'center',
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
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: {
email: {
fontSize: theme.typography.fontSize.sm,
color: "rgba(255, 255, 255, 0.8)",
color: 'rgba(255, 255, 255, 0.8)',
marginBottom: 12,
},
memberBadge: {
backgroundColor: 'rgba(255, 255, 255, 0.2)',
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: theme.borderRadius.full,
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.3)',
},
memberText: {
color: theme.colors.white,
fontSize: theme.typography.fontSize.xs,
fontWeight: theme.typography.fontWeight.bold,
letterSpacing: 0.5,
},
content: {
padding: 20,
marginTop: -20,
},
section: {
marginBottom: 24,
},
sectionTitle: {
fontSize: theme.typography.fontSize.xl,
fontWeight: theme.typography.fontWeight.semibold,
fontSize: theme.typography.fontSize.lg,
fontWeight: theme.typography.fontWeight.bold,
color: theme.colors.gray900,
marginBottom: 12,
marginLeft: 4,
},
infoCard: {
backgroundColor: theme.colors.white,
borderRadius: theme.borderRadius.xl,
padding: 16,
padding: 8,
borderWidth: 1,
borderColor: theme.colors.gray100,
},
infoRow: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingVertical: 14,
borderBottomWidth: 1,
borderBottomColor: theme.colors.gray200,
flexDirection: 'row',
alignItems: 'center',
padding: 12,
},
infoLabel: {
flexDirection: "row",
alignItems: "center",
gap: 10,
},
infoIconContainer: {
iconContainer: {
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",
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
marginRight: 12,
},
actionButtonText: {
infoLabel: {
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,
divider: {
height: 1,
backgroundColor: theme.colors.gray100,
marginLeft: 60,
},
logoutText: {
color: theme.colors.white,
fontSize: theme.typography.fontSize.base,
fontWeight: theme.typography.fontWeight.semibold,
signOutButton: {
marginTop: 8,
},
version: {
textAlign: "center",
textAlign: 'center',
marginTop: 24,
color: theme.colors.gray400,
fontSize: theme.typography.fontSize.xs,
color: theme.colors.gray500,
marginTop: 8,
marginBottom: 20,
},
});