Subscription Home Screen
This commit is contained in:
parent
c52ec09119
commit
3c3b84c3bd
@ -1,5 +1,7 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- boost (1.83.0)
|
- boost (1.83.0)
|
||||||
|
- BVLinearGradient (2.8.3):
|
||||||
|
- React-Core
|
||||||
- CocoaAsyncSocket (7.6.5)
|
- CocoaAsyncSocket (7.6.5)
|
||||||
- DoubleConversion (1.1.6)
|
- DoubleConversion (1.1.6)
|
||||||
- FBLazyVector (0.73.6)
|
- FBLazyVector (0.73.6)
|
||||||
@ -1132,6 +1134,7 @@ PODS:
|
|||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||||
|
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
|
||||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||||
@ -1229,6 +1232,8 @@ SPEC REPOS:
|
|||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
boost:
|
boost:
|
||||||
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
|
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
|
||||||
|
BVLinearGradient:
|
||||||
|
:path: "../node_modules/react-native-linear-gradient"
|
||||||
DoubleConversion:
|
DoubleConversion:
|
||||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||||
FBLazyVector:
|
FBLazyVector:
|
||||||
@ -1337,6 +1342,7 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
||||||
|
BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3
|
||||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||||
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
|
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
|
||||||
FBLazyVector: f64d1e2ea739b4d8f7e4740cde18089cd97fe864
|
FBLazyVector: f64d1e2ea739b4d8f7e4740cde18089cd97fe864
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
"react-i18next": "^14.1.0",
|
"react-i18next": "^14.1.0",
|
||||||
"react-native": "0.73.6",
|
"react-native": "0.73.6",
|
||||||
"react-native-gesture-handler": "^2.15.0",
|
"react-native-gesture-handler": "^2.15.0",
|
||||||
|
"react-native-linear-gradient": "^2.8.3",
|
||||||
"react-native-safe-area-context": "^4.9.0",
|
"react-native-safe-area-context": "^4.9.0",
|
||||||
"react-native-screens": "^3.29.0",
|
"react-native-screens": "^3.29.0",
|
||||||
"react-native-sqlite-storage": "^6.0.1",
|
"react-native-sqlite-storage": "^6.0.1",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
|
|||||||
import {NavigationContainer} from '@react-navigation/native';
|
import {NavigationContainer} from '@react-navigation/native';
|
||||||
import Icon from 'react-native-vector-icons/Ionicons';
|
import Icon from 'react-native-vector-icons/Ionicons';
|
||||||
import {useTranslation} from 'react-i18next';
|
import {useTranslation} from 'react-i18next';
|
||||||
import { RootTabParamList } from "./type.ts";
|
import {RootTabParamList} from './type.ts';
|
||||||
|
|
||||||
import OverviewPage from '../pages/OverviewPage';
|
import OverviewPage from '../pages/OverviewPage';
|
||||||
import SubscriptionPage from '../pages/SubscriptionPage';
|
import SubscriptionPage from '../pages/SubscriptionPage';
|
||||||
@ -48,7 +48,11 @@ const BottomTabNavigator: React.FC = () => {
|
|||||||
tabBarInactiveTintColor: 'gray',
|
tabBarInactiveTintColor: 'gray',
|
||||||
})}>
|
})}>
|
||||||
<Tab.Screen name="Overview" component={OverviewPage} />
|
<Tab.Screen name="Overview" component={OverviewPage} />
|
||||||
<Tab.Screen name="Subscription" component={SubscriptionPage} />
|
<Tab.Screen
|
||||||
|
name="Subscription"
|
||||||
|
component={SubscriptionPage}
|
||||||
|
options={{headerShown: false}}
|
||||||
|
/>
|
||||||
<Tab.Screen name="Saving" component={SavingPage} />
|
<Tab.Screen name="Saving" component={SavingPage} />
|
||||||
<Tab.Screen name="Profile" component={ProfilePage} />
|
<Tab.Screen name="Profile" component={ProfilePage} />
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
|
|||||||
@ -1,10 +1,100 @@
|
|||||||
import React from 'react';
|
import React, {useState, useEffect} from 'react';
|
||||||
import { View, Text, StyleSheet } from 'react-native';
|
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 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 (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text>Subscription Page</Text>
|
<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>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -12,9 +102,87 @@ const SubscriptionPage: React.FC = () => {
|
|||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
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',
|
justifyContent: 'center',
|
||||||
alignItems: '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;
|
export default SubscriptionPage;
|
||||||
|
|||||||
@ -5839,6 +5839,11 @@ react-native-gesture-handler@^2.15.0, "react-native-gesture-handler@>= 1.0.0":
|
|||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
|
react-native-linear-gradient@^2.8.3:
|
||||||
|
version "2.8.3"
|
||||||
|
resolved "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz"
|
||||||
|
integrity sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==
|
||||||
|
|
||||||
react-native-safe-area-context@^4.9.0, "react-native-safe-area-context@>= 3.0.0":
|
react-native-safe-area-context@^4.9.0, "react-native-safe-area-context@>= 3.0.0":
|
||||||
version "4.9.0"
|
version "4.9.0"
|
||||||
resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.9.0.tgz"
|
resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.9.0.tgz"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user