mobileapp / src /components /profile /UserCard.tsx
Antaram Dev Bot
feat: complete ANTARAM.ORG ride-sharing app frontend
5c876be
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { useTheme, Avatar, Card, Text } from 'react-native-paper';
export interface UserCardProps {
/** User data to display */
user: {
displayName: string;
email?: string;
avatarUrl?: string;
ratingAvg?: number;
totalRides?: number;
};
/** Callback when the card is pressed */
onPress?: () => void;
/** Visual size variant */
size?: 'small' | 'medium' | 'large';
}
/**
* User profile summary card showing avatar, name, email,
* rating, and ride count. Supports three size variants.
*/
export function UserCard({ user, onPress, size = 'medium' }: UserCardProps) {
const theme = useTheme();
const avatarSize = size === 'small' ? 36 : size === 'medium' ? 52 : 72;
const initials = user.displayName
.split(' ')
.map((w) => w.charAt(0))
.join('')
.toUpperCase()
.slice(0, 2);
return (
<Card
style={[styles.card, { backgroundColor: theme.colors.surface }]}
onPress={onPress}
mode={size === 'large' ? 'elevated' : 'outlined'}
elevation={size === 'large' ? 2 : 0}
>
<Card.Content
style={[
styles.content,
size === 'large' && styles.contentLarge,
]}
>
<Avatar.Text
size={avatarSize}
label={initials}
source={user.avatarUrl ? { uri: user.avatarUrl } : undefined}
style={{ backgroundColor: theme.colors.primaryContainer }}
color={theme.colors.onPrimaryContainer}
/>
<View style={styles.info}>
<Text
variant={size === 'large' ? 'headlineSmall' : 'titleMedium'}
style={{ color: theme.colors.onSurface }}
>
{user.displayName}
</Text>
{user.email ? (
<Text
variant="bodySmall"
style={{ color: theme.colors.onSurfaceVariant }}
>
{user.email}
</Text>
) : null}
<View style={styles.metaRow}>
{user.ratingAvg != null && user.ratingAvg > 0 && (
<Text
variant="labelSmall"
style={{ color: theme.colors.onSurfaceVariant }}
>
⭐ {user.ratingAvg.toFixed(1)}
</Text>
)}
{user.totalRides != null && user.totalRides > 0 && (
<Text
variant="labelSmall"
style={{ color: theme.colors.onSurfaceVariant }}
>
{user.totalRides} ride{user.totalRides !== 1 ? 's' : ''}
</Text>
)}
</View>
</View>
</Card.Content>
</Card>
);
}
const styles = StyleSheet.create({
card: {
borderRadius: 12,
},
content: {
flexDirection: 'row',
alignItems: 'center',
gap: 14,
paddingVertical: 10,
paddingHorizontal: 14,
},
contentLarge: {
flexDirection: 'column',
alignItems: 'center',
gap: 10,
paddingVertical: 20,
},
info: {
flex: 1,
gap: 2,
},
metaRow: {
flexDirection: 'row',
gap: 12,
marginTop: 2,
},
});