189 lines
4.1 KiB
TypeScript
189 lines
4.1 KiB
TypeScript
import React, {useState, useEffect} from 'react';
|
|
import {View, Text, StyleSheet, FlatList, TouchableOpacity} from 'react-native';
|
|
import Icon from 'react-native-vector-icons/Ionicons';
|
|
import LinearGradient from 'react-native-linear-gradient';
|
|
|
|
type Subscription = {
|
|
id: number;
|
|
name: string;
|
|
amount: number;
|
|
startDate: string;
|
|
endDate: string;
|
|
color: string[];
|
|
};
|
|
|
|
const mockSubscriptions: Subscription[] = [
|
|
{
|
|
id: 1,
|
|
name: 'Netflix',
|
|
amount: 12.99,
|
|
startDate: '2021-01-01',
|
|
endDate: '2022-01-01',
|
|
color: ['#e52d27', '#b31217'],
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Spotify',
|
|
amount: 9.99,
|
|
startDate: '2021-02-01',
|
|
endDate: '2022-02-01',
|
|
color: ['#1db954', '#1ed760'],
|
|
},
|
|
{
|
|
id: 3,
|
|
name: 'Amazon Prime',
|
|
amount: 14.99,
|
|
startDate: '2021-03-01',
|
|
endDate: '2022-03-01',
|
|
color: ['#f90', '#ff9900'],
|
|
},
|
|
{
|
|
id: 4,
|
|
name: 'Disney+',
|
|
amount: 7.99,
|
|
startDate: '2021-04-01',
|
|
endDate: '2022-04-01',
|
|
color: ['#113ccf', '#5e91f2'],
|
|
},
|
|
// 更多示例数据...
|
|
];
|
|
|
|
const SubscriptionPage: React.FC = () => {
|
|
const [subscriptions, setSubscriptions] =
|
|
useState<Subscription[]>(mockSubscriptions);
|
|
const fetchSubscriptions = () => {
|
|
setSubscriptions(mockSubscriptions);
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchSubscriptions();
|
|
}, []);
|
|
|
|
const renderItem = ({item}: {item: Subscription}) => {
|
|
return (
|
|
<LinearGradient
|
|
colors={item.color}
|
|
style={styles.card}
|
|
start={{x: 0, y: 0}}
|
|
end={{x: 1, y: 1}}>
|
|
<View style={styles.iconPlaceholder} />
|
|
<View style={styles.textContainer}>
|
|
<Text style={styles.name}>{item.name}</Text>
|
|
<Text style={styles.date}>{item.endDate}</Text>
|
|
</View>
|
|
<Text style={styles.amount}>${item.amount}</Text>
|
|
<TouchableOpacity style={styles.editButton}>
|
|
<Icon name="pencil" size={20} color="#fff" />
|
|
</TouchableOpacity>
|
|
</LinearGradient>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<View style={styles.header}>
|
|
<Text style={styles.headerTitle}>Subscriptions</Text>
|
|
</View>
|
|
<FlatList
|
|
contentContainerStyle={styles.listContainer}
|
|
data={subscriptions}
|
|
renderItem={renderItem}
|
|
keyExtractor={item => item.id.toString()}
|
|
numColumns={2}
|
|
columnWrapperStyle={styles.row}
|
|
/>
|
|
<TouchableOpacity style={styles.addButton}>
|
|
<Icon name="add" size={30} color="#fff" />
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#f7f7f7',
|
|
},
|
|
listContainer: {
|
|
paddingHorizontal: 16,
|
|
},
|
|
row: {
|
|
justifyContent: 'space-between',
|
|
marginBottom: 16,
|
|
},
|
|
card: {
|
|
borderRadius: 15,
|
|
padding: 15,
|
|
width: '48%',
|
|
shadowColor: '#000',
|
|
shadowOpacity: 0.1,
|
|
shadowRadius: 10,
|
|
shadowOffset: {width: 0, height: 4},
|
|
elevation: 5,
|
|
},
|
|
iconPlaceholder: {
|
|
width: 50,
|
|
height: 50,
|
|
borderRadius: 25,
|
|
backgroundColor: '#fff',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
textContainer: {
|
|
flexDirection: 'column',
|
|
marginTop: 10,
|
|
},
|
|
name: {
|
|
fontSize: 18,
|
|
fontWeight: 'bold',
|
|
color: '#fff',
|
|
},
|
|
date: {
|
|
fontSize: 14,
|
|
color: '#fff',
|
|
marginTop: 5,
|
|
},
|
|
amount: {
|
|
fontSize: 16,
|
|
fontWeight: 'bold',
|
|
color: '#fff',
|
|
position: 'absolute',
|
|
top: 10,
|
|
right: 10,
|
|
},
|
|
editButton: {
|
|
position: 'absolute',
|
|
bottom: 10,
|
|
right: 10,
|
|
},
|
|
addButton: {
|
|
backgroundColor: '#4F8EF7',
|
|
position: 'absolute',
|
|
bottom: 30,
|
|
right: 30,
|
|
width: 50,
|
|
height: 50,
|
|
borderRadius: 25,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
shadowColor: '#000',
|
|
shadowOffset: {width: 0, height: 2},
|
|
shadowOpacity: 0.2,
|
|
shadowRadius: 8,
|
|
elevation: 5,
|
|
},
|
|
header: {
|
|
paddingTop: 70,
|
|
paddingBottom: 15,
|
|
paddingLeft: 15,
|
|
alignItems: 'flex-start',
|
|
},
|
|
headerTitle: {
|
|
fontSize: 27,
|
|
fontWeight: 'bold',
|
|
color: '#333',
|
|
},
|
|
});
|
|
|
|
export default SubscriptionPage;
|