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"