131 lines
3.0 KiB
TypeScript
131 lines
3.0 KiB
TypeScript
import { View, StyleSheet, StyleProp, type ViewStyle } from 'react-native';
|
|
import { ThemedText } from '@/components/themed-text';
|
|
import { ThemedView } from '@/components/themed-view';
|
|
import { Button } from '@/components/ui/button';
|
|
import { useThemeColor } from '@/hooks/use-theme-color';
|
|
import { Colors, Spacing, BorderRadius, FontSize, Shadow } from '@/constants/theme';
|
|
|
|
export interface GiftCardProps {
|
|
icon: string;
|
|
title: string;
|
|
description: string;
|
|
points: number;
|
|
onExchange?: () => void;
|
|
style?: StyleProp<ViewStyle>;
|
|
}
|
|
|
|
export function GiftCard({
|
|
icon,
|
|
title,
|
|
description,
|
|
points,
|
|
onExchange,
|
|
style,
|
|
}: GiftCardProps) {
|
|
const cardBackgroundColor = useThemeColor(
|
|
{ light: '#fff', dark: '#1F2223' },
|
|
'card'
|
|
);
|
|
const borderColor = useThemeColor(
|
|
{ light: '#e0e0e0', dark: '#2C2E2F' },
|
|
'cardBorder'
|
|
);
|
|
const pointsColor = '#FF6B6B';
|
|
const descriptionColor = useThemeColor(
|
|
{ light: '#666666', dark: '#9BA1A6' },
|
|
'text'
|
|
);
|
|
|
|
return (
|
|
<ThemedView
|
|
style={[
|
|
styles.card,
|
|
{ backgroundColor: cardBackgroundColor, borderColor },
|
|
style,
|
|
]}
|
|
>
|
|
<View style={styles.header}>
|
|
<View style={styles.iconContainer}>
|
|
<ThemedText style={styles.icon}>{icon}</ThemedText>
|
|
</View>
|
|
<ThemedText style={styles.title}>{title}</ThemedText>
|
|
</View>
|
|
|
|
<View style={styles.content}>
|
|
<ThemedText style={[styles.description, { color: descriptionColor }]}>
|
|
{description}
|
|
</ThemedText>
|
|
</View>
|
|
|
|
<View style={styles.footer}>
|
|
<View style={styles.pointsContainer}>
|
|
<ThemedText style={[styles.points, { color: pointsColor }]}>
|
|
{points.toLocaleString()}
|
|
</ThemedText>
|
|
<ThemedText style={[styles.pointsLabel, { color: descriptionColor }]}>
|
|
积分
|
|
</ThemedText>
|
|
</View>
|
|
<Button variant="primary" size="md" onPress={onExchange}>
|
|
兑换
|
|
</Button>
|
|
</View>
|
|
</ThemedView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
card: {
|
|
borderRadius: BorderRadius.md,
|
|
padding: Spacing.md,
|
|
borderWidth: 1,
|
|
...Shadow.small,
|
|
},
|
|
header: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
marginBottom: Spacing.md,
|
|
},
|
|
iconContainer: {
|
|
width: 40,
|
|
height: 40,
|
|
borderRadius: 20,
|
|
backgroundColor: Colors.background.tertiary,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
marginRight: Spacing.md,
|
|
},
|
|
icon: {
|
|
fontSize: 20,
|
|
},
|
|
title: {
|
|
fontSize: FontSize.md,
|
|
fontWeight: '600',
|
|
flex: 1,
|
|
},
|
|
content: {
|
|
marginBottom: Spacing.md,
|
|
},
|
|
description: {
|
|
fontSize: FontSize.sm,
|
|
lineHeight: 20,
|
|
},
|
|
footer: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
},
|
|
pointsContainer: {
|
|
flexDirection: 'row',
|
|
alignItems: 'baseline',
|
|
},
|
|
points: {
|
|
fontSize: FontSize.lg,
|
|
fontWeight: '700',
|
|
marginRight: Spacing.xs,
|
|
},
|
|
pointsLabel: {
|
|
fontSize: FontSize.xs,
|
|
},
|
|
});
|