claude take :(
This commit is contained in:
1 parent
fc12cecd30
commit
73d2c4c1ed
13 files changed
+1460
-517
No files matched your search
@@ -1,18 +1,30 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
Animated,
|
||||
} from "react-native";
|
||||
import { useUser } from "@clerk/clerk-expo";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useRouter } from "expo-router";
|
||||
import { LinearGradient } from "expo-linear-gradient";
|
||||
import { theme } from "../../styles/theme";
|
||||
|
||||
export default function HomeScreen() {
|
||||
const { user, isLoaded } = useUser();
|
||||
const router = useRouter();
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current;
|
||||
|
||||
useEffect(() => {
|
||||
Animated.timing(fadeAnim, {
|
||||
toValue: 1,
|
||||
duration: 500,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
}, []);
|
||||
|
||||
if (!isLoaded || !user) {
|
||||
return (
|
||||
@@ -27,32 +39,67 @@ export default function HomeScreen() {
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.container}>
|
||||
<View style={styles.content}>
|
||||
{/* Welcome Header */}
|
||||
<View style={styles.header}>
|
||||
<Animated.View style={[styles.content, { opacity: fadeAnim }]}>
|
||||
{/* Gradient Header */}
|
||||
<LinearGradient
|
||||
colors={theme.gradients.primary}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 1 }}
|
||||
style={styles.header}
|
||||
>
|
||||
<Text style={styles.greeting}>{greeting}!</Text>
|
||||
<Text style={styles.name}>{firstName}</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
|
||||
{/* Quick Stats */}
|
||||
{/* Quick Stats with Glassmorphism */}
|
||||
<View style={styles.statsContainer}>
|
||||
<View style={styles.statCard}>
|
||||
<Ionicons name="calendar-outline" size={32} color="#2563eb" />
|
||||
<LinearGradient
|
||||
colors={['rgba(59, 130, 246, 0.1)', 'rgba(139, 92, 246, 0.1)']}
|
||||
style={[styles.statCard, theme.shadows.medium]}
|
||||
>
|
||||
<View style={styles.statIconContainer}>
|
||||
<LinearGradient
|
||||
colors={theme.gradients.primary}
|
||||
style={styles.statIconGradient}
|
||||
>
|
||||
<Ionicons name="calendar-outline" size={24} color="#fff" />
|
||||
</LinearGradient>
|
||||
</View>
|
||||
<Text style={styles.statValue}>0</Text>
|
||||
<Text style={styles.statLabel}>This Month</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
|
||||
<View style={styles.statCard}>
|
||||
<Ionicons name="flame-outline" size={32} color="#ef4444" />
|
||||
<LinearGradient
|
||||
colors={['rgba(239, 68, 68, 0.1)', 'rgba(236, 72, 153, 0.1)']}
|
||||
style={[styles.statCard, theme.shadows.medium]}
|
||||
>
|
||||
<View style={styles.statIconContainer}>
|
||||
<LinearGradient
|
||||
colors={theme.gradients.danger}
|
||||
style={styles.statIconGradient}
|
||||
>
|
||||
<Ionicons name="flame-outline" size={24} color="#fff" />
|
||||
</LinearGradient>
|
||||
</View>
|
||||
<Text style={styles.statValue}>0</Text>
|
||||
<Text style={styles.statLabel}>Day Streak</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
|
||||
<View style={styles.statCard}>
|
||||
<Ionicons name="trophy-outline" size={32} color="#f59e0b" />
|
||||
<LinearGradient
|
||||
colors={['rgba(245, 158, 11, 0.1)', 'rgba(217, 119, 6, 0.1)']}
|
||||
style={[styles.statCard, theme.shadows.medium]}
|
||||
>
|
||||
<View style={styles.statIconContainer}>
|
||||
<LinearGradient
|
||||
colors={theme.gradients.warning}
|
||||
style={styles.statIconGradient}
|
||||
>
|
||||
<Ionicons name="trophy-outline" size={24} color="#fff" />
|
||||
</LinearGradient>
|
||||
</View>
|
||||
<Text style={styles.statValue}>0</Text>
|
||||
<Text style={styles.statLabel}>Total Visits</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</View>
|
||||
|
||||
{/* Quick Actions */}
|
||||
@@ -60,12 +107,16 @@ export default function HomeScreen() {
|
||||
<Text style={styles.sectionTitle}>Quick Actions</Text>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.actionButton}
|
||||
style={[styles.actionButton, theme.shadows.medium]}
|
||||
onPress={() => router.push("/fitness-profile")}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<View style={styles.actionIcon}>
|
||||
<LinearGradient
|
||||
colors={['rgba(236, 72, 153, 0.15)', 'rgba(236, 72, 153, 0.05)']}
|
||||
style={styles.actionIcon}
|
||||
>
|
||||
<Ionicons name="fitness-outline" size={24} color="#ec4899" />
|
||||
</View>
|
||||
</LinearGradient>
|
||||
<View style={styles.actionContent}>
|
||||
<Text style={styles.actionTitle}>Fitness Profile</Text>
|
||||
<Text style={styles.actionSubtitle}>
|
||||
@@ -75,12 +126,16 @@ export default function HomeScreen() {
|
||||
<Ionicons name="chevron-forward" size={20} color="#9ca3af" />
|
||||
</TouchableOpacity>
|
||||
|
||||
|
||||
|
||||
<View style={styles.actionButton}>
|
||||
<View style={styles.actionIcon}>
|
||||
<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.actionIcon}
|
||||
>
|
||||
<Ionicons name="log-in-outline" size={24} color="#2563eb" />
|
||||
</View>
|
||||
</LinearGradient>
|
||||
<View style={styles.actionContent}>
|
||||
<Text style={styles.actionTitle}>Check In</Text>
|
||||
<Text style={styles.actionSubtitle}>
|
||||
@@ -88,13 +143,18 @@ export default function HomeScreen() {
|
||||
</Text>
|
||||
</View>
|
||||
<Ionicons name="chevron-forward" size={20} color="#9ca3af" />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
|
||||
<View style={styles.actionButton}>
|
||||
<View style={styles.actionIcon}>
|
||||
<TouchableOpacity
|
||||
style={[styles.actionButton, theme.shadows.medium]}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<LinearGradient
|
||||
colors={['rgba(16, 185, 129, 0.15)', 'rgba(16, 185, 129, 0.05)']}
|
||||
style={styles.actionIcon}
|
||||
>
|
||||
<Ionicons name="calendar-outline" size={24} color="#10b981" />
|
||||
</View>
|
||||
</LinearGradient>
|
||||
<View style={styles.actionContent}>
|
||||
<Text style={styles.actionTitle}>View Schedule</Text>
|
||||
<Text style={styles.actionSubtitle}>
|
||||
@@ -102,24 +162,35 @@ export default function HomeScreen() {
|
||||
</Text>
|
||||
</View>
|
||||
<Ionicons name="chevron-forward" size={20} color="#9ca3af" />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.actionButton}>
|
||||
<View style={styles.actionIcon}>
|
||||
<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.actionIcon}
|
||||
>
|
||||
<Ionicons name="card-outline" size={24} color="#8b5cf6" />
|
||||
</View>
|
||||
</LinearGradient>
|
||||
<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>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Membership Info */}
|
||||
{/* Membership Info with Gradient */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Membership</Text>
|
||||
<View style={styles.membershipCard}>
|
||||
<LinearGradient
|
||||
colors={theme.gradients.primary}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 1 }}
|
||||
style={[styles.membershipCard, theme.shadows.strong]}
|
||||
>
|
||||
<View style={styles.membershipHeader}>
|
||||
<Text style={styles.membershipType}>Basic Plan</Text>
|
||||
<View style={styles.statusBadge}>
|
||||
@@ -132,21 +203,28 @@ export default function HomeScreen() {
|
||||
<Text style={styles.membershipDate}>
|
||||
Member since {new Date(user.createdAt!).toLocaleDateString()}
|
||||
</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</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" />
|
||||
<View style={[styles.emptyState, theme.shadows.medium]}>
|
||||
<View style={styles.emptyIconContainer}>
|
||||
<LinearGradient
|
||||
colors={['rgba(209, 213, 219, 0.3)', 'rgba(209, 213, 219, 0.1)']}
|
||||
style={styles.emptyIconGradient}
|
||||
>
|
||||
<Ionicons name="barbell-outline" size={48} color="#9ca3af" />
|
||||
</LinearGradient>
|
||||
</View>
|
||||
<Text style={styles.emptyStateText}>No recent activity</Text>
|
||||
<Text style={styles.emptyStateSubtext}>
|
||||
Check in to start tracking your workouts
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Animated.View>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
@@ -161,81 +239,90 @@ function getGreeting(): string {
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#f5f5f5",
|
||||
backgroundColor: theme.colors.background,
|
||||
},
|
||||
content: {
|
||||
padding: 20,
|
||||
paddingBottom: 20,
|
||||
},
|
||||
header: {
|
||||
marginBottom: 24,
|
||||
padding: 24,
|
||||
paddingTop: 60,
|
||||
paddingBottom: 32,
|
||||
borderBottomLeftRadius: theme.borderRadius['2xl'],
|
||||
borderBottomRightRadius: theme.borderRadius['2xl'],
|
||||
marginBottom: 20,
|
||||
},
|
||||
greeting: {
|
||||
fontSize: 16,
|
||||
color: "#6b7280",
|
||||
fontSize: theme.typography.fontSize.base,
|
||||
color: "rgba(255, 255, 255, 0.9)",
|
||||
marginBottom: 4,
|
||||
},
|
||||
name: {
|
||||
fontSize: 32,
|
||||
fontWeight: "bold",
|
||||
color: "#1a1a1a",
|
||||
fontSize: theme.typography.fontSize['4xl'],
|
||||
fontWeight: theme.typography.fontWeight.bold,
|
||||
color: theme.colors.white,
|
||||
},
|
||||
statsContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
paddingHorizontal: 16,
|
||||
marginBottom: 24,
|
||||
gap: 12,
|
||||
},
|
||||
statCard: {
|
||||
flex: 1,
|
||||
backgroundColor: "white",
|
||||
borderRadius: 12,
|
||||
backgroundColor: theme.colors.white,
|
||||
borderRadius: theme.borderRadius.xl,
|
||||
padding: 16,
|
||||
alignItems: "center",
|
||||
marginHorizontal: 4,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
borderWidth: 1,
|
||||
borderColor: "rgba(255, 255, 255, 0.3)",
|
||||
},
|
||||
statIconContainer: {
|
||||
marginBottom: 8,
|
||||
},
|
||||
statIconGradient: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 24,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
statValue: {
|
||||
fontSize: 24,
|
||||
fontWeight: "bold",
|
||||
color: "#1a1a1a",
|
||||
marginTop: 8,
|
||||
fontSize: theme.typography.fontSize['2xl'],
|
||||
fontWeight: theme.typography.fontWeight.bold,
|
||||
color: theme.colors.gray900,
|
||||
marginTop: 4,
|
||||
marginBottom: 4,
|
||||
},
|
||||
statLabel: {
|
||||
fontSize: 12,
|
||||
color: "#6b7280",
|
||||
fontSize: theme.typography.fontSize.xs,
|
||||
color: theme.colors.gray600,
|
||||
textAlign: "center",
|
||||
fontWeight: theme.typography.fontWeight.medium,
|
||||
},
|
||||
section: {
|
||||
marginBottom: 24,
|
||||
paddingHorizontal: 20,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: "600",
|
||||
color: "#1a1a1a",
|
||||
fontSize: theme.typography.fontSize.xl,
|
||||
fontWeight: theme.typography.fontWeight.semibold,
|
||||
color: theme.colors.gray900,
|
||||
marginBottom: 12,
|
||||
},
|
||||
actionButton: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: "white",
|
||||
borderRadius: 12,
|
||||
backgroundColor: theme.colors.white,
|
||||
borderRadius: theme.borderRadius.xl,
|
||||
padding: 16,
|
||||
marginBottom: 8,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
marginBottom: 12,
|
||||
},
|
||||
actionIcon: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 24,
|
||||
backgroundColor: "#f0f9ff",
|
||||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: 28,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginRight: 12,
|
||||
@@ -244,77 +331,77 @@ const styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
},
|
||||
actionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: "600",
|
||||
color: "#1a1a1a",
|
||||
fontSize: theme.typography.fontSize.base,
|
||||
fontWeight: theme.typography.fontWeight.semibold,
|
||||
color: theme.colors.gray900,
|
||||
marginBottom: 2,
|
||||
},
|
||||
actionSubtitle: {
|
||||
fontSize: 14,
|
||||
color: "#6b7280",
|
||||
fontSize: theme.typography.fontSize.sm,
|
||||
color: theme.colors.gray600,
|
||||
},
|
||||
membershipCard: {
|
||||
backgroundColor: "white",
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
borderRadius: theme.borderRadius.xl,
|
||||
padding: 20,
|
||||
},
|
||||
membershipHeader: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
marginBottom: 8,
|
||||
marginBottom: 12,
|
||||
},
|
||||
membershipType: {
|
||||
fontSize: 18,
|
||||
fontWeight: "600",
|
||||
color: "#1a1a1a",
|
||||
fontSize: theme.typography.fontSize.xl,
|
||||
fontWeight: theme.typography.fontWeight.semibold,
|
||||
color: theme.colors.white,
|
||||
},
|
||||
statusBadge: {
|
||||
backgroundColor: "#dcfce7",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.25)",
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 4,
|
||||
borderRadius: 12,
|
||||
paddingVertical: 6,
|
||||
borderRadius: theme.borderRadius.lg,
|
||||
borderWidth: 1,
|
||||
borderColor: "rgba(255, 255, 255, 0.3)",
|
||||
},
|
||||
statusText: {
|
||||
fontSize: 12,
|
||||
fontWeight: "600",
|
||||
color: "#16a34a",
|
||||
fontSize: theme.typography.fontSize.xs,
|
||||
fontWeight: theme.typography.fontWeight.semibold,
|
||||
color: theme.colors.white,
|
||||
},
|
||||
membershipEmail: {
|
||||
fontSize: 14,
|
||||
color: "#6b7280",
|
||||
fontSize: theme.typography.fontSize.sm,
|
||||
color: "rgba(255, 255, 255, 0.9)",
|
||||
marginBottom: 4,
|
||||
},
|
||||
membershipDate: {
|
||||
fontSize: 12,
|
||||
color: "#9ca3af",
|
||||
fontSize: theme.typography.fontSize.xs,
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
},
|
||||
emptyState: {
|
||||
backgroundColor: "white",
|
||||
borderRadius: 12,
|
||||
backgroundColor: theme.colors.white,
|
||||
borderRadius: theme.borderRadius.xl,
|
||||
padding: 32,
|
||||
alignItems: "center",
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
},
|
||||
emptyIconContainer: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
emptyIconGradient: {
|
||||
width: 96,
|
||||
height: 96,
|
||||
borderRadius: 48,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
emptyStateText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "600",
|
||||
color: "#6b7280",
|
||||
marginTop: 12,
|
||||
fontSize: theme.typography.fontSize.base,
|
||||
fontWeight: theme.typography.fontWeight.semibold,
|
||||
color: theme.colors.gray700,
|
||||
marginBottom: 4,
|
||||
},
|
||||
emptyStateSubtext: {
|
||||
fontSize: 14,
|
||||
color: "#9ca3af",
|
||||
fontSize: theme.typography.fontSize.sm,
|
||||
color: theme.colors.gray500,
|
||||
textAlign: "center",
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user