Compare commits
5 Commits
c1ab05c46c
...
3c3b84c3bd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c3b84c3bd | ||
|
|
c52ec09119 | ||
|
|
800ec5ead1 | ||
|
|
f13166f490 | ||
|
|
67a4f27b8d |
118
App.tsx
118
App.tsx
@ -1,118 +0,0 @@
|
|||||||
/**
|
|
||||||
* Sample React Native App
|
|
||||||
* https://github.com/facebook/react-native
|
|
||||||
*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import type {PropsWithChildren} from 'react';
|
|
||||||
import {
|
|
||||||
SafeAreaView,
|
|
||||||
ScrollView,
|
|
||||||
StatusBar,
|
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
useColorScheme,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Colors,
|
|
||||||
DebugInstructions,
|
|
||||||
Header,
|
|
||||||
LearnMoreLinks,
|
|
||||||
ReloadInstructions,
|
|
||||||
} from 'react-native/Libraries/NewAppScreen';
|
|
||||||
|
|
||||||
type SectionProps = PropsWithChildren<{
|
|
||||||
title: string;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
function Section({children, title}: SectionProps): React.JSX.Element {
|
|
||||||
const isDarkMode = useColorScheme() === 'dark';
|
|
||||||
return (
|
|
||||||
<View style={styles.sectionContainer}>
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
styles.sectionTitle,
|
|
||||||
{
|
|
||||||
color: isDarkMode ? Colors.white : Colors.black,
|
|
||||||
},
|
|
||||||
]}>
|
|
||||||
{title}
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
styles.sectionDescription,
|
|
||||||
{
|
|
||||||
color: isDarkMode ? Colors.light : Colors.dark,
|
|
||||||
},
|
|
||||||
]}>
|
|
||||||
{children}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function App(): React.JSX.Element {
|
|
||||||
const isDarkMode = useColorScheme() === 'dark';
|
|
||||||
|
|
||||||
const backgroundStyle = {
|
|
||||||
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SafeAreaView style={backgroundStyle}>
|
|
||||||
<StatusBar
|
|
||||||
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
|
|
||||||
backgroundColor={backgroundStyle.backgroundColor}
|
|
||||||
/>
|
|
||||||
<ScrollView
|
|
||||||
contentInsetAdjustmentBehavior="automatic"
|
|
||||||
style={backgroundStyle}>
|
|
||||||
<Header />
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
backgroundColor: isDarkMode ? Colors.black : Colors.white,
|
|
||||||
}}>
|
|
||||||
<Section title="Step One">
|
|
||||||
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
|
|
||||||
screen and then come back to see your edits.
|
|
||||||
</Section>
|
|
||||||
<Section title="See Your Changes">
|
|
||||||
<ReloadInstructions />
|
|
||||||
</Section>
|
|
||||||
<Section title="Debug">
|
|
||||||
<DebugInstructions />
|
|
||||||
</Section>
|
|
||||||
<Section title="Learn More">
|
|
||||||
Read the docs to discover what to do next:
|
|
||||||
</Section>
|
|
||||||
<LearnMoreLinks />
|
|
||||||
</View>
|
|
||||||
</ScrollView>
|
|
||||||
</SafeAreaView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
sectionContainer: {
|
|
||||||
marginTop: 32,
|
|
||||||
paddingHorizontal: 24,
|
|
||||||
},
|
|
||||||
sectionTitle: {
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: '600',
|
|
||||||
},
|
|
||||||
sectionDescription: {
|
|
||||||
marginTop: 8,
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: '400',
|
|
||||||
},
|
|
||||||
highlight: {
|
|
||||||
fontWeight: '700',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import 'react-native';
|
import 'react-native';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import App from '../App';
|
import App from '../src/App.tsx';
|
||||||
|
|
||||||
// Note: import explicitly to use the types shipped with jest.
|
// Note: import explicitly to use the types shipped with jest.
|
||||||
import {it} from '@jest/globals';
|
import {it} from '@jest/globals';
|
||||||
|
|||||||
3
index.js
3
index.js
@ -3,7 +3,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppRegistry} from 'react-native';
|
import {AppRegistry} from 'react-native';
|
||||||
import App from './App';
|
import App from './src/App';
|
||||||
import {name as appName} from './app.json';
|
import {name as appName} from './app.json';
|
||||||
|
import 'react-native-gesture-handler';
|
||||||
|
|
||||||
AppRegistry.registerComponent(appName, () => App);
|
AppRegistry.registerComponent(appName, () => App);
|
||||||
|
|||||||
@ -10,6 +10,10 @@
|
|||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>UIAppFonts</key>
|
||||||
|
<array>
|
||||||
|
<string>Ionicons.ttf</string>
|
||||||
|
</array>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
@ -26,7 +30,6 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<!-- Do not change NSAllowsArbitraryLoads to true, or you will risk app rejection! -->
|
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
|||||||
@ -28,6 +28,8 @@ end
|
|||||||
target 'MyAccountApp' do
|
target 'MyAccountApp' do
|
||||||
config = use_native_modules!
|
config = use_native_modules!
|
||||||
|
|
||||||
|
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
||||||
|
|
||||||
use_react_native!(
|
use_react_native!(
|
||||||
:path => config[:reactNativePath],
|
:path => config[:reactNativePath],
|
||||||
# Enables Flipper.
|
# Enables Flipper.
|
||||||
|
|||||||
@ -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)
|
||||||
@ -944,6 +946,10 @@ PODS:
|
|||||||
- React-Mapbuffer (0.73.6):
|
- React-Mapbuffer (0.73.6):
|
||||||
- glog
|
- glog
|
||||||
- React-debug
|
- React-debug
|
||||||
|
- react-native-safe-area-context (4.9.0):
|
||||||
|
- React-Core
|
||||||
|
- react-native-sqlite-storage (6.0.1):
|
||||||
|
- React-Core
|
||||||
- React-nativeconfig (0.73.6)
|
- React-nativeconfig (0.73.6)
|
||||||
- React-NativeModulesApple (0.73.6):
|
- React-NativeModulesApple (0.73.6):
|
||||||
- glog
|
- glog
|
||||||
@ -1111,11 +1117,24 @@ PODS:
|
|||||||
- React-jsi (= 0.73.6)
|
- React-jsi (= 0.73.6)
|
||||||
- React-logger (= 0.73.6)
|
- React-logger (= 0.73.6)
|
||||||
- React-perflogger (= 0.73.6)
|
- React-perflogger (= 0.73.6)
|
||||||
|
- RNGestureHandler (2.15.0):
|
||||||
|
- glog
|
||||||
|
- RCT-Folly (= 2022.05.16.00)
|
||||||
|
- React-Core
|
||||||
|
- RNScreens (3.29.0):
|
||||||
|
- glog
|
||||||
|
- RCT-Folly (= 2022.05.16.00)
|
||||||
|
- React-Core
|
||||||
|
- RNVectorIcons (10.0.3):
|
||||||
|
- glog
|
||||||
|
- RCT-Folly (= 2022.05.16.00)
|
||||||
|
- React-Core
|
||||||
- SocketRocket (0.6.1)
|
- SocketRocket (0.6.1)
|
||||||
- Yoga (1.14.0)
|
- Yoga (1.14.0)
|
||||||
|
|
||||||
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`)
|
||||||
@ -1167,6 +1186,8 @@ DEPENDENCIES:
|
|||||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector-modern`)
|
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector-modern`)
|
||||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||||
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
|
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
|
||||||
|
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||||
|
- react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`)
|
||||||
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
|
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
|
||||||
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
|
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
|
||||||
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||||
@ -1187,6 +1208,9 @@ DEPENDENCIES:
|
|||||||
- React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
|
- React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
|
||||||
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
|
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
|
||||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||||
|
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||||
|
- RNScreens (from `../node_modules/react-native-screens`)
|
||||||
|
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
||||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
@ -1208,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:
|
||||||
@ -1261,6 +1287,10 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||||
React-Mapbuffer:
|
React-Mapbuffer:
|
||||||
:path: "../node_modules/react-native/ReactCommon"
|
:path: "../node_modules/react-native/ReactCommon"
|
||||||
|
react-native-safe-area-context:
|
||||||
|
:path: "../node_modules/react-native-safe-area-context"
|
||||||
|
react-native-sqlite-storage:
|
||||||
|
:path: "../node_modules/react-native-sqlite-storage"
|
||||||
React-nativeconfig:
|
React-nativeconfig:
|
||||||
:path: "../node_modules/react-native/ReactCommon"
|
:path: "../node_modules/react-native/ReactCommon"
|
||||||
React-NativeModulesApple:
|
React-NativeModulesApple:
|
||||||
@ -1301,11 +1331,18 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../node_modules/react-native/ReactCommon/react/utils"
|
:path: "../node_modules/react-native/ReactCommon/react/utils"
|
||||||
ReactCommon:
|
ReactCommon:
|
||||||
:path: "../node_modules/react-native/ReactCommon"
|
:path: "../node_modules/react-native/ReactCommon"
|
||||||
|
RNGestureHandler:
|
||||||
|
:path: "../node_modules/react-native-gesture-handler"
|
||||||
|
RNScreens:
|
||||||
|
:path: "../node_modules/react-native-screens"
|
||||||
|
RNVectorIcons:
|
||||||
|
:path: "../node_modules/react-native-vector-icons"
|
||||||
Yoga:
|
Yoga:
|
||||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
||||||
|
BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3
|
||||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||||
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
|
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
|
||||||
FBLazyVector: f64d1e2ea739b4d8f7e4740cde18089cd97fe864
|
FBLazyVector: f64d1e2ea739b4d8f7e4740cde18089cd97fe864
|
||||||
@ -1344,6 +1381,8 @@ SPEC CHECKSUMS:
|
|||||||
React-jsinspector: 85583ef014ce53d731a98c66a0e24496f7a83066
|
React-jsinspector: 85583ef014ce53d731a98c66a0e24496f7a83066
|
||||||
React-logger: 3eb80a977f0d9669468ef641a5e1fabbc50a09ec
|
React-logger: 3eb80a977f0d9669468ef641a5e1fabbc50a09ec
|
||||||
React-Mapbuffer: 84ea43c6c6232049135b1550b8c60b2faac19fab
|
React-Mapbuffer: 84ea43c6c6232049135b1550b8c60b2faac19fab
|
||||||
|
react-native-safe-area-context: b97eb6f9e3b7f437806c2ce5983f479f8eb5de4b
|
||||||
|
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
|
||||||
React-nativeconfig: b4d4e9901d4cabb57be63053fd2aa6086eb3c85f
|
React-nativeconfig: b4d4e9901d4cabb57be63053fd2aa6086eb3c85f
|
||||||
React-NativeModulesApple: cd26e56d56350e123da0c1e3e4c76cb58a05e1ee
|
React-NativeModulesApple: cd26e56d56350e123da0c1e3e4c76cb58a05e1ee
|
||||||
React-perflogger: 5f49905de275bac07ac7ea7f575a70611fa988f2
|
React-perflogger: 5f49905de275bac07ac7ea7f575a70611fa988f2
|
||||||
@ -1364,9 +1403,12 @@ SPEC CHECKSUMS:
|
|||||||
React-runtimescheduler: 9636eee762c699ca7c85751a359101797e4c8b3b
|
React-runtimescheduler: 9636eee762c699ca7c85751a359101797e4c8b3b
|
||||||
React-utils: d16c1d2251c088ad817996621947d0ac8167b46c
|
React-utils: d16c1d2251c088ad817996621947d0ac8167b46c
|
||||||
ReactCommon: 2aa35648354bd4c4665b9a5084a7d37097b89c10
|
ReactCommon: 2aa35648354bd4c4665b9a5084a7d37097b89c10
|
||||||
|
RNGestureHandler: 67fb54b3e6ca338a8044e85cd6f340265aa41091
|
||||||
|
RNScreens: 17e2f657f1b09a71ec3c821368a04acbb7ebcb46
|
||||||
|
RNVectorIcons: 73ab573085f65a572d3b6233e68996d4707fd505
|
||||||
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
|
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
|
||||||
Yoga: d17d2cc8105eed528474683b42e2ea310e1daf61
|
Yoga: 805bf71192903b20fc14babe48080582fee65a80
|
||||||
|
|
||||||
PODFILE CHECKSUM: 29407bd75db4abdbd07d3a8c1b06fc5c12f802b3
|
PODFILE CHECKSUM: fbd48ab9bd2d7cd12f0450d3da23a3d3a87ccb0b
|
||||||
|
|
||||||
COCOAPODS: 1.14.3
|
COCOAPODS: 1.15.2
|
||||||
|
|||||||
16
package.json
16
package.json
@ -10,8 +10,21 @@
|
|||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-navigation/bottom-tabs": "^6.5.19",
|
||||||
|
"@react-navigation/native": "^6.1.16",
|
||||||
|
"@react-navigation/stack": "^6.3.28",
|
||||||
|
"i18next": "^23.10.1",
|
||||||
|
"i18next-browser-languagedetector": "^7.2.0",
|
||||||
|
"i18next-http-backend": "^2.5.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.73.6"
|
"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",
|
||||||
|
"react-native-vector-icons": "^10.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
@ -22,6 +35,7 @@
|
|||||||
"@react-native/metro-config": "0.73.5",
|
"@react-native/metro-config": "0.73.5",
|
||||||
"@react-native/typescript-config": "0.73.1",
|
"@react-native/typescript-config": "0.73.1",
|
||||||
"@types/react": "^18.2.6",
|
"@types/react": "^18.2.6",
|
||||||
|
"@types/react-native-vector-icons": "^6.4.18",
|
||||||
"@types/react-test-renderer": "^18.0.0",
|
"@types/react-test-renderer": "^18.0.0",
|
||||||
"babel-jest": "^29.6.3",
|
"babel-jest": "^29.6.3",
|
||||||
"eslint": "^8.19.0",
|
"eslint": "^8.19.0",
|
||||||
|
|||||||
21
src/App.tsx
Normal file
21
src/App.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React, {useEffect} from 'react';
|
||||||
|
import AppNavigator from './AppNavigator';
|
||||||
|
import {initializeDatabase} from './utils/DatabaseService.js';
|
||||||
|
import DatabaseTestPage from './pages/DatabaseServiceTest.js';
|
||||||
|
import BottomTabNavigator from './components/BottomTabNavigator.tsx';
|
||||||
|
|
||||||
|
function App(): React.JSX.Element {
|
||||||
|
useEffect(() => {
|
||||||
|
initializeDatabase()
|
||||||
|
.then(_db => {
|
||||||
|
console.log('Database ready');
|
||||||
|
})
|
||||||
|
.catch(_error => {
|
||||||
|
console.error('Database failed to initialize');
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//return <AppNavigator />;
|
||||||
|
return <BottomTabNavigator />;
|
||||||
|
}
|
||||||
|
export default App;
|
||||||
24
src/AppNavigator.tsx
Normal file
24
src/AppNavigator.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// src/AppNavigator.tsx
|
||||||
|
import React from 'react';
|
||||||
|
import {createStackNavigator} from '@react-navigation/stack';
|
||||||
|
import {NavigationContainer} from '@react-navigation/native';
|
||||||
|
import LoginPage from './pages/LoginPage';
|
||||||
|
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
|
||||||
|
const AppNavigator = () => {
|
||||||
|
return (
|
||||||
|
<NavigationContainer>
|
||||||
|
<Stack.Navigator initialRouteName="Login">
|
||||||
|
<Stack.Screen
|
||||||
|
name="Login"
|
||||||
|
component={LoginPage}
|
||||||
|
options={{title: 'Login'}}
|
||||||
|
/>
|
||||||
|
{/* 添加其他页面的路由 */}
|
||||||
|
</Stack.Navigator>
|
||||||
|
</NavigationContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppNavigator;
|
||||||
63
src/components/BottomTabNavigator.tsx
Normal file
63
src/components/BottomTabNavigator.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// BottomTabNavigator.tsx
|
||||||
|
import React from 'react';
|
||||||
|
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 OverviewPage from '../pages/OverviewPage';
|
||||||
|
import SubscriptionPage from '../pages/SubscriptionPage';
|
||||||
|
import SavingPage from '../pages/SavingPage';
|
||||||
|
import ProfilePage from '../pages/ProfilePage';
|
||||||
|
|
||||||
|
const Tab = createBottomTabNavigator<RootTabParamList>(); // 使用类型
|
||||||
|
|
||||||
|
const BottomTabNavigator: React.FC = () => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
return (
|
||||||
|
<NavigationContainer>
|
||||||
|
<Tab.Navigator
|
||||||
|
screenOptions={({route}) => ({
|
||||||
|
tabBarLabel: t(route.name), // 使用翻译函数获取标签
|
||||||
|
tabBarIcon: ({focused, color, size}) => {
|
||||||
|
let iconName: string;
|
||||||
|
|
||||||
|
switch (route.name) {
|
||||||
|
case 'Overview':
|
||||||
|
iconName = focused ? 'home' : 'home-outline';
|
||||||
|
break;
|
||||||
|
case 'Subscription':
|
||||||
|
iconName = focused ? 'list' : 'list-outline';
|
||||||
|
break;
|
||||||
|
case 'Saving':
|
||||||
|
iconName = focused ? 'wallet' : 'wallet-outline';
|
||||||
|
break;
|
||||||
|
case 'Profile':
|
||||||
|
iconName = focused ? 'person' : 'person-outline';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
iconName = 'ios-alert';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(iconName, size, color);
|
||||||
|
return <Icon name={iconName} size={size} color={color} />;
|
||||||
|
},
|
||||||
|
tabBarActiveTintColor: 'tomato',
|
||||||
|
tabBarInactiveTintColor: 'gray',
|
||||||
|
})}>
|
||||||
|
<Tab.Screen name="Overview" component={OverviewPage} />
|
||||||
|
<Tab.Screen
|
||||||
|
name="Subscription"
|
||||||
|
component={SubscriptionPage}
|
||||||
|
options={{headerShown: false}}
|
||||||
|
/>
|
||||||
|
<Tab.Screen name="Saving" component={SavingPage} />
|
||||||
|
<Tab.Screen name="Profile" component={ProfilePage} />
|
||||||
|
</Tab.Navigator>
|
||||||
|
</NavigationContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BottomTabNavigator;
|
||||||
7
src/components/type.ts
Normal file
7
src/components/type.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// types.ts
|
||||||
|
export type RootTabParamList = {
|
||||||
|
Overview: undefined;
|
||||||
|
Subscription: undefined;
|
||||||
|
Saving: undefined;
|
||||||
|
Profile: undefined;
|
||||||
|
};
|
||||||
20
src/i18n/i18n.js
Normal file
20
src/i18n/i18n.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import i18n from 'i18next';
|
||||||
|
import {initReactI18next} from 'react-i18next';
|
||||||
|
import en from './locales/en.json';
|
||||||
|
import zh from './locales/zh.json';
|
||||||
|
|
||||||
|
i18n
|
||||||
|
.use(initReactI18next) // 将 i18next 传递给 react-i18next
|
||||||
|
.init({
|
||||||
|
resources: {
|
||||||
|
en: {translation: en},
|
||||||
|
zh: {translation: zh},
|
||||||
|
},
|
||||||
|
lng: 'en', // 默认语言
|
||||||
|
fallbackLng: 'en',
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
||||||
8
src/i18n/locales/en.json
Normal file
8
src/i18n/locales/en.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"welcome": "Welcome to MyAccountApp",
|
||||||
|
"login": "Log In",
|
||||||
|
"Overview": "Overview",
|
||||||
|
"Subscription": "Subscription",
|
||||||
|
"Saving": "Saving",
|
||||||
|
"Profile": "Profile"
|
||||||
|
}
|
||||||
8
src/i18n/locales/zh.json
Normal file
8
src/i18n/locales/zh.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"welcome": "欢迎使用 MyAccountApp",
|
||||||
|
"login": "登录",
|
||||||
|
"Overview": "概览",
|
||||||
|
"Subscription": "订阅",
|
||||||
|
"Saving": "存钱",
|
||||||
|
"Profile": "我的"
|
||||||
|
}
|
||||||
128
src/pages/DatabaseServiceTest.js
Normal file
128
src/pages/DatabaseServiceTest.js
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// src/pages/DatabaseTestPage.js
|
||||||
|
import React, {useState, useEffect} from 'react';
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
Button,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
} from 'react-native';
|
||||||
|
import {initializeDatabase} from '../utils/DatabaseService';
|
||||||
|
|
||||||
|
const DatabaseTestPage = () => {
|
||||||
|
const [db, setDb] = useState(null);
|
||||||
|
const [users, setUsers] = useState([]);
|
||||||
|
const [username, setUsername] = useState('');
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initializeDatabase().then(database => {
|
||||||
|
setDb(database);
|
||||||
|
fetchUsers(database);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchUsers = database => {
|
||||||
|
database.transaction(tx => {
|
||||||
|
tx.executeSql('SELECT * FROM Users', [], (tx, results) => { m
|
||||||
|
const fetchedUsers = [];
|
||||||
|
for (let i = 0; i < results.rows.length; i++) {
|
||||||
|
fetchedUsers.push(results.rows.item(i));
|
||||||
|
}
|
||||||
|
setUsers(fetchedUsers);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const addUser = () => {
|
||||||
|
if (db && username && email) {
|
||||||
|
db.transaction(tx => {
|
||||||
|
tx.executeSql(
|
||||||
|
'INSERT INTO Users (username, email, created_at, updated_at) VALUES (?, ?, datetime("now"), datetime("now"))',
|
||||||
|
[username, email],
|
||||||
|
() => {
|
||||||
|
fetchUsers(db);
|
||||||
|
setUsername('');
|
||||||
|
setEmail('');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteUser = userId => {
|
||||||
|
if (db) {
|
||||||
|
db.transaction(tx => {
|
||||||
|
tx.executeSql('DELETE FROM Users WHERE id = ?', [userId], () => {
|
||||||
|
fetchUsers(db);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
<View style={styles.form}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Username"
|
||||||
|
value={username}
|
||||||
|
onChangeText={setUsername}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Email"
|
||||||
|
value={email}
|
||||||
|
onChangeText={setEmail}
|
||||||
|
/>
|
||||||
|
<Button title="Add User" onPress={addUser} />
|
||||||
|
</View>
|
||||||
|
<View style={styles.usersList}>
|
||||||
|
{users.map(user => (
|
||||||
|
<View key={user.id} style={styles.userItem}>
|
||||||
|
<Text style={styles.userText}>
|
||||||
|
{user.id}: {user.username} - {user.email}
|
||||||
|
</Text>
|
||||||
|
<Button title="Delete" onPress={() => deleteUser(user.id)} />
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 20,
|
||||||
|
marginTop: 50,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
marginBottom: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#ccc',
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
paddingVertical: 5,
|
||||||
|
},
|
||||||
|
usersList: {
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderColor: '#ccc',
|
||||||
|
},
|
||||||
|
userItem: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderColor: '#ccc',
|
||||||
|
},
|
||||||
|
userText: {
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DatabaseTestPage;
|
||||||
20
src/pages/OverviewPage.tsx
Normal file
20
src/pages/OverviewPage.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View, Text, StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
const OverviewPage: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>Overview Page</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default OverviewPage;
|
||||||
20
src/pages/ProfilePage.tsx
Normal file
20
src/pages/ProfilePage.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View, Text, StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
const ProfilePage: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>Profile Page</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ProfilePage;
|
||||||
20
src/pages/SavingPage.tsx
Normal file
20
src/pages/SavingPage.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View, Text, StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
const SavingPage: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>Saving Page</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default SavingPage;
|
||||||
188
src/pages/SubscriptionPage.tsx
Normal file
188
src/pages/SubscriptionPage.tsx
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
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;
|
||||||
66
src/utils/DatabaseService.js
Normal file
66
src/utils/DatabaseService.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// DatabaseService.js
|
||||||
|
import SQLite from 'react-native-sqlite-storage';
|
||||||
|
|
||||||
|
SQLite.enablePromise(true);
|
||||||
|
|
||||||
|
const databaseName = 'MyAccountApp.db';
|
||||||
|
const databaseVersion = '1.0';
|
||||||
|
const databaseDisplayName = 'My Account App Database';
|
||||||
|
const databaseSize = 200000; // 大约 200KB
|
||||||
|
|
||||||
|
async function initializeDatabase() {
|
||||||
|
try {
|
||||||
|
const db = await SQLite.openDatabase(
|
||||||
|
databaseName,
|
||||||
|
databaseVersion,
|
||||||
|
databaseDisplayName,
|
||||||
|
databaseSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
await db.transaction(async tx => {
|
||||||
|
// 创建 Users 表
|
||||||
|
await tx.executeSql(
|
||||||
|
'CREATE TABLE IF NOT EXISTS Users (id INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(30), password VARCHAR(30), email VARCHAR(30), created_at DATETIME, updated_at DATETIME)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建 Accounts 表
|
||||||
|
await tx.executeSql(
|
||||||
|
'CREATE TABLE IF NOT EXISTS Accounts (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, name VARCHAR(30), currency VARCHAR(10), balance DECIMAL, created_at DATETIME, updated_at DATETIME)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建 Ledgers 表
|
||||||
|
await tx.executeSql(
|
||||||
|
'CREATE TABLE IF NOT EXISTS Ledgers (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, name VARCHAR(30), created_at DATETIME, updated_at DATETIME)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建 Transactions 表
|
||||||
|
await tx.executeSql(
|
||||||
|
'CREATE TABLE IF NOT EXISTS Transactions (id INTEGER PRIMARY KEY AUTOINCREMENT, ledger_id INTEGER, account_id INTEGER, type VARCHAR(10), amount DECIMAL, currency VARCHAR(10), date DATE, description VARCHAR(255), created_at DATETIME, updated_at DATETIME)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建 FixedExpenses 表
|
||||||
|
await tx.executeSql(
|
||||||
|
'CREATE TABLE IF NOT EXISTS FixedExpenses (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, name VARCHAR(30), amount DECIMAL, frequency VARCHAR(10), created_at DATETIME, updated_at DATETIME)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建 Subscriptions 表
|
||||||
|
await tx.executeSql(
|
||||||
|
'CREATE TABLE IF NOT EXISTS Subscriptions (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, name VARCHAR(30), amount DECIMAL, start_date DATE, end_date DATE, created_at DATETIME, updated_at DATETIME)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建 AAPayments 表
|
||||||
|
await tx.executeSql(
|
||||||
|
'CREATE TABLE IF NOT EXISTS AAPayments (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, event VARCHAR(30), total_amount DECIMAL, participants INTEGER, paid_by INTEGER, created_at DATETIME, updated_at DATETIME)',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 其他表的创建语句...
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Database initialized');
|
||||||
|
return db;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error initializing database:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {initializeDatabase};
|
||||||
Loading…
Reference in New Issue
Block a user