Compare commits
14 Commits
61fb0b2d96
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceabc0079c | ||
|
|
9b26ddaa37 | ||
|
|
0d12a01812 | ||
| 388d5e9a82 | |||
| 99bdb01644 | |||
| a41851dfcc | |||
|
|
27f43a77fd | ||
|
|
27f16f3c38 | ||
|
|
2eb41db2e5 | ||
|
|
61bcb6aa3f | ||
| 66f5271640 | |||
| db6a9e2bc0 | |||
| 14db29ab61 | |||
| 5ca3bb4f17 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -38,3 +38,5 @@ yarn-error.*
|
||||
|
||||
android/
|
||||
ios/
|
||||
.android/
|
||||
.ios/
|
||||
|
||||
17
App.js
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>
|
||||
);
|
||||
}
|
||||
|
||||
23
app.json
23
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"
|
||||
@@ -36,15 +44,12 @@
|
||||
[
|
||||
"expo-splash-screen",
|
||||
{
|
||||
"backgroundColor": "#17b69b",
|
||||
"backgroundColor": "#ffffff",
|
||||
"image": "./assets/splash-icon.png",
|
||||
"dark": {
|
||||
"image": "./assets/splash-icon.png",
|
||||
"backgroundColor": "#232323"
|
||||
},
|
||||
"imageWidth": 200
|
||||
}
|
||||
]
|
||||
],
|
||||
"expo-system-ui"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
226
package-lock.json
generated
226
package-lock.json
generated
@@ -18,9 +18,12 @@
|
||||
"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",
|
||||
@@ -4191,6 +4194,164 @@
|
||||
"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",
|
||||
@@ -4204,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",
|
||||
@@ -4409,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",
|
||||
@@ -6536,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",
|
||||
@@ -6855,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",
|
||||
|
||||
@@ -17,17 +17,20 @@
|
||||
"@react-navigation/native": "^7.1.14",
|
||||
"@react-navigation/stack": "^7.4.2",
|
||||
"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",
|
||||
"react-native-svg": "15.11.2",
|
||||
"react-native-webview": "13.13.5",
|
||||
"expo-font": "~13.3.2",
|
||||
"react-native-gesture-handler": "~2.24.0"
|
||||
"react-native-webview": "13.13.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -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,7 +3,6 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
ActivityIndicator,
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
} 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';
|
||||
@@ -103,6 +103,7 @@ const STATIC_TRANSACTIONS = [
|
||||
|
||||
const HomeScreen = () => {
|
||||
const { user, logout } = useAuth();
|
||||
const insets = useSafeAreaInsets();
|
||||
const [metrics, setMetrics] = useState(null);
|
||||
const [loadingMetrics, setLoadingMetrics] = useState(true);
|
||||
const [cardBalance, setCardBalance] = useState(null);
|
||||
@@ -244,7 +245,7 @@ const HomeScreen = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.container}>
|
||||
<StatusBar style="dark" />
|
||||
|
||||
<ScrollView
|
||||
@@ -259,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>
|
||||
@@ -320,7 +321,7 @@ const HomeScreen = () => {
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -337,7 +338,6 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 24,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 24,
|
||||
backgroundColor: COLORS.white,
|
||||
marginBottom: 16,
|
||||
|
||||
@@ -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,7 +3,6 @@ import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
Alert,
|
||||
@@ -13,6 +12,7 @@ import {
|
||||
} 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';
|
||||
@@ -20,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);
|
||||
@@ -81,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 },
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -105,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();
|
||||
@@ -279,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>
|
||||
|
||||
@@ -336,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>
|
||||
@@ -388,7 +389,7 @@ const ProfileScreen = () => {
|
||||
initialData={profileData || user}
|
||||
isLoading={isUpdatingProfile}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -400,7 +401,6 @@ const styles = StyleSheet.create({
|
||||
header: {
|
||||
backgroundColor: COLORS.white,
|
||||
paddingHorizontal: 24,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 24,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: COLORS.gray[200],
|
||||
@@ -550,6 +550,16 @@ const styles = StyleSheet.create({
|
||||
link: {
|
||||
color: COLORS.primary,
|
||||
},
|
||||
profileItemTitleDanger: {
|
||||
fontSize: 16,
|
||||
color: COLORS.error,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
profileItemValueDanger: {
|
||||
fontSize: 14,
|
||||
color: COLORS.error,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
|
||||
export default ProfileScreen;
|
||||
Reference in New Issue
Block a user