This commit is contained in:
Ninjas Code - 4 2023-03-31 09:45:49 +05:00
commit fceae9007d
13 changed files with 832 additions and 452 deletions

View File

@ -1,7 +1,7 @@
{
"expo": {
"name": "Enatega",
"version": "1.0.18",
"version": "1.0.20",
"scheme": "enategasinglevendor",
"description": "Enatega is a starter kit food ordering app built in React Native using Expo for IOS and Android. It's made keeping good aesthetics in mind as well keeping the best coding practices in mind. Its fully customisable to easily help you in your next food delivery project. https://market.nativebase.io/view/react-native-food-delivery-backend-app",
"slug": "enategasinglevendor",
@ -46,12 +46,12 @@
"androidCollapsedTitle": "Enatega"
},
"android": {
"versionCode": 23,
"versionCode": 24,
"package": "com.enatega.vendor",
"googleServicesFile": "./google-services-prod.json",
"config": {
"googleMaps": {
"apiKey": ""
"apiKey": "AIzaSyCzNP5qQql2a5y8lOoO-1yj1lj_tzjVImA"
}
},
"adaptiveIcon": {

View File

@ -7,11 +7,9 @@ import Constants from "expo-constants";
const ENV = {
development: {
GRAPHQL_URL: "http://10.97.28.48:8000/graphql",
WS_GRAPHQL_URL: "ws://10.97.28.48:8000/graphql",
SERVER_URL: "http://10.97.28.48:8000/", // put / at the end of server url
Expo_CLIENT_ID_GOOGLE:
"630195385603-82e52jpb722a8l0huhkspq3tqh2d6r6f.apps.googleusercontent.com",
GRAPHQL_URL: "http://10.97.28.39:8000/graphql",
WS_GRAPHQL_URL: "ws://110.97.28.39.90:8000/graphql",
SERVER_URL: "http://110.97.28.39.90:8000/",
IOS_CLIENT_ID_GOOGLE:
"967541328677-uq7f7odvmeea2pb2sq0l7q320ds86536.apps.googleusercontent.com",
ANDROID_CLIENT_ID_GOOGLE:

View File

@ -31,6 +31,7 @@
"apollo-utilities": "^1.3.4",
"deprecated-react-native-prop-types": "^4.0.0",
"expo": "^47.0.12",
"expo-app-auth": "~11.1.0",
"expo-app-loading": "~2.1.1",
"expo-apple-authentication": "~5.0.1",
"expo-application": "~5.0.1",
@ -2141,9 +2142,9 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz",
"integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
"dev": true,
"dependencies": {
"eslint-visitor-keys": "^3.3.0"
@ -2156,9 +2157,9 @@
}
},
"node_modules/@eslint-community/regexpp": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz",
"integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.1.tgz",
"integrity": "sha512-BISJ6ZE4xQsuL/FmsyRaiffpq977bMlsKfGHTQrOGFErfByxIe6iZTxPf/00Zon9b9a7iUykfQwejN3s2ZW/Bw==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@ -6033,9 +6034,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "18.15.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz",
"integrity": "sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw=="
"version": "18.15.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.7.tgz",
"integrity": "sha512-LFmUbFunqmBn26wJZgZPYZPrDR1RwGOu2v79Mgcka1ndO6V0/cwjivPTc4yoK6n9kmw4/ls1r8cLrvh2iMibFA=="
},
"node_modules/@types/prettier": {
"version": "2.7.2",
@ -6064,9 +6065,9 @@
}
},
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
},
"node_modules/@types/stack-utils": {
"version": "2.0.1",
@ -6075,9 +6076,9 @@
"dev": true
},
"node_modules/@types/yargs": {
"version": "17.0.22",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz",
"integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==",
"version": "17.0.23",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.23.tgz",
"integrity": "sha512-yuogunc04OnzGQCrfHx+Kk883Q4X0aSwmYZhKjI21m+SVYzjIbrWl8dOOwSv5hf2Um2pdCOXWo9isteZTNXUZQ==",
"dependencies": {
"@types/yargs-parser": "*"
}
@ -8248,9 +8249,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001468",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001468.tgz",
"integrity": "sha512-zgAo8D5kbOyUcRAgSmgyuvBkjrGk5CGYG5TYgFdpQv+ywcyEpo1LOWoG8YmoflGnh+V+UsNuKYedsoYs0hzV5A==",
"version": "1.0.30001469",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz",
"integrity": "sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g==",
"funding": [
{
"type": "opencollective",
@ -9278,9 +9279,9 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/electron-to-chromium": {
"version": "1.4.333",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.333.tgz",
"integrity": "sha512-YyE8+GKyGtPEP1/kpvqsdhD6rA/TP1DUFDN4uiU/YI52NzDxmwHkEb3qjId8hLBa5siJvG0sfC3O66501jMruQ=="
"version": "1.4.339",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.339.tgz",
"integrity": "sha512-MSXHBJGcbBydq/DQDlpBeUKnJ6C7aTiNCTRpfDV5Iz0sNr/Ng6RJFloq82AAicp/SrmDq4zF6XsKG0B8Xwn1UQ=="
},
"node_modules/emittery": {
"version": "0.13.1",
@ -10383,6 +10384,249 @@
"expo-error-recovery": "~4.0.1"
}
},
"node_modules/expo-app-auth": {
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/expo-app-auth/-/expo-app-auth-11.1.1.tgz",
"integrity": "sha512-BYsVJ54GySnpVjRLmUX//XkDkqlqigpOS+MWBARURecPu038Ei2tsIsboLqbaa6oyoWhtU9OfYacVHczE/BFmQ==",
"deprecated": "Please migrate to expo-auth-session",
"dependencies": {
"@expo/config-plugins": "^4.0.2",
"invariant": "^2.2.4"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-app-auth/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-app-auth/node_modules/@expo/config-plugins": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-4.1.5.tgz",
"integrity": "sha512-RVvU40RtZt12HavuDAe+LDIq9lHj7sheOfMEHdmpJ/uTA8pgvkbc56XF6JHQD+yRr6+uhhb+JnAasGq49dsQbw==",
"dependencies": {
"@expo/config-types": "^45.0.0",
"@expo/json-file": "8.2.36",
"@expo/plist": "0.0.18",
"@expo/sdk-runtime-versions": "^1.0.0",
"@react-native/normalize-color": "^2.0.0",
"chalk": "^4.1.2",
"debug": "^4.3.1",
"find-up": "~5.0.0",
"getenv": "^1.0.0",
"glob": "7.1.6",
"resolve-from": "^5.0.0",
"semver": "^7.3.5",
"slash": "^3.0.0",
"xcode": "^3.0.1",
"xml2js": "0.4.23"
}
},
"node_modules/expo-app-auth/node_modules/@expo/config-types": {
"version": "45.0.0",
"resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-45.0.0.tgz",
"integrity": "sha512-/QGhhLWyaGautgEyU50UJr5YqKJix5t77ePTwreOVAhmZH+ff3nrrtYTTnccx+qF08ZNQmfAyYMCD3rQfzpiJA=="
},
"node_modules/expo-app-auth/node_modules/@expo/json-file": {
"version": "8.2.36",
"resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-8.2.36.tgz",
"integrity": "sha512-tOZfTiIFA5KmMpdW9KF7bc6CFiGjb0xnbieJhTGlHrLL+ps2G0OkqmuZ3pFEXBOMnJYUVpnSy++52LFxvpa5ZQ==",
"dependencies": {
"@babel/code-frame": "~7.10.4",
"json5": "^1.0.1",
"write-file-atomic": "^2.3.0"
}
},
"node_modules/expo-app-auth/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/expo-app-auth/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/expo-app-auth/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/expo-app-auth/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/expo-app-auth/node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dependencies": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/expo-app-auth/node_modules/glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/expo-app-auth/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/expo-app-auth/node_modules/json5": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dependencies": {
"minimist": "^1.2.0"
},
"bin": {
"json5": "lib/cli.js"
}
},
"node_modules/expo-app-auth/node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dependencies": {
"p-locate": "^5.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/expo-app-auth/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/expo-app-auth/node_modules/p-locate": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dependencies": {
"p-limit": "^3.0.2"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/expo-app-auth/node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"engines": {
"node": ">=8"
}
},
"node_modules/expo-app-auth/node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/expo-app-auth/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/expo-app-auth/node_modules/write-file-atomic": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
"integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
"dependencies": {
"graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
"signal-exit": "^3.0.2"
}
},
"node_modules/expo-app-auth/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/expo-app-loading": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/expo-app-loading/-/expo-app-loading-2.1.1.tgz",
@ -14846,9 +15090,9 @@
"integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww=="
},
"node_modules/joi": {
"version": "17.8.4",
"resolved": "https://registry.npmjs.org/joi/-/joi-17.8.4.tgz",
"integrity": "sha512-jjdRHb5WtL+KgSHvOULQEPPv4kcl+ixd1ybOFQq3rWLgEEqc03QMmilodL0GVJE14U/SQDXkUhQUSZANGDH/AA==",
"version": "17.9.1",
"resolved": "https://registry.npmjs.org/joi/-/joi-17.9.1.tgz",
"integrity": "sha512-FariIi9j6QODKATGBrEX7HZcja8Bsh3rfdGYy/Sb65sGlZWK/QWesU1ghk7aJWDj95knjXlQfSmzFSPPkLVsfw==",
"dependencies": {
"@hapi/hoek": "^9.0.0",
"@hapi/topo": "^5.0.0",
@ -14863,9 +15107,9 @@
"integrity": "sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ=="
},
"node_modules/js-sdsl": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
"integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
"integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
"dev": true,
"funding": {
"type": "opencollective",
@ -18837,9 +19081,9 @@
}
},
"node_modules/prettier": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.5.tgz",
"integrity": "sha512-3gzuxrHbKUePRBB4ZeU08VNkUcqEHaUaouNt0m7LGP4Hti/NuB07C7PPTM/LkWqXoJYJn2McEo5+kxPNrtQkLQ==",
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
"integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@ -20273,9 +20517,9 @@
"deprecated": "https://github.com/lydell/resolve-url#deprecated"
},
"node_modules/resolve.exports": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.1.tgz",
"integrity": "sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
"integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
"dev": true,
"engines": {
"node": ">=10"
@ -21391,9 +21635,9 @@
}
},
"node_modules/sucrase": {
"version": "3.29.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.29.0.tgz",
"integrity": "sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==",
"version": "3.30.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.30.0.tgz",
"integrity": "sha512-7d37d3vLF0IeH2dzvHpzDNDxUqpbDHJXTJOAnQ8jvMW04o2Czps6mxtaSnKWpE+hUS/eczqfWPUgQTrazKZPnQ==",
"dependencies": {
"commander": "^4.0.0",
"glob": "7.1.6",

View File

@ -46,6 +46,7 @@
"deprecated-react-native-prop-types": "^4.0.0",
"expo": "^47.0.12",
"expo-app-loading": "~2.1.1",
"expo-app-auth": "~11.1.0",
"expo-apple-authentication": "~5.0.1",
"expo-application": "~5.0.1",
"expo-asset": "~8.7.0",

1
CustomerApp/src/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/node_modules

View File

@ -1,92 +1,92 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { defaultDataIdFromObject, InMemoryCache } from 'apollo-cache-inmemory'
import { persistCache } from 'apollo-cache-persist'
import { ApolloClient } from 'apollo-client'
import { ApolloLink, concat, Observable, split } from 'apollo-link'
import { createHttpLink } from 'apollo-link-http'
import { WebSocketLink } from 'apollo-link-ws'
import { getMainDefinition } from 'apollo-utilities'
import getEnvVars from '../../environment'
import AsyncStorage from "@react-native-async-storage/async-storage";
import { defaultDataIdFromObject, InMemoryCache } from "apollo-cache-inmemory";
import { persistCache } from "apollo-cache-persist";
import { ApolloClient } from "apollo-client";
import { ApolloLink, concat, Observable, split } from "apollo-link";
import { createHttpLink } from "apollo-link-http";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
import getEnvVars from "../../environment";
const { GRAPHQL_URL, WS_GRAPHQL_URL } = getEnvVars()
const { GRAPHQL_URL, WS_GRAPHQL_URL } = getEnvVars();
const cache = new InMemoryCache({
dataIdFromObject: object => {
dataIdFromObject: (object) => {
switch (object.__typename) {
case 'CartItem':
return object.key // use `key` as the primary key
case "CartItem":
return object.key; // use `key` as the primary key
default:
return defaultDataIdFromObject(object) // fall back to default handling
return defaultDataIdFromObject(object); // fall back to default handling
}
}
})
},
});
const httpLink = createHttpLink({
uri: GRAPHQL_URL
})
uri: GRAPHQL_URL,
});
const wsLink = new WebSocketLink({
uri: WS_GRAPHQL_URL,
options: {
reconnect: true
}
})
const request = async operation => {
const token = await AsyncStorage.getItem('token')
reconnect: true,
},
});
const request = async (operation) => {
const token = await AsyncStorage.getItem("token");
console.log("token", token);
operation.setContext({
// get the authentication token from local storage if it exists
// return the headers to the context so httpLink can read them
headers: {
authorization: token ? `Bearer ${token}` : ''
}
})
}
authorization: token ? `Bearer ${token}` : "",
},
});
};
const requestLink = new ApolloLink(
(operation, forward) =>
new Observable(observer => {
new Observable((observer) => {
// console.log(observer)
let handle
let handle;
Promise.resolve(operation)
.then(oper => request(oper))
.then((oper) => request(oper))
.then(() => {
handle = forward(operation).subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer)
complete: observer.complete.bind(observer),
});
})
})
.catch(observer.error.bind(observer))
.catch(observer.error.bind(observer));
return () => {
if (handle) handle.unsubscribe()
}
if (handle) handle.unsubscribe();
};
})
)
);
const terminatingLink = split(({ query }) => {
const { kind, operation } = getMainDefinition(query)
return kind === 'OperationDefinition' && operation === 'subscription'
}, wsLink)
const { kind, operation } = getMainDefinition(query);
return kind === "OperationDefinition" && operation === "subscription";
}, wsLink);
const setupApollo = async () => {
await persistCache({
cache,
storage: AsyncStorage
})
storage: AsyncStorage,
});
const client = new ApolloClient({
link: concat(ApolloLink.from([terminatingLink, requestLink]), httpLink),
cache,
resolvers: {}
})
resolvers: {},
});
// set ref for global use
// eslint-disable-next-line no-undef
clientRef = client
clientRef = client;
return client
}
return client;
};
export default setupApollo
export default setupApollo;

