Compare commits
9 Commits
89200eacd5
...
6b9631dcfd
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b9631dcfd | |||
| d4b81ee3e0 | |||
| 7f182d3a07 | |||
| dc4bef93c1 | |||
| 452887148d | |||
| 50d299fb24 | |||
| 8f16f14796 | |||
| 3eb5442a14 | |||
| f16e8c19b6 |
206
package-lock.json
generated
206
package-lock.json
generated
@@ -9,22 +9,22 @@
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "^14.1.0",
|
||||
"@react-native-async-storage/async-storage": "^2.2.0",
|
||||
"@react-native-community/datetimepicker": "^7.7.0",
|
||||
"@react-native-async-storage/async-storage": "2.1.2",
|
||||
"@react-native-community/datetimepicker": "8.4.1",
|
||||
"@react-native-picker/picker": "^2.4.12",
|
||||
"@react-navigation/bottom-tabs": "^7.4.2",
|
||||
"@react-navigation/native": "^7.1.14",
|
||||
"@react-navigation/stack": "^7.4.2",
|
||||
"expo": "~53.0.16",
|
||||
"expo": "53.0.19",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-modal-datetime-picker": "^15.0.1",
|
||||
"react-native-safe-area-context": "^5.5.1",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "^4.11.1",
|
||||
"react-native-svg": "^15.12.0",
|
||||
"react-native-webview": "^13.11.0"
|
||||
"react-native-svg": "15.11.2",
|
||||
"react-native-webview": "13.13.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0"
|
||||
@@ -1415,24 +1415,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli": {
|
||||
"version": "0.24.17",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.24.17.tgz",
|
||||
"integrity": "sha512-1Rz8EU6v7/gyMSLkRxXqoO6Tzkvkk4vR6DT49lfXElpHqWIu+wtgSpCxw5UfEfZKh6sK3Goswxb3g9LVtL/bCw==",
|
||||
"version": "0.24.20",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.24.20.tgz",
|
||||
"integrity": "sha512-uF1pOVcd+xizNtVTuZqNGzy7I6IJon5YMmQidsURds1Ww96AFDxrR/NEACqeATNAmY60m8wy1VZZpSg5zLNkpw==",
|
||||
"dependencies": {
|
||||
"@0no-co/graphql.web": "^1.0.8",
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@expo/code-signing-certificates": "^0.0.5",
|
||||
"@expo/config": "~11.0.11",
|
||||
"@expo/config-plugins": "~10.1.0",
|
||||
"@expo/config": "~11.0.13",
|
||||
"@expo/config-plugins": "~10.1.2",
|
||||
"@expo/devcert": "^1.1.2",
|
||||
"@expo/env": "~1.0.6",
|
||||
"@expo/image-utils": "^0.7.5",
|
||||
"@expo/json-file": "^9.1.4",
|
||||
"@expo/metro-config": "~0.20.16",
|
||||
"@expo/osascript": "^2.2.4",
|
||||
"@expo/package-manager": "^1.8.5",
|
||||
"@expo/plist": "^0.3.4",
|
||||
"@expo/prebuild-config": "^9.0.9",
|
||||
"@expo/env": "~1.0.7",
|
||||
"@expo/image-utils": "^0.7.6",
|
||||
"@expo/json-file": "^9.1.5",
|
||||
"@expo/metro-config": "~0.20.17",
|
||||
"@expo/osascript": "^2.2.5",
|
||||
"@expo/package-manager": "^1.8.6",
|
||||
"@expo/plist": "^0.3.5",
|
||||
"@expo/prebuild-config": "^9.0.11",
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"@expo/ws-tunnel": "^1.0.1",
|
||||
"@expo/xcpretty": "^4.3.0",
|
||||
@@ -1506,12 +1506,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/config": {
|
||||
"version": "11.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config/-/config-11.0.12.tgz",
|
||||
"integrity": "sha512-XEh7g5F8OziJ6eZzBi93qt2YwmPceD3yAEd4Qv/ODK3MrgFCmB5IAJJ2ZFepdeoQFpcxS26Nl4aUuIJYEhJiUw==",
|
||||
"version": "11.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config/-/config-11.0.13.tgz",
|
||||
"integrity": "sha512-TnGb4u/zUZetpav9sx/3fWK71oCPaOjZHoVED9NaEncktAd0Eonhq5NUghiJmkUGt3gGSjRAEBXiBbbY9/B1LA==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "~7.10.4",
|
||||
"@expo/config-plugins": "~10.1.1",
|
||||
"@expo/config-plugins": "~10.1.2",
|
||||
"@expo/config-types": "^53.0.5",
|
||||
"@expo/json-file": "^9.1.5",
|
||||
"deepmerge": "^4.3.1",
|
||||
@@ -1526,9 +1526,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/config-plugins": {
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-10.1.1.tgz",
|
||||
"integrity": "sha512-2L/ryY/R/AzwHfLpzBBsj0qdwN+E2RkF24uwo33L7M5DOswbLVaA007IdLlun+G6ctZYnwgm3TDLxjbvqZ9Avw==",
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-10.1.2.tgz",
|
||||
"integrity": "sha512-IMYCxBOcnuFStuK0Ay+FzEIBKrwW8OVUMc65+v0+i7YFIIe8aL342l7T4F8lR4oCfhXn7d6M5QPgXvjtc/gAcw==",
|
||||
"dependencies": {
|
||||
"@expo/config-types": "^53.0.5",
|
||||
"@expo/json-file": "~9.1.5",
|
||||
@@ -1600,9 +1600,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/env": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/env/-/env-1.0.6.tgz",
|
||||
"integrity": "sha512-aokrM+EYgyaJNmyo8QhphP3egVi0E7/4PiAx+riW1k39wu26POCg5NBdOSBHoYGmq1NXbhpFepIFDWVaCw1UeA==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@expo/env/-/env-1.0.7.tgz",
|
||||
"integrity": "sha512-qSTEnwvuYJ3umapO9XJtrb1fAqiPlmUUg78N0IZXXGwQRt+bkp0OBls+Y5Mxw/Owj8waAM0Z3huKKskRADR5ow==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"debug": "^4.3.4",
|
||||
@@ -1612,9 +1612,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/fingerprint": {
|
||||
"version": "0.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.13.3.tgz",
|
||||
"integrity": "sha512-Ziore8lpUzTvZaZigcol0op3muvEiBpwNn8M500qij/RvVFLEOH5sNadEBKwEmzdpUC5ij3eJzkr9b7Gr7///g==",
|
||||
"version": "0.13.4",
|
||||
"resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.13.4.tgz",
|
||||
"integrity": "sha512-MYfPYBTMfrrNr07DALuLhG6EaLVNVrY/PXjEzsjWdWE4ZFn0yqI0IdHNkJG7t1gePT8iztHc7qnsx+oo/rDo6w==",
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"arg": "^5.0.2",
|
||||
@@ -1645,9 +1645,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/image-utils": {
|
||||
"version": "0.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.7.5.tgz",
|
||||
"integrity": "sha512-92sk+dplZHlZuv4jAWmGBOqWf70hcb0zoObmjQRgxvZbKWXlQ6ifANaOUhoeJKgNWSB9BrLoW6v/mUyrDUdK+A==",
|
||||
"version": "0.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.7.6.tgz",
|
||||
"integrity": "sha512-GKnMqC79+mo/1AFrmAcUcGfbsXXTRqOMNS1umebuevl3aaw+ztsYEFEiuNhHZW7PQ3Xs3URNT513ZxKhznDscw==",
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"chalk": "^4.0.0",
|
||||
@@ -1689,17 +1689,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/metro-config": {
|
||||
"version": "0.20.16",
|
||||
"resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.20.16.tgz",
|
||||
"integrity": "sha512-qsCQqYCGYR1t2KNDoPESxMbuvrkljsdQBblfJoOsRB/9TC+1OtmYsbIUuXZDFm1/mgYA42j4dAQqP/mck5ouuw==",
|
||||
"version": "0.20.17",
|
||||
"resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.20.17.tgz",
|
||||
"integrity": "sha512-lpntF2UZn5bTwrPK6guUv00Xv3X9mkN3YYla+IhEHiYXWyG7WKOtDU0U4KR8h3ubkZ6SPH3snDyRyAzMsWtZFA==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
"@babel/generator": "^7.20.5",
|
||||
"@babel/parser": "^7.20.0",
|
||||
"@babel/types": "^7.20.0",
|
||||
"@expo/config": "~11.0.11",
|
||||
"@expo/env": "~1.0.6",
|
||||
"@expo/json-file": "~9.1.4",
|
||||
"@expo/config": "~11.0.12",
|
||||
"@expo/env": "~1.0.7",
|
||||
"@expo/json-file": "~9.1.5",
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"chalk": "^4.1.0",
|
||||
"debug": "^4.3.2",
|
||||
@@ -1715,9 +1715,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/osascript": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.2.4.tgz",
|
||||
"integrity": "sha512-Q+Oyj+1pdRiHHpev9YjqfMZzByFH8UhKvSszxa0acTveijjDhQgWrq4e9T/cchBHi0GWZpGczWyiyJkk1wM1dg==",
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.2.5.tgz",
|
||||
"integrity": "sha512-Bpp/n5rZ0UmpBOnl7Li3LtM7la0AR3H9NNesqL+ytW5UiqV/TbonYW3rDZY38u4u/lG7TnYflVIVQPD+iqZJ5w==",
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"exec-async": "^2.2.0"
|
||||
@@ -1727,11 +1727,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/package-manager": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.8.5.tgz",
|
||||
"integrity": "sha512-C9dl6GLUtzeY80g5wxOnZ/tEdAlSlCh8h6vTJkuTM9dPtdpQwg40w0/Gx4ONKeegExYLlGDw7dilL+xrxz/d+w==",
|
||||
"version": "1.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.8.6.tgz",
|
||||
"integrity": "sha512-gcdICLuL+nHKZagPIDC5tX8UoDDB8vNA5/+SaQEqz8D+T2C4KrEJc2Vi1gPAlDnKif834QS6YluHWyxjk0yZlQ==",
|
||||
"dependencies": {
|
||||
"@expo/json-file": "^9.1.4",
|
||||
"@expo/json-file": "^9.1.5",
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"chalk": "^4.0.0",
|
||||
"npm-package-arg": "^11.0.0",
|
||||
@@ -1750,15 +1750,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/prebuild-config": {
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-9.0.9.tgz",
|
||||
"integrity": "sha512-uGt5K6FGDhK12WJXcgcm3Cirakt4llil99rLxFx/WgQQdE5BK58O0irrhKz5kwhXmWCco0CRSUdAoddq1JK91w==",
|
||||
"version": "9.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-9.0.11.tgz",
|
||||
"integrity": "sha512-0DsxhhixRbCCvmYskBTq8czsU0YOBsntYURhWPNpkl0IPVpeP9haE5W4OwtHGzXEbmHdzaoDwNmVcWjS/mqbDw==",
|
||||
"dependencies": {
|
||||
"@expo/config": "~11.0.11",
|
||||
"@expo/config-plugins": "~10.1.0",
|
||||
"@expo/config-types": "^53.0.4",
|
||||
"@expo/image-utils": "^0.7.5",
|
||||
"@expo/json-file": "^9.1.4",
|
||||
"@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",
|
||||
"debug": "^4.3.1",
|
||||
"resolve-from": "^5.0.0",
|
||||
@@ -2131,9 +2131,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-async-storage/async-storage": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.2.0.tgz",
|
||||
"integrity": "sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.1.2.tgz",
|
||||
"integrity": "sha512-dvlNq4AlGWC+ehtH12p65+17V0Dx7IecOWl6WanF2ja38O1Dcjjvn7jVzkUHJ5oWkQBlyASurTPlTHgKXyYiow==",
|
||||
"dependencies": {
|
||||
"merge-options": "^3.0.4"
|
||||
},
|
||||
@@ -2142,11 +2142,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-community/datetimepicker": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-7.7.0.tgz",
|
||||
"integrity": "sha512-nYzZy4DQLRFUzKJShWzRleCaebmCJfZ1lIcFmZgMXJoiVuGJNw3OIGHSWmHhPETh3OhP1RO3to882d7WmDIyrA==",
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-8.4.1.tgz",
|
||||
"integrity": "sha512-DrK+CUS5fZnz8dhzBezirkzQTcNDdaXer3oDLh0z4nc2tbdIdnzwvXCvi8IEOIvleoc9L95xS5tKUl0/Xv71Mg==",
|
||||
"dependencies": {
|
||||
"invariant": "^2.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": ">=52.0.0",
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-windows": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"expo": {
|
||||
"optional": true
|
||||
},
|
||||
"react-native-windows": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-picker/picker": {
|
||||
@@ -3892,24 +3906,24 @@
|
||||
"integrity": "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw=="
|
||||
},
|
||||
"node_modules/expo": {
|
||||
"version": "53.0.16",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-53.0.16.tgz",
|
||||
"integrity": "sha512-ogHgh11/H3tU/k4bwT4OuCpSPb+hh66H4aro137BiODDhkECfGx90TwQE3XXPV4jRZMSUlVcyNexmp8bQ4Di1g==",
|
||||
"version": "53.0.19",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-53.0.19.tgz",
|
||||
"integrity": "sha512-hZWEKw6h5dlfKy6+c3f2exx5x3Loio8p0b2s/Pk1eQfTffqpkQRVVlOzcTWU1RSuMfc47ZMpr97pUJWQczOGsQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@expo/cli": "0.24.17",
|
||||
"@expo/config": "~11.0.11",
|
||||
"@expo/config-plugins": "~10.1.0",
|
||||
"@expo/fingerprint": "0.13.3",
|
||||
"@expo/metro-config": "0.20.16",
|
||||
"@expo/cli": "0.24.20",
|
||||
"@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.2",
|
||||
"expo-asset": "~11.1.6",
|
||||
"expo-constants": "~17.1.6",
|
||||
"babel-preset-expo": "~13.2.3",
|
||||
"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.13",
|
||||
"expo-modules-autolinking": "2.1.14",
|
||||
"expo-modules-core": "2.4.2",
|
||||
"react-native-edge-to-edge": "1.6.0",
|
||||
"whatwg-url-without-unicode": "8.0.0-3"
|
||||
@@ -3939,12 +3953,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-asset": {
|
||||
"version": "11.1.6",
|
||||
"resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.1.6.tgz",
|
||||
"integrity": "sha512-52wIPe0kVzgschXJ/cPCJ4N6r5z5ejQ0b+NOUZ8iwkWFfqynBNqFdGp4hPDjmNel39ukAQ57UNybiedRF4LZiw==",
|
||||
"version": "11.1.7",
|
||||
"resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.1.7.tgz",
|
||||
"integrity": "sha512-b5P8GpjUh08fRCf6m5XPVAh7ra42cQrHBIMgH2UXP+xsj4Wufl6pLy6jRF5w6U7DranUMbsXm8TOyq4EHy7ADg==",
|
||||
"dependencies": {
|
||||
"@expo/image-utils": "^0.7.5",
|
||||
"expo-constants": "~17.1.6"
|
||||
"@expo/image-utils": "^0.7.6",
|
||||
"expo-constants": "~17.1.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
@@ -3953,12 +3967,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-constants": {
|
||||
"version": "17.1.6",
|
||||
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.1.6.tgz",
|
||||
"integrity": "sha512-q5mLvJiLtPcaZ7t2diSOlQ2AyxIO8YMVEJsEfI/ExkGj15JrflNQ7CALEW6IF/uNae/76qI/XcjEuuAyjdaCNw==",
|
||||
"version": "17.1.7",
|
||||
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.1.7.tgz",
|
||||
"integrity": "sha512-byBjGsJ6T6FrLlhOBxw4EaiMXrZEn/MlUYIj/JAd+FS7ll5X/S4qVRbIimSJtdW47hXMq0zxPfJX6njtA56hHA==",
|
||||
"dependencies": {
|
||||
"@expo/config": "~11.0.9",
|
||||
"@expo/env": "~1.0.5"
|
||||
"@expo/config": "~11.0.12",
|
||||
"@expo/env": "~1.0.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
@@ -4015,9 +4029,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-modules-autolinking": {
|
||||
"version": "2.1.13",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.1.13.tgz",
|
||||
"integrity": "sha512-+SaiYkdP3LXOFm/26CHMHBof9Xq/0MHNDzL/K0OwPgHLhZ6wpDWIDYWRHNueWYtGpAeLw2XAhR0HX4FNtU09qw==",
|
||||
"version": "2.1.14",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.1.14.tgz",
|
||||
"integrity": "sha512-nT5ERXwc+0ZT/pozDoJjYZyUQu5RnXMk9jDGm5lg+PiKvsrCTSA/2/eftJGMxLkTjVI2MXp5WjSz3JRjbA7UXA==",
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"chalk": "^4.1.0",
|
||||
@@ -6432,9 +6446,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-safe-area-context": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.5.1.tgz",
|
||||
"integrity": "sha512-WYxV+mm7SWuapVWxq2071lkQlDUXjSwcu7Cc2bUtNcF80/Bl0WnuWAZ8+tO46M38PclMrQIIgbv83BvDHJNQ5g==",
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.4.0.tgz",
|
||||
"integrity": "sha512-JaEThVyJcLhA+vU0NU8bZ0a1ih6GiF4faZ+ArZLqpYbL6j7R3caRqj+mE3lEtKCuHgwjLg3bCxLL1GPUJZVqUA==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
@@ -6455,9 +6469,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-svg": {
|
||||
"version": "15.12.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.12.0.tgz",
|
||||
"integrity": "sha512-iE25PxIJ6V0C6krReLquVw6R0QTsRTmEQc4K2Co3P6zsimU/jltcDBKYDy1h/5j9S/fqmMeXnpM+9LEWKJKI6A==",
|
||||
"version": "15.11.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.11.2.tgz",
|
||||
"integrity": "sha512-+YfF72IbWQUKzCIydlijV1fLuBsQNGMT6Da2kFlo1sh+LE3BIm/2Q7AR1zAAR6L0BFLi1WaQPLfFUC9bNZpOmw==",
|
||||
"dependencies": {
|
||||
"css-select": "^5.1.0",
|
||||
"css-tree": "^1.1.3",
|
||||
@@ -6469,9 +6483,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-webview": {
|
||||
"version": "13.15.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.15.0.tgz",
|
||||
"integrity": "sha512-Vzjgy8mmxa/JO6l5KZrsTC7YemSdq+qB01diA0FqjUTaWGAGwuykpJ73MDj3+mzBSlaDxAEugHzTtkUQkQEQeQ==",
|
||||
"version": "13.13.5",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.13.5.tgz",
|
||||
"integrity": "sha512-MfC2B+woL4Hlj2WCzcb1USySKk+SteXnUKmKktOk/H/AQy5+LuVdkPKm8SknJ0/RxaxhZ48WBoTRGaqgR137hw==",
|
||||
"dependencies": {
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"invariant": "2.2.4"
|
||||
|
||||
18
package.json
18
package.json
@@ -4,28 +4,28 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "expo start",
|
||||
"android": "expo start --android",
|
||||
"ios": "expo start --ios",
|
||||
"android": "expo run:android",
|
||||
"ios": "expo run:ios",
|
||||
"web": "expo start --web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "^14.1.0",
|
||||
"@react-native-async-storage/async-storage": "^2.2.0",
|
||||
"@react-native-community/datetimepicker": "^7.7.0",
|
||||
"@react-native-async-storage/async-storage": "2.1.2",
|
||||
"@react-native-community/datetimepicker": "8.4.1",
|
||||
"@react-native-picker/picker": "^2.4.12",
|
||||
"@react-navigation/bottom-tabs": "^7.4.2",
|
||||
"@react-navigation/native": "^7.1.14",
|
||||
"@react-navigation/stack": "^7.4.2",
|
||||
"expo": "~53.0.16",
|
||||
"expo": "53.0.19",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.5",
|
||||
"react-native-modal-datetime-picker": "^15.0.1",
|
||||
"react-native-safe-area-context": "^5.5.1",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "^4.11.1",
|
||||
"react-native-svg": "^15.12.0",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"react-native-webview": "^13.11.0"
|
||||
"react-native-svg": "15.11.2",
|
||||
"react-native-webview": "13.13.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0"
|
||||
|
||||
@@ -45,6 +45,8 @@ const EditProfileModal = ({
|
||||
|
||||
const [errors, setErrors] = useState({});
|
||||
const [showPassportPicker, setShowPassportPicker] = useState(false);
|
||||
const [showMonthPicker, setShowMonthPicker] = useState(false);
|
||||
const [showYearPicker, setShowYearPicker] = useState(false);
|
||||
|
||||
const phoneInputRef = useRef(null);
|
||||
const passwordInputRef = useRef(null);
|
||||
@@ -88,9 +90,9 @@ const EditProfileModal = ({
|
||||
newErrors.card_name = 'Kartyň ady 255 harpdan köp bolmaly däl';
|
||||
}
|
||||
|
||||
// Card number validation (optional, must be 16 digits)
|
||||
if (formData.card_number && !/^\d{16}$/.test(formData.card_number.trim())) {
|
||||
newErrors.card_number = 'Kart belgisi 16 sany sandan durmaly';
|
||||
// Card number validation (optional, must be 16 digits and allow hyphens)
|
||||
if (formData.card_number && !/^[0-9]{4}-?[0-9]{4}-?[0-9]{4}-?[0-9]{4}$/.test(formData.card_number.trim())) {
|
||||
newErrors.card_number = 'Kart belgisi 16 sany sandan durmaly (mysal: 9999-9999-9999-9999)';
|
||||
}
|
||||
|
||||
// Card month validation (optional, 1-12)
|
||||
@@ -102,8 +104,12 @@ const EditProfileModal = ({
|
||||
}
|
||||
|
||||
// Card year validation (optional, 4 digits and reasonable year)
|
||||
if (formData.card_year && !/^\d{4}$/.test(formData.card_year.trim())) {
|
||||
newErrors.card_year = 'Ýyl 4 sany sandan durmaly';
|
||||
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`;
|
||||
}
|
||||
}
|
||||
|
||||
setErrors(newErrors);
|
||||
@@ -147,7 +153,8 @@ const EditProfileModal = ({
|
||||
}
|
||||
|
||||
if (formData.card_number) {
|
||||
updateData.card_number = formData.card_number.trim();
|
||||
// Remove all non-digit characters before sending
|
||||
updateData.card_number = formData.card_number.replace(/[^\d]/g, '');
|
||||
}
|
||||
|
||||
onSave(updateData);
|
||||
@@ -167,6 +174,7 @@ const EditProfileModal = ({
|
||||
card_number: initialData.card_number ? initialData.card_number.toString() : '',
|
||||
});
|
||||
setErrors({});
|
||||
Keyboard.dismiss(); // Dismiss keyboard when modal closes
|
||||
onClose();
|
||||
};
|
||||
|
||||
@@ -244,6 +252,129 @@ const EditProfileModal = ({
|
||||
);
|
||||
};
|
||||
|
||||
const renderMonthPicker = () => {
|
||||
if (!showMonthPicker) return null;
|
||||
|
||||
const months = Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, '0'));
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={showMonthPicker}
|
||||
transparent={true}
|
||||
animationType="slide"
|
||||
onRequestClose={() => setShowMonthPicker(false)}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={() => setShowMonthPicker(false)}>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.pickerContainer}>
|
||||
<View style={styles.pickerHeader}>
|
||||
<Text style={styles.pickerTitle}>Kart aýy</Text>
|
||||
<TouchableOpacity onPress={() => setShowMonthPicker(false)}>
|
||||
<Text style={styles.pickerDoneText}>Boldy</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<ScrollView style={styles.pickerList}>
|
||||
<TouchableOpacity
|
||||
style={styles.pickerItem}
|
||||
onPress={() => {
|
||||
updateFormData('card_month', '');
|
||||
setShowMonthPicker(false);
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.pickerItemText, styles.placeholderText]}>
|
||||
Saýlaň
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{months.map((month) => (
|
||||
<TouchableOpacity
|
||||
key={month}
|
||||
style={[
|
||||
styles.pickerItem,
|
||||
formData.card_month === month && styles.selectedPickerItem
|
||||
]}
|
||||
onPress={() => {
|
||||
updateFormData('card_month', month);
|
||||
setShowMonthPicker(false);
|
||||
}}
|
||||
>
|
||||
<Text style={[
|
||||
styles.pickerItemText,
|
||||
formData.card_month === month && styles.selectedPickerItemText
|
||||
]}>
|
||||
{month}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const renderYearPicker = () => {
|
||||
if (!showYearPicker) return null;
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const years = Array.from({ length: 75 }, (_, i) => String(currentYear - 10 + i)); // +/- 10 years
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={showYearPicker}
|
||||
transparent={true}
|
||||
animationType="slide"
|
||||
onRequestClose={() => setShowYearPicker(false)}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={() => setShowYearPicker(false)}>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.pickerContainer}>
|
||||
<View style={styles.pickerHeader}>
|
||||
<Text style={styles.pickerTitle}>Kartyň senesi</Text>
|
||||
<TouchableOpacity onPress={() => setShowYearPicker(false)}>
|
||||
<Text style={styles.pickerDoneText}>Boldy</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<ScrollView style={styles.pickerList}>
|
||||
<TouchableOpacity
|
||||
style={styles.pickerItem}
|
||||
onPress={() => {
|
||||
updateFormData('card_year', '');
|
||||
setShowYearPicker(false);
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.pickerItemText, styles.placeholderText]}>
|
||||
Saýlaň
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{years.map((year) => (
|
||||
<TouchableOpacity
|
||||
key={year}
|
||||
style={[
|
||||
styles.pickerItem,
|
||||
formData.card_year === year && styles.selectedPickerItem
|
||||
]}
|
||||
onPress={() => {
|
||||
updateFormData('card_year', year);
|
||||
setShowYearPicker(false);
|
||||
}}
|
||||
>
|
||||
<Text style={[
|
||||
styles.pickerItemText,
|
||||
formData.card_year === year && styles.selectedPickerItemText
|
||||
]}>
|
||||
{year}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
@@ -256,167 +387,193 @@ const EditProfileModal = ({
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<View style={styles.content}>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={handleClose} style={styles.closeButton}>
|
||||
<Ionicons name="close" size={24} color={COLORS.text} />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.title}>Şahsy maglumatlar</Text>
|
||||
<View style={styles.placeholder} />
|
||||
</View>
|
||||
|
||||
{/* Form */}
|
||||
<ScrollView style={styles.form} showsVerticalScrollIndicator={false} keyboardShouldPersistTaps="handled" contentContainerStyle={{paddingBottom:80}}>
|
||||
<View style={styles.formSection}>
|
||||
<Text style={styles.sectionTitle}>Esasy maglumatlar</Text>
|
||||
|
||||
<Input
|
||||
label="Ady *"
|
||||
value={formData.name}
|
||||
onChangeText={(value) => updateFormData('name', value)}
|
||||
error={errors.name}
|
||||
maxLength={255}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => phoneInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={phoneInputRef}
|
||||
label="Telefon belgisi *"
|
||||
value={formData.phone}
|
||||
onChangeText={(value) => updateFormData('phone', value)}
|
||||
error={errors.phone}
|
||||
keyboardType="numeric"
|
||||
maxLength={8}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => passwordInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={passwordInputRef}
|
||||
label="Täze parol"
|
||||
value={formData.password}
|
||||
onChangeText={(value) => updateFormData('password', value)}
|
||||
error={errors.password}
|
||||
secureTextEntry
|
||||
placeholder="Parol üýtgetmezlik üçin boş goýuň"
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => passportIdInputRef.current?.focus()}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formSection}>
|
||||
<Text style={styles.sectionTitle}>Passport maglumatlary</Text>
|
||||
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.label}>Passport seriýasy</Text>
|
||||
<TouchableOpacity
|
||||
style={[styles.pickerButton, errors.passport_serie && styles.inputError]}
|
||||
onPress={() => setShowPassportPicker(true)}
|
||||
>
|
||||
<Text style={[styles.pickerButtonText, !formData.passport_serie && styles.placeholderText]}>
|
||||
{formData.passport_serie || 'Saýlaň'}
|
||||
</Text>
|
||||
<Ionicons name="chevron-down" size={20} color={COLORS.textSecondary} />
|
||||
</TouchableOpacity>
|
||||
{errors.passport_serie && (
|
||||
<Text style={styles.errorText}>{errors.passport_serie}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Input
|
||||
ref={passportIdInputRef}
|
||||
label="Passport ID"
|
||||
value={formData.passport_id}
|
||||
onChangeText={(value) => updateFormData('passport_id', value)}
|
||||
error={errors.passport_id}
|
||||
keyboardType="numeric"
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => cardNameInputRef.current?.focus()}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formSection}>
|
||||
<Text style={styles.sectionTitle}>Kart maglumatlary</Text>
|
||||
|
||||
<Input
|
||||
ref={cardNameInputRef}
|
||||
label="Kartdaky ady"
|
||||
value={formData.card_name}
|
||||
onChangeText={(value) => updateFormData('card_name', value)}
|
||||
error={errors.card_name}
|
||||
maxLength={255}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => cardNumberInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={cardNumberInputRef}
|
||||
label="Kart belgisi"
|
||||
value={formData.card_number}
|
||||
onChangeText={(value) => updateFormData('card_number', value)}
|
||||
error={errors.card_number}
|
||||
keyboardType="numeric"
|
||||
maxLength={16}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => cardMonthInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={cardMonthInputRef}
|
||||
label="Kart aýy (MM)"
|
||||
value={formData.card_month}
|
||||
onChangeText={(value) => updateFormData('card_month', value)}
|
||||
error={errors.card_month}
|
||||
keyboardType="numeric"
|
||||
maxLength={2}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => cardYearInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={cardYearInputRef}
|
||||
label="Kartyň senesi (YYYY)"
|
||||
value={formData.card_year}
|
||||
onChangeText={(value) => updateFormData('card_year', value)}
|
||||
error={errors.card_year}
|
||||
keyboardType="numeric"
|
||||
maxLength={4}
|
||||
returnKeyType="done"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.note}>
|
||||
<Ionicons name="information-circle" size={16} color={COLORS.textSecondary} />
|
||||
<Text style={styles.noteText}>
|
||||
* belgisi bolan meýdanlar hökmany doldurulmaly
|
||||
</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* Save Button */}
|
||||
<View style={styles.footer}>
|
||||
<Button
|
||||
title="Ýatda sakla"
|
||||
onPress={handleSave}
|
||||
disabled={isLoading}
|
||||
style={styles.saveButton}
|
||||
/>
|
||||
{isLoading && (
|
||||
<ActivityIndicator
|
||||
size="small"
|
||||
color={COLORS.primary}
|
||||
style={styles.loader}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.content}>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={handleClose} style={styles.closeButton}>
|
||||
<Ionicons name="close" size={24} color={COLORS.text} />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.title}>Şahsy maglumatlar</Text>
|
||||
<View style={styles.placeholder} />
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
|
||||
{/* Form */}
|
||||
<ScrollView
|
||||
style={styles.form}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
contentContainerStyle={{paddingBottom:80}}
|
||||
keyboardDismissMode="on-drag"
|
||||
>
|
||||
<View style={styles.formSection}>
|
||||
<Text style={styles.sectionTitle}>Esasy maglumatlar</Text>
|
||||
|
||||
<Input
|
||||
label="Ady *"
|
||||
value={formData.name}
|
||||
onChangeText={(value) => updateFormData('name', value)}
|
||||
error={errors.name}
|
||||
maxLength={255}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => phoneInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={phoneInputRef}
|
||||
label="Telefon belgisi *"
|
||||
value={formData.phone}
|
||||
onChangeText={(value) => updateFormData('phone', value)}
|
||||
error={errors.phone}
|
||||
keyboardType="numeric"
|
||||
maxLength={8}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => passwordInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={passwordInputRef}
|
||||
label="Täze parol"
|
||||
value={formData.password}
|
||||
onChangeText={(value) => updateFormData('password', value)}
|
||||
error={errors.password}
|
||||
secureTextEntry
|
||||
placeholder="Parol üýtgetmezlik üçin boş goýuň"
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => passportIdInputRef.current?.focus()}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formSection}>
|
||||
<Text style={styles.sectionTitle}>Passport maglumatlary</Text>
|
||||
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.label}>Passport seriýasy</Text>
|
||||
<TouchableOpacity
|
||||
style={[styles.pickerButton, errors.passport_serie && styles.inputError]}
|
||||
onPress={() => setShowPassportPicker(true)}
|
||||
>
|
||||
<Text style={[styles.pickerButtonText, !formData.passport_serie && styles.placeholderText]}>
|
||||
{formData.passport_serie || 'Saýlaň'}
|
||||
</Text>
|
||||
<Ionicons name="chevron-down" size={20} color={COLORS.textSecondary} />
|
||||
</TouchableOpacity>
|
||||
{errors.passport_serie && (
|
||||
<Text style={styles.errorText}>{errors.passport_serie}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Input
|
||||
ref={passportIdInputRef}
|
||||
label="Passport ID"
|
||||
value={formData.passport_id}
|
||||
onChangeText={(value) => updateFormData('passport_id', value)}
|
||||
error={errors.passport_id}
|
||||
keyboardType="numeric"
|
||||
returnKeyType="next"
|
||||
maxLength={6}
|
||||
onSubmitEditing={() => cardNameInputRef.current?.focus()}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formSection}>
|
||||
<Text style={styles.sectionTitle}>Kart maglumatlary</Text>
|
||||
|
||||
<Input
|
||||
ref={cardNameInputRef}
|
||||
label="Kartdaky ady"
|
||||
value={formData.card_name}
|
||||
onChangeText={(value) => updateFormData('card_name', value)}
|
||||
error={errors.card_name}
|
||||
maxLength={255}
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => cardNumberInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<Input
|
||||
ref={cardNumberInputRef}
|
||||
label="Kart belgisi"
|
||||
value={formData.card_number}
|
||||
onChangeText={(value) => {
|
||||
const unmaskedValue = value.replace(/[^\d]/g, ''); // Remove non-digits
|
||||
let maskedValue = '';
|
||||
for (let i = 0; i < unmaskedValue.length; i++) {
|
||||
if (i > 0 && i % 4 === 0) {
|
||||
maskedValue += '-';
|
||||
}
|
||||
maskedValue += unmaskedValue[i];
|
||||
}
|
||||
updateFormData('card_number', maskedValue);
|
||||
}}
|
||||
error={errors.card_number}
|
||||
keyboardType="numeric"
|
||||
maxLength={19} // 16 digits + 3 hyphens
|
||||
returnKeyType="next"
|
||||
onSubmitEditing={() => cardMonthInputRef.current?.focus()}
|
||||
/>
|
||||
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.label}>Kart aýy (MM)</Text>
|
||||
<TouchableOpacity
|
||||
style={[styles.pickerButton, errors.card_month && styles.inputError]}
|
||||
onPress={() => setShowMonthPicker(true)}
|
||||
>
|
||||
<Text style={[styles.pickerButtonText, !formData.card_month && styles.placeholderText]}>
|
||||
{formData.card_month || 'Saýlaň'}
|
||||
</Text>
|
||||
<Ionicons name="chevron-down" size={20} color={COLORS.textSecondary} />
|
||||
</TouchableOpacity>
|
||||
{errors.card_month && (
|
||||
<Text style={styles.errorText}>{errors.card_month}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.label}>Kartyň senesi (YYYY)</Text>
|
||||
<TouchableOpacity
|
||||
style={[styles.pickerButton, errors.card_year && styles.inputError]}
|
||||
onPress={() => setShowYearPicker(true)}
|
||||
>
|
||||
<Text style={[styles.pickerButtonText, !formData.card_year && styles.placeholderText]}>
|
||||
{formData.card_year || 'Saýlaň'}
|
||||
</Text>
|
||||
<Ionicons name="chevron-down" size={20} color={COLORS.textSecondary} />
|
||||
</TouchableOpacity>
|
||||
{errors.card_year && (
|
||||
<Text style={styles.errorText}>{errors.card_year}</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.note}>
|
||||
<Ionicons name="information-circle" size={16} color={COLORS.textSecondary} />
|
||||
<Text style={styles.noteText}>
|
||||
* belgisi bolan meýdanlar hökmany doldurulmaly
|
||||
</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* Save Button */}
|
||||
<View style={styles.footer}>
|
||||
<Button
|
||||
title="Ýatda sakla"
|
||||
onPress={handleSave}
|
||||
disabled={isLoading}
|
||||
style={styles.saveButton}
|
||||
/>
|
||||
{isLoading && (
|
||||
<ActivityIndicator
|
||||
size="small"
|
||||
color={COLORS.primary}
|
||||
style={styles.loader}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
{renderPassportSeriesPicker()}
|
||||
{renderMonthPicker()}
|
||||
{renderYearPicker()}
|
||||
</SafeAreaView>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ 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 HomeScreen from '../screens/Main/HomeScreen';
|
||||
import MenuNavigator from './MenuNavigator';
|
||||
@@ -33,9 +34,9 @@ const MainNavigator = () => {
|
||||
backgroundColor: COLORS.white,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: COLORS.gray[200],
|
||||
paddingBottom: 8,
|
||||
paddingBottom: Platform.OS === 'android' ? 16 : 8,
|
||||
paddingTop: 8,
|
||||
height: 88,
|
||||
height: Platform.OS === 'android' ? 96 : 88,
|
||||
},
|
||||
tabBarLabelStyle: {
|
||||
fontSize: 12,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import MenuScreen from '../screens/Main/MenuScreen';
|
||||
import LoanRemainingOrdersScreen from '../screens/Loan/LoanRemainingOrdersScreen';
|
||||
import CreateLoanRemainingOrderScreen from '../screens/Loan/CreateLoanRemainingOrderScreen';
|
||||
@@ -28,32 +29,34 @@ import CardOrderDetailsScreen from '../screens/Card/CardOrderDetailsScreen';
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
const MenuNavigator = () => (
|
||||
<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 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>
|
||||
);
|
||||
|
||||
export default MenuNavigator;
|
||||
@@ -7,8 +7,8 @@ import apiService from '../../services/apiService';
|
||||
import { COLORS } from '../../constants/colors';
|
||||
import { useBaseEnums } from '../../contexts/BaseEnumsContext';
|
||||
|
||||
const CARD_BG = '#EFF6FF';
|
||||
const CIRCLE_BG = '#7FB3FF';
|
||||
const CARD_BG = '#F1F9F1';
|
||||
const CIRCLE_BG = '#A2E4A4';
|
||||
|
||||
const CardOrdersScreen = () => {
|
||||
const navigation = useNavigation();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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, SafeAreaView, Alert } from 'react-native';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
@@ -47,6 +47,32 @@ const LoanOrdersScreen = () => {
|
||||
const amount = (item.loan_amount + ' TMT') || '-';
|
||||
const created = item.created_at ? new Date(item.created_at).toLocaleDateString() : '';
|
||||
|
||||
const handleDelete = async (orderId) => {
|
||||
Alert.alert(
|
||||
"Sargyty pozmak",
|
||||
"Siz hakykatdanam bu sargyty pozmak isleýärsiňizmi?",
|
||||
[
|
||||
{ text: "Ýok", style: "cancel" },
|
||||
{
|
||||
text: "Hawa",
|
||||
onPress: async () => {
|
||||
try {
|
||||
const res = await apiService.deleteLoanOrder(orderId);
|
||||
if (res.success) {
|
||||
setOrders(prevOrders => prevOrders.filter(order => order.id !== orderId));
|
||||
} else {
|
||||
console.warn('Failed to delete order:', res.error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error deleting order:', e.message);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={styles.card} onPress={() => navigation.navigate('LoanOrderDetails', { orderId: item.id })}>
|
||||
<View style={styles.circle}>
|
||||
@@ -58,8 +84,11 @@ const LoanOrdersScreen = () => {
|
||||
<Text style={{ color: COLORS.textPrimary }}>{amount}</Text>
|
||||
</Text>
|
||||
|
||||
<Text style={styles.dateText}>{created}</Text>
|
||||
<Text style={styles.dateText}>Döredilen senesi: {created}</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => handleDelete(item.id)} style={styles.deleteButton}>
|
||||
<Ionicons name="trash" size={24} color={COLORS.error} />
|
||||
</TouchableOpacity>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
@@ -112,6 +141,7 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
circle: {
|
||||
width: 40,
|
||||
@@ -127,7 +157,7 @@ const styles = StyleSheet.create({
|
||||
passportText: { fontWeight: '700', color: COLORS.textPrimary, marginBottom: 4 },
|
||||
accountLabel: { color: COLORS.textSecondary, fontSize: 14 },
|
||||
accountValue: { color: COLORS.textPrimary, marginBottom: 4 },
|
||||
dateText: { color: COLORS.textSecondary, fontSize: 12, textAlign: 'right' },
|
||||
dateText: { color: COLORS.textSecondary, fontSize: 12, textAlign: 'left' },
|
||||
emptyContainer: { flex: 1, justifyContent: 'center', alignItems: 'center' },
|
||||
emptyText: { fontSize: 16, color: COLORS.textSecondary },
|
||||
fab: {
|
||||
@@ -142,6 +172,9 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
elevation: 4,
|
||||
},
|
||||
deleteButton: {
|
||||
padding: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default LoanOrdersScreen;
|
||||
@@ -1,5 +1,5 @@
|
||||
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, SafeAreaView, Alert } from 'react-native';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useNavigation, useFocusEffect } from '@react-navigation/native';
|
||||
import apiService from '../../services/apiService';
|
||||
@@ -47,6 +47,32 @@ const LoanPaidOffLetterOrdersScreen = () => {
|
||||
const accountLine = `Karz hasaby:`;
|
||||
const created = item.created_at ? new Date(item.created_at).toLocaleDateString() : '';
|
||||
|
||||
const handleDelete = async (orderId) => {
|
||||
Alert.alert(
|
||||
"Sargyty pozmak",
|
||||
"Siz hakykatdanam bu sargyty pozmak isleýärsiňizmi?",
|
||||
[
|
||||
{ text: "Ýok", style: "cancel" },
|
||||
{
|
||||
text: "Hawa",
|
||||
onPress: async () => {
|
||||
try {
|
||||
const res = await apiService.deleteLoanPaidOffLetterOrder(orderId);
|
||||
if (res.success) {
|
||||
setOrders(prevOrders => prevOrders.filter(order => order.id !== orderId));
|
||||
} else {
|
||||
console.warn('Failed to delete order:', res.error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error deleting order:', e.message);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={styles.card} onPress={() => navigation.navigate('LoanPaidOffLetterOrderDetails', { orderId: item.id })}>
|
||||
<View style={styles.circle}>
|
||||
@@ -58,6 +84,9 @@ const LoanPaidOffLetterOrdersScreen = () => {
|
||||
<Text style={styles.accountValue}>{item.loan_contract_number || '-'}</Text>
|
||||
<Text style={styles.dateText}>{created}</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => handleDelete(item.id)} style={styles.deleteButton}>
|
||||
<Ionicons name="trash" size={24} color={COLORS.error} />
|
||||
</TouchableOpacity>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
@@ -110,6 +139,7 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
circle: {
|
||||
width: 40,
|
||||
@@ -140,6 +170,9 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
elevation: 4,
|
||||
},
|
||||
deleteButton: {
|
||||
padding: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default LoanPaidOffLetterOrdersScreen;
|
||||
@@ -65,6 +65,32 @@ const LoanRemainingOrdersScreen = () => {
|
||||
const accountLabel = 'Karz hasaby:';
|
||||
const created = item.created_at ? new Date(item.created_at).toLocaleDateString() : '';
|
||||
|
||||
const handleDelete = async (orderId) => {
|
||||
Alert.alert(
|
||||
"Sargyty pozmak",
|
||||
"Siz hakykatdanam bu sargyty pozmak isleýärsiňizmi?",
|
||||
[
|
||||
{ text: "Ýok", style: "cancel" },
|
||||
{
|
||||
text: "Hawa",
|
||||
onPress: async () => {
|
||||
try {
|
||||
const res = await apiService.deleteLoanRemainingOrder(orderId);
|
||||
if (res.success) {
|
||||
setOrders(prevOrders => prevOrders.filter(order => order.id !== orderId));
|
||||
} else {
|
||||
console.warn('Failed to delete order:', res.error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error deleting order:', e.message);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={styles.card} onPress={() => handleItemPress(item)}>
|
||||
<View style={styles.circle}>
|
||||
@@ -74,8 +100,11 @@ const LoanRemainingOrdersScreen = () => {
|
||||
<Text style={styles.passportText}>{passportLine}</Text>
|
||||
<Text style={styles.accountLabel}>{accountLabel}</Text>
|
||||
<Text style={styles.accountValue}>{item.account_number}</Text>
|
||||
<Text style={styles.dateText}>{created}</Text>
|
||||
<Text style={styles.dateText}>Döredilen senesi: {created}</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => handleDelete(item.id)} style={styles.deleteButton}>
|
||||
<Ionicons name="trash" size={24} color={COLORS.error} />
|
||||
</TouchableOpacity>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
@@ -204,6 +233,7 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between', // Added to push delete button to the right
|
||||
},
|
||||
circle: {
|
||||
width: 40,
|
||||
@@ -318,6 +348,9 @@ const styles = StyleSheet.create({
|
||||
fontWeight: '600',
|
||||
color: COLORS.textPrimary,
|
||||
},
|
||||
deleteButton: {
|
||||
padding: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default LoanRemainingOrdersScreen;
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
ActivityIndicator,
|
||||
RefreshControl,
|
||||
} from 'react-native';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
@@ -23,6 +24,7 @@ const HomeScreen = () => {
|
||||
const [loadingCardBalance, setLoadingCardBalance] = useState(true);
|
||||
const [cardBalanceError, setCardBalanceError] = useState(null);
|
||||
const [isBalanceVisible, setIsBalanceVisible] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const showBalanceCard = !loadingCardBalance && cardBalanceError === null && cardBalance !== null;
|
||||
|
||||
@@ -79,11 +81,64 @@ const HomeScreen = () => {
|
||||
fetchCardBalance();
|
||||
}, [user]);
|
||||
|
||||
const handleRefresh = async () => {
|
||||
setRefreshing(true);
|
||||
await Promise.all([
|
||||
(async () => {
|
||||
try {
|
||||
const response = await apiService.getMetrics();
|
||||
if (response.success) {
|
||||
setMetrics(response.data);
|
||||
} else {
|
||||
console.warn('Failed to fetch metrics during refresh:', response.error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Error fetching metrics during refresh:', error);
|
||||
}
|
||||
})(),
|
||||
(async () => {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await apiService.getCardBalanceQuickCheck();
|
||||
if (res.success) {
|
||||
const raw = res.data;
|
||||
let balanceValue = null;
|
||||
if (raw && typeof raw === 'object') {
|
||||
balanceValue = raw.balance ?? raw.card_balance ?? raw.amount ?? null;
|
||||
}
|
||||
setCardBalance(balanceValue);
|
||||
setCardBalanceError(null);
|
||||
} else {
|
||||
console.warn('Failed to fetch card balance during refresh:', res.error);
|
||||
setCardBalanceError(res.error || 'Error');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error fetching card balance during refresh:', e);
|
||||
}
|
||||
})(),
|
||||
]);
|
||||
setRefreshing(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<StatusBar style="dark" />
|
||||
|
||||
<ScrollView style={styles.scrollView} showsVerticalScrollIndicator={false}>
|
||||
<ScrollView
|
||||
style={styles.scrollView}
|
||||
showsVerticalScrollIndicator={false}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={handleRefresh}
|
||||
tintColor={COLORS.primary}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<View>
|
||||
|
||||
@@ -81,6 +81,7 @@ const ProfileScreen = () => {
|
||||
// { 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 },
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -102,6 +103,12 @@ const ProfileScreen = () => {
|
||||
case 5: // Security
|
||||
handleSecuritySettings();
|
||||
break;
|
||||
case 13: // About App
|
||||
Alert.alert('Üns beriň', 'Programma barada maglumatlar açylýar...');
|
||||
break;
|
||||
case 14: // Delete Account
|
||||
handleDeleteAccount();
|
||||
break;
|
||||
default:
|
||||
// Alert.alert('Üns beriň', 'Bu funksiýa entek işlenok');
|
||||
}
|
||||
@@ -201,6 +208,40 @@ const ProfileScreen = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteAccount = () => {
|
||||
Alert.alert(
|
||||
'Hasaby pozmak',
|
||||
'Hasabyňyzy pozmak isleýändigiňize ynamlymy? Bu amal yzyna gaýtarylmaz.',
|
||||
[
|
||||
{
|
||||
text: 'Ýok',
|
||||
style: 'cancel',
|
||||
},
|
||||
{
|
||||
text: 'Hawa',
|
||||
style: 'destructive',
|
||||
onPress: async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const result = await apiService.deleteAccount();
|
||||
|
||||
if (result.message == 'user deleted successfully') {
|
||||
Alert.alert('Üstünlik', 'Hasabyňyz üstünlikli pozuldy.');
|
||||
logout(); // Log out the user after successful deletion
|
||||
} else {
|
||||
Alert.alert('Ýalňyşlyk', result.error || 'Hasaby pozmak amala aşmady.');
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.alert('Ýalňyşlyk', error.message || 'Hasaby pozmakda näsazlyk ýüze çykdy.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
const handleNotificationSettings = () => {
|
||||
Alert.alert('Bildirişler', 'Bildiriş sazlamalary sahypasy açylýar...');
|
||||
};
|
||||
@@ -294,7 +335,7 @@ const ProfileScreen = () => {
|
||||
>
|
||||
<View style={styles.profileItemLeft}>
|
||||
<View style={styles.profileItemIcon}>
|
||||
<Ionicons name={item.icon} size={20} color={COLORS.primary} />
|
||||
<Ionicons name={item.icon} size={20} color={item.color || COLORS.primary} />
|
||||
</View>
|
||||
<Text style={styles.profileItemTitle}>{item.title}</Text>
|
||||
</View>
|
||||
|
||||
@@ -170,7 +170,7 @@ class AuthService {
|
||||
}
|
||||
|
||||
async deleteAccount() {
|
||||
return this.makeRequest('/user/delete-account', null, true, 'DELETE');
|
||||
return this.makeRequest(API_CONFIG.ENDPOINTS.AUTH.DELETE_USER, null, true, 'POST');
|
||||
}
|
||||
|
||||
// ================================
|
||||
|
||||
Reference in New Issue
Block a user