clerkauth

implemented, sync with db to be added
This commit is contained in:
dimitar committed 2025-11-10 04:16:31 +01:00
1 parent ca790a7b97
commit 3a58d420d6
49 files changed
+9423 -779

No files matched your search

+266 -75
View File
@@ -1,116 +1,307 @@
import React from 'react'
import { View, Text, StyleSheet, TouchableOpacity, Alert } from 'react-native'
import { useAuth } from '@/contexts/AuthContext'
import { useRouter } from 'expo-router'
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";
export default function ProfileScreen() {
const { user, logout } = useAuth()
const router = useRouter()
const { user } = useUser();
const { signOut } = useAuth();
const router = useRouter();
const handleLogout = async () => {
Alert.alert(
'Logout',
'Are you sure you want to logout?',
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Logout',
style: 'destructive',
onPress: async () => {
try {
await logout()
router.replace('/login')
} catch (error) {
Alert.alert('Error', 'Failed to logout')
}
},
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 (
<View style={styles.container}>
<View style={styles.profileCard}>
<Text style={styles.title}>Profile</Text>
<Text style={styles.name}>
{user?.firstName} {user?.lastName}
</Text>
<Text style={styles.email}>{user?.email}</Text>
{user?.phone && <Text style={styles.phone}>{user.phone}</Text>}
<View style={styles.roleBadge}>
<Text style={styles.roleText}>
{user?.role.charAt(0).toUpperCase() + user?.role.slice(1)}
</Text>
</View>
</View>
<ScrollView style={styles.container}>
<View style={styles.content}>
{/* Profile Header */}
<View style={styles.profileCard}>
<View style={styles.avatarContainer}>
{user.imageUrl ? (
<View style={styles.avatar}>
<Text style={styles.avatarText}>
{user.firstName?.charAt(0)}
{user.lastName?.charAt(0)}
</Text>
</View>
) : (
<View style={styles.avatar}>
<Ionicons name="person" size={40} color="#fff" />
</View>
)}
</View>
<TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
<Text style={styles.logoutText}>Logout</Text>
</TouchableOpacity>
</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>
)}
</View>
{/* Account Information */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Account Information</Text>
<View style={styles.infoRow}>
<View style={styles.infoLabel}>
<Ionicons name="mail-outline" size={20} color="#666" />
<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}>
<Ionicons name="call-outline" size={20} color="#666" />
<Text style={styles.infoLabelText}>Phone</Text>
</View>
<Text style={styles.infoValue}>
{user.primaryPhoneNumber.phoneNumber}
</Text>
</View>
)}
<View style={styles.infoRow}>
<View style={styles.infoLabel}>
<Ionicons name="calendar-outline" size={20} color="#666" />
<Text style={styles.infoLabelText}>Member Since</Text>
</View>
<Text style={styles.infoValue}>
{new Date(user.createdAt!).toLocaleDateString()}
</Text>
</View>
<View style={styles.infoRow}>
<View style={styles.infoLabel}>
<Ionicons
name="shield-checkmark-outline"
size={20}
color="#666"
/>
<Text style={styles.infoLabelText}>Email Verified</Text>
</View>
<Text style={styles.infoValue}>
{user.primaryEmailAddress?.verification?.status === "verified"
? "Yes"
: "No"}
</Text>
</View>
</View>
{/* Quick Actions */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Quick Actions</Text>
<TouchableOpacity style={styles.actionButton}>
<Ionicons name="person-outline" size={24} color="#2563eb" />
<Text style={styles.actionButtonText}>Edit Profile</Text>
<Ionicons name="chevron-forward" size={20} color="#999" />
</TouchableOpacity>
<TouchableOpacity style={styles.actionButton}>
<Ionicons name="notifications-outline" size={24} color="#2563eb" />
<Text style={styles.actionButtonText}>Notifications</Text>
<Ionicons name="chevron-forward" size={20} color="#999" />
</TouchableOpacity>
<TouchableOpacity style={styles.actionButton}>
<Ionicons name="card-outline" size={24} color="#2563eb" />
<Text style={styles.actionButtonText}>Payment History</Text>
<Ionicons name="chevron-forward" size={20} color="#999" />
</TouchableOpacity>
<TouchableOpacity style={styles.actionButton}>
<Ionicons name="settings-outline" size={24} color="#2563eb" />
<Text style={styles.actionButtonText}>Settings</Text>
<Ionicons name="chevron-forward" size={20} color="#999" />
</TouchableOpacity>
</View>
{/* Sign Out Button */}
<TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
<Ionicons name="log-out-outline" size={20} color="#fff" />
<Text style={styles.logoutText}>Sign Out</Text>
</TouchableOpacity>
{/* App Version */}
<Text style={styles.version}>Version 1.0.0</Text>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f5f5f5",
},
content: {
padding: 20,
backgroundColor: '#f5f5f5',
},
profileCard: {
backgroundColor: 'white',
borderRadius: 12,
backgroundColor: "white",
borderRadius: 16,
padding: 24,
alignItems: 'center',
shadowColor: '#000',
alignItems: "center",
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
shadowRadius: 8,
elevation: 4,
marginBottom: 24,
},
title: {
fontSize: 24,
fontWeight: 'bold',
avatarContainer: {
marginBottom: 16,
},
avatar: {
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: "#2563eb",
justifyContent: "center",
alignItems: "center",
},
avatarText: {
fontSize: 32,
fontWeight: "bold",
color: "#fff",
},
name: {
fontSize: 20,
fontWeight: '600',
fontSize: 24,
fontWeight: "bold",
color: "#1a1a1a",
marginBottom: 4,
},
email: {
fontSize: 16,
color: '#666',
color: "#666",
marginBottom: 4,
},
phone: {
fontSize: 16,
color: '#666',
fontSize: 14,
color: "#999",
},
section: {
backgroundColor: "white",
borderRadius: 16,
padding: 20,
marginBottom: 16,
shadowColor: "#000",
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 4,
elevation: 2,
},
sectionTitle: {
fontSize: 18,
fontWeight: "600",
color: "#1a1a1a",
marginBottom: 16,
},
roleBadge: {
backgroundColor: '#3b82f6',
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 20,
infoRow: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingVertical: 12,
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
},
roleText: {
color: 'white',
infoLabel: {
flexDirection: "row",
alignItems: "center",
gap: 8,
},
infoLabelText: {
fontSize: 14,
fontWeight: '600',
color: "#666",
fontWeight: "500",
},
infoValue: {
fontSize: 14,
color: "#1a1a1a",
fontWeight: "500",
},
actionButton: {
flexDirection: "row",
alignItems: "center",
paddingVertical: 16,
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
},
actionButtonText: {
flex: 1,
fontSize: 16,
color: "#1a1a1a",
marginLeft: 12,
fontWeight: "500",
},
logoutButton: {
backgroundColor: '#ef4444',
paddingVertical: 14,
borderRadius: 8,
alignItems: 'center',
marginTop: 24,
backgroundColor: "#ef4444",
paddingVertical: 16,
borderRadius: 12,
alignItems: "center",
justifyContent: "center",
flexDirection: "row",
gap: 8,
marginTop: 8,
marginBottom: 16,
shadowColor: "#ef4444",
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 4,
},
logoutText: {
color: 'white',
color: "white",
fontSize: 16,
fontWeight: '600',
fontWeight: "600",
},
})
version: {
textAlign: "center",
fontSize: 12,
color: "#999",
marginTop: 8,
marginBottom: 20,
},
});