Compare commits
25 Commits
6b9631dcfd
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceabc0079c | ||
|
|
9b26ddaa37 | ||
|
|
0d12a01812 | ||
| 388d5e9a82 | |||
| 99bdb01644 | |||
| a41851dfcc | |||
|
|
27f43a77fd | ||
|
|
27f16f3c38 | ||
|
|
2eb41db2e5 | ||
|
|
61bcb6aa3f | ||
| 66f5271640 | |||
| db6a9e2bc0 | |||
| 14db29ab61 | |||
| 5ca3bb4f17 | |||
| 61fb0b2d96 | |||
| daae154aee | |||
| 6751cc506e | |||
| 056b4a5627 | |||
| d9b8e3f7ac | |||
| 5f59609d6f | |||
| b9b604167b | |||
| 4630b195b9 | |||
| 4efaf2543e | |||
| b925b48dd4 | |||
|
|
3380c9d85b |
5
.gitignore
vendored
@@ -35,3 +35,8 @@ yarn-error.*
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
|
||||
android/
|
||||
ios/
|
||||
.android/
|
||||
.ios/
|
||||
|
||||
17
App.js
@@ -2,15 +2,18 @@ import React from 'react';
|
||||
import { AuthProvider } from './src/contexts/AuthContext';
|
||||
import RootNavigator from './src/navigation/RootNavigator';
|
||||
import { BaseEnumsProvider } from './src/contexts/BaseEnumsContext';
|
||||
import { StatusBar } from 'react-native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<AuthProvider>
|
||||
<BaseEnumsProvider>
|
||||
<StatusBar barStyle="dark-content" backgroundColor="#fff"/>
|
||||
<RootNavigator />
|
||||
</BaseEnumsProvider>
|
||||
</AuthProvider>
|
||||
<SafeAreaProvider>
|
||||
<AuthProvider>
|
||||
<BaseEnumsProvider>
|
||||
<StatusBar style="dark" />
|
||||
<RootNavigator />
|
||||
</BaseEnumsProvider>
|
||||
</AuthProvider>
|
||||
</SafeAreaProvider>
|
||||
);
|
||||
}
|
||||
|
||||
28
app.json
@@ -10,10 +10,14 @@
|
||||
"splash": {
|
||||
"image": "./assets/splash-icon.png",
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#17b69b"
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"ios": {
|
||||
"supportsTablet": true
|
||||
"supportsTablet": true,
|
||||
"statusBar": {
|
||||
"barStyle": "dark-content"
|
||||
},
|
||||
"bundleIdentifier": "com.nurmuhammet.ali.tbbankonline"
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
@@ -21,7 +25,11 @@
|
||||
"backgroundColor": "#17b69b"
|
||||
},
|
||||
"edgeToEdgeEnabled": true,
|
||||
"package": "com.nurmuhammet.ali.tbbankonline"
|
||||
"package": "com.nurmuhammet.ali.tbbankonline",
|
||||
"statusBar": {
|
||||
"barStyle": "dark-content",
|
||||
"backgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
"web": {
|
||||
"favicon": "./assets/favicon.png"
|
||||
@@ -30,6 +38,18 @@
|
||||
"eas": {
|
||||
"projectId": "280bed78-9335-4b73-a686-15a9f726a7ad"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"expo-font",
|
||||
[
|
||||
"expo-splash-screen",
|
||||
{
|
||||
"backgroundColor": "#ffffff",
|
||||
"image": "./assets/splash-icon.png",
|
||||
"imageWidth": 200
|
||||
}
|
||||
],
|
||||
"expo-system-ui"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
assets/icon.png
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 156 KiB |
619
package-lock.json
generated
@@ -15,11 +15,16 @@
|
||||
"@react-navigation/bottom-tabs": "^7.4.2",
|
||||
"@react-navigation/native": "^7.1.14",
|
||||
"@react-navigation/stack": "^7.4.2",
|
||||
"expo": "53.0.19",
|
||||
"expo": "53.0.22",
|
||||
"expo-font": "~13.3.2",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"expo-splash-screen": "^31.0.8",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"expo-system-ui": "~5.0.11",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-confirmation-code-field": "^8.0.1",
|
||||
"react-native-gesture-handler": "~2.24.0",
|
||||
"react-native-modal-datetime-picker": "^15.0.1",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "^4.11.1",
|
||||
@@ -31,9 +36,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@0no-co/graphql.web": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.1.2.tgz",
|
||||
"integrity": "sha512-N2NGsU5FLBhT8NZ+3l2YrzZSHITjNXNuDhC4iDiikv0IujaJ0Xc6xIxQZ/Ek3Cb+rgPjnLHYyJm11tInuJn+cw==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.2.0.tgz",
|
||||
"integrity": "sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==",
|
||||
"peerDependencies": {
|
||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
||||
},
|
||||
@@ -106,12 +111,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz",
|
||||
"integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
|
||||
"integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.0",
|
||||
"@babel/types": "^7.28.0",
|
||||
"@babel/parser": "^7.28.3",
|
||||
"@babel/types": "^7.28.2",
|
||||
"@jridgewell/gen-mapping": "^0.3.12",
|
||||
"@jridgewell/trace-mapping": "^0.3.28",
|
||||
"jsesc": "^3.0.2"
|
||||
@@ -147,16 +152,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz",
|
||||
"integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz",
|
||||
"integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.1",
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-member-expression-to-functions": "^7.27.1",
|
||||
"@babel/helper-optimise-call-expression": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.27.1",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
|
||||
"@babel/traverse": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.3",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -333,13 +338,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-wrap-function": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz",
|
||||
"integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz",
|
||||
"integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.27.1",
|
||||
"@babel/traverse": "^7.27.1",
|
||||
"@babel/types": "^7.27.1"
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/traverse": "^7.28.3",
|
||||
"@babel/types": "^7.28.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -436,11 +441,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
|
||||
"integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
|
||||
"integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.0"
|
||||
"@babel/types": "^7.28.4"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@@ -784,9 +789,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz",
|
||||
"integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz",
|
||||
"integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
@@ -813,16 +818,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-classes": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz",
|
||||
"integrity": "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
|
||||
"integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.0"
|
||||
"@babel/traverse": "^7.28.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1008,15 +1013,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-object-rest-spread": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz",
|
||||
"integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz",
|
||||
"integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==",
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.0",
|
||||
"@babel/plugin-transform-parameters": "^7.27.7",
|
||||
"@babel/traverse": "^7.28.0"
|
||||
"@babel/traverse": "^7.28.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1189,9 +1194,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-regenerator": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.0.tgz",
|
||||
"integrity": "sha512-LOAozRVbqxEVjSKfhGnuLoE4Kz4Oc5UJzuvFUhSsQzdCdaAQu06mG8zDv2GFSerM62nImUZ7K92vxnQcLSDlCQ==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz",
|
||||
"integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
@@ -1203,9 +1208,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-runtime": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.0.tgz",
|
||||
"integrity": "sha512-dGopk9nZrtCs2+nfIem25UuHyt5moSJamArzIoh9/vezUQPmYDOzjaHDCkAzuGJibCIkPup8rMT2+wYB6S73cA==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.3.tgz",
|
||||
"integrity": "sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg==",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
@@ -1356,16 +1361,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz",
|
||||
"integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz",
|
||||
"integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.0",
|
||||
"@babel/generator": "^7.28.3",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/parser": "^7.28.0",
|
||||
"@babel/parser": "^7.28.4",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.0",
|
||||
"@babel/types": "^7.28.4",
|
||||
"debug": "^4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1391,9 +1396,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz",
|
||||
"integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
|
||||
"integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.27.1"
|
||||
@@ -1406,7 +1411,6 @@
|
||||
"version": "2.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
|
||||
"integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/hammerjs": "^2.0.36"
|
||||
},
|
||||
@@ -1415,9 +1419,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli": {
|
||||
"version": "0.24.20",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.24.20.tgz",
|
||||
"integrity": "sha512-uF1pOVcd+xizNtVTuZqNGzy7I6IJon5YMmQidsURds1Ww96AFDxrR/NEACqeATNAmY60m8wy1VZZpSg5zLNkpw==",
|
||||
"version": "0.24.21",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.24.21.tgz",
|
||||
"integrity": "sha512-DT6K9vgFHqqWL/19mU1ofRcPoO1pn4qmgi76GtuiNU4tbBe/02mRHwFsQw7qRfFAT28If5e/wiwVozgSuZVL8g==",
|
||||
"dependencies": {
|
||||
"@0no-co/graphql.web": "^1.0.8",
|
||||
"@babel/runtime": "^7.20.0",
|
||||
@@ -1433,10 +1437,11 @@
|
||||
"@expo/package-manager": "^1.8.6",
|
||||
"@expo/plist": "^0.3.5",
|
||||
"@expo/prebuild-config": "^9.0.11",
|
||||
"@expo/schema-utils": "^0.1.0",
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"@expo/ws-tunnel": "^1.0.1",
|
||||
"@expo/xcpretty": "^4.3.0",
|
||||
"@react-native/dev-middleware": "0.79.5",
|
||||
"@react-native/dev-middleware": "0.79.6",
|
||||
"@urql/core": "^5.0.6",
|
||||
"@urql/exchange-retry": "^1.3.0",
|
||||
"accepts": "^1.3.8",
|
||||
@@ -1485,6 +1490,56 @@
|
||||
"expo-internal": "build/bin/cli"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/@react-native/debugger-frontend": {
|
||||
"version": "0.79.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.79.6.tgz",
|
||||
"integrity": "sha512-lIK/KkaH7ueM22bLO0YNaQwZbT/oeqhaghOvmZacaNVbJR1Cdh/XAqjT8FgCS+7PUnbxA8B55NYNKGZG3O2pYw==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/@react-native/dev-middleware": {
|
||||
"version": "0.79.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.79.6.tgz",
|
||||
"integrity": "sha512-BK3GZBa9c7XSNR27EDRtxrgyyA3/mf1j3/y+mPk7Ac0Myu85YNrXnC9g3mL5Ytwo0g58TKrAIgs1fF2Q5Mn6mQ==",
|
||||
"dependencies": {
|
||||
"@isaacs/ttlcache": "^1.4.1",
|
||||
"@react-native/debugger-frontend": "0.79.6",
|
||||
"chrome-launcher": "^0.15.2",
|
||||
"chromium-edge-launcher": "^0.2.0",
|
||||
"connect": "^3.6.5",
|
||||
"debug": "^2.2.0",
|
||||
"invariant": "^2.2.4",
|
||||
"nullthrows": "^1.1.1",
|
||||
"open": "^7.0.3",
|
||||
"serve-static": "^1.16.2",
|
||||
"ws": "^6.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/@react-native/dev-middleware/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/@react-native/dev-middleware/node_modules/ws": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
|
||||
"integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
|
||||
"dependencies": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/semver": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
@@ -1715,9 +1770,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/osascript": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.2.5.tgz",
|
||||
"integrity": "sha512-Bpp/n5rZ0UmpBOnl7Li3LtM7la0AR3H9NNesqL+ytW5UiqV/TbonYW3rDZY38u4u/lG7TnYflVIVQPD+iqZJ5w==",
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.6.tgz",
|
||||
"integrity": "sha512-EMi4/YgWN/dHSkE9A4A5EJE8WrGnp71+BcVAKY80KMYtq5s6mOhLyDm8ytvHeUISUrPcPTRZ/6c8JMd6F8Ggmg==",
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"exec-async": "^2.2.0"
|
||||
@@ -1727,11 +1782,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/package-manager": {
|
||||
"version": "1.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.8.6.tgz",
|
||||
"integrity": "sha512-gcdICLuL+nHKZagPIDC5tX8UoDDB8vNA5/+SaQEqz8D+T2C4KrEJc2Vi1gPAlDnKif834QS6YluHWyxjk0yZlQ==",
|
||||
"version": "1.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.7.tgz",
|
||||
"integrity": "sha512-k3uky8Qzlv21rxuPvP2KUTAy8NI0b/LP7BSXcwJpS/rH7RmiAqUXgzPar3I1OmKGgxpod78Y9Mae//F8d3aiOQ==",
|
||||
"dependencies": {
|
||||
"@expo/json-file": "^9.1.5",
|
||||
"@expo/json-file": "^10.0.7",
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"chalk": "^4.0.0",
|
||||
"npm-package-arg": "^11.0.0",
|
||||
@@ -1739,6 +1794,23 @@
|
||||
"resolve-workspace-root": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/package-manager/node_modules/@babel/code-frame": {
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
|
||||
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.10.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/package-manager/node_modules/@expo/json-file": {
|
||||
"version": "10.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.7.tgz",
|
||||
"integrity": "sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "~7.10.4",
|
||||
"json5": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/plist": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.3.5.tgz",
|
||||
@@ -1750,22 +1822,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/prebuild-config": {
|
||||
"version": "9.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-9.0.11.tgz",
|
||||
"integrity": "sha512-0DsxhhixRbCCvmYskBTq8czsU0YOBsntYURhWPNpkl0IPVpeP9haE5W4OwtHGzXEbmHdzaoDwNmVcWjS/mqbDw==",
|
||||
"version": "9.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-9.0.12.tgz",
|
||||
"integrity": "sha512-AKH5Scf+gEMgGxZZaimrJI2wlUJlRoqzDNn7/rkhZa5gUTnO4l6slKak2YdaH+nXlOWCNfAQWa76NnpQIfmv6Q==",
|
||||
"dependencies": {
|
||||
"@expo/config": "~11.0.13",
|
||||
"@expo/config-plugins": "~10.1.2",
|
||||
"@expo/config-types": "^53.0.5",
|
||||
"@expo/image-utils": "^0.7.6",
|
||||
"@expo/json-file": "^9.1.5",
|
||||
"@react-native/normalize-colors": "0.79.5",
|
||||
"@react-native/normalize-colors": "0.79.6",
|
||||
"debug": "^4.3.1",
|
||||
"resolve-from": "^5.0.0",
|
||||
"semver": "^7.6.0",
|
||||
"xml2js": "0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/prebuild-config/node_modules/@react-native/normalize-colors": {
|
||||
"version": "0.79.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.79.6.tgz",
|
||||
"integrity": "sha512-0v2/ruY7eeKun4BeKu+GcfO+SHBdl0LJn4ZFzTzjHdWES0Cn+ONqKljYaIv8p9MV2Hx/kcdEvbY4lWI34jC/mQ=="
|
||||
},
|
||||
"node_modules/@expo/prebuild-config/node_modules/semver": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
@@ -1777,6 +1854,11 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/schema-utils": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.6.tgz",
|
||||
"integrity": "sha512-arKkNlPZYD0uUxGPbSwV/6v4owmZcUNrXk9Vq/o+p2Eqt1DM9jIjbXwrqlmvkTsPkjUtNLDGB0EDiosVJ4OvDg=="
|
||||
},
|
||||
"node_modules/@expo/sdk-runtime-versions": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz",
|
||||
@@ -2184,21 +2266,81 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-plugin-codegen": {
|
||||
"version": "0.79.5",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.5.tgz",
|
||||
"integrity": "sha512-Rt/imdfqXihD/sn0xnV4flxxb1aLLjPtMF1QleQjEhJsTUPpH4TFlfOpoCvsrXoDl4OIcB1k4FVM24Ez92zf5w==",
|
||||
"version": "0.79.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.6.tgz",
|
||||
"integrity": "sha512-CS5OrgcMPixOyUJ/Sk/HSsKsKgyKT5P7y3CojimOQzWqRZBmoQfxdST4ugj7n1H+ebM2IKqbgovApFbqXsoX0g==",
|
||||
"dependencies": {
|
||||
"@babel/traverse": "^7.25.3",
|
||||
"@react-native/codegen": "0.79.5"
|
||||
"@react-native/codegen": "0.79.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-plugin-codegen/node_modules/@react-native/codegen": {
|
||||
"version": "0.79.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.79.6.tgz",
|
||||
"integrity": "sha512-iRBX8Lgbqypwnfba7s6opeUwVyaR23mowh9ILw7EcT2oLz3RqMmjJdrbVpWhGSMGq2qkPfqAH7bhO8C7O+xfjQ==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/parser": "^7.25.3",
|
||||
"glob": "^7.1.1",
|
||||
"hermes-parser": "0.25.1",
|
||||
"invariant": "^2.2.4",
|
||||
"nullthrows": "^1.1.1",
|
||||
"yargs": "^17.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-plugin-codegen/node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-plugin-codegen/node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-plugin-codegen/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-preset": {
|
||||
"version": "0.79.5",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.79.5.tgz",
|
||||
"integrity": "sha512-GDUYIWslMLbdJHEgKNfrOzXk8EDKxKzbwmBXUugoiSlr6TyepVZsj3GZDLEFarOcTwH1EXXHJsixihk8DCRQDA==",
|
||||
"version": "0.79.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.79.6.tgz",
|
||||
"integrity": "sha512-H+FRO+r2Ql6b5IwfE0E7D52JhkxjeGSBSUpCXAI5zQ60zSBJ54Hwh2bBJOohXWl4J+C7gKYSAd2JHMUETu+c/A==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.24.7",
|
||||
@@ -2241,7 +2383,7 @@
|
||||
"@babel/plugin-transform-typescript": "^7.25.2",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.24.7",
|
||||
"@babel/template": "^7.25.0",
|
||||
"@react-native/babel-plugin-codegen": "0.79.5",
|
||||
"@react-native/babel-plugin-codegen": "0.79.6",
|
||||
"babel-plugin-syntax-hermes-parser": "0.25.1",
|
||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
||||
"react-refresh": "^0.14.0"
|
||||
@@ -2602,8 +2744,7 @@
|
||||
"node_modules/@types/hammerjs": {
|
||||
"version": "2.0.46",
|
||||
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz",
|
||||
"integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==",
|
||||
"peer": true
|
||||
"integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw=="
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.6",
|
||||
@@ -2955,9 +3096,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/babel-preset-expo": {
|
||||
"version": "13.2.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-13.2.3.tgz",
|
||||
"integrity": "sha512-wQJn92lqj8GKR7Ojg/aW4+GkqI6ZdDNTDyOqhhl7A9bAqk6t0ukUOWLDXQb4p0qKJjMDV1F6gNWasI2KUbuVTQ==",
|
||||
"version": "13.2.4",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-13.2.4.tgz",
|
||||
"integrity": "sha512-3IKORo3KR+4qtLdCkZNDj8KeA43oBn7RRQejFGWfiZgu/NeaRUSri8YwYjZqybm7hn3nmMv9OLahlvXBX23o5Q==",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.25.9",
|
||||
"@babel/plugin-proposal-decorators": "^7.12.9",
|
||||
@@ -2973,7 +3114,7 @@
|
||||
"@babel/plugin-transform-runtime": "^7.24.7",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@babel/preset-typescript": "^7.23.0",
|
||||
"@react-native/babel-preset": "0.79.5",
|
||||
"@react-native/babel-preset": "0.79.6",
|
||||
"babel-plugin-react-native-web": "~0.19.13",
|
||||
"babel-plugin-syntax-hermes-parser": "^0.25.1",
|
||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
||||
@@ -3108,9 +3249,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.25.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
|
||||
"integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
|
||||
"version": "4.25.4",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz",
|
||||
"integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -3126,8 +3267,8 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001726",
|
||||
"electron-to-chromium": "^1.5.173",
|
||||
"caniuse-lite": "^1.0.30001737",
|
||||
"electron-to-chromium": "^1.5.211",
|
||||
"node-releases": "^2.0.19",
|
||||
"update-browserslist-db": "^1.1.3"
|
||||
},
|
||||
@@ -3221,9 +3362,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001726",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz",
|
||||
"integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==",
|
||||
"version": "1.0.30001741",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz",
|
||||
"integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -3435,15 +3576,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/compression": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
|
||||
"integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
|
||||
"integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"compressible": "~2.0.18",
|
||||
"debug": "2.6.9",
|
||||
"negotiator": "~0.6.4",
|
||||
"on-headers": "~1.0.2",
|
||||
"on-headers": "~1.1.0",
|
||||
"safe-buffer": "5.2.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
@@ -3510,11 +3651,11 @@
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
|
||||
},
|
||||
"node_modules/core-js-compat": {
|
||||
"version": "3.43.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz",
|
||||
"integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==",
|
||||
"version": "3.45.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz",
|
||||
"integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.25.0"
|
||||
"browserslist": "^4.25.3"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -3796,9 +3937,9 @@
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.179",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.179.tgz",
|
||||
"integrity": "sha512-UWKi/EbBopgfFsc5k61wFpV7WrnnSlSzW/e2XcBmS6qKYTivZlLtoll5/rdqRTxGglGHkmkW0j0pFNJG10EUIQ=="
|
||||
"version": "1.5.217",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.217.tgz",
|
||||
"integrity": "sha512-Pludfu5iBxp9XzNl0qq2G87hdD17ZV7h5T4n6rQXDi3nCyloBV3jreE9+8GC6g4X/5yxqVgXEURpcLtM0WS4jA=="
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
@@ -3906,25 +4047,25 @@
|
||||
"integrity": "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw=="
|
||||
},
|
||||
"node_modules/expo": {
|
||||
"version": "53.0.19",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-53.0.19.tgz",
|
||||
"integrity": "sha512-hZWEKw6h5dlfKy6+c3f2exx5x3Loio8p0b2s/Pk1eQfTffqpkQRVVlOzcTWU1RSuMfc47ZMpr97pUJWQczOGsQ==",
|
||||
"version": "53.0.22",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-53.0.22.tgz",
|
||||
"integrity": "sha512-sJ2I4W/e5iiM4u/wYCe3qmW4D7WPCRqByPDD0hJcdYNdjc9HFFFdO4OAudZVyC/MmtoWZEIH5kTJP1cw9FjzYA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@expo/cli": "0.24.20",
|
||||
"@expo/cli": "0.24.21",
|
||||
"@expo/config": "~11.0.13",
|
||||
"@expo/config-plugins": "~10.1.2",
|
||||
"@expo/fingerprint": "0.13.4",
|
||||
"@expo/metro-config": "0.20.17",
|
||||
"@expo/vector-icons": "^14.0.0",
|
||||
"babel-preset-expo": "~13.2.3",
|
||||
"babel-preset-expo": "~13.2.4",
|
||||
"expo-asset": "~11.1.7",
|
||||
"expo-constants": "~17.1.7",
|
||||
"expo-file-system": "~18.1.11",
|
||||
"expo-font": "~13.3.2",
|
||||
"expo-keep-awake": "~14.1.4",
|
||||
"expo-modules-autolinking": "2.1.14",
|
||||
"expo-modules-core": "2.4.2",
|
||||
"expo-modules-core": "2.5.0",
|
||||
"react-native-edge-to-edge": "1.6.0",
|
||||
"whatwg-url-without-unicode": "8.0.0-3"
|
||||
},
|
||||
@@ -4046,13 +4187,171 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-modules-core": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.4.2.tgz",
|
||||
"integrity": "sha512-RCb0wniYCJkxwpXrkiBA/WiNGxzYsEpL0sB50gTnS/zEfX3DImS2npc4lfZ3hPZo1UF9YC6OSI9Do+iacV0NUg==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.5.0.tgz",
|
||||
"integrity": "sha512-aIbQxZE2vdCKsolQUl6Q9Farlf8tjh/ROR4hfN1qT7QBGPl1XrJGnaOKkcgYaGrlzCPg/7IBe0Np67GzKMZKKQ==",
|
||||
"dependencies": {
|
||||
"invariant": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen": {
|
||||
"version": "31.0.8",
|
||||
"resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-31.0.8.tgz",
|
||||
"integrity": "sha512-NNgNhrqkuJAt98k9CKJ9JeCInv5g/xRhe1fWbciQrqTQWPXeIGg3tn5T5HNFwfRD1aKr2uOs1Ctly8rE6i5vtQ==",
|
||||
"dependencies": {
|
||||
"@expo/prebuild-config": "^10.0.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@babel/code-frame": {
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
|
||||
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.10.4"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/config": {
|
||||
"version": "12.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.8.tgz",
|
||||
"integrity": "sha512-yFadXa5Cmja57EVOSyEYV1hF7kCaSbPnd1twx0MfvTr1Yj2abIbrEu2MUZqcvElNQOtgADnLRP0YJiuEdgoO5A==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "~7.10.4",
|
||||
"@expo/config-plugins": "~54.0.0",
|
||||
"@expo/config-types": "^54.0.7",
|
||||
"@expo/json-file": "^10.0.7",
|
||||
"deepmerge": "^4.3.1",
|
||||
"getenv": "^2.0.0",
|
||||
"glob": "^10.4.2",
|
||||
"require-from-string": "^2.0.2",
|
||||
"resolve-from": "^5.0.0",
|
||||
"resolve-workspace-root": "^2.0.0",
|
||||
"semver": "^7.6.0",
|
||||
"slugify": "^1.3.4",
|
||||
"sucrase": "3.35.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/config-plugins": {
|
||||
"version": "11.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-11.0.7.tgz",
|
||||
"integrity": "sha512-kak5m27fPTzwmzYPbaYL6I67OFnhdrzV0h5JcoljrEC7uM3R18V/RrnEMzv10XQk+s+qmPfMkr0aK9YYgGqR6g==",
|
||||
"dependencies": {
|
||||
"@expo/config-types": "^54.0.7",
|
||||
"@expo/json-file": "~10.0.6",
|
||||
"@expo/plist": "^0.4.6",
|
||||
"@expo/sdk-runtime-versions": "^1.0.0",
|
||||
"chalk": "^4.1.2",
|
||||
"debug": "^4.3.5",
|
||||
"getenv": "^2.0.0",
|
||||
"glob": "^10.4.2",
|
||||
"resolve-from": "^5.0.0",
|
||||
"semver": "^7.5.4",
|
||||
"slash": "^3.0.0",
|
||||
"slugify": "^1.6.6",
|
||||
"xcode": "^3.0.1",
|
||||
"xml2js": "0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/config-types": {
|
||||
"version": "54.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-54.0.7.tgz",
|
||||
"integrity": "sha512-f0UehgPd2gUqUtQ6euHAL6MqTT/A07r847Ztw2yZYWTUr0hRZr4nCP4U+lr8/pPtsHQYMKoPB1mOeAaTO25ruw=="
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/config/node_modules/@expo/config-plugins": {
|
||||
"version": "54.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.0.tgz",
|
||||
"integrity": "sha512-b2yFNKwaiHjDfh7K+zhMvRKA09gdaP/raqIzB112qeacVJaT66vka8m6cffYbbiXMe1srqofSJvyvr+g3H6+nA==",
|
||||
"dependencies": {
|
||||
"@expo/config-types": "^54.0.7",
|
||||
"@expo/json-file": "~10.0.6",
|
||||
"@expo/plist": "^0.4.6",
|
||||
"@expo/sdk-runtime-versions": "^1.0.0",
|
||||
"chalk": "^4.1.2",
|
||||
"debug": "^4.3.5",
|
||||
"getenv": "^2.0.0",
|
||||
"glob": "^10.4.2",
|
||||
"resolve-from": "^5.0.0",
|
||||
"semver": "^7.5.4",
|
||||
"slash": "^3.0.0",
|
||||
"slugify": "^1.6.6",
|
||||
"xcode": "^3.0.1",
|
||||
"xml2js": "0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/image-utils": {
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.7.tgz",
|
||||
"integrity": "sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w==",
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"chalk": "^4.0.0",
|
||||
"getenv": "^2.0.0",
|
||||
"jimp-compact": "0.16.1",
|
||||
"parse-png": "^2.1.0",
|
||||
"resolve-from": "^5.0.0",
|
||||
"resolve-global": "^1.0.0",
|
||||
"semver": "^7.6.0",
|
||||
"temp-dir": "~2.0.0",
|
||||
"unique-string": "~2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/json-file": {
|
||||
"version": "10.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.7.tgz",
|
||||
"integrity": "sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "~7.10.4",
|
||||
"json5": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/plist": {
|
||||
"version": "0.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.6.tgz",
|
||||
"integrity": "sha512-6yklhtUWohs1rBSC8dGyBBpElEbosjXN0zJN/+1/B121n7pPWvd9y/UGJm+2x7b81VnW3AHmWVnbU/u0INQsqA==",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.8",
|
||||
"base64-js": "^1.2.3",
|
||||
"xmlbuilder": "^15.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@expo/prebuild-config": {
|
||||
"version": "10.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-10.0.8.tgz",
|
||||
"integrity": "sha512-9ibcRuWngmMnoYe25XXfZEWcPCdx6LiyzqHqpojsvHBI+sMsyZPf4b/5y/zmeJy3PKjR4LSzMRonEitTfUSL/A==",
|
||||
"dependencies": {
|
||||
"@expo/config": "~12.0.7",
|
||||
"@expo/config-plugins": "~11.0.7",
|
||||
"@expo/config-types": "^54.0.7",
|
||||
"@expo/image-utils": "^0.8.6",
|
||||
"@expo/json-file": "^10.0.6",
|
||||
"@react-native/normalize-colors": "0.81.1",
|
||||
"debug": "^4.3.1",
|
||||
"resolve-from": "^5.0.0",
|
||||
"semver": "^7.6.0",
|
||||
"xml2js": "0.6.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/@react-native/normalize-colors": {
|
||||
"version": "0.81.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.81.1.tgz",
|
||||
"integrity": "sha512-TsaeZlE8OYFy3PSWc+1VBmAzI2T3kInzqxmwXoGU4w1d4XFkQFg271Ja9GmDi9cqV3CnBfqoF9VPwRxVlc/l5g=="
|
||||
},
|
||||
"node_modules/expo-splash-screen/node_modules/semver": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-status-bar": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.2.3.tgz",
|
||||
@@ -4066,6 +4365,32 @@
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-system-ui": {
|
||||
"version": "5.0.11",
|
||||
"resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-5.0.11.tgz",
|
||||
"integrity": "sha512-PG5VdaG5cwBe1Rj02mJdnsihKl9Iw/w/a6+qh2mH3f2K/IvQ+Hf7aG2kavSADtkGNCNj7CEIg7Rn4DQz/SE5rQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-native/normalize-colors": "0.79.6",
|
||||
"debug": "^4.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
"react-native": "*",
|
||||
"react-native-web": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-native-web": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/expo-system-ui/node_modules/@react-native/normalize-colors": {
|
||||
"version": "0.79.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.79.6.tgz",
|
||||
"integrity": "sha512-0v2/ruY7eeKun4BeKu+GcfO+SHBdl0LJn4ZFzTzjHdWES0Cn+ONqKljYaIv8p9MV2Hx/kcdEvbY4lWI34jC/mQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/exponential-backoff": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz",
|
||||
@@ -4271,6 +4596,17 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/global-dirs": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
|
||||
"integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==",
|
||||
"dependencies": {
|
||||
"ini": "^1.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
@@ -4312,7 +4648,6 @@
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
@@ -4320,8 +4655,7 @@
|
||||
"node_modules/hoist-non-react-statics/node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"peer": true
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "7.0.2",
|
||||
@@ -5807,9 +6141,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/on-headers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
|
||||
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
|
||||
"integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -6400,6 +6734,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-confirmation-code-field": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-confirmation-code-field/-/react-native-confirmation-code-field-8.0.1.tgz",
|
||||
"integrity": "sha512-pwrhQtspFEp0y/gxZRp8hrra+UjAYfwAsW5Sn3yYtdUZVyRjAZPBnUb3rOc+z5L5o2ml03z5P3uvTK0yQwXsmA==",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.4.0",
|
||||
"react-native": ">=0.64.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-native": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-edge-to-edge": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-edge-to-edge/-/react-native-edge-to-edge-1.6.0.tgz",
|
||||
@@ -6410,10 +6761,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-gesture-handler": {
|
||||
"version": "2.27.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.27.1.tgz",
|
||||
"integrity": "sha512-57TUWerhdz589OcDD21e/YlL923Ma4OIpyWsP0hy7gItBCPm5d7qIUW7Yo/cS2wo1qDdOhJaNlvlBD1lDou1fA==",
|
||||
"peer": true,
|
||||
"version": "2.24.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.24.0.tgz",
|
||||
"integrity": "sha512-ZdWyOd1C8axKJHIfYxjJKCcxjWEpUtUWgTOVY2wynbiveSQDm8X/PDyAKXSer/GOtIpjudUbACOndZXCN3vHsw==",
|
||||
"dependencies": {
|
||||
"@egjs/hammerjs": "^2.0.17",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
@@ -6598,9 +6948,9 @@
|
||||
"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
|
||||
},
|
||||
"node_modules/regenerate-unicode-properties": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
|
||||
"integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
|
||||
"version": "10.2.2",
|
||||
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz",
|
||||
"integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==",
|
||||
"dependencies": {
|
||||
"regenerate": "^1.4.2"
|
||||
},
|
||||
@@ -6614,16 +6964,16 @@
|
||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||
},
|
||||
"node_modules/regexpu-core": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
|
||||
"integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.3.1.tgz",
|
||||
"integrity": "sha512-DzcswPr252wEr7Qz8AyAVbfyBDKLoYp6eRA1We2Fa9qirRFSdtkP5sHr3yglDKy2BbA0fd2T+j/CUSKes3FeVQ==",
|
||||
"dependencies": {
|
||||
"regenerate": "^1.4.2",
|
||||
"regenerate-unicode-properties": "^10.2.0",
|
||||
"regenerate-unicode-properties": "^10.2.2",
|
||||
"regjsgen": "^0.8.0",
|
||||
"regjsparser": "^0.12.0",
|
||||
"unicode-match-property-ecmascript": "^2.0.0",
|
||||
"unicode-match-property-value-ecmascript": "^2.1.0"
|
||||
"unicode-match-property-value-ecmascript": "^2.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -6720,6 +7070,17 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-global": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz",
|
||||
"integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==",
|
||||
"dependencies": {
|
||||
"global-dirs": "^0.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-workspace-root": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.0.tgz",
|
||||
@@ -7602,9 +7963,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/unicode-match-property-value-ecmascript": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
|
||||
"integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
|
||||
"integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
|
||||
@@ -16,11 +16,16 @@
|
||||
"@react-navigation/bottom-tabs": "^7.4.2",
|
||||
"@react-navigation/native": "^7.1.14",
|
||||
"@react-navigation/stack": "^7.4.2",
|
||||
"expo": "53.0.19",
|
||||
"expo": "53.0.22",
|
||||
"expo-font": "~13.3.2",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"expo-splash-screen": "^31.0.8",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"expo-system-ui": "~5.0.11",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-confirmation-code-field": "^8.0.1",
|
||||
"react-native-gesture-handler": "~2.24.0",
|
||||
"react-native-modal-datetime-picker": "^15.0.1",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "^4.11.1",
|
||||
|
||||
@@ -104,13 +104,9 @@ const EditProfileModal = ({
|
||||
}
|
||||
|
||||
// Card year validation (optional, 4 digits and reasonable year)
|
||||
if (formData.card_year) {
|
||||
const year = parseInt(formData.card_year.trim(), 10);
|
||||
const currentYear = new Date().getFullYear();
|
||||
if (!/^[0-9]{4}$/.test(formData.card_year.trim()) || year < currentYear - 10 || year > currentYear + 10) {
|
||||
newErrors.card_year = `Ýyl ${currentYear - 10}-den ${currentYear + 10}-e çenli bolmaly`;
|
||||
}
|
||||
}
|
||||
// if (formData.card_year) {
|
||||
|
||||
// }
|
||||
|
||||
setErrors(newErrors);
|
||||
return Object.keys(newErrors).length === 0;
|
||||
|
||||
132
src/components/TransactionList.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import React from 'react';
|
||||
import { View, Text, FlatList, StyleSheet } from 'react-native';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { COLORS } from '../constants/colors';
|
||||
|
||||
const TransactionList = ({ transactions }) => {
|
||||
if (!transactions || transactions.length === 0) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.emptyText}>Soňky 10 günde kart hereketleri ýok...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const groupedTransactions = transactions.reduce((acc, transaction) => {
|
||||
const date = new Date(transaction.date).toLocaleDateString('tk', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
});
|
||||
if (!acc[date]) {
|
||||
acc[date] = [];
|
||||
}
|
||||
acc[date].push(transaction);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const renderTransactionItem = ({ item }) => (
|
||||
<View style={styles.transactionItem}>
|
||||
<View style={styles.transactionIcon}>
|
||||
<Ionicons
|
||||
name={item.type === 'credit' ? 'arrow-down' : 'arrow-up'}
|
||||
size={20}
|
||||
color={item.type === 'credit' ? COLORS.success : COLORS.danger}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.transactionDetails}>
|
||||
<Text style={styles.transactionTitle}>{item.description}</Text>
|
||||
<Text style={styles.transactionDate}>{item.time ?? '-'}</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={[
|
||||
styles.transactionAmount,
|
||||
{ color: item.type === 'credit' ? COLORS.success : COLORS.textPrimary },
|
||||
]}
|
||||
>
|
||||
{item.type === 'credit' ? '+' : '-'}
|
||||
{item.amount} {item.currency}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderTransactionSection = ({ item: date }) => (
|
||||
<View>
|
||||
<Text style={styles.transactionDateHeader}>{date}</Text>
|
||||
<FlatList
|
||||
data={groupedTransactions[date]}
|
||||
renderItem={renderTransactionItem}
|
||||
keyExtractor={(item) => item.id?.toString()}
|
||||
scrollEnabled={false}
|
||||
ItemSeparatorComponent={() => <View style={styles.separator} />}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
data={Object.keys(groupedTransactions)}
|
||||
renderItem={renderTransactionSection}
|
||||
keyExtractor={(date) => date}
|
||||
scrollEnabled={false}
|
||||
ItemSeparatorComponent={() => <View style={styles.separator} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
padding: 16,
|
||||
},
|
||||
emptyText: {
|
||||
textAlign: 'center',
|
||||
color: COLORS.textSecondary,
|
||||
},
|
||||
transactionItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 12,
|
||||
},
|
||||
transactionIcon: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
borderRadius: 22,
|
||||
backgroundColor: COLORS.background,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 16,
|
||||
},
|
||||
transactionDetails: {
|
||||
flex: 1,
|
||||
},
|
||||
transactionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: COLORS.textPrimary,
|
||||
marginBottom: 2,
|
||||
},
|
||||
transactionDate: {
|
||||
fontSize: 13,
|
||||
color: COLORS.textSecondary,
|
||||
},
|
||||
transactionAmount: {
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
},
|
||||
transactionDateHeader: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: COLORS.textSecondary,
|
||||
backgroundColor: COLORS.white,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 8,
|
||||
paddingHorizontal: 4,
|
||||
},
|
||||
separator: {
|
||||
height: 1,
|
||||
backgroundColor: COLORS.gray[200],
|
||||
marginLeft: 60,
|
||||
},
|
||||
});
|
||||
|
||||
export default TransactionList;
|
||||
@@ -2,7 +2,8 @@ import React from 'react';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { COLORS } from '../constants/colors';
|
||||
import { View, ActivityIndicator, Platform } from 'react-native';
|
||||
import { View, ActivityIndicator, Platform, OS } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import HomeScreen from '../screens/Main/HomeScreen';
|
||||
import MenuNavigator from './MenuNavigator';
|
||||
@@ -11,6 +12,8 @@ import ProfileScreen from '../screens/Main/ProfileScreen';
|
||||
const Tab = createBottomTabNavigator();
|
||||
|
||||
const MainNavigator = () => {
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
return (
|
||||
<Tab.Navigator
|
||||
screenOptions={({ route }) => ({
|
||||
@@ -34,9 +37,17 @@ const MainNavigator = () => {
|
||||
backgroundColor: COLORS.white,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: COLORS.gray[200],
|
||||
paddingBottom: Platform.OS === 'android' ? 16 : 8,
|
||||
paddingBottom: (insets.bottom || 16),
|
||||
paddingTop: 8,
|
||||
height: Platform.OS === 'android' ? 96 : 88,
|
||||
height: Platform.OS === 'ios' ? 100 : (82 + (insets.bottom || 16)),
|
||||
elevation: 8,
|
||||
shadowColor: COLORS.gray[900],
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: -2,
|
||||
},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 4,
|
||||
},
|
||||
tabBarLabelStyle: {
|
||||
fontSize: 12,
|
||||
@@ -44,7 +55,7 @@ const MainNavigator = () => {
|
||||
marginTop: 4,
|
||||
},
|
||||
tabBarItemStyle: {
|
||||
paddingVertical: 4,
|
||||
paddingVertical: 2,
|
||||
},
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -29,34 +29,32 @@ import CardOrderDetailsScreen from '../screens/Card/CardOrderDetailsScreen';
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
const MenuNavigator = () => (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||
<Stack.Screen name="MenuHome" component={MenuScreen} />
|
||||
<Stack.Screen name="LoanRemainingOrders" component={LoanRemainingOrdersScreen} />
|
||||
<Stack.Screen name="CreateLoanRemainingOrder" component={CreateLoanRemainingOrderScreen} />
|
||||
<Stack.Screen name="LoanPaidOffLetterOrders" component={LoanPaidOffLetterOrdersScreen} />
|
||||
<Stack.Screen name="CreateLoanPaidOffLetterOrder" component={CreateLoanPaidOffLetterOrderScreen} />
|
||||
<Stack.Screen name="LoanPaidOffLetterOrderDetails" component={LoanPaidOffLetterOrderDetailsScreen} />
|
||||
<Stack.Screen name="LoanOrders" component={LoanOrdersScreen} />
|
||||
<Stack.Screen name="CreateLoanOrder" component={CreateLoanOrderScreen} />
|
||||
<Stack.Screen name="LoanOrderDetails" component={LoanOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardTransactionOrders" component={CardTransactionOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardTransactionOrder" component={CreateCardTransactionOrderScreen} />
|
||||
<Stack.Screen name="CardTransactionOrderDetails" component={CardTransactionOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardBalanceOrders" component={CardBalanceOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardBalanceOrder" component={CreateCardBalanceOrderScreen} />
|
||||
<Stack.Screen name="CardBalanceOrderDetails" component={CardBalanceOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardRequisiteOrders" component={CardRequisiteOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardRequisiteOrder" component={CreateCardRequisiteOrderScreen} />
|
||||
<Stack.Screen name="CardRequisiteOrderDetails" component={CardRequisiteOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardPinOrders" component={CardPinOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardPinOrder" component={CreateCardPinOrderScreen} />
|
||||
<Stack.Screen name="CardPinOrderDetails" component={CardPinOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardOrders" component={CardOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardOrder" component={CreateCardOrderScreen} />
|
||||
<Stack.Screen name="CardOrderDetails" component={CardOrderDetailsScreen} />
|
||||
</Stack.Navigator>
|
||||
</SafeAreaView>
|
||||
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||
<Stack.Screen name="MenuHome" component={MenuScreen} />
|
||||
<Stack.Screen name="LoanRemainingOrders" component={LoanRemainingOrdersScreen} />
|
||||
<Stack.Screen name="CreateLoanRemainingOrder" component={CreateLoanRemainingOrderScreen} />
|
||||
<Stack.Screen name="LoanPaidOffLetterOrders" component={LoanPaidOffLetterOrdersScreen} />
|
||||
<Stack.Screen name="CreateLoanPaidOffLetterOrder" component={CreateLoanPaidOffLetterOrderScreen} />
|
||||
<Stack.Screen name="LoanPaidOffLetterOrderDetails" component={LoanPaidOffLetterOrderDetailsScreen} />
|
||||
<Stack.Screen name="LoanOrders" component={LoanOrdersScreen} />
|
||||
<Stack.Screen name="CreateLoanOrder" component={CreateLoanOrderScreen} />
|
||||
<Stack.Screen name="LoanOrderDetails" component={LoanOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardTransactionOrders" component={CardTransactionOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardTransactionOrder" component={CreateCardTransactionOrderScreen} />
|
||||
<Stack.Screen name="CardTransactionOrderDetails" component={CardTransactionOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardBalanceOrders" component={CardBalanceOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardBalanceOrder" component={CreateCardBalanceOrderScreen} />
|
||||
<Stack.Screen name="CardBalanceOrderDetails" component={CardBalanceOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardRequisiteOrders" component={CardRequisiteOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardRequisiteOrder" component={CreateCardRequisiteOrderScreen} />
|
||||
<Stack.Screen name="CardRequisiteOrderDetails" component={CardRequisiteOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardPinOrders" component={CardPinOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardPinOrder" component={CreateCardPinOrderScreen} />
|
||||
<Stack.Screen name="CardPinOrderDetails" component={CardPinOrderDetailsScreen} />
|
||||
<Stack.Screen name="CardOrders" component={CardOrdersScreen} />
|
||||
<Stack.Screen name="CreateCardOrder" component={CreateCardOrderScreen} />
|
||||
<Stack.Screen name="CardOrderDetails" component={CardOrderDetailsScreen} />
|
||||
</Stack.Navigator>
|
||||
);
|
||||
|
||||
export default MenuNavigator;
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
KeyboardAvoidingView,
|
||||
ScrollView,
|
||||
Platform,
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
TouchableWithoutFeedback,
|
||||
Keyboard,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import Button from '../../components/Button';
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
KeyboardAvoidingView,
|
||||
ScrollView,
|
||||
Platform,
|
||||
@@ -11,6 +10,7 @@ import {
|
||||
TouchableWithoutFeedback,
|
||||
Keyboard,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import Button from '../../components/Button';
|
||||
|
||||
@@ -3,27 +3,40 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
Alert,
|
||||
TouchableOpacity,
|
||||
TouchableWithoutFeedback,
|
||||
Keyboard,
|
||||
BackHandler,
|
||||
Platform,
|
||||
KeyboardAvoidingView,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import Button from '../../components/Button';
|
||||
import Input from '../../components/Input';
|
||||
import {
|
||||
CodeField,
|
||||
Cursor,
|
||||
useBlurOnFulfill,
|
||||
useClearByFocusCell,
|
||||
} from 'react-native-confirmation-code-field';
|
||||
import { COLORS } from '../../constants/colors';
|
||||
|
||||
const CELL_COUNT = 6;
|
||||
|
||||
const VerificationScreen = ({ navigation }) => {
|
||||
const [code, setCode] = useState('');
|
||||
const [countdown, setCountdown] = useState(60);
|
||||
const [canResend, setCanResend] = useState(false);
|
||||
const { verify, isLoading, pendingVerification, clearPendingVerification } = useAuth();
|
||||
const countdownRef = useRef(null);
|
||||
const ref = useBlurOnFulfill({ value: code, cellCount: CELL_COUNT });
|
||||
const [props, getCellOnLayoutHandler] = useClearByFocusCell({
|
||||
value: code,
|
||||
setValue: setCode,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!pendingVerification) {
|
||||
@@ -73,18 +86,18 @@ const VerificationScreen = ({ navigation }) => {
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const handleVerify = async () => {
|
||||
if (!code.trim()) {
|
||||
const handleVerify = async (filledCode) => {
|
||||
if (!filledCode.trim()) {
|
||||
Alert.alert('Ýalňyşlyk', 'Tassyklama koduny giriziň');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/^\d{6}$/.test(code.trim())) {
|
||||
if (!/^\d{6}$/.test(filledCode.trim())) {
|
||||
Alert.alert('Ýalňyşlyk', 'Tassyklama kody 6 sanly bolmaly');
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await verify(code.trim());
|
||||
const result = await verify(filledCode.trim());
|
||||
|
||||
if (result.success) {
|
||||
// Navigation will be handled by AuthContext
|
||||
@@ -93,6 +106,8 @@ const VerificationScreen = ({ navigation }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleVerifyWrapper = () => handleVerify(code);
|
||||
|
||||
const handleResendCode = async () => {
|
||||
if (!canResend) return;
|
||||
|
||||
@@ -134,54 +149,66 @@ const VerificationScreen = ({ navigation }) => {
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<View style={styles.content}>
|
||||
<View style={styles.logoContainer}>
|
||||
<View style={styles.verificationIcon}>
|
||||
<Text style={styles.verificationIconText}>✓</Text>
|
||||
<KeyboardAvoidingView
|
||||
style={{ flex: 1 }}
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<View style={styles.content}>
|
||||
<View style={styles.logoContainer}>
|
||||
<View style={styles.verificationIcon}>
|
||||
<Text style={styles.verificationIconText}>✓</Text>
|
||||
</View>
|
||||
<Text style={styles.title}>Tassyklama</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
{formatPhoneNumber(pendingVerification.phone)} belgisine iberilen
|
||||
6 sanly tassyklama koduny giriziň
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.title}>Tassyklama</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
{formatPhoneNumber(pendingVerification.phone)} belgisine iberilen
|
||||
6 sanly tassyklama koduny giriziň
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.formContainer}>
|
||||
<Input
|
||||
label="Tassyklama kody"
|
||||
value={code}
|
||||
onChangeText={setCode}
|
||||
placeholder="123456"
|
||||
keyboardType="numeric"
|
||||
maxLength={6}
|
||||
style={styles.codeInput}
|
||||
textAlign="center"
|
||||
returnKeyType="done"
|
||||
onSubmitEditing={handleVerify}
|
||||
/>
|
||||
<View style={styles.formContainer}>
|
||||
<CodeField
|
||||
ref={ref}
|
||||
{...props}
|
||||
value={code}
|
||||
onChangeText={setCode}
|
||||
cellCount={CELL_COUNT}
|
||||
rootStyle={styles.otpContainer}
|
||||
keyboardType="number-pad"
|
||||
textContentType="oneTimeCode"
|
||||
renderCell={({ index, symbol, isFocused }) => (
|
||||
<Text
|
||||
key={index}
|
||||
style={[styles.otpInput, isFocused && styles.otpInputHighlight]}
|
||||
onLayout={getCellOnLayoutHandler(index)}>
|
||||
{symbol || (isFocused ? <Cursor/> : null)}
|
||||
</Text>
|
||||
)}
|
||||
onSubmitEditing={handleVerifyWrapper}
|
||||
/>
|
||||
|
||||
<Button
|
||||
title="Tassykla"
|
||||
onPress={handleVerify}
|
||||
loading={isLoading}
|
||||
style={styles.verifyButton}
|
||||
/>
|
||||
<Button
|
||||
title="Tassykla"
|
||||
onPress={handleVerifyWrapper}
|
||||
loading={isLoading}
|
||||
style={styles.verifyButton}
|
||||
/>
|
||||
|
||||
<View style={styles.resendContainer}>
|
||||
{canResend ? (
|
||||
<TouchableOpacity onPress={handleResendCode}>
|
||||
<Text style={styles.resendText}>Kodu gaýtadan iber</Text>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<Text style={styles.countdownText}>
|
||||
Gaýtadan ibermek üçin {countdown} sekunt garaşyň
|
||||
</Text>
|
||||
)}
|
||||
<View style={styles.resendContainer}>
|
||||
{canResend ? (
|
||||
<TouchableOpacity onPress={handleResendCode}>
|
||||
<Text style={styles.resendText}>Kodu gaýtadan iber</Text>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<Text style={styles.countdownText}>
|
||||
Gaýtadan ibermek üçin {countdown} sekunt garaşyň
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</TouchableWithoutFeedback>
|
||||
</KeyboardAvoidingView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
@@ -251,10 +278,25 @@ const styles = StyleSheet.create({
|
||||
formContainer: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
codeInput: {
|
||||
width: '100%',
|
||||
otpContainer: {
|
||||
width: '90%',
|
||||
marginBottom: 32,
|
||||
},
|
||||
otpInput: {
|
||||
width: 45,
|
||||
height: 60,
|
||||
lineHeight: 58,
|
||||
borderWidth: 1,
|
||||
borderRadius: 12,
|
||||
borderColor: COLORS.gray[300],
|
||||
color: COLORS.textPrimary,
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
},
|
||||
otpInputHighlight: {
|
||||
borderColor: COLORS.primary,
|
||||
},
|
||||
verifyButton: {
|
||||
width: '100%',
|
||||
marginBottom: 32,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, SafeAreaView, Modal } from 'react-native';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, Modal } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, ScrollView, SafeAreaView, Image, Alert, Linking } from 'react-native';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, ScrollView, Image, Alert, Linking } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, TouchableOpacity, ActivityIndicator, RefreshControl, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, TouchableOpacity, ActivityIndicator, RefreshControl } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, SafeAreaView, Image, Linking } from 'react-native';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, Image, Linking } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, SafeAreaView, Image } from 'react-native';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, Image } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
@@ -137,6 +138,9 @@ const CardRequisiteOrderDetailsScreen = () => {
|
||||
</View>
|
||||
|
||||
{/* Actions */}
|
||||
<TouchableOpacity style={styles.actionBtn} onPress={handleDownload}>
|
||||
<Text style={styles.actionText}>Ýükle (PDF)</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.deleteBtn} onPress={handleDelete}>
|
||||
<Text style={styles.deleteText}>Poz</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useCallback, useRef } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, SafeAreaView, Modal } from 'react-native';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, Modal } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
@@ -93,7 +94,7 @@ const CardTransactionOrderDetailsScreen = () => {
|
||||
if (!order) {
|
||||
return (
|
||||
<View style={styles.centered}>
|
||||
<Text>No data</Text>
|
||||
<Text>Maglumat tapylmady</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, SafeAreaView, ScrollView } from 'react-native';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, SafeAreaView, ScrollView, Modal } from 'react-native';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView, Modal } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, SafeAreaView, ScrollView } from 'react-native';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, SafeAreaView, ScrollView } from 'react-native';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, SafeAreaView, ScrollView } from 'react-native';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView, SafeAreaView, View } from 'react-native';
|
||||
import { Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { COLORS } from '../../constants/colors';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView, SafeAreaView } from 'react-native';
|
||||
import { Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, ScrollView } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { COLORS } from '../../constants/colors';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, Alert } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, SafeAreaView, Alert } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, Alert } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView, SafeAreaView } from 'react-native';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, ScrollView } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, SafeAreaView, Alert } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, Alert } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
@@ -63,7 +64,7 @@ const LoanRemainingOrderDetailsScreen = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<SafeAreaView style={styles.container}>
|
||||
<TouchableOpacity style={styles.backBtn} onPress={() => navigation.goBack()}>
|
||||
<Ionicons name="close" size={28} color={COLORS.textPrimary} />
|
||||
</TouchableOpacity>
|
||||
@@ -82,7 +83,7 @@ const LoanRemainingOrderDetailsScreen = () => {
|
||||
<TouchableOpacity style={styles.deleteBtn} onPress={handleDelete}>
|
||||
<Text style={styles.deleteText}>Poz</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, Modal, ScrollView, Alert, SafeAreaView, Pressable } from 'react-native';
|
||||
import { View, Text, StyleSheet, FlatList, ActivityIndicator, TouchableOpacity, RefreshControl, Modal, ScrollView, Alert, Pressable } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
@@ -133,7 +134,7 @@ const LoanRemainingOrdersScreen = () => {
|
||||
renderItem={renderItem}
|
||||
contentContainerStyle={orders.length === 0 && styles.emptyContainer}
|
||||
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
|
||||
ListEmptyComponent={<Text style={styles.emptyText}>No orders yet</Text>}
|
||||
ListEmptyComponent={<Text style={styles.emptyText}>Sargyt ýok</Text>}
|
||||
/>
|
||||
|
||||
{/* Floating Action Button */}
|
||||
|
||||
@@ -3,21 +3,107 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
ActivityIndicator,
|
||||
RefreshControl,
|
||||
FlatList,
|
||||
} from 'react-native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import { COLORS } from '../../constants/colors';
|
||||
import MetricCard from '../../components/MetricCard';
|
||||
import apiService from '../../services/apiService';
|
||||
import TransactionList from '../../components/TransactionList';
|
||||
|
||||
const STATIC_TRANSACTIONS = [
|
||||
{
|
||||
id: 1,
|
||||
type: 'debit',
|
||||
description: 'Canva Design and Publishing',
|
||||
date: '2025-09-07T10:30:00Z',
|
||||
amount: 10.0,
|
||||
currency: 'EUR',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
type: 'debit',
|
||||
description: 'Google',
|
||||
date: '2025-09-07T11:00:00Z',
|
||||
amount: 12.99,
|
||||
currency: 'SAR',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
type: 'debit',
|
||||
description: 'Canva Design and Publishing',
|
||||
date: '2025-09-05T14:15:00Z',
|
||||
amount: 10.0,
|
||||
currency: 'EUR',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
type: 'credit',
|
||||
description: 'Töleg alyňýan hasap',
|
||||
date: '2025-09-03T09:00:00Z',
|
||||
amount: 20.0,
|
||||
currency: 'USD',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
type: 'debit',
|
||||
description: 'Комиссия за оплату',
|
||||
date: '2025-09-03T09:01:00Z',
|
||||
amount: 0.12,
|
||||
currency: 'USD',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
type: 'credit',
|
||||
description: 'Hasaby doldurmak',
|
||||
date: '2025-09-02T18:45:00Z',
|
||||
amount: 10.0,
|
||||
currency: 'USD',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
type: 'debit',
|
||||
description: 'Canva Design and Publishing',
|
||||
date: '2025-09-01T12:00:00Z',
|
||||
amount: 10.0,
|
||||
currency: 'EUR',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
type: 'debit',
|
||||
description: 'Netflix',
|
||||
date: '2025-08-28T16:00:00Z',
|
||||
amount: 9.99,
|
||||
currency: 'USD',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
type: 'credit',
|
||||
description: 'Bank Transfer',
|
||||
date: '2025-08-25T08:20:00Z',
|
||||
amount: 500.0,
|
||||
currency: 'TMT',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
type: 'debit',
|
||||
description: 'Amazon',
|
||||
date: '2025-08-23T19:55:00Z',
|
||||
amount: 45.5,
|
||||
currency: 'USD',
|
||||
},
|
||||
];
|
||||
|
||||
const HomeScreen = () => {
|
||||
const { user, logout } = useAuth();
|
||||
const insets = useSafeAreaInsets();
|
||||
const [metrics, setMetrics] = useState(null);
|
||||
const [loadingMetrics, setLoadingMetrics] = useState(true);
|
||||
const [cardBalance, setCardBalance] = useState(null);
|
||||
@@ -25,6 +111,8 @@ const HomeScreen = () => {
|
||||
const [cardBalanceError, setCardBalanceError] = useState(null);
|
||||
const [isBalanceVisible, setIsBalanceVisible] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [transactions, setTransactions] = useState([]);
|
||||
const [loadingTransactions, setLoadingTransactions] = useState(true);
|
||||
|
||||
const showBalanceCard = !loadingCardBalance && cardBalanceError === null && cardBalance !== null;
|
||||
|
||||
@@ -50,16 +138,20 @@ const HomeScreen = () => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchCardBalance = async () => {
|
||||
const fetchCardData = async () => {
|
||||
// Ensure user has filled all required card & passport fields
|
||||
if (!user?.passport_serie || !user?.passport_id || !user?.card_number || !user?.card_month || !user?.card_year) {
|
||||
setLoadingCardBalance(false);
|
||||
setLoadingTransactions(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoadingCardBalance(true);
|
||||
setLoadingTransactions(true);
|
||||
|
||||
try {
|
||||
const res = await apiService.getCardBalanceQuickCheck();
|
||||
if (res.success) {
|
||||
// Try common balance keys else fallback to raw
|
||||
const raw = res.data;
|
||||
let balanceValue = null;
|
||||
if (raw && typeof raw === 'object') {
|
||||
@@ -73,12 +165,26 @@ const HomeScreen = () => {
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error fetching card balance:', e);
|
||||
setCardBalanceError('Error fetching balance');
|
||||
} finally {
|
||||
setLoadingCardBalance(false);
|
||||
}
|
||||
|
||||
try {
|
||||
const transRes = await apiService.getCardTransactionsLastMonth();
|
||||
if (transRes.success) {
|
||||
setTransactions(transRes.data || []);
|
||||
} else {
|
||||
console.warn('Failed to fetch transactions:', transRes.error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error fetching transactions:', e);
|
||||
} finally {
|
||||
setLoadingTransactions(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchCardBalance();
|
||||
fetchCardData();
|
||||
}, [user]);
|
||||
|
||||
const handleRefresh = async () => {
|
||||
@@ -100,6 +206,8 @@ const HomeScreen = () => {
|
||||
if (!user?.passport_serie || !user?.passport_id || !user?.card_number || !user?.card_month || !user?.card_year) {
|
||||
setCardBalance(null); // Clear previous balance if conditions are not met
|
||||
setCardBalanceError(null);
|
||||
setTransactions([]);
|
||||
setLoadingTransactions(false);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -119,13 +227,25 @@ const HomeScreen = () => {
|
||||
} catch (e) {
|
||||
console.warn('Error fetching card balance during refresh:', e);
|
||||
}
|
||||
try {
|
||||
const transRes = await apiService.getCardTransactionsLastMonth();
|
||||
if (transRes.success) {
|
||||
setTransactions(transRes.data || []);
|
||||
} else {
|
||||
console.warn('Failed to fetch transactions during refresh:', transRes.error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error fetching transactions during refresh:', e);
|
||||
} finally {
|
||||
setLoadingTransactions(false);
|
||||
}
|
||||
})(),
|
||||
]);
|
||||
setRefreshing(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.container}>
|
||||
<StatusBar style="dark" />
|
||||
|
||||
<ScrollView
|
||||
@@ -140,7 +260,7 @@ const HomeScreen = () => {
|
||||
}
|
||||
>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<View style={[styles.header, { paddingTop: insets.top + 16 }]}>
|
||||
<View>
|
||||
<Text style={styles.greeting}>Salam,</Text>
|
||||
<Text style={styles.userName}>{user?.name || 'Ulanyjy'}</Text>
|
||||
@@ -149,7 +269,7 @@ const HomeScreen = () => {
|
||||
|
||||
{/* Metrics */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Metrics</Text>
|
||||
<Text style={styles.sectionTitle}>Görkezijiler</Text>
|
||||
{loadingMetrics ? (
|
||||
<ActivityIndicator color={COLORS.primary} style={{ marginTop: 16 }} />
|
||||
) : (
|
||||
@@ -181,8 +301,27 @@ const HomeScreen = () => {
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Card Transactions */}
|
||||
{showBalanceCard && (
|
||||
<View style={styles.section}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text style={styles.sectionTitle}>Kart hereketleri</Text>
|
||||
<Text style={styles.sectionSubtitle}>Soňky 10 günde</Text>
|
||||
|
||||
<TouchableOpacity>
|
||||
{/* <Text style={styles.seeAllText}>Hemmesi</Text> */}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{loadingTransactions ? (
|
||||
<ActivityIndicator color={COLORS.primary} style={{ marginTop: 16 }} />
|
||||
) : (
|
||||
<TransactionList transactions={transactions} />
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -199,7 +338,6 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 24,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 24,
|
||||
backgroundColor: COLORS.white,
|
||||
marginBottom: 16,
|
||||
@@ -273,16 +411,16 @@ const styles = StyleSheet.create({
|
||||
padding: 20,
|
||||
},
|
||||
sectionHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
color: COLORS.textPrimary,
|
||||
marginBottom: 16,
|
||||
},
|
||||
sectionSubtitle: {
|
||||
fontSize: 14,
|
||||
color: COLORS.textSecondary,
|
||||
},
|
||||
seeAllText: {
|
||||
fontSize: 14,
|
||||
@@ -310,58 +448,6 @@ const styles = StyleSheet.create({
|
||||
color: COLORS.textSecondary,
|
||||
textAlign: 'center',
|
||||
},
|
||||
transactionsList: {
|
||||
gap: 16,
|
||||
},
|
||||
transactionItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
transactionIcon: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: COLORS.backgroundSecondary,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 12,
|
||||
},
|
||||
transactionDetails: {
|
||||
flex: 1,
|
||||
},
|
||||
transactionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: COLORS.textPrimary,
|
||||
},
|
||||
transactionDate: {
|
||||
fontSize: 14,
|
||||
color: COLORS.textSecondary,
|
||||
},
|
||||
transactionAmount: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: COLORS.success,
|
||||
},
|
||||
servicesGrid: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
serviceItem: {
|
||||
width: '48%',
|
||||
padding: 16,
|
||||
backgroundColor: COLORS.backgroundSecondary,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
serviceText: {
|
||||
fontSize: 12,
|
||||
color: COLORS.textSecondary,
|
||||
textAlign: 'center',
|
||||
marginTop: 8,
|
||||
},
|
||||
metricsGrid: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
|
||||
@@ -4,16 +4,17 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { COLORS } from '../../constants/colors';
|
||||
|
||||
const MenuScreen = () => {
|
||||
const navigation = useNavigation();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const menuSections = [
|
||||
{
|
||||
@@ -66,10 +67,10 @@ const MenuScreen = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.container}>
|
||||
<StatusBar style="dark" />
|
||||
|
||||
<View style={styles.header}>
|
||||
<View style={[styles.header, { paddingTop: insets.top + 16 }]}>
|
||||
<Text style={styles.headerTitle}>Hyzmatlar</Text>
|
||||
</View>
|
||||
|
||||
@@ -105,7 +106,7 @@ const MenuScreen = () => {
|
||||
|
||||
<View style={styles.bottomSpacing} />
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -116,7 +117,6 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
header: {
|
||||
paddingHorizontal: 24,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 24,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: COLORS.gray[200],
|
||||
|
||||
@@ -3,15 +3,16 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
Alert,
|
||||
ActivityIndicator,
|
||||
RefreshControl,
|
||||
Linking,
|
||||
} from 'react-native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import apiService from '../../services/apiService';
|
||||
import EditProfileModal from '../../components/EditProfileModal';
|
||||
@@ -19,6 +20,7 @@ import { COLORS } from '../../constants/colors';
|
||||
|
||||
const ProfileScreen = () => {
|
||||
const { user, logout, fetchUserProfile } = useAuth();
|
||||
const insets = useSafeAreaInsets();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const [profileData, setProfileData] = useState(null);
|
||||
@@ -80,8 +82,8 @@ const ProfileScreen = () => {
|
||||
items: [
|
||||
// { id: 11, title: 'Ulanmak düzgünleri', icon: 'document-text', hasArrow: true },
|
||||
// { id: 12, title: 'Gizlinlik syýasaty', icon: 'lock-open', hasArrow: true },
|
||||
{ id: 13, title: 'Programma barada', icon: 'information-circle', value: 'v1.0.0', hasArrow: true },
|
||||
{ id: 14, title: 'Hasaby poz', icon: 'trash', hasArrow: false, color: COLORS.red },
|
||||
{ id: 13, title: 'Programma barada', icon: 'information-circle', value: 'v1.0.0', hasArrow: false },
|
||||
{ id: 14, title: 'Hasaby poz', icon: 'trash', hasArrow: false, danger: true },
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -104,7 +106,7 @@ const ProfileScreen = () => {
|
||||
handleSecuritySettings();
|
||||
break;
|
||||
case 13: // About App
|
||||
Alert.alert('Üns beriň', 'Programma barada maglumatlar açylýar...');
|
||||
// Alert.alert('Üns beriň', 'Programma barada maglumatlar açylýar...');
|
||||
break;
|
||||
case 14: // Delete Account
|
||||
handleDeleteAccount();
|
||||
@@ -278,10 +280,10 @@ const ProfileScreen = () => {
|
||||
const currentUser = profileData || user;
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.container}>
|
||||
<StatusBar style="dark" />
|
||||
|
||||
<View style={styles.header}>
|
||||
<View style={[styles.header, { paddingTop: insets.top + 16 }]}>
|
||||
<Text style={styles.headerTitle}>Profil</Text>
|
||||
</View>
|
||||
|
||||
@@ -335,16 +337,16 @@ const ProfileScreen = () => {
|
||||
>
|
||||
<View style={styles.profileItemLeft}>
|
||||
<View style={styles.profileItemIcon}>
|
||||
<Ionicons name={item.icon} size={20} color={item.color || COLORS.primary} />
|
||||
<Ionicons name={item.icon} size={20} color={item.danger ? COLORS.error : COLORS.primary} />
|
||||
</View>
|
||||
<Text style={styles.profileItemTitle}>{item.title}</Text>
|
||||
<Text style={item.danger ? styles.profileItemTitleDanger : styles.profileItemTitle}>{item.title}</Text>
|
||||
</View>
|
||||
<View style={styles.profileItemRight}>
|
||||
{item.value && (
|
||||
<Text style={styles.profileItemValue}>{item.value}</Text>
|
||||
<Text style={item.danger ? styles.profileItemValueDanger : styles.profileItemValue}>{item.value}</Text>
|
||||
)}
|
||||
{item.hasArrow && (
|
||||
<Ionicons name="chevron-forward" size={16} color={COLORS.gray[400]} />
|
||||
<Ionicons name="chevron-forward" size={16} color={item.danger ? COLORS.error : COLORS.gray[400]} />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
@@ -362,6 +364,21 @@ const ProfileScreen = () => {
|
||||
</View>
|
||||
|
||||
<View style={styles.bottomSpacing} />
|
||||
|
||||
{/* Copyright */}
|
||||
<Text style={styles.copyrightText}>
|
||||
Copyright{' '}
|
||||
<Text
|
||||
style={styles.link}
|
||||
onPress={() => Linking.openURL('https://webulgam.com')}
|
||||
>
|
||||
Webulgam IT Company
|
||||
</Text>{' '}
|
||||
© {new Date().getFullYear()}.
|
||||
</Text>
|
||||
<Text style={styles.copyrightText}>
|
||||
Ähli hukular goralan.
|
||||
</Text>
|
||||
</ScrollView>
|
||||
|
||||
{/* Edit Profile Modal */}
|
||||
@@ -372,7 +389,7 @@ const ProfileScreen = () => {
|
||||
initialData={profileData || user}
|
||||
isLoading={isUpdatingProfile}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -384,7 +401,6 @@ const styles = StyleSheet.create({
|
||||
header: {
|
||||
backgroundColor: COLORS.white,
|
||||
paddingHorizontal: 24,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 24,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: COLORS.gray[200],
|
||||
@@ -526,6 +542,24 @@ const styles = StyleSheet.create({
|
||||
bottomSpacing: {
|
||||
height: 24,
|
||||
},
|
||||
copyrightText: {
|
||||
fontSize: 12,
|
||||
color: COLORS.textSecondary,
|
||||
textAlign: 'center',
|
||||
},
|
||||
link: {
|
||||
color: COLORS.primary,
|
||||
},
|
||||
profileItemTitleDanger: {
|
||||
fontSize: 16,
|
||||
color: COLORS.error,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
profileItemValueDanger: {
|
||||
fontSize: 14,
|
||||
color: COLORS.error,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
|
||||
export default ProfileScreen;
|
||||
@@ -67,6 +67,37 @@ class ApiService {
|
||||
return authService.getTransactions(page, limit);
|
||||
}
|
||||
|
||||
async getCardTransactionsLastMonth() {
|
||||
try {
|
||||
const response = await authService.getCardTransactionsLastMonth();
|
||||
if (response && response.data && Array.isArray(response.data.transactions)) {
|
||||
const mappedTransactions = response.data.transactions.map((t, index) => ({
|
||||
id: `${t.rrn}-${index}`,
|
||||
type: t.sign === '-' ? 'debit' : 'credit',
|
||||
description: t.binfo || t.opername,
|
||||
date: `${t.operdate}`,
|
||||
time: t.trantime,
|
||||
amount: t.currOperSum,
|
||||
currency: t.currCode,
|
||||
})).reverse();
|
||||
return {
|
||||
success: true,
|
||||
data: mappedTransactions,
|
||||
};
|
||||
}
|
||||
console.warn('Invalid transaction data structure:', response);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Could not parse transaction data.',
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer and payments
|
||||
async transferMoney(data) {
|
||||
return authService.transferMoney(data);
|
||||
|
||||
@@ -162,6 +162,10 @@ class AuthService {
|
||||
return this.makeRequest(`/user/cards/${cardId}/unblock`, null, true);
|
||||
}
|
||||
|
||||
async getCardTransactionsLastMonth() {
|
||||
return this.makeRequest('/card-transactions-last-month', null, true, 'GET');
|
||||
}
|
||||
|
||||
async changePassword(currentPassword, newPassword) {
|
||||
return this.makeRequest('/user/change-password', {
|
||||
current_password: currentPassword,
|
||||
|
||||