View File

@ -3,13 +3,14 @@ mutation Login($facebookId:String,$email:String,$password:String,$type:String!,$
login(facebookId:$facebookId,email:$email,password:$password,type:$type,appleId:$appleId,name:$name,notificationToken:$notificationToken){
userId
token
is_active
tokenExpiration
name
email
phone
}
}
`
`;
export const categories = `
{
@ -19,7 +20,7 @@ export const categories = `
description
img_menu
}
}`
}`;
export const foods = `
query FoodByCategory($category:String!,$onSale:Boolean,$inStock:Boolean,$min:Float,$max:Float,$search:String){
@ -50,7 +51,7 @@ query FoodByCategory($category:String!,$onSale:Boolean,$inStock:Boolean,$min:Flo
img_url
stock
}
}`
}`;
export const createUser = `
mutation CreateUser($facebookId:String,$phone:String,$email:String,$password:String,$name:String,$notificationToken:String,$appleId:String){
@ -71,16 +72,17 @@ export const createUser = `
phone
notificationToken
}
}`
}`;
export const updateUser = `
mutation UpdateUser($name:String!,$phone:String!){
updateUser(updateUserInput:{name:$name,phone:$phone}){
mutation UpdateUser($name:String!,$phone:String!,$is_active:Boolean!){
updateUser(updateUserInput:{name:$name,phone:$phone,is_active:$is_active}){
_id
name
phone
is_active
}
}`
}`;
export const updateNotificationStatus = `
mutation UpdateNotificationStatus($offerNotification:Boolean!,$orderNotification:Boolean!){
@ -90,7 +92,7 @@ export const updateNotificationStatus = `
is_order_notification
is_offer_notification
}
}`
}`;
export const profile = `
query{
profile{
@ -98,6 +100,8 @@ export const profile = `
name
phone
email
is_active
notificationToken
is_order_notification
is_offer_notification
@ -111,7 +115,7 @@ export const profile = `
selected
}
}
}`
}`;
export const order = `query Order($id:String!){
order(id:$id){
@ -184,7 +188,7 @@ export const order = `query Order($id:String!){
}
}
}
`
`;
export const myOrders = `query Orders($offset:Int){
orders(offset:$offset){
@ -257,7 +261,7 @@ export const myOrders = `query Orders($offset:Int){
}
}
}
`
`;
//
// can we get userId from request instead??
@ -340,7 +344,7 @@ export const orderStatusChanged = `subscription OrderStatusChanged($userId:Strin
}
}
}
`
`;
//
// status queue??
@ -417,7 +421,7 @@ mutation PlaceOrder($orderInput:[OrderInput!]!,$paymentMethod:String!,$couponCod
description
}
}
}`
}`;
export const reviewOrder = `mutation ReviewOrder(
$orderId:String!,
@ -440,7 +444,7 @@ export const reviewOrder = `mutation ReviewOrder(
updatedAt
is_active
}
}`
}`;
//
// use this to push token instead of login, signup mutation?
@ -451,7 +455,7 @@ export const pushToken = `mutation PushToken($token:String!){
_id
notificationToken
}
}`
}`;
export const getConfiguration = `query Configuration{
configuration{
@ -460,7 +464,7 @@ export const getConfiguration = `query Configuration{
currency_symbol
delivery_charges
}
}`
}`;
export const foodByIds = `query FoodByIds($ids:[String!]!){
foodByIds(ids: $ids) {
@ -492,7 +496,7 @@ export const foodByIds = `query FoodByIds($ids:[String!]!){
}
}
}
}`
}`;
export const getCoupon = `mutation Coupon($coupon:String!){
coupon(coupon:$coupon){
@ -501,7 +505,7 @@ export const getCoupon = `mutation Coupon($coupon:String!){
discount
enabled
}
}`
}`;
export const deleteAddress = `mutation DeleteAddress($id:ID!){
deleteAddress(id:$id){
@ -516,7 +520,7 @@ export const deleteAddress = `mutation DeleteAddress($id:ID!){
selected
}
}
}`
}`;
export const createAddress = `mutation CreateAddress($addressInput:AddressInput!){
createAddress(addressInput:$addressInput){
@ -531,7 +535,7 @@ export const createAddress = `mutation CreateAddress($addressInput:AddressInput!
selected
}
}
}`
}`;
export const editAddress = `mutation EditAddress($addressInput:AddressInput!){
editAddress(addressInput:$addressInput){
@ -542,17 +546,17 @@ export const editAddress = `mutation EditAddress($addressInput:AddressInput!){
longitude
latitude
}
}`
}`;
export const changePassword = `mutation ChangePassword($oldPassword:String!,$newPassword:String!){
changePassword(oldPassword:$oldPassword,newPassword:$newPassword)
}`
}`;
export const forgotPassword = `mutation ForgotPassword($email:String!){
forgotPassword(email:$email){
result
}
}`
}`;
export const selectAddress = `mutation SelectAddress($id:String!){
selectAddress(id:$id){
@ -567,7 +571,7 @@ export const selectAddress = `mutation SelectAddress($id:String!){
selected
}
}
}`
}`;
export const subscriptionRiderLocation = `subscription SubscriptionRiderLocation($riderId:String!){
subscriptionRiderLocation(riderId:$riderId) {
@ -577,7 +581,7 @@ export const subscriptionRiderLocation = `subscription SubscriptionRiderLocation
longitude
}
}
}`
}`;
export const rider = `query Rider($id:String){
rider(id:$id){
@ -587,4 +591,4 @@ export const rider = `query Rider($id:String){
longitude
}
}
}`
}`;

View File

@ -1,49 +1,49 @@
/* eslint-disable react/prop-types */
import { SimpleLineIcons } from '@expo/vector-icons'
import { DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer'
import { SimpleLineIcons } from "@expo/vector-icons";
import { DrawerContentScrollView, DrawerItem } from "@react-navigation/drawer";
import {
DrawerActions,
useNavigation,
useTheme
} from '@react-navigation/native'
import React, { useContext } from 'react'
import { Animated, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import i18n from '../../../i18n'
import UserContext from '../../context/User'
import NavigationService from '../../routes/navigationService'
import { alignment } from '../../utils/alignment'
import { ICONS_NAME, NAVIGATION_SCREEN } from '../../utils/constant'
import { scale } from '../../utils/scaling'
import { CustomIcon } from '../CustomIcon'
import SideDrawerProfile from '../Drawer/Profile/DrawerProfile'
import { TextDefault } from '../Text'
import useStyle from './styles'
useTheme,
} from "@react-navigation/native";
import React, { useContext } from "react";
import { Animated, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import i18n from "../../../i18n";
import UserContext from "../../context/User";
import NavigationService from "../../routes/navigationService";
import { alignment } from "../../utils/alignment";
import { ICONS_NAME, NAVIGATION_SCREEN } from "../../utils/constant";
import { scale } from "../../utils/scaling";
import { CustomIcon } from "../CustomIcon";
import SideDrawerProfile from "../Drawer/Profile/DrawerProfile";
import { TextDefault } from "../Text";
import useStyle from "./styles";
const MENU = [
{
title: 'home',
title: "home",
icon: ICONS_NAME.Home,
navigateTo: NAVIGATION_SCREEN.Menu,
isAuth: false
isAuth: false,
},
{
title: 'titleProfile',
icon: 'user',
navigateTo: 'Profile',
isAuth: true
title: "titleProfile",
icon: "user",
navigateTo: "Profile",
isAuth: true,
},
{
title: 'titleOrders',
title: "titleOrders",
icon: ICONS_NAME.Cart,
navigateTo: NAVIGATION_SCREEN.MyOrders,
isAuth: true
isAuth: true,
},
{
title: 'myAddresses',
title: "myAddresses",
icon: ICONS_NAME.Location,
navigateTo: NAVIGATION_SCREEN.Addresses,
isAuth: true
isAuth: true,
},
// {
// title: 'titleChat',
@ -52,36 +52,38 @@ const MENU = [
// isAuth: false
// },
{
title: 'titleHelp',
title: "titleHelp",
icon: ICONS_NAME.Info,
navigateTo: NAVIGATION_SCREEN.Help,
isAuth: false
isAuth: false,
},
{
title: 'titleSettings',
title: "titleSettings",
icon: ICONS_NAME.Setting,
navigateTo: NAVIGATION_SCREEN.Settings,
isAuth: true
}
]
isAuth: true,
},
];
function SidebBar(props) {
const styles = useStyle()
const { colors } = useTheme()
const navigation = useNavigation()
const inset = useSafeAreaInsets()
const { isLoggedIn, logout } = useContext(UserContext)
const navigationName = NavigationService.currentRoute()?.name
const styles = useStyle();
const { colors } = useTheme();
const navigation = useNavigation();
const inset = useSafeAreaInsets();
const { isLoggedIn, logout } = useContext(UserContext);
const navigationName = NavigationService.currentRoute()?.name;
return (
<DrawerContentScrollView
{...props}
contentContainerStyle={styles.scrollContent}>
contentContainerStyle={styles.scrollContent}
>
<Animated.View
style={{
flex: 1,
backgroundColor: 'transparent',
marginBottom: inset.bottom
}}>
backgroundColor: "transparent",
marginBottom: inset.bottom,
}}
>
<View style={styles.headerContainer}>
<SideDrawerProfile />
</View>
@ -89,31 +91,32 @@ function SidebBar(props) {
<View>
{MENU.map((item, index) => (
<DrawerItem
pressColor={'rgba(0,0,0,0.2)'}
pressColor={"rgba(0,0,0,0.2)"}
key={`DRAWER_ITEM_LIST_${index}`}
style={styles.drawerItem}
activeBackgroundColor={'transparent'}
activeBackgroundColor={"transparent"}
activeTintColor={colors.black}
inactiveTintColor={colors.fontWhite}
focused={navigationName === item.navigateTo}
label={props => (
label={(props) => (
<TextDefault
H5
medium
textColor={props.color}
style={[styles.textView, styles.flex]}>
style={[styles.textView, styles.flex]}
>
{i18n.t(item.title)}
</TextDefault>
)}
icon={props => {
if (item.icon !== 'user') {
icon={(props) => {
if (item.icon !== "user") {
return (
<CustomIcon
name={item.icon}
color={props.color}
size={scale(22)}
/>
)
);
} else {
return (
<SimpleLineIcons
@ -121,14 +124,14 @@ function SidebBar(props) {
color={props.color}
size={scale(22)}
/>
)
);
}
}}
onPress={async () => {
if (item.isAuth && !isLoggedIn) {
navigation.navigate(NAVIGATION_SCREEN.CreateAccount)
navigation.navigate(NAVIGATION_SCREEN.CreateAccount);
} else {
navigation.navigate(item.navigateTo)
navigation.navigate(item.navigateTo);
}
}}
/>
@ -137,15 +140,16 @@ function SidebBar(props) {
<View style={alignment.PBmedium}>
{isLoggedIn && (
<DrawerItem
pressColor={'rgba(0,0,0,0.2)'}
pressColor={"rgba(0,0,0,0.2)"}
style={styles.drawerItem}
label={() => (
<TextDefault
H5
medium
textColor={styles.whiteFont.color}
style={[styles.textView, styles.flex]}>
{i18n.t('titleLogout')}
style={[styles.textView, styles.flex]}
>
{i18n.t("titleLogout")}
</TextDefault>
)}
icon={() => (
@ -156,11 +160,11 @@ function SidebBar(props) {
/>
)}
onPress={async () => {
logout()
logout();
navigation.reset({
routes: [{ name: 'Menu' }]
})
navigation.dispatch(DrawerActions.closeDrawer())
routes: [{ name: "Menu" }],
});
navigation.dispatch(DrawerActions.closeDrawer());
// await client.resetStore();
}}
/>
@ -169,6 +173,6 @@ function SidebBar(props) {
</View>
</Animated.View>
</DrawerContentScrollView>
)
);
}
export default SidebBar
export default SidebBar;

View File

@ -62,6 +62,12 @@ const CreateAccount = () => {
}
async function onCompleted(data) {
if (!data.login.is_active) {
FlashMessage({
message: "Can't Login,This Account is Deleted!",
});
setLoading(false);
} else {
try {
const trackingOpts = {
id: data.login.userId,
@ -77,6 +83,7 @@ const CreateAccount = () => {
setLoading(false);
}
}
}
function onError(error) {
try {
console.log(JSON.stringify(error));
@ -139,6 +146,7 @@ const CreateAccount = () => {
};
mutateLogin(user);
}
loginButtonSetter("Apple");
// signed in
} catch (e) {

View File

@ -1,9 +1,9 @@
import { useMutation } from '@apollo/react-hooks'
import { useNavigation, useTheme } from '@react-navigation/native'
import * as Notifications from 'expo-notifications'
import Constants from 'expo-constants'
import gql from 'graphql-tag'
import React, { useContext, useEffect, useState } from 'react'
import { useMutation } from "@apollo/react-hooks";
import { useNavigation, useTheme } from "@react-navigation/native";
import * as Notifications from "expo-notifications";
import Constants from "expo-constants";
import gql from "graphql-tag";
import React, { useContext, useEffect, useState } from "react";
import {
ActivityIndicator,
BackHandler,
@ -11,141 +11,151 @@ import {
Platform,
ScrollView,
TouchableOpacity,
View
} from 'react-native'
import { FilledTextField } from 'react-native-material-textfield'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import i18n from '../../../i18n'
import { login } from '../../apollo/server'
View,
} from "react-native";
import { FilledTextField } from "react-native-material-textfield";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import i18n from "../../../i18n";
import { login } from "../../apollo/server";
import {
EnategaImage,
FlashMessage,
RegistrationHeader,
TextDefault,
WrapperView
} from '../../components'
import UserContext from '../../context/User'
import { alignment } from '../../utils/alignment'
import Analytics from '../../utils/analytics'
import { NAVIGATION_SCREEN } from '../../utils/constant'
import { scale, verticalScale } from '../../utils/scaling'
import useStyle from './styles'
WrapperView,
} from "../../components";
import UserContext from "../../context/User";
import { alignment } from "../../utils/alignment";
import Analytics from "../../utils/analytics";
import { NAVIGATION_SCREEN } from "../../utils/constant";
import { scale, verticalScale } from "../../utils/scaling";
import useStyle from "./styles";
// Constants
const LOGIN = gql`
${login}
`
`;
const Logo = require('../../../assets/logo.png')
const Logo = require("../../../assets/logo.png");
function Login() {
let _didFocusSubscription = null
let _willBlurSubscription = null
const styles = useStyle()
const inset = useSafeAreaInsets()
const { colors } = useTheme()
const navigation = useNavigation()
const [email, setEmail] = useState('john@test.com')
const [loading, setLoading] = useState(false)
const [password, setPassword] = useState('123123')
const [emailError, setEmailError] = useState('')
const { setTokenAsync } = useContext(UserContext)
const [passwordError, setPasswordError] = useState(null)
let _didFocusSubscription = null;
let _willBlurSubscription = null;
const styles = useStyle();
const inset = useSafeAreaInsets();
const { colors } = useTheme();
const navigation = useNavigation();
const [email, setEmail] = useState("john@test.com");
const [loading, setLoading] = useState(false);
const [password, setPassword] = useState("123123");
const [emailError, setEmailError] = useState("");
const { setTokenAsync, logout } = useContext(UserContext);
const [passwordError, setPasswordError] = useState(null);
const [mutate] = useMutation(LOGIN, { onCompleted, onError })
const [mutate] = useMutation(LOGIN, { onCompleted, onError });
useEffect(() => {
_didFocusSubscription = navigation.addListener('didFocus', () => {
_didFocusSubscription = navigation.addListener("didFocus", () => {
BackHandler.addEventListener(
'hardwareBackPress',
"hardwareBackPress",
onBackButtonPressAndroid
)
})
_willBlurSubscription = navigation.addListener('willBlur', () => {
);
});
_willBlurSubscription = navigation.addListener("willBlur", () => {
BackHandler.removeEventListener(
'hardwareBackPress',
"hardwareBackPress",
onBackButtonPressAndroid
)
})
);
});
return () => {
_didFocusSubscription && _didFocusSubscription()
_willBlurSubscription && _willBlurSubscription()
_didFocusSubscription && _didFocusSubscription();
_willBlurSubscription && _willBlurSubscription();
BackHandler.removeEventListener(
'hardwareBackPress',
"hardwareBackPress",
onBackButtonPressAndroid
)
}
}, [])
);
};
}, []);
function validateCredentials() {
let result = true
setEmailError(null)
setPasswordError(null)
let result = true;
setEmailError(null);
setPasswordError(null);
if (!email) {
setEmailError('Email/Phone is required')
result = false
setEmailError("Email/Phone is required");
result = false;
} else {
const emailRegex = /^\w+([\\.-]?\w+)*@\w+([\\.-]?\w+)*(\.\w{2,3})+$/
const phoneRegex = /^[+]\d{6,15}$/
const emailRegex = /^\w+([\\.-]?\w+)*@\w+([\\.-]?\w+)*(\.\w{2,3})+$/;
const phoneRegex = /^[+]\d{6,15}$/;
if (emailRegex.test(email) !== true && phoneRegex.test(email) !== true) {
setEmailError('Invalid Email/Phone')
result = false
setEmailError("Invalid Email/Phone");
result = false;
}
}
if (!password) {
setPasswordError('Password is required')
result = false
setPasswordError("Password is required");
result = false;
}
return result
return result;
}
async function onCompleted(data) {
if (!data.login.is_active) {
FlashMessage({
message: "Can't Login,This Account is Deleted!",
});
setLoading(false);
} else {
try {
const trackingOpts = {
id: data.login.userId,
usernameOrEmail: data.login.email
}
Analytics.identify(data.login.userId, trackingOpts)
Analytics.track(Analytics.events.USER_LOGGED_IN, trackingOpts)
setTokenAsync(data.login.token)
navigation.navigate(NAVIGATION_SCREEN.Menu)
usernameOrEmail: data.login.email,
};
Analytics.identify(data.login.userId, trackingOpts);
Analytics.track(Analytics.events.USER_LOGGED_IN, trackingOpts);
setTokenAsync(data.login.token);
console.log("Data Before Navigation:", data.login.is_active);
navigation.navigate(NAVIGATION_SCREEN.Menu);
} catch (e) {
console.log(e)
console.log(e);
} finally {
setLoading(false)
setLoading(false);
}
}
}
function onError(error) {
try {
console.log(JSON.stringify(error))
console.log(JSON.stringify(error));
FlashMessage({
message: error.graphQLErrors[0].message
})
message: error.graphQLErrors[0].message,
});
} catch (e) {
console.log(e)
console.log(e);
} finally {
setLoading(false)
setLoading(false);
}
}
function onBackButtonPressAndroid() {
navigation.navigate(NAVIGATION_SCREEN.Menu)
return true
navigation.navigate(NAVIGATION_SCREEN.Menu);
return true;
}
async function mutateLogin(user) {
try {
setLoading(true)
let notificationToken = null
setLoading(true);
let notificationToken = null;
if (Constants.isDevice) {
const { status: existingStatus } =
await Notifications.getPermissionsAsync()
if (existingStatus === 'granted') {
notificationToken = (await Notifications.getExpoPushTokenAsync()).data
await Notifications.getPermissionsAsync();
if (existingStatus === "granted") {
notificationToken = (await Notifications.getExpoPushTokenAsync())
.data;
}
}
mutate({ variables: { ...user, notificationToken } })
mutate({ variables: { ...user, notificationToken } });
} catch (e) {
console.log(e)
console.log(e);
} finally {
}
}
@ -159,37 +169,40 @@ function Login() {
const user = {
email: email,
password: password,
type: 'default'
}
type: "default",
};
if (validateCredentials()) {
mutateLogin(user)
mutateLogin(user);
}
}}>
}}
>
{loading ? (
<ActivityIndicator
size="large"
style={{ flex: 1, justifyContent: 'center' }}
style={{ flex: 1, justifyContent: "center" }}
color={colors.buttonText}
/>
) : (
<TextDefault bold>{i18n.t('loginBtn')}</TextDefault>
<TextDefault bold>{i18n.t("loginBtn")}</TextDefault>
)}
</TouchableOpacity>
)
);
}
return (
<WrapperView>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.flex}>
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.flex}
>
<ScrollView
style={[styles.flex, { paddingTop: inset.top }]}
contentContainerStyle={{ flexGrow: 1, paddingTop: verticalScale(20) }}
showsVerticalScrollIndicator={false}
alwaysBounceVertical={false}>
alwaysBounceVertical={false}
>
<View style={styles.mainContainer}>
<RegistrationHeader title={'Login'} back />
<RegistrationHeader title={"Login"} back />
<View style={styles.subContainer}>
<View style={[styles.flex, styles.upperContainer]}>
<EnategaImage
@ -204,10 +217,10 @@ function Login() {
</TextDefault>
<View style={styles.marginTop3} />
<FilledTextField
defaultValue={'john@test.com'}
defaultValue={"john@test.com"}
error={emailError}
keyboardType={'email-address'}
label={i18n.t('emailphone')}
keyboardType={"email-address"}
label={i18n.t("emailphone")}
labelFontSize={scale(12)}
fontSize={scale(12)}
activeLineWidth={0}
@ -219,14 +232,14 @@ function Login() {
tintColor={colors.selected}
labelTextStyle={styles.labelStyle}
inputContainerStyle={styles.textContainer}
onChangeText={text => {
setEmail(text.toLowerCase().trim())
onChangeText={(text) => {
setEmail(text.toLowerCase().trim());
}}
/>
<FilledTextField
defaultValue={'123123'}
defaultValue={"123123"}
error={passwordError}
label={i18n.t('password')}
label={i18n.t("password")}
secureTextEntry
labelFontSize={scale(12)}
fontSize={scale(12)}
@ -239,20 +252,22 @@ function Login() {
tintColor={colors.selected}
labelTextStyle={styles.labelStyle}
inputContainerStyle={styles.textContainer}
onChangeText={text => {
setPassword(text.trim())
onChangeText={(text) => {
setPassword(text.trim());
}}
/>
<TouchableOpacity
activeOpacity={0.7}
style={{ alignSelf: 'flex-end' }}
style={{ alignSelf: "flex-end" }}
onPress={() =>
navigation.navigate(NAVIGATION_SCREEN.ForgotPassword)
}>
}
>
<TextDefault
style={[alignment.PTmedium, alignment.PBxSmall]}
medium
center>
center
>
Forgot Password?
</TextDefault>
</TouchableOpacity>
@ -262,7 +277,8 @@ function Login() {
style={[alignment.MTlarge, styles.loginBtn, styles.whiteBtn]}
onPress={() =>
navigation.navigate(NAVIGATION_SCREEN.CreateAccount)
}>
}
>
<TextDefault textColor={colors.fontSecondColor} bold center>
Create New Account
</TextDefault>
@ -273,7 +289,7 @@ function Login() {
</ScrollView>
</KeyboardAvoidingView>
</WrapperView>
)
);
}
export default Login
export default Login;

View File

@ -1,139 +1,139 @@
import { useMutation } from '@apollo/react-hooks'
import { MaterialCommunityIcons } from '@expo/vector-icons'
import { useNavigation, useRoute, useTheme } from '@react-navigation/native'
import gql from 'graphql-tag'
import { useMutation } from "@apollo/react-hooks";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { useNavigation, useRoute, useTheme } from "@react-navigation/native";
import gql from "graphql-tag";
import React, {
useContext,
useEffect,
useLayoutEffect,
useRef,
useState
} from 'react'
useState,
} from "react";
import {
KeyboardAvoidingView,
Platform,
ScrollView,
TouchableOpacity,
View
} from 'react-native'
import { TextField } from 'react-native-material-textfield'
import i18n from '../../../i18n'
import { updateUser } from '../../apollo/server'
View,
} from "react-native";
import { TextField } from "react-native-material-textfield";
import i18n from "../../../i18n";
import { updateUser } from "../../apollo/server";
import {
FlashMessage,
RightButton,
TextDefault,
WrapperView
} from '../../components'
import UserContext from '../../context/User'
import { alignment } from '../../utils/alignment'
import { ICONS_NAME } from '../../utils/constant'
import { moderateScale, scale } from '../../utils/scaling'
import { textStyles } from '../../utils/textStyles'
import ChangePassword from './ChangePassword'
import useStyle from './styles'
WrapperView,
} from "../../components";
import UserContext from "../../context/User";
import { alignment } from "../../utils/alignment";
import { ICONS_NAME } from "../../utils/constant";
import { moderateScale, scale } from "../../utils/scaling";
import { textStyles } from "../../utils/textStyles";
import ChangePassword from "./ChangePassword";
import useStyle from "./styles";
const UPDATEUSER = gql`
${updateUser}
`
`;
function Profile() {
const refName = useRef()
const route = useRoute()
const styles = useStyle()
const refPhone = useRef(null)
const { colors } = useTheme()
const navigation = useNavigation()
const refName = useRef();
const route = useRoute();
const styles = useStyle();
const refPhone = useRef(null);
const { colors } = useTheme();
const navigation = useNavigation();
const [nameError, setNameError] = useState('')
const [phoneError, setPhoneError] = useState('')
const [toggleView, setToggleView] = useState(true)
const [modelVisible, setModalVisible] = useState(false)
const [nameError, setNameError] = useState("");
const [phoneError, setPhoneError] = useState("");
const [toggleView, setToggleView] = useState(true);
const [modelVisible, setModalVisible] = useState(false);
const { profile } = useContext(UserContext)
const backScreen = route.params ? route.params.backScreen : null
const { profile } = useContext(UserContext);
const backScreen = route.params ? route.params.backScreen : null;
const [mutate, { loading: loadingMutation }] = useMutation(UPDATEUSER, {
onCompleted,
onError
})
onError,
});
useLayoutEffect(() => {
navigation.setOptions({
title: 'Profile',
title: "Profile",
headerRight: () => (
<RightButton
icon={toggleView ? ICONS_NAME.Pencil : ICONS_NAME.Cross}
onPress={viewHideAndShow}
iconSize={scale(18)}
/>
)
})
}, [navigation, toggleView])
),
});
}, [navigation, toggleView]);
useEffect(() => {
if (backScreen) {
viewHideAndShow()
setPhoneError('Phone number is required')
viewHideAndShow();
setPhoneError("Phone number is required");
FlashMessage({
message: 'Phone Number is missing'
})
message: "Phone Number is missing",
});
}
}, [backScreen])
}, [backScreen]);
function viewHideAndShow() {
setToggleView(prev => !prev)
setToggleView((prev) => !prev);
}
function onCompleted({ updateUser }) {
if (updateUser) {
FlashMessage({
message: "User's Info Updated"
})
message: "User's Info Updated",
});
if (backScreen) {
navigation.goBack()
navigation.goBack();
}
}
}
function validateInfo() {
// clear errors
setNameError('')
setPhoneError('')
setNameError("");
setPhoneError("");
const name = refName.current.value()
const phone = refPhone.current.value()
const name = refName.current.value();
const phone = refPhone.current.value();
if (name === profile.name && phone === profile.phone && phone.length > 0) {
return
return;
}
let res = true
let res = true;
if (!name.trim()) {
refName.current.focus()
setNameError('Name is required')
res = false
refName.current.focus();
setNameError("Name is required");
res = false;
}
const num = phone.trim().replace('.', '')
const num = phone.trim().replace(".", "");
if (num.length < 11 || num.length > 15 || isNaN(num)) {
setPhoneError('Minimum 11 and maximum 15 characters allowed')
setPhoneError("Minimum 11 and maximum 15 characters allowed");
if (res) {
refPhone.current.focus()
refPhone.current.focus();
}
res = false
res = false;
}
return res
return res;
}
function onError(error) {
try {
if (error.graphQLErrors) {
FlashMessage({
message: error.graphQLErrors[0].message
})
message: error.graphQLErrors[0].message,
});
} else if (error.networkError) {
FlashMessage({
message: error.networkError.result.errors[0].message
})
message: error.networkError.result.errors[0].message,
});
}
} catch (err) {}
}
@ -142,7 +142,7 @@ function Profile() {
return (
<View style={styles.containerInfo}>
<TextField
label={i18n.t('name')}
label={i18n.t("name")}
ref={refName}
editable={false}
defaultValue={profile.name}
@ -151,27 +151,27 @@ function Profile() {
style={{
...textStyles.Medium,
...textStyles.H5,
color: colors.fontMainColor
color: colors.fontMainColor,
}}
maxLength={20}
textColor={colors.fontMainColor}
baseColor={colors.fontSecondColor}
errorColor={colors.errorColor}
tintColor={!nameError ? colors.tagColor : 'red'}
tintColor={!nameError ? colors.tagColor : "red"}
labelTextStyle={{
...textStyles.Normal,
paddingTop: scale(1)
paddingTop: scale(1),
}}
error={nameError}
/>
<View style={{ ...alignment.MTxSmall }}></View>
<TextField
keyboardType={'email-address'}
label={i18n.t('email')}
keyboardType={"email-address"}
label={i18n.t("email")}
style={{
...textStyles.Medium,
...textStyles.H5,
color: colors.fontMainColor
color: colors.fontMainColor,
}}
editable={false}
defaultValue={profile.email}
@ -183,20 +183,20 @@ function Profile() {
tintColor={colors.tagColor}
labelTextStyle={{
...textStyles.Normal,
paddingTop: scale(1)
paddingTop: scale(1),
}}
/>
<View style={{ ...alignment.MTxSmall }}></View>
<TextField
keyboardType={'phone-pad'}
label={i18n.t('phone')}
keyboardType={"phone-pad"}
label={i18n.t("phone")}
ref={refPhone}
editable={false}
defaultValue={profile.phone}
style={{
...textStyles.Medium,
...textStyles.H5,
color: colors.fontMainColor
color: colors.fontMainColor,
}}
labelFontSize={scale(12)}
fontSize={scale(12)}
@ -204,25 +204,26 @@ function Profile() {
textColor={colors.fontMainColor}
baseColor={colors.fontSecondColor}
errorColor={colors.errorColor}
tintColor={!phoneError ? colors.tagColor : 'red'}
tintColor={!phoneError ? colors.tagColor : "red"}
labelTextStyle={{
...textStyles.Normal,
paddingTop: scale(1)
paddingTop: scale(1),
}}
error={phoneError}
/>
<TouchableOpacity
onPress={() => setModalVisible(true)}
style={styles.changePassword}>
style={styles.changePassword}
>
<TextDefault>Change Password</TextDefault>
<MaterialCommunityIcons
name={'pencil'}
name={"pencil"}
size={20}
color={colors.tagColor}
/>
</TouchableOpacity>
</View>
)
);
}
return (
@ -230,29 +231,31 @@ function Profile() {
<ChangePassword
modalVisible={modelVisible}
hideModal={() => {
setModalVisible(false)
setModalVisible(false);
}}
/>
<View style={styles.formContainer}>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : null}
style={styles.flex}>
behavior={Platform.OS === "ios" ? "padding" : null}
style={styles.flex}
>
<ScrollView style={styles.flex}>
<View style={[styles.formSubContainer]}>
<View
style={{
width: scale(100),
paddingTop: scale(10),
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
position: "absolute",
alignItems: "center",
justifyContent: "center",
height: scale(100),
top: moderateScale(-50),
borderColor: colors.buttonBackground,
borderWidth: 2,
borderRadius: scale(10),
borderStyle: 'dashed'
}}>
borderStyle: "dashed",
}}
>
<View style={styles.imgContainer}>
<TextDefault textColor={colors.tagColor} bold H1>
{profile.name.substr(0, 1).toUpperCase()}
@ -266,13 +269,13 @@ function Profile() {
<View>
<View style={{ margin: scale(0) }}></View>
<TextField
label={i18n.t('name')}
label={i18n.t("name")}
ref={refName}
defaultValue={profile.name}
style={{
...textStyles.Bold,
...textStyles.H5,
color: colors.fontMainColor
color: colors.fontMainColor,
}}
labelFontSize={scale(12)}
fontSize={scale(12)}
@ -280,21 +283,21 @@ function Profile() {
textColor={colors.fontMainColor}
baseColor={colors.fontSecondColor}
errorColor={colors.errorColor}
tintColor={!nameError ? colors.buttonBackground : 'red'}
tintColor={!nameError ? colors.buttonBackground : "red"}
labelTextStyle={{
...textStyles.Normal,
paddingTop: scale(1)
paddingTop: scale(1),
}}
error={nameError}
/>
<View style={{ ...alignment.MTxSmall }}></View>
<TextField
keyboardType={'email-address'}
label={i18n.t('email')}
keyboardType={"email-address"}
label={i18n.t("email")}
style={{
...textStyles.Bold,
...textStyles.H5,
color: colors.fontMainColor
color: colors.fontMainColor,
}}
editable={false}
defaultValue={profile.email}
@ -306,17 +309,17 @@ function Profile() {
tintColor={colors.buttonBackground}
labelTextStyle={{
...textStyles.Normal,
paddingTop: scale(1)
paddingTop: scale(1),
}}
/>
<View style={{ ...alignment.MTxSmall }}></View>
<TextField
keyboardType={'phone-pad'}
label={i18n.t('phone')}
keyboardType={"phone-pad"}
label={i18n.t("phone")}
style={{
...textStyles.Bold,
...textStyles.H5,
color: colors.fontMainColor
color: colors.fontMainColor,
}}
ref={refPhone}
defaultValue={profile.phone}
@ -326,10 +329,10 @@ function Profile() {
textColor={colors.fontMainColor}
baseColor={colors.fontSecondColor}
errorColor={colors.errorColor}
tintColor={!phoneError ? colors.buttonBackground : 'red'}
tintColor={!phoneError ? colors.buttonBackground : "red"}
labelTextStyle={{
...textStyles.Normal,
paddingTop: scale(1)
paddingTop: scale(1),
}}
error={phoneError}
/>
@ -344,29 +347,34 @@ function Profile() {
mutate({
variables: {
name: refName.current.value(),
phone: refPhone.current.value()
phone: refPhone.current.value(),
is_active: true,
},
});
}
})
}
}}>
}}
>
<TextDefault
textColor={colors.buttonText}
H5
bold
style={[alignment.MTsmall, alignment.MBsmall]}>
{i18n.t('saveBtn')}
style={[alignment.MTsmall, alignment.MBsmall]}
>
{i18n.t("saveBtn")}
</TextDefault>
</TouchableOpacity>
<TouchableOpacity
style={{ alignSelf: 'center', ...alignment.MTsmall }}
style={{ alignSelf: "center", ...alignment.MTsmall }}
activeOpacity={0.7}
onPress={viewHideAndShow}>
onPress={viewHideAndShow}
>
<TextDefault
textColor={colors.fontMainColor}
H5
bold
style={[alignment.MTsmall, alignment.MBsmall]}>
{'Cancel'}
style={[alignment.MTsmall, alignment.MBsmall]}
>
{"Cancel"}
</TextDefault>
</TouchableOpacity>
</View>
@ -375,14 +383,15 @@ function Profile() {
<TextDefault
center
textColor={colors.fontSecondColor}
style={alignment.MBsmall}>
style={alignment.MBsmall}
>
All rights are reserved by Enatega
</TextDefault>
</ScrollView>
</KeyboardAvoidingView>
</View>
</WrapperView>
)
);
}
export default Profile
export default Profile;

View File

@ -16,9 +16,14 @@ import {
TouchableOpacity,
View,
} from "react-native";
import { Modalize } from "react-native-modalize";
import { async } from "validate.js";
import i18n from "../../../i18n";
import { moderateScale } from "../../utils/scaling";
import {
updateUser,
profile,
pushToken,
updateNotificationStatus,
@ -55,12 +60,14 @@ const UPDATE_NOTIFICATION_TOKEN = gql`
const PROFILE = gql`
${profile}
`;
const UPDATEUSER = gql`
${updateUser}
`;
function Settings() {
const styles = useStyle();
const { colors } = useTheme();
const navigation = useNavigation();
const { profile } = useContext(UserContext);
const { profile, logout } = useContext(UserContext);
const [languageName, languageNameSetter] = useState("English");
const [offerNotification, offerNotificationSetter] = useState(
@ -73,6 +80,7 @@ function Settings() {
// eslint-disable-next-line no-unused-vars
const [appState, setAppState] = useState(AppState.currentState);
const [uploadToken] = useMutation(PUSH_TOKEN);
const [updateUserInfo] = useMutation(UPDATEUSER);
const [mutate, { loading }] = useMutation(UPDATE_NOTIFICATION_TOKEN, {
onCompleted,
onError,
@ -204,6 +212,16 @@ function Settings() {
});
}
async function updateUserInformation() {
console.log("profile data", profile);
updateUserInfo({
variables: {
name: profile.name,
phone: profile.phone,
is_active: false,
},
});
}
return (
<WrapperView>
{loading && (
@ -289,6 +307,34 @@ function Settings() {
/>
</View>
</TouchableOpacity>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => modalizeRef.current.open("top")}
// onPress={
// async () => {
// await updateUserInformation();
// logout();
// navigation.reset({
// routes: [{ name: "Menu" }],
// }
// );
// //navigation.dispatch(DrawerActions.closeDrawer());
// }}
style={[styles.notificationContainer, styles.shadow]}
>
<View style={styles.notificationChekboxContainer}>
<TextDefault numberOfLines={1} textColor={"red"}>
{" "}
Delete Account{" "}
</TextDefault>
<CustomIcon
name={ICONS_NAME.Trash}
size={scale(28)}
color={"red"}
/>
</View>
</TouchableOpacity>
<View style={styles.versionContainer}>
<TextDefault textColor={colors.fontSecondColor}>
Version: {Constants.manifest.version}
@ -322,6 +368,52 @@ function Settings() {
activeRadio={activeRadio}
/>
</Modalize>
{/* Modal for Delete Account */}
<Modalize
ref={modalizeRef}
adjustToContentHeight
handlePosition="inside"
avoidKeyboardLikeIOS={Platform.select({
ios: true,
android: true,
})}
keyboardAvoidingOffset={2}
keyboardAvoidingBehavior="height"
>
<View style={{ flex: 1, alignItems: "center" }}>
<TextDefault bolder H5 style={{ marginTop: 20 }}>
Are you Sure you want to delete Account?
</TextDefault>
<TouchableOpacity
activeOpacity={0.7}
style={{
justifyContent: "center",
alignItems: "center",
backgroundColor: colors.buttonBackgroundBlue,
borderRadius: moderateScale(10),
width: "70%",
padding: moderateScale(15),
...alignment.MTlarge,
}}
onPress={async () => {
await updateUserInformation();
logout();
navigation.reset({
routes: [{ name: "Menu" }],
});
}}
>
<TextDefault center>Delete Account</TextDefault>
</TouchableOpacity>
<TouchableOpacity
activeOpacity={0.7}
style={[styles.width100, alignment.PBlarge, alignment.PTlarge]}
onPress={() => onClose()}
>
<TextDefault center>Cancel</TextDefault>
</TouchableOpacity>
</View>
</Modalize>
</WrapperView>
);
}

View File

@ -1,24 +1,24 @@
import { useTheme } from '@react-navigation/native'
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import { TouchableOpacity, View } from 'react-native'
import RadioButton from '../../../components/FdRadioBtn/RadioBtn'
import TextDefault from '../../../components/Text/TextDefault/TextDefault'
import { alignment } from '../../../utils/alignment'
import useStyle from './styles'
import { useTheme } from "@react-navigation/native";
import PropTypes from "prop-types";
import React, { useState } from "react";
import { TouchableOpacity, View } from "react-native";
import RadioButton from "../../../components/FdRadioBtn/RadioBtn";
import TextDefault from "../../../components/Text/TextDefault/TextDefault";
import { alignment } from "../../../utils/alignment";
import useStyle from "./styles";
const languageTypes = [
{ value: 'English', code: 'en', index: 0 },
{ value: 'français', code: 'fr', index: 1 },
{ value: 'ភាសាខ្មែរ', code: 'km', index: 2 },
{ value: '中文', code: 'zh', index: 3 },
{ value: 'Deutsche', code: 'de', index: 4 }
]
{ value: "English", code: "en", index: 0 },
{ value: "français", code: "fr", index: 1 },
{ value: "ភាសាខ្មែរ", code: "km", index: 2 },
{ value: "中文", code: "zh", index: 3 },
{ value: "Deutsche", code: "de", index: 4 },
];
function SettingModal(props) {
const styles = useStyle()
const { colors } = useTheme()
const [activeRadio, activeRadioSetter] = useState(props.activeRadio)
const styles = useStyle();
const { colors } = useTheme();
const [activeRadio, activeRadioSetter] = useState(props.activeRadio);
return (
<View style={styles.flex}>
@ -31,12 +31,13 @@ function SettingModal(props) {
activeOpacity={0.7}
key={item.index}
onPress={() => activeRadioSetter(item.index)}
style={[styles.radioContainer]}>
style={[styles.radioContainer]}
>
<TextDefault numberOfLines={1} bold style={alignment.MLsmall}>
{item.value}
</TextDefault>
<RadioButton
animation={'bounceIn'}
animation={"bounceIn"}
size={13}
outerColor={colors.radioOuterColor}
innerColor={colors.radioColor}
@ -51,7 +52,8 @@ function SettingModal(props) {
<TouchableOpacity
activeOpacity={0.7}
style={styles.button}
onPress={() => props.onSelectedLanguage(activeRadio)}>
onPress={() => props.onSelectedLanguage(activeRadio)}
>
<TextDefault textColor={colors.lightBackground} bolder uppercase>
Done
</TextDefault>
@ -59,17 +61,18 @@ function SettingModal(props) {
<TouchableOpacity
activeOpacity={0.7}
style={[styles.width100, alignment.PBlarge, alignment.PTlarge]}
onPress={() => props.onClose()}>
onPress={() => props.onClose()}
>
<TextDefault center>Cancel</TextDefault>
</TouchableOpacity>
{/* </View> */}
</View>
)
);
}
SettingModal.propTypes = {
activeRadio: PropTypes.number,
onSelectedLanguage: PropTypes.func,
onClose: PropTypes.func
}
export default SettingModal
onClose: PropTypes.func,
};
export default SettingModal;