diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 4fea45b..2dd875a 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -1,5 +1,7 @@
PODS:
- boost (1.83.0)
+ - BVLinearGradient (2.8.3):
+ - React-Core
- CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6)
- FBLazyVector (0.73.6)
@@ -1132,6 +1134,7 @@ PODS:
DEPENDENCIES:
- 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`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
@@ -1229,6 +1232,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
boost:
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
+ BVLinearGradient:
+ :path: "../node_modules/react-native-linear-gradient"
DoubleConversion:
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
FBLazyVector:
@@ -1337,6 +1342,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
+ BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
FBLazyVector: f64d1e2ea739b4d8f7e4740cde18089cd97fe864
diff --git a/package.json b/package.json
index 11a8d5b..f9be068 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"react-i18next": "^14.1.0",
"react-native": "0.73.6",
"react-native-gesture-handler": "^2.15.0",
+ "react-native-linear-gradient": "^2.8.3",
"react-native-safe-area-context": "^4.9.0",
"react-native-screens": "^3.29.0",
"react-native-sqlite-storage": "^6.0.1",
diff --git a/src/components/BottomTabNavigator.tsx b/src/components/BottomTabNavigator.tsx
index 7c4b1cd..d36d105 100644
--- a/src/components/BottomTabNavigator.tsx
+++ b/src/components/BottomTabNavigator.tsx
@@ -4,7 +4,7 @@ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {NavigationContainer} from '@react-navigation/native';
import Icon from 'react-native-vector-icons/Ionicons';
import {useTranslation} from 'react-i18next';
-import { RootTabParamList } from "./type.ts";
+import {RootTabParamList} from './type.ts';
import OverviewPage from '../pages/OverviewPage';
import SubscriptionPage from '../pages/SubscriptionPage';
@@ -48,7 +48,11 @@ const BottomTabNavigator: React.FC = () => {
tabBarInactiveTintColor: 'gray',
})}>
-
+
diff --git a/src/pages/SubscriptionPage.tsx b/src/pages/SubscriptionPage.tsx
index 6f43827..68baf06 100644
--- a/src/pages/SubscriptionPage.tsx
+++ b/src/pages/SubscriptionPage.tsx
@@ -1,10 +1,100 @@
-import React from 'react';
-import { View, Text, StyleSheet } from 'react-native';
+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(mockSubscriptions);
+ const fetchSubscriptions = () => {
+ setSubscriptions(mockSubscriptions);
+ };
+
+ useEffect(() => {
+ fetchSubscriptions();
+ }, []);
+
+ const renderItem = ({item}: {item: Subscription}) => {
+ return (
+
+
+
+ {item.name}
+ {item.endDate}
+
+ ${item.amount}
+
+
+
+
+ );
+ };
+
return (
- Subscription Page
+
+ Subscriptions
+
+ item.id.toString()}
+ numColumns={2}
+ columnWrapperStyle={styles.row}
+ />
+
+
+
);
};
@@ -12,9 +102,87 @@ const SubscriptionPage: React.FC = () => {
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;
diff --git a/yarn.lock b/yarn.lock
index eae2df7..c37f6e6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5839,6 +5839,11 @@ react-native-gesture-handler@^2.15.0, "react-native-gesture-handler@>= 1.0.0":
lodash "^4.17.21"
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":
version "4.9.0"
resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.9.0.tgz"