| import React from 'react'; |
| import { StyleSheet, View } from 'react-native'; |
| import { useTheme, Avatar, Card, Text } from 'react-native-paper'; |
|
|
| export interface UserCardProps { |
| |
| user: { |
| displayName: string; |
| email?: string; |
| avatarUrl?: string; |
| ratingAvg?: number; |
| totalRides?: number; |
| }; |
| |
| onPress?: () => void; |
| |
| size?: 'small' | 'medium' | 'large'; |
| } |
|
|
| |
| |
| |
| |
| 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, |
| }, |
| }); |
|
|