321 lines
8.4 KiB
TypeScript
321 lines
8.4 KiB
TypeScript
import React from "react";
|
|
import {
|
|
View,
|
|
Text,
|
|
StyleSheet,
|
|
ScrollView,
|
|
TouchableOpacity,
|
|
} from "react-native";
|
|
import { useUser } from "@clerk/clerk-expo";
|
|
import { Ionicons } from "@expo/vector-icons";
|
|
import { useRouter } from "expo-router";
|
|
|
|
export default function HomeScreen() {
|
|
const { user, isLoaded } = useUser();
|
|
const router = useRouter();
|
|
|
|
if (!isLoaded || !user) {
|
|
return (
|
|
<View style={styles.container}>
|
|
<Text>Loading...</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const firstName = user.firstName || "User";
|
|
const greeting = getGreeting();
|
|
|
|
return (
|
|
<ScrollView style={styles.container}>
|
|
<View style={styles.content}>
|
|
{/* Welcome Header */}
|
|
<View style={styles.header}>
|
|
<Text style={styles.greeting}>{greeting}!</Text>
|
|
<Text style={styles.name}>{firstName}</Text>
|
|
</View>
|
|
|
|
{/* Quick Stats */}
|
|
<View style={styles.statsContainer}>
|
|
<View style={styles.statCard}>
|
|
<Ionicons name="calendar-outline" size={32} color="#2563eb" />
|
|
<Text style={styles.statValue}>0</Text>
|
|
<Text style={styles.statLabel}>This Month</Text>
|
|
</View>
|
|
|
|
<View style={styles.statCard}>
|
|
<Ionicons name="flame-outline" size={32} color="#ef4444" />
|
|
<Text style={styles.statValue}>0</Text>
|
|
<Text style={styles.statLabel}>Day Streak</Text>
|
|
</View>
|
|
|
|
<View style={styles.statCard}>
|
|
<Ionicons name="trophy-outline" size={32} color="#f59e0b" />
|
|
<Text style={styles.statValue}>0</Text>
|
|
<Text style={styles.statLabel}>Total Visits</Text>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Quick Actions */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>Quick Actions</Text>
|
|
|
|
<TouchableOpacity
|
|
style={styles.actionButton}
|
|
onPress={() => router.push("/fitness-profile")}
|
|
>
|
|
<View style={styles.actionIcon}>
|
|
<Ionicons name="fitness-outline" size={24} color="#ec4899" />
|
|
</View>
|
|
<View style={styles.actionContent}>
|
|
<Text style={styles.actionTitle}>Fitness Profile</Text>
|
|
<Text style={styles.actionSubtitle}>
|
|
Manage your fitness information
|
|
</Text>
|
|
</View>
|
|
<Ionicons name="chevron-forward" size={20} color="#9ca3af" />
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
<View style={styles.actionButton}>
|
|
<View style={styles.actionIcon}>
|
|
<Ionicons name="log-in-outline" size={24} color="#2563eb" />
|
|
</View>
|
|
<View style={styles.actionContent}>
|
|
<Text style={styles.actionTitle}>Check In</Text>
|
|
<Text style={styles.actionSubtitle}>
|
|
Start your workout session
|
|
</Text>
|
|
</View>
|
|
<Ionicons name="chevron-forward" size={20} color="#9ca3af" />
|
|
</View>
|
|
|
|
|
|
<View style={styles.actionButton}>
|
|
<View style={styles.actionIcon}>
|
|
<Ionicons name="calendar-outline" size={24} color="#10b981" />
|
|
</View>
|
|
<View style={styles.actionContent}>
|
|
<Text style={styles.actionTitle}>View Schedule</Text>
|
|
<Text style={styles.actionSubtitle}>
|
|
Check your upcoming classes
|
|
</Text>
|
|
</View>
|
|
<Ionicons name="chevron-forward" size={20} color="#9ca3af" />
|
|
</View>
|
|
|
|
<View style={styles.actionButton}>
|
|
<View style={styles.actionIcon}>
|
|
<Ionicons name="card-outline" size={24} color="#8b5cf6" />
|
|
</View>
|
|
<View style={styles.actionContent}>
|
|
<Text style={styles.actionTitle}>Payments</Text>
|
|
<Text style={styles.actionSubtitle}>View payment history</Text>
|
|
</View>
|
|
<Ionicons name="chevron-forward" size={20} color="#9ca3af" />
|
|
</View>
|
|
</View>
|
|
|
|
{/* Membership Info */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>Membership</Text>
|
|
<View style={styles.membershipCard}>
|
|
<View style={styles.membershipHeader}>
|
|
<Text style={styles.membershipType}>Basic Plan</Text>
|
|
<View style={styles.statusBadge}>
|
|
<Text style={styles.statusText}>Active</Text>
|
|
</View>
|
|
</View>
|
|
<Text style={styles.membershipEmail}>
|
|
{user.primaryEmailAddress?.emailAddress}
|
|
</Text>
|
|
<Text style={styles.membershipDate}>
|
|
Member since {new Date(user.createdAt!).toLocaleDateString()}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Recent Activity */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>Recent Activity</Text>
|
|
<View style={styles.emptyState}>
|
|
<Ionicons name="barbell-outline" size={48} color="#d1d5db" />
|
|
<Text style={styles.emptyStateText}>No recent activity</Text>
|
|
<Text style={styles.emptyStateSubtext}>
|
|
Check in to start tracking your workouts
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</ScrollView>
|
|
);
|
|
}
|
|
|
|
function getGreeting(): string {
|
|
const hour = new Date().getHours();
|
|
if (hour < 12) return "Good morning";
|
|
if (hour < 18) return "Good afternoon";
|
|
return "Good evening";
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: "#f5f5f5",
|
|
},
|
|
content: {
|
|
padding: 20,
|
|
},
|
|
header: {
|
|
marginBottom: 24,
|
|
},
|
|
greeting: {
|
|
fontSize: 16,
|
|
color: "#6b7280",
|
|
marginBottom: 4,
|
|
},
|
|
name: {
|
|
fontSize: 32,
|
|
fontWeight: "bold",
|
|
color: "#1a1a1a",
|
|
},
|
|
statsContainer: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
marginBottom: 24,
|
|
},
|
|
statCard: {
|
|
flex: 1,
|
|
backgroundColor: "white",
|
|
borderRadius: 12,
|
|
padding: 16,
|
|
alignItems: "center",
|
|
marginHorizontal: 4,
|
|
shadowColor: "#000",
|
|
shadowOffset: { width: 0, height: 1 },
|
|
shadowOpacity: 0.05,
|
|
shadowRadius: 2,
|
|
elevation: 2,
|
|
},
|
|
statValue: {
|
|
fontSize: 24,
|
|
fontWeight: "bold",
|
|
color: "#1a1a1a",
|
|
marginTop: 8,
|
|
marginBottom: 4,
|
|
},
|
|
statLabel: {
|
|
fontSize: 12,
|
|
color: "#6b7280",
|
|
textAlign: "center",
|
|
},
|
|
section: {
|
|
marginBottom: 24,
|
|
},
|
|
sectionTitle: {
|
|
fontSize: 18,
|
|
fontWeight: "600",
|
|
color: "#1a1a1a",
|
|
marginBottom: 12,
|
|
},
|
|
actionButton: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
backgroundColor: "white",
|
|
borderRadius: 12,
|
|
padding: 16,
|
|
marginBottom: 8,
|
|
shadowColor: "#000",
|
|
shadowOffset: { width: 0, height: 1 },
|
|
shadowOpacity: 0.05,
|
|
shadowRadius: 2,
|
|
elevation: 2,
|
|
},
|
|
actionIcon: {
|
|
width: 48,
|
|
height: 48,
|
|
borderRadius: 24,
|
|
backgroundColor: "#f0f9ff",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
marginRight: 12,
|
|
},
|
|
actionContent: {
|
|
flex: 1,
|
|
},
|
|
actionTitle: {
|
|
fontSize: 16,
|
|
fontWeight: "600",
|
|
color: "#1a1a1a",
|
|
marginBottom: 2,
|
|
},
|
|
actionSubtitle: {
|
|
fontSize: 14,
|
|
color: "#6b7280",
|
|
},
|
|
membershipCard: {
|
|
backgroundColor: "white",
|
|
borderRadius: 12,
|
|
padding: 16,
|
|
shadowColor: "#000",
|
|
shadowOffset: { width: 0, height: 1 },
|
|
shadowOpacity: 0.05,
|
|
shadowRadius: 2,
|
|
elevation: 2,
|
|
},
|
|
membershipHeader: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
marginBottom: 8,
|
|
},
|
|
membershipType: {
|
|
fontSize: 18,
|
|
fontWeight: "600",
|
|
color: "#1a1a1a",
|
|
},
|
|
statusBadge: {
|
|
backgroundColor: "#dcfce7",
|
|
paddingHorizontal: 12,
|
|
paddingVertical: 4,
|
|
borderRadius: 12,
|
|
},
|
|
statusText: {
|
|
fontSize: 12,
|
|
fontWeight: "600",
|
|
color: "#16a34a",
|
|
},
|
|
membershipEmail: {
|
|
fontSize: 14,
|
|
color: "#6b7280",
|
|
marginBottom: 4,
|
|
},
|
|
membershipDate: {
|
|
fontSize: 12,
|
|
color: "#9ca3af",
|
|
},
|
|
emptyState: {
|
|
backgroundColor: "white",
|
|
borderRadius: 12,
|
|
padding: 32,
|
|
alignItems: "center",
|
|
shadowColor: "#000",
|
|
shadowOffset: { width: 0, height: 1 },
|
|
shadowOpacity: 0.05,
|
|
shadowRadius: 2,
|
|
elevation: 2,
|
|
},
|
|
emptyStateText: {
|
|
fontSize: 16,
|
|
fontWeight: "600",
|
|
color: "#6b7280",
|
|
marginTop: 12,
|
|
marginBottom: 4,
|
|
},
|
|
emptyStateSubtext: {
|
|
fontSize: 14,
|
|
color: "#9ca3af",
|
|
textAlign: "center",
|
|
},
|
|
});
|