Initial commit: expo-popcore project
This commit is contained in:
130
components/GiftCard.tsx
Normal file
130
components/GiftCard.tsx
Normal file
@@ -0,0 +1,130 @@
|
||||
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,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user