Commit cc533bed authored by devinmunasinghe's avatar devinmunasinghe

resolve-conflicts

parents c8cb6562 828c667b
{
"java.compile.nullAnalysis.mode": "automatic"
}
\ No newline at end of file
......@@ -7,14 +7,15 @@ LogBox.ignoreAllLogs();
const App = () => {
// Your Firebase project config
const firebaseConfig = {
apiKey: "AIzaSyDYUf2gYWwE_qvQk2e-8ErEZ_PYBZ7eX0o",
authDomain: "emidwife-382f9.firebaseapp.com",
databaseURL: "https://emidwife-382f9-default-rtdb.asia-southeast1.firebasedatabase.app",
projectId: "emidwife-382f9",
storageBucket: "emidwife-382f9.appspot.com",
messagingSenderId: "586342030256",
appId: "1:586342030256:web:a88085b0dd2a72a953d475"
apiKey: "AIzaSyCeAB4zi1RAoBPPJyE6qii36pz01tfKrYQ",
authDomain: "esp32-emidwife.firebaseapp.com",
databaseURL: "https://esp32-emidwife-default-rtdb.firebaseio.com",
projectId: "esp32-emidwife",
storageBucket: "esp32-emidwife.appspot.com",
messagingSenderId: "590307045316",
appId: "1:590307045316:web:3471bfeaec9f74f6dcbe91"
};
// Initialize Firebase
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
......
......@@ -85,6 +85,15 @@ android {
versionName "1.0"
}
signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
debug {
storeFile file('debug.keystore')
storePassword 'android'
......@@ -99,7 +108,7 @@ android {
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- optionally, if you want to record audio: -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
......
......@@ -39,3 +39,8 @@ newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=midwife
MYAPP_UPLOAD_KEY_PASSWORD=midwife
\ No newline at end of file
......@@ -30,6 +30,7 @@
"react-native-safe-area-context": "^4.10.1",
"react-native-screens": "^3.31.1",
"react-native-snap-carousel-v4": "^1.0.1",
"react-native-sound": "^0.11.2",
"react-native-svg": "^15.2.0",
"react-native-svg-transformer": "^1.3.0",
"react-native-vector-icons": "^10.1.0",
......@@ -50,6 +51,7 @@
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-native-image-picker": "^7.1.1",
"react-test-renderer": "18.2.0",
"typescript": "5.0.4"
},
......@@ -165,6 +167,7 @@
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz",
"integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==",
"dev": true,
"dependencies": {
"@babel/types": "^7.22.15"
},
......@@ -474,6 +477,7 @@
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz",
"integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==",
"dev": true,
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-plugin-utils": "^7.24.5"
......@@ -489,6 +493,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz",
"integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -503,6 +508,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz",
"integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
......@@ -519,6 +525,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz",
"integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==",
"dev": true,
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -667,6 +674,7 @@
"version": "7.21.0-placeholder-for-preset-env.2",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
"dev": true,
"engines": {
"node": ">=6.9.0"
},
......@@ -701,6 +709,7 @@
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
"integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13"
},
......@@ -712,6 +721,7 @@
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
"integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
},
......@@ -751,6 +761,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
"integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.3"
},
......@@ -776,6 +787,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz",
"integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -790,6 +802,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz",
"integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -804,6 +817,7 @@
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
"integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
},
......@@ -815,6 +829,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
"integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
......@@ -840,6 +855,7 @@
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
"integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
},
......@@ -920,6 +936,7 @@
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
"integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
},
......@@ -948,6 +965,7 @@
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
"integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
"dev": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
"@babel/helper-plugin-utils": "^7.18.6"
......@@ -977,6 +995,7 @@
"version": "7.24.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz",
"integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==",
"dev": true,
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-plugin-utils": "^7.24.0",
......@@ -1010,6 +1029,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz",
"integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1038,6 +1058,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz",
"integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==",
"dev": true,
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.24.1",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -1053,6 +1074,7 @@
"version": "7.24.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz",
"integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==",
"dev": true,
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.24.4",
"@babel/helper-plugin-utils": "^7.24.0",
......@@ -1119,6 +1141,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz",
"integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==",
"dev": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.15",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -1134,6 +1157,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz",
"integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1148,6 +1172,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz",
"integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3"
......@@ -1163,6 +1188,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz",
"integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==",
"dev": true,
"dependencies": {
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -1178,6 +1204,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz",
"integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-export-namespace-from": "^7.8.3"
......@@ -1208,6 +1235,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz",
"integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
......@@ -1239,6 +1267,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz",
"integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-json-strings": "^7.8.3"
......@@ -1268,6 +1297,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz",
"integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
......@@ -1283,6 +1313,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz",
"integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1297,6 +1328,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz",
"integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==",
"dev": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.23.3",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -1328,6 +1360,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz",
"integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==",
"dev": true,
"dependencies": {
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-module-transforms": "^7.23.3",
......@@ -1345,6 +1378,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz",
"integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==",
"dev": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.23.3",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -1375,6 +1409,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz",
"integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1389,6 +1424,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz",
"integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
......@@ -1404,6 +1440,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz",
"integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-numeric-separator": "^7.10.4"
......@@ -1419,6 +1456,7 @@
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz",
"integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==",
"dev": true,
"dependencies": {
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-plugin-utils": "^7.24.5",
......@@ -1436,6 +1474,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz",
"integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/helper-replace-supers": "^7.24.1"
......@@ -1451,6 +1490,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz",
"integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
......@@ -1466,6 +1506,7 @@
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz",
"integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.5",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
......@@ -1528,6 +1569,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz",
"integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1602,6 +1644,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz",
"integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0",
"regenerator-transform": "^0.15.2"
......@@ -1617,6 +1660,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz",
"integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1693,6 +1737,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz",
"integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1707,6 +1752,7 @@
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz",
"integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.5"
},
......@@ -1738,6 +1784,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz",
"integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.0"
},
......@@ -1752,6 +1799,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz",
"integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==",
"dev": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.15",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -1782,6 +1830,7 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz",
"integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==",
"dev": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.15",
"@babel/helper-plugin-utils": "^7.24.0"
......@@ -1797,6 +1846,7 @@
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz",
"integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.24.4",
"@babel/helper-compilation-targets": "^7.23.6",
......@@ -1907,6 +1957,7 @@
"version": "0.1.6-no-external-plugins",
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
"integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/types": "^7.4.4",
......@@ -3210,6 +3261,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-native-community/cli-config/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@react-native-community/cli-config/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
......@@ -3313,6 +3372,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-native-community/cli-doctor/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@react-native-community/cli-doctor/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
......@@ -3898,6 +3965,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-native-community/cli/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@react-native-community/cli/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
......@@ -4348,22 +4423,6 @@
"react": "*"
}
},
"node_modules/@react-navigation/core/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-navigation/core/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/@react-navigation/elements": {
"version": "1.3.30",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.30.tgz",
......@@ -4390,17 +4449,6 @@
"react-native": "*"
}
},
"node_modules/@react-navigation/native/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-navigation/routers": {
"version": "6.1.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
......@@ -4794,6 +4842,14 @@
}
}
},
"node_modules/@svgr/plugin-svgo/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@svgr/plugin-svgo/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
......@@ -6035,6 +6091,14 @@
"node": ">=4"
}
},
"node_modules/chalk/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/char-regex": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
......@@ -6061,17 +6125,6 @@
"node": ">=12.13.0"
}
},
"node_modules/chrome-launcher/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/chromium-edge-launcher": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz",
......@@ -6085,17 +6138,6 @@
"rimraf": "^3.0.2"
}
},
"node_modules/chromium-edge-launcher/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/chromium-edge-launcher/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
......@@ -6749,9 +6791,9 @@
"dev": true
},
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
"engines": {
"node": ">=0.10.0"
}
......@@ -7216,11 +7258,14 @@
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=0.8.0"
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint": {
......@@ -7309,6 +7354,15 @@
"eslint": ">=4.19.1"
}
},
"node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/eslint-plugin-ft-flow": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-ft-flow/-/eslint-plugin-ft-flow-2.0.3.tgz",
......@@ -7548,18 +7602,6 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/eslint/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint/node_modules/eslint-scope": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
......@@ -7772,6 +7814,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
......@@ -8240,14 +8283,6 @@
"react": ">=16.8.0"
}
},
"node_modules/formik/node_modules/deepmerge": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
......@@ -8611,11 +8646,6 @@
"react-is": "^16.7.0"
}
},
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hsluv": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/hsluv/-/hsluv-0.0.3.tgz",
......@@ -9736,6 +9766,15 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/jest-config/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/jest-config/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
......@@ -12812,6 +12851,11 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/pretty-format/node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
......@@ -12847,11 +12891,6 @@
"react-is": "^16.13.1"
}
},
"node_modules/prop-types/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
......@@ -12981,9 +13020,9 @@
}
},
"node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-native": {
"version": "0.73.6",
......@@ -13082,6 +13121,16 @@
"react-native": "*"
}
},
"node_modules/react-native-image-picker": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-7.1.2.tgz",
"integrity": "sha512-b5y5nP60RIPxlAXlptn2QwlIuZWCUDWa/YPUVjgHc0Ih60mRiOg1PSzf0IjHSLeOZShCpirpvSPGnDExIpTRUg==",
"dev": true,
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-linear-gradient": {
"version": "2.8.3",
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
......@@ -13107,27 +13156,6 @@
"react-native": "*"
}
},
"node_modules/react-native-reanimated": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.11.0.tgz",
"integrity": "sha512-BNw/XDgUfs8UhfY1X6IniU8kWpnotWGyt8qmQviaHisTi5lvwnaOdXQKfN1KGONx6ekdFRHRP5EFwLi0UajwKA==",
"peer": true,
"dependencies": {
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0",
"@babel/plugin-transform-optional-chaining": "^7.0.0-0",
"@babel/plugin-transform-shorthand-properties": "^7.0.0-0",
"@babel/plugin-transform-template-literals": "^7.0.0-0",
"@babel/preset-typescript": "^7.16.7",
"convert-source-map": "^2.0.0",
"invariant": "^2.2.4"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0",
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-redash": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/react-native-redash/-/react-native-redash-18.1.3.tgz",
......@@ -13179,6 +13207,14 @@
"react-native": ">=0.58.0"
}
},
"node_modules/react-native-sound": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.11.2.tgz",
"integrity": "sha512-LmGc8lgOK3qecYMVQpyHvww/C+wgT6sWeMpVbOe4NCRGC2yKd4fo4U0KBUo9PO7AqKESO3I/2GZg1/C0+bwiiA==",
"peerDependencies": {
"react-native": ">=0.8.0"
}
},
"node_modules/react-native-svg": {
"version": "15.2.0",
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.2.0.tgz",
......@@ -13469,6 +13505,12 @@
"react": "^18.2.0"
}
},
"node_modules/react-test-renderer/node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"dev": true
},
"node_modules/react-test-renderer/node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
......@@ -13556,6 +13598,7 @@
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
"integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.8.4"
}
......@@ -14764,7 +14807,7 @@
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"devOptional": true,
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
......@@ -15253,4 +15296,4 @@
}
}
}
}
}
\ No newline at end of file
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
const RadioButton = ({label, selected, onPress, textColor}) => (
<TouchableOpacity onPress={onPress}>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<View
style={{
width: 20,
height: 20,
borderRadius: 10,
borderWidth: 2,
borderColor: selected ? '#0047AB' : 'gray',
marginRight: 10,
justifyContent: 'center',
alignItems: 'center',
}}>
{selected && (
<View
style={{
width: 10,
height: 10,
borderRadius: 5,
backgroundColor: 'black',
}}
/>
)}
</View>
<Text
style={{
color: '#0047AB',
fontSize: 15,
fontWeight: 'bold',
color: textColor || '#000',
}}>
{label}
</Text>
</View>
</TouchableOpacity>
);
export default RadioButton;
......@@ -9,4 +9,16 @@ export default {
gray: '#666666',
grayLight: '#ccc',
black: '#0a0a0a',
blue: '#ADC4CE',
navyBlue: '#000080',
purple: '#DFCCFB',
light_purple: '#D9ACF5',
dark_purple: '#BEADFA',
pink: '#EF9595',
normal_purple: '#80558C',
rose: '#FFACC7',
pastalBlue: '#D2E9E9',
purple_new: '#AC87C5',
pink_new: '#FF8080',
pastal_blue: '#7469B6',
};
......@@ -5,4 +5,65 @@ export default {
ex_2: require('../assets/ex_2.jpg'),
ex_3: require('../assets/ex_3.jpg'),
ex_4: require('../assets/ex_4.jpg'),
sk_1: require('../assets/sk_1.png'),
sk_2: require('../assets/sk_2.png'),
sk_3: require('../assets/sk_3.png'),
sk_7: require('../assets/sk_7.png'),
sk_5: require('../assets/sk_5.png'),
sk_8: require('../assets/sk_8.png'),
sk_9: require('../assets/sk_9.png'),
sk_14: require('../assets/sk_14.jpg'),
sk_15: require('../assets/sk_15.png'),
sk_16: require('../assets/sk_16.png'),
//games
game_img_1: require('../assets/game_img_1.png'),
game_img_2: require('../assets/game_img_2.png'),
game_img_3: require('../assets/Game01.jpg'),
game_img_4: require('../assets/Game02.jpg'),
game_img_5: require('../assets/score_background.png'),
game_img_6: require('../assets/gameBackground.jpg'),
game_img_7: require('../assets/Game02background.jpg'),
game_img_8: require('../assets/game03background.jpg'),
game_img_9: require('../assets/rockpapergame.jpeg'),
game_img_10: require('../assets/rock.png'),
game_img_11: require('../assets/paper.png'),
game_img_12: require('../assets/scissors.png'),
game_img_13: require('../assets/baby.png'),
game_img_14: require('../assets/cart.png'),
game_img_15: require('../assets/background06.jpeg'),
game_img_16: require('../assets/shoes.png'),
game_img_17: require('../assets/cloths.png'),
game_img_18: require('../assets/shoppingCart.png'),
game_img_19: require('../assets/games/Spinach.png'),
game_img_20: require('../assets/games/Candy.png'),
game_img_21: require('../assets/games/Carrot.png'),
game_img_22: require('../assets/games/FrenchFries.png'),
game_img_23: require('../assets/games/Tomato.png'),
game_img_24: require('../assets/games/Doughnut.png'),
game_img_25: require('../assets/games/Fruits.png'),
game_img_26: require('../assets/games/Eggs.png'),
game_img_27: require('../assets/games/Milk.png'),
game_img_28: require('../assets/games/Water.png'),
game_img_29: require('../assets/games/Hotdogs.png'),
game_img_30: require('../assets/games/Oats.png'),
game_img_31: require('../assets/games/level0201.png'),
game_img_32: require('../assets/games/level0202.png'),
game_img_33: require('../assets/games/level0203.png'),
game_img_34: require('../assets/games/level0204.png'),
game_img_35: require('../assets/games/level0205.png'),
game_img_36: require('../assets/games/level0206.png'),
game_img_37: require('../assets/games/level0207.png'),
game_img_38: require('../assets/games/level0208.png'),
game_img_39: require('../assets/games/level0209.png'),
game_img_40: require('../assets/games/level0210.png'),
game_img_41: require('../assets/games/level0211.png'),
game_img_42: require('../assets/games/level0212.png'),
game_img_43: require('../assets/games/baby02.png'),
game_img_44: require('../assets/games/game02Backgroundnew.jpeg'),
game_img_45: require('../assets/games/game02Backgroundnew02.jpeg'),
home_page: require('../assets/home_page.png'),
well_being: require('../assets/games/wellBeing.jpg'),
motherWithMidWife: require('../assets/games/motherAndMidWife.jpg'),
};
......@@ -20,7 +20,69 @@ export default {
EXERCISE_HOME: 'Exercise_Home',
EXERCISE_FORM: 'Health_Form',
EXERCISE_MAIN_MENU: 'Exercise_Home_Menu',
EXERCISE_MAIN_NEW_MENU: 'Exercise_Home_New_Menu',
EXERCISE_VIEW: 'Exercise_View',
EXERCISE_ACTION_VIEW: 'Exercise_ACTION_View',
EXERCISE_PROGRESS: 'Exercise_PROGRESS'
EXERCISE_PROGRESS: 'Exercise_PROGRESS',
EXERCISE_NEW_VIEW: 'Exercise_NEW_View',
EXERCISE_NEW_ACTION_VIEW: 'Exercise_NEW_ACTION_View',
EXERCISE_NEW_PROGRESS: 'Exercise_NEW_PROGRESS',
//skin
SKIN_WELCOME: 'Skin_Welcome',
SKIN_UPLOAD: 'Skin_Upload',
SKIN_RISK: 'Skin_Risk',
SKIN_VIDEO: 'Skin_Video',
SKIN_VIDEO1: 'Skin_Video1',
SKIN_VIDEO2: 'Skin_Video2',
SKIN_VIDEO3: 'Skin_Video3',
SKIN_VIDEO4: 'Skin_Video4',
SKIN_VIDEO5: 'Skin_Video5',
SKIN_INFO:'skin_info',
//GAMES
GAME_HOME: 'Game_Home',
GAME_WELCOME: 'Game_Welcome',
GAME_FORM: 'Game_Form',
GAME_MAIN_MENU: 'Game_Home_Menu',
GAME_VIEW: 'Game_View',
GAME_QUIZ_OPTIONS: 'Game_Quiz_Options',
GAME_QUIZ_IN_ENGLISH: 'Game_Quiz_In_English',
GAME_QUIZ_IN_SINHALA: 'Game_Quiz_In_Sinhala',
GAME_MAIN_DETAILS: 'Main_Details_Form',
QUIZ_SCORE: 'Quiz_Score',
CHOOSE_GAME: 'Choose_Game',
Level01Instructions: 'Level01Instructions',
GameLevel1: 'GameLevel1',
GameLevel2: 'GameLevel2',
GameLevel3: 'GameLevel3',
GameLevel4: 'GameLevel4',
GameLevel5: 'GameLevel5',
GameLevel6: 'GameLevel6',
GameLevel0: 'GameLevel0',
Game02Level01: 'Game02Level01',
CravingsPuzzleGame02Level02: 'CravingsPuzzleGame02Level02',
PuzzleGame02Level03: 'PuzzleGame02Level03',
Game02Level04: 'Game02Level04',
Game02Level05: 'Game02Level05',
Game02Level06: 'Game02Level06',
Game02Level07: 'Game02Level07',
GameLevelPage: 'GameLevelPage',
MainDetailsFormInSinhala: 'MainDetailsFormInSinhala',
Level01: 'Level01',
Level02: 'Level02',
Level03: 'Level03',
Level04: 'Level04',
Level05: 'Level05',
Level06: 'Level06',
Game02ProgressLevel01: 'Game02ProgressLevel01',
Game02ProgressLevel02: 'Game02ProgressLevel02',
Game02ProgressLevel03: 'Game02ProgressLevel03',
Game02ProgressLevel04: 'Game02ProgressLevel04',
Game02ProgressLevel05: 'Game02ProgressLevel05',
Game02ProgressLevel06: 'Game02ProgressLevel06',
MentalWellBeingTypes: 'MentalWellBeingTypes',
};
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Home from '../screens/home/Home';
import Wallet from '../screens/home/Wallet';
import Settings from '../screens/home/Settings';
import WelcomeExercise from '../screens/home/exercise/WelcomeExercise';
import Settings from '../screens/home/Settings';
import WelcomeExercise from '../screens/home/exercise/WelcomeExercise';
// import { Home, Wallet, Settings, WelcomeExercise} from '../screens';
import ExerciseNavigator from './ExerciseNavigator'
import SkinNavigator from './SkinNavigator';
import {COLORS, ROUTES} from '../constants';
import Icon from 'react-native-vector-icons/Ionicons';
import { StyleSheet } from 'react-native';
import {StyleSheet} from 'react-native';
import CustomTabBarButton from '../components/CustomTabBarButton';
import CustomTabBar from '../components/CustomTabBar';
import Logo from '../assets/icons/fitness1.svg';
import Logo1 from '../assets/icons/fitness2.svg';
import { Button, TextInput, View,SafeAreaView,KeyboardAvoidingView} from 'react-native';
import GameNavigator from './GameNavigator';
import AuthNavigator from './AuthNavigator';
const Tab = createBottomTabNavigator();
function BottomTabNavigator() {
return (
// <KeyboardAvoidingView>
<Tab.Navigator
tabBar={props => <CustomTabBar {...props} />}
screenOptions={({route}) =>({
tabBarHideOnKeyboard: true,
headerShown: false,
tabBarStyle: styles.tabBarStyle,
tabBarInactiveTintColor: COLORS.dark,
tabBarActiveTintColor: COLORS.primary,
tabBarShowLabel:false,
tabBarIcon: ({color, size, focused}) =>
{
if (route.name === ROUTES.HOME_TAB) {
return focused ? <Icon name='home' size={22} color={color} /> :<Icon name='home-outline' size={22} color={color} />;
} else if (route.name === ROUTES.EXERCISE_HOME) {
return focused ? <Logo1 width={22} height={22} /> : <Logo width={22} height={22} /> ;
} else if (route.name === ROUTES.WALLET) {
return focused ? <Icon name='wallet' size={22} color={color} /> :<Icon name='wallet-outline' size={22} color={color} />;
} else if (route.name === ROUTES.SETTINGS) {
return focused ? <Icon name='notifications-sharp' size={22} color={color} /> :<Icon name='notifications-outline' size={22} color={color} />;
}
}
})}>
<Tab.Screen name={ROUTES.HOME_TAB} component={Home}
options={{
tabBarButton: props => <CustomTabBarButton {...props} />,
}}
/>
<Tab.Screen name={ROUTES.SETTINGS} component={Settings}
options={{
tabBarButton: props => <CustomTabBarButton {...props} />,
}}/>
<Tab.Screen name={ROUTES.WALLET} component={Wallet}
options={{
tabBarButton: props => <CustomTabBarButton {...props} />,
}}/>
<Tab.Screen options={{
tabBar={props => <CustomTabBar {...props} />}
screenOptions={({route}) => ({
tabBarHideOnKeyboard: true,
headerShown: false,
headerBackTitleVisible: false,
tabBarButton: props => <CustomTabBarButton {...props} />,
tabBarStyle: styles.tabBarStyle,
tabBarInactiveTintColor: COLORS.dark,
tabBarActiveTintColor: COLORS.primary,
tabBarShowLabel: false,
tabBarIcon: ({color, size, focused}) => {
if (route.name === ROUTES.HOME_TAB) {
return focused ? (
<Icon name="home-sharp" size={22} color={color} />
) : (
<Icon name="home-outline" size={22} color={color} />
);
} else if (route.name === ROUTES.SKIN_WELCOME) {
return focused ? (
<Icon name="pulse-sharp" size={22} color={color} />
) : (
<Icon name="pulse-outline" size={22} color={color} />
);
} else if (route.name === ROUTES.EXERCISE_HOME) {
return focused ? (
<Logo1 width={22} height={22} />
) : (
<Logo width={22} height={22} />
);
} else if (route.name === ROUTES.GAME_HOME) {
return focused ? (
<Icon name="game-controller-sharp" size={22} color={color}/>
) : (
<Icon name="game-controller-outline" size={22} color={color}/>
);
} else if (route.name === ROUTES.LOGIN) {
return focused ? (
<Icon name="person-circle-sharp" size={22} color={color} />
) : (
<Icon name="person-circle-outline" size={22} color={color} />
);
}
},
})}>
<Tab.Screen
name={ROUTES.HOME_TAB}
component={Home}
options={{
tabBarButton: props => <CustomTabBarButton {...props} />,
}}
/>
<Tab.Screen
name={ROUTES.SKIN_WELCOME}
component={SkinNavigator}
options={{
tabBarButton: props => <CustomTabBarButton {...props} />,
}}
name={ROUTES.EXERCISE_HOME} component={ExerciseNavigator} />
/>
<Tab.Screen
name={ROUTES.GAME_HOME}
component={GameNavigator}
options={{
tabBarButton: props => <CustomTabBarButton {...props} />,
}}
/>
<Tab.Screen
options={{
headerShown: false,
headerBackTitleVisible: false,
tabBarButton: props => <CustomTabBarButton {...props} />,
}}
name={ROUTES.EXERCISE_HOME}
component={ExerciseNavigator}
/>
<Tab.Screen
options={{
headerShown: false,
headerBackTitleVisible: false,
tabBarButton: props => <CustomTabBarButton {...props} />,
}}
name={ROUTES.LOGIN}
component={AuthNavigator}
/>
</Tab.Navigator>
// </KeyboardAvoidingView>
);
......@@ -73,14 +115,14 @@ const styles = StyleSheet.create({
backgroundColor: 'rgba(255,255,255,0.1)',
borderTopWidth: 0,
borderColor: COLORS.white,
bottom: 5,
right: 10,
left: 10,
height: 58
bottom: 0,
right: 0,
left: 0,
height: 58,
},
mr7: {
color: COLORS.primary,
stroke: COLORS.primary,
fill: COLORS.primary
}
})
\ No newline at end of file
fill: COLORS.primary,
},
});
......@@ -68,7 +68,10 @@ function ExerciseNavigator() {
<>
<Stack.Screen name={ROUTES.EXERCISE_WELCOME} component={WelcomeExercise} key="ExerciseWelcome" />
<Stack.Screen name={ROUTES.EXERCISE_FORM} component={HealthFormExercise} key="ExerciseForm" />
<Stack.Screen name={ROUTES.EXERCISE_MAIN_MENU} component={MainMenuExercise} key="MainMenuExercise" />
<Stack.Screen name={ROUTES.EXERCISE_MAIN_NEW_MENU} component={MainMenuExercise} key="MainMenuNewExercise" />
<Stack.Screen name={ROUTES.EXERCISE_NEW_VIEW} component={ExerciseView} key="ExerciseNewView" />
<Stack.Screen name={ROUTES.EXERCISE_NEW_ACTION_VIEW} component={ExerciseActionView} key="ExerciseActionNewView" />
<Stack.Screen name={ROUTES.EXERCISE_NEW_PROGRESS} component={ExercisesProgress} key="ExercisesNewProgress" />
</>
)}
</Stack.Navigator>
......
import React from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import WelcomeExercise from '../screens/home/exercise/WelcomeExercise';
import HealthFormExercise from '../screens/home/exercise/HealthFormExercise';
import MainMenuExercise from '../screens/home/exercise/MainMenuExercise';
import ExerciseView from '../screens/home/exercise/ExerciseView';
import {COLORS, ROUTES} from '../constants';
import WelcomePageGame from '../screens/home/game/WelcomeGame';
import QuizOptionsPage from '../screens/home/game/QuizOptions';
import QuestionInEnglishPage from '../screens/home/game/QuestionsInEnglish';
import QuestionInSinhalaPage from '../screens/home/game/QuestionsInShinhala';
import MainDetailsForm from '../screens/home/game/MainDetailsForm';
import QuizScoreDisplayPage from '../screens/home/game/QuizScore';
import ChooseGame from '../screens/home/game/ChooseGame';
import Level01InstructionsPage from '../screens/home/game/game01/Level01Instructions';
import GameLevel1 from '../screens/home/game/game01/GameLevel1';
import CandyCrushGameLevel02 from '../screens/home/game/game01/GameLevel2';
import CandyCrushGameLevel03 from '../screens/home/game/game01/GameLevel3';
import CandyCrushGameLevel04 from '../screens/home/game/game01/GameLevel04';
import GameLevel5 from '../screens/home/game/game01/GameLevel5';
import GameLevel6 from '../screens/home/game/game01/GameLevel6';
import GameLevel0 from '../screens/home/game/game01/GameLevel0';
import Game02Level01 from '../screens/home/game/game02/level01';
import CravingsPuzzleGame02Level02 from '../screens/home/game/game02/level02';
import PuzzleGame02Level03 from '../screens/home/game/game02/level03';
import Game02Level04 from '../screens/home/game/game02/level04';
import Game02Level05 from '../screens/home/game/game02/level05';
import Game02Level06 from '../screens/home/game/game02/level06';
import Game02Level07 from '../screens/home/game/game02/level07';
import GameLevelPage from '../screens/home/game/GameLevelPage';
import MainDetailsFormInSinhala from '../screens/home/game/MainDetailsFormInSinhala';
import Level01 from '../screens/home/game/game01/progress/Level01';
import Level02 from '../screens/home/game/game01/progress/Level02';
import Level03 from '../screens/home/game/game01/progress/Level03';
import Level04 from '../screens/home/game/game01/progress/Level04';
import Level05 from '../screens/home/game/game01/progress/Level05';
import Level06 from '../screens/home/game/game01/progress/Level06';
import Game02ProgressLevel01 from '../screens/home/game/game02/progress/Level01';
import Game02ProgressLevel02 from '../screens/home/game/game02/progress/Level02';
import Game02ProgressLevel03 from '../screens/home/game/game02/progress/Level03';
import Game02ProgressLevel04 from '../screens/home/game/game02/progress/Level04';
import Game02ProgressLevel05 from '../screens/home/game/game02/progress/Level05';
import Game02ProgressLevel06 from '../screens/home/game/game02/progress/Level06';
import MentalWellBeingTypes from '../screens/home/game/MentalWellBeingTypes';
const Stack = createStackNavigator();
function GameNavigator() {
return (
<Stack.Navigator
screenOptions={{
headerBackTitleVisible: false,
headerShown: false,
}}
initialRouteName={ROUTES.EXERCISE_MAIN_MENU}>
<Stack.Screen name={ROUTES.GAME_WELCOME} component={WelcomePageGame} />
<Stack.Screen
name={ROUTES.GAME_QUIZ_OPTIONS}
component={QuizOptionsPage}
/>
<Stack.Screen
name={ROUTES.GAME_QUIZ_IN_ENGLISH}
component={QuestionInEnglishPage}
/>
<Stack.Screen
name={ROUTES.GAME_QUIZ_IN_SINHALA}
component={QuestionInSinhalaPage}
/>
<Stack.Screen name={ROUTES.GAME_FORM} component={HealthFormExercise} />
<Stack.Screen name={ROUTES.GAME_MAIN_MENU} component={MainMenuExercise} />
<Stack.Screen name={ROUTES.GAME_VIEW} component={ExerciseView} />
<Stack.Screen name={ROUTES.QUIZ_SCORE} component={QuizScoreDisplayPage} />
<Stack.Screen name={ROUTES.CHOOSE_GAME} component={ChooseGame} />
{/* {/* <Stack.Screen name={ROUTES.CHOOSE_GAME} component={ChooseGame} /> */}
{/* <Stack.Screen name={ROUTES.CHOOSE_GAME} component={ChooseGame} />
<Stack.Screen name={ROUTES.CHOOSE_GAME} component={ChooseGame} /> */}
<Stack.Screen name={ROUTES.GameLevel1} component={GameLevel1} />
<Stack.Screen
name={ROUTES.GameLevel2}
component={CandyCrushGameLevel02}
/>
<Stack.Screen
name={ROUTES.GameLevel3}
component={CandyCrushGameLevel03}
/>
<Stack.Screen
name={ROUTES.GameLevel4}
component={CandyCrushGameLevel04}
/>
<Stack.Screen name={ROUTES.GameLevel5} component={GameLevel5} />
<Stack.Screen name={ROUTES.GameLevel0} component={GameLevel0} />
<Stack.Screen name={ROUTES.GameLevel6} component={GameLevel6} />
<Stack.Screen name={ROUTES.Game02Level01} component={Game02Level01} />
<Stack.Screen
name={ROUTES.CravingsPuzzleGame02Level02}
component={CravingsPuzzleGame02Level02}
/>
<Stack.Screen
name={ROUTES.PuzzleGame02Level03}
component={PuzzleGame02Level03}
/>
<Stack.Screen name={ROUTES.Game02Level04} component={Game02Level04} />
<Stack.Screen
name={ROUTES.Level01Instructions}
component={Level01InstructionsPage}
/>
<Stack.Screen name={ROUTES.Game02Level05} component={Game02Level05} />
<Stack.Screen name={ROUTES.Game02Level06} component={Game02Level06} />
<Stack.Screen name={ROUTES.Game02Level07} component={Game02Level07} />
<Stack.Screen
name={ROUTES.GAME_MAIN_DETAILS}
component={MainDetailsForm}
/>
<Stack.Screen
name={ROUTES.MainDetailsFormInSinhala}
component={MainDetailsFormInSinhala}
/>
<Stack.Screen
name={ROUTES.MentalWellBeingTypes}
component={MentalWellBeingTypes}
/>
<Stack.Screen name={ROUTES.GameLevelPage} component={GameLevelPage} />
<Stack.Screen name={ROUTES.Level01} component={Level01} />
<Stack.Screen name={ROUTES.Level02} component={Level02} />
<Stack.Screen name={ROUTES.Level03} component={Level03} />
<Stack.Screen name={ROUTES.Level04} component={Level04} />
<Stack.Screen name={ROUTES.Level05} component={Level05} />
<Stack.Screen name={ROUTES.Level06} component={Level06} />
<Stack.Screen
name={ROUTES.Game02ProgressLevel01}
component={Game02ProgressLevel01}
/>
<Stack.Screen
name={ROUTES.Game02ProgressLevel02}
component={Game02ProgressLevel02}
/>
<Stack.Screen
name={ROUTES.Game02ProgressLevel03}
component={Game02ProgressLevel03}
/>
<Stack.Screen
name={ROUTES.Game02ProgressLevel04}
component={Game02ProgressLevel04}
/>
<Stack.Screen
name={ROUTES.Game02ProgressLevel05}
component={Game02ProgressLevel05}
/>
<Stack.Screen
name={ROUTES.Game02ProgressLevel06}
component={Game02ProgressLevel06}
/>
</Stack.Navigator>
);
}
export default GameNavigator;
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import WelcomeSkin from '../screens/home/skin/WelcomeSkin';
import Camera from '../screens/home/skin/SkinUploader';
import SkinRisk from '../screens/home/skin/SkinRisk';
import AdditionalSymptoms from '../screens/home/skin/AdditionalSymptoms';
import AdditionalSymptoms1 from '../screens/home/skin/AdditionalSymptoms1';
import AdditionalSymptoms2 from '../screens/home/skin/AdditionalSymptoms2';
import AdditionalSymptoms3 from '../screens/home/skin/AdditionalSymptoms3';
import AdditionalSymptoms4 from '../screens/home/skin/AdditionalSymptoms4';
import AdditionalSymptoms5 from '../screens/home/skin/AdditionalSymptoms5';
import Additionalinformation from '../screens/home/skin/information1';
import {COLORS, ROUTES} from "../constants"
const Stack = createStackNavigator();
function SkinNavigator() {
return (
<Stack.Navigator screenOptions={{
headerBackTitleVisible: false,
headerShown: false
}}
initialRouteName={ROUTES.SKIN_WELCOME}>
<Stack.Screen name={ROUTES.SKIN_WELCOME} component={WelcomeSkin} />
<Stack.Screen name={ROUTES.SKIN_UPLOAD} component={Camera} />
<Stack.Screen name={ROUTES.SKIN_VIDEO} component={AdditionalSymptoms} />
<Stack.Screen name={ROUTES.SKIN_RISK} component={SkinRisk} />
<Stack.Screen name={ROUTES.SKIN_VIDEO1} component={AdditionalSymptoms1} />
<Stack.Screen name={ROUTES.SKIN_VIDEO2} component={AdditionalSymptoms2} />
<Stack.Screen name={ROUTES.SKIN_VIDEO3} component={AdditionalSymptoms3} />
<Stack.Screen name={ROUTES.SKIN_VIDEO4} component={AdditionalSymptoms4} />
<Stack.Screen name={ROUTES.SKIN_VIDEO5} component={AdditionalSymptoms5} />
<Stack.Screen name={ROUTES.SKIN_INFO} component={Additionalinformation} />
</Stack.Navigator>
);
}
export default SkinNavigator;
\ No newline at end of file
......@@ -8,86 +8,100 @@ import {
TouchableOpacity,
KeyboardAvoidingView,
ScrollView,
ToastAndroid
ToastAndroid,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, ROUTES} from '../../constants';
import Logo from '../../assets/icons/mother.svg';
import { Formik } from 'formik';
import { signin } from '../../services/auth/index';
import {Formik} from 'formik';
import {signin} from '../../services/auth/index';
const Login = (props) => {
const Login = props => {
const {navigation} = props;
const onSubmit = async (values) => {
console.log("dataset2")
const onSubmit = async values => {
console.log('dataset2');
let respond = await signin(values.email, values.password);
console.log("dataset3",respond.data)
if(respond.data){
if(respond.data.success === true){
console.log("dataset")
navigation.navigate(ROUTES.HOME)
}
else{
console.log('dataset3', respond.data);
if (respond.data) {
if (respond.data.success === true) {
console.log('dataset');
ToastAndroid.show('Logged Successfully', ToastAndroid.SHORT);
navigation.navigate(ROUTES.HOME);
} else {
ToastAndroid.show('Email or password incorrect !', ToastAndroid.SHORT);
}
}
else{
} else {
ToastAndroid.show('Network Error !', ToastAndroid.SHORT);
}
}
};
return (
<KeyboardAvoidingView style={{flex:1}}>
<ScrollView contentContainerStyle={{flex:1}} bounces={false}>
<View style={Styles.container}>
<View style={Styles.wFull}>
<Formik
initialValues={{ email: '' , password: ''}}
onSubmit={values => onSubmit(values)}
>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<>
<View style={Styles.row}>
<Logo width={55} height={55} style={Styles.mr7} />
<Text style={Styles.brandName}>EmidWife</Text>
</View>
<KeyboardAvoidingView style={{flex: 1}}>
<ScrollView contentContainerStyle={{flex: 1}} bounces={false}>
<View style={Styles.container}>
<View style={Styles.wFull}>
<Formik
initialValues={{email: '', password: ''}}
onSubmit={values => onSubmit(values)}>
{({handleChange, handleBlur, handleSubmit, values}) => (
<>
<View style={Styles.row}>
<Logo width={55} height={55} style={Styles.mr7} />
<Text style={Styles.brandName}>EmidWife</Text>
</View>
<Text style={Styles.loginContinueTxt}>Login in to continue</Text>
<TextInput style={Styles.input} placeholder="Email" onChangeText={handleChange('email')} value={values.email}/>
<TextInput style={Styles.input} placeholder="Password" onChangeText={handleChange('password')} value={values.password}/>
<Text style={Styles.loginContinueTxt}>
Login in to continue
</Text>
<TextInput
style={Styles.input}
placeholder="Email"
onChangeText={handleChange('email')}
value={values.email}
/>
<TextInput
style={Styles.input}
placeholder="Password"
onChangeText={handleChange('password')}
value={values.password}
/>
<View style={Styles.loginBtnWrapper}>
<LinearGradient
colors={[COLORS.gradientForm, COLORS.bgColor]}
style={Styles.linearGradient}
start={{y: 0.0, x: 0.0}}
end={{y: 1.0, x: 0.0}}>
{/******************** LOGIN BUTTON *********************/}
<TouchableOpacity activeOpacity={0.7} style={Styles.loginBtn} onPress={handleSubmit}>
<Text style={Styles.loginText}>Log In</Text>
</TouchableOpacity>
</LinearGradient>
</View>
<View style={Styles.loginBtnWrapper}>
<LinearGradient
colors={[COLORS.gradientForm, COLORS.bgColor]}
style={Styles.linearGradient}
start={{y: 0.0, x: 0.0}}
end={{y: 1.0, x: 0.0}}>
{/******************** LOGIN BUTTON *********************/}
<TouchableOpacity
activeOpacity={0.7}
style={Styles.loginBtn}
onPress={handleSubmit}>
<Text style={Styles.loginText}>Log In</Text>
</TouchableOpacity>
</LinearGradient>
</View>
{/***************** FORGOT PASSWORD BUTTON *****************/}
<TouchableOpacity style={Styles.loginBtn} onPress={() => navigation.navigate(ROUTES.FORGOT_PASSWORD)}>
<Text style={Styles.forgotPassText}>Forgot Password?</Text>
</TouchableOpacity>
</>
)}
</Formik>
</View>
{/***************** FORGOT PASSWORD BUTTON *****************/}
<TouchableOpacity
style={Styles.loginBtn}
onPress={() => navigation.navigate(ROUTES.FORGOT_PASSWORD)}>
<Text style={Styles.forgotPassText}>Forgot Password?</Text>
</TouchableOpacity>
</>
)}
</Formik>
</View>
<View style={Styles.footer}>
<Text style={Styles.footerText}> Don't have an account? </Text>
{/******************** REGISTER BUTTON *********************/}
<TouchableOpacity onPress={() => navigation.navigate(ROUTES.REGISTER)}>
<Text style={Styles.signupBtn}>Sign Up</Text>
</TouchableOpacity>
<View style={Styles.footer}>
<Text style={Styles.footerText}> Don't have an account? </Text>
{/******************** REGISTER BUTTON *********************/}
<TouchableOpacity
onPress={() => navigation.navigate(ROUTES.REGISTER)}>
<Text style={Styles.signupBtn}>Sign Up</Text>
</TouchableOpacity>
</View>
</View>
</View>
</ScrollView>
</ScrollView>
</KeyboardAvoidingView>
);
};
......@@ -120,7 +134,6 @@ const Styles = StyleSheet.create({
color: COLORS.gray,
marginBottom: 16,
fontWeight: 'bold',
},
input: {
borderWidth: 1,
......@@ -130,7 +143,7 @@ const Styles = StyleSheet.create({
borderRadius: 12,
height: 45,
paddingVertical: 0,
color: "black"
color: 'black',
},
// Login Btn Styles
loginBtnWrapper: {
......
......@@ -8,58 +8,98 @@ import {
TouchableOpacity,
KeyboardAvoidingView,
ScrollView,
ToastAndroid
ToastAndroid,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { COLORS, ROUTES } from '../../constants';
import {COLORS, ROUTES} from '../../constants';
import Logo from '../../assets/icons/mother.svg';
import { Formik } from 'formik';
import { signup } from '../../services/auth/index';
import {Formik} from 'formik';
import {signup} from '../../services/auth/index';
const Register = ({ navigation }) => {
const onSubmit = async (values) => {
let respond = await signup(values.name, values.password, values.email, values.age, values.week);
console.log("dataset3",respond.data)
if(respond.data.success === true){
console.log("dataset")
navigation.navigate(ROUTES.HOME)
ToastAndroid.show('Login success', ToastAndroid.SHORT);
}
else{
const Register = ({navigation}) => {
const onSubmit = async values => {
let respond = await signup(
values.name,
values.password,
values.email,
values.age,
values.week,
);
console.log('dataset3', respond.data);
if (respond.data.success === true) {
console.log('dataset');
ToastAndroid.show('Registered Successfully', ToastAndroid.SHORT);
navigation.navigate(ROUTES.HOME);
} else {
ToastAndroid.show('Network or details not clear !', ToastAndroid.SHORT);
}
};
return (
<KeyboardAvoidingView style={{ flex: 1 }}>
<ScrollView contentContainerStyle={{ flexGrow: 1 }} bounces={false}>
<KeyboardAvoidingView style={{flex: 1}}>
<ScrollView contentContainerStyle={{flexGrow: 1}} bounces={false}>
<View style={styles.container}>
<View style={styles.wFull}>
<Formik
initialValues={{ email: '', password: '', name: '', age: '', week: '' }}
onSubmit={values => onSubmit(values)}
>
{({ handleChange, handleBlur, handleSubmit, values }) => (
initialValues={{
email: '',
password: '',
name: '',
age: '',
week: '',
}}
onSubmit={values => onSubmit(values)}>
{({handleChange, handleBlur, handleSubmit, values}) => (
<>
<View style={styles.row}>
<Logo width={55} height={55} style={styles.mr7} />
<Text style={styles.brandName}>EmidWife</Text>
</View>
<Text style={styles.loginContinueTxt}>Register to continue</Text>
<TextInput style={styles.input} placeholder="Name" onChangeText={handleChange('name')} value={values.name} />
<TextInput style={styles.input} placeholder="Email" onChangeText={handleChange('email')} value={values.email} />
<TextInput style={styles.input} placeholder="Password" onChangeText={handleChange('password')} value={values.password} />
<TextInput style={styles.input} placeholder="Age" onChangeText={handleChange('age')} value={values.age} />
<TextInput style={styles.input} placeholder="Week" onChangeText={handleChange('week')} value={values.week} />
<Text style={styles.loginContinueTxt}>
Register to continue
</Text>
<TextInput
style={styles.input}
placeholder="Name"
onChangeText={handleChange('name')}
value={values.name}
/>
<TextInput
style={styles.input}
placeholder="Email"
onChangeText={handleChange('email')}
value={values.email}
/>
<TextInput
style={styles.input}
placeholder="Password"
onChangeText={handleChange('password')}
value={values.password}
/>
<TextInput
style={styles.input}
placeholder="Age"
onChangeText={handleChange('age')}
value={values.age}
/>
<TextInput
style={styles.input}
placeholder="Week"
onChangeText={handleChange('week')}
value={values.week}
/>
<View style={styles.loginBtnWrapper}>
<LinearGradient
colors={[COLORS.gradientForm, COLORS.bgColor]}
colors={[COLORS.gradientForm, COLORS.bgColor]}
style={styles.linearGradient}
start={{ y: 0.0, x: 0.0 }}
end={{ y: 1.0, x: 0.0 }}>
<TouchableOpacity activeOpacity={0.7} style={styles.loginBtn} onPress={handleSubmit}>
start={{y: 0.0, x: 0.0}}
end={{y: 1.0, x: 0.0}}>
<TouchableOpacity
activeOpacity={0.7}
style={styles.loginBtn}
onPress={handleSubmit}>
<Text style={styles.loginText}>Sign Up</Text>
</TouchableOpacity>
</LinearGradient>
......@@ -114,6 +154,7 @@ const styles = StyleSheet.create({
borderRadius: 12,
height: 45,
paddingVertical: 0,
color: COLORS.black,
},
// Login Btn Styles
loginBtnWrapper: {
......
import React from 'react';
import { SafeAreaView, StyleSheet, Text, View } from 'react-native';
import {Image, TouchableOpacity, Text, View} from 'react-native';
import {COLORS, IMGS} from '../../constants';
import LinearGradient from 'react-native-linear-gradient';
const Home = () => {
return (
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[COLORS.dark_purple, COLORS.white, COLORS.dark_purple]}>
<View>
<View>
<Text>Register</Text>
<Image
source={IMGS.home_page}
style={{
height: 360,
width: '100%',
position: 'absolute',
top: 100,
}}
/>
</View>
);
<View
style={{
paddingHorizontal: 67,
position: 'absolute',
top: 510,
width: '100%',
}}>
<Text
style={{
fontSize: 45,
color: COLORS.black,
fontWeight: 'bold',
textAlign: 'center',
fontFamily: 'monospace',
}}>
Welcome to
</Text>
<Text
style={{
fontSize: 45,
color: COLORS.black,
fontWeight: 'bold',
textAlign: 'center',
fontFamily: 'monospace',
}}>
e-MidWife
</Text>
{/* <View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.purple_new,
borderColor: COLORS.purple_new,
height: 50,
marginBottom: 50,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: '100%',
zIndex: 3,
elevation: 10,
}}
onPress={() => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS)}
>
<Text
medium
center
style={{color: 'white', fontSize: 24, fontWeight: 'bold'}}>
Start
</Text>
</TouchableOpacity>
</View> */}
</View>
</View>
</LinearGradient>
);
};
export default Home;
import React, { useState, useRef, useEffect } from 'react';
import { StyleSheet, Text, View, ActivityIndicator, TouchableOpacity } from 'react-native';
import { StyleSheet, Text, View, ActivityIndicator, TouchableOpacity, ToastAndroid, Dimensions, SafeAreaView, ScrollView,FlatList } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import Video from 'react-native-video';
import { Camera, useCameraDevice, CameraPermissionStatus } from 'react-native-vision-camera';
import CircleProgressBar from '../../../components/CircleProgressBar';
import { COLORS, ROUTES } from '../../../constants';
import Dot from '../../../assets/icons/dot.svg';
const { width } = Dimensions.get('window');
const cameraWidth = width * 0.8; // Example: 80% of the screen width
const cameraHeight = cameraWidth * (16 / 9); // Maintain 16:9 aspect ratio
const { height: screenHeight } = Dimensions.get('window');
const ExerciseView = (props) => {
const { route } = props;
const { data } = route.params; // Assuming you pass videoUrl as a route parameter
let { route, navigation } = props;
let { data } = route.params; // Assuming you pass videoUrl as a route parameter
const videoRef = useRef(null);
const cameraRef = useRef(null);
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [remainingTime, setRemainingTime] = useState(data.duration);
const [remainingTime, setRemainingTime] = useState(null);
const [startCountDown, setStartCountDown] = useState(false);
const [isRecording, setIsRecording] = useState(false);
const [videoSource, setVideoSource] = useState('');
const [completeStatus, setCompleteStatus] = useState(false);
const device = useCameraDevice('front')
const handleLoad = () => {
setLoading(false);
......@@ -30,81 +41,158 @@ const ExerciseView = (props) => {
setVideoPaused(true);
};
const moveToNext = () => {
navigation.navigate(ROUTES.EXERCISE_MAIN_MENU)
ToastAndroid.show('Navigation successfully !', ToastAndroid.SHORT);
};
const handleStop = () => {
setRemainingTime(0);
setCompleteStatus(true)
navigation.navigate(ROUTES.EXERCISE_MAIN_MENU)
ToastAndroid.show('Navigation successfully !', ToastAndroid.SHORT);
};
const handleVideoEnd = () => {
setVideoPaused(true);
setStartCountDown(true);
// setStartCountDown(true);
setRemainingTime(data.duration); // Reset remaining time
};
const startRecording = async () => {
if (cameraRef.current && !isRecording) {
setIsRecording(true);
const video = await cameraRef.current.startRecording({
onRecordingFinished: (video) => {
setVideoSource(video.path);
setIsRecording(false);
console.log(video.path);
},
onRecordingError: (error) => {
console.error(`Recording Error: ${error.message}`);
setIsRecording(false);
},
});
}
};
const stopRecording = () => {
if (cameraRef.current && isRecording) {
cameraRef.current.stopRecording();
setIsRecording(false);
}
};
useEffect(() => {
// Initialize remainingTime when component mounts
setRemainingTime(data.duration * 2);
}, [data.duration]);
useEffect(() => {
if (remainingTime > 0 && startCountDown) {
const interval = setInterval(() => {
setRemainingTime((prevTime) => prevTime - 1);
let interval;
if (!videoPaused && remainingTime > 0) {
interval = setInterval(() => {
setRemainingTime(prevTime => prevTime - 1);
}, 1000);
}
return () => clearInterval(interval);
return () => clearInterval(interval);
}, [videoPaused, remainingTime]);
useEffect(() => {
async function requestPermissions() {
const cameraPermission = await Camera.requestCameraPermission();
const microphonePermission = await Camera.requestMicrophonePermission();
if (cameraPermission !== CameraPermissionStatus.AUTHORIZED || microphonePermission !== CameraPermissionStatus.AUTHORIZED) {
Linking.openSettings();
}
}
}, [remainingTime, startCountDown]);
requestPermissions();
}, []);
return (
<View style={styles.container}>
<Text style={styles.title}>Exercise Details</Text>
<View style={styles.videoContainer}>
<Video
ref={videoRef}
source={{ uri: data.exercise_video_url }}
style={styles.video}
controls={true}
paused={videoPaused}
resizeMode="contain"
onLoad={handleLoad}
onBuffer={handleBuffer}
onEnd={handleVideoEnd}
/>
{loading && <ActivityIndicator style={styles.loader} size="large" color="#0000ff" />}
<View style={styles.buttonsContainer}>
<TouchableOpacity style={styles.button} onPress={videoPaused ? handlePlay : handlePause}>
<Text style={styles.buttonText}>{videoPaused ? 'Play' : 'Pause'}</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={handlePause}>
<Text style={styles.buttonText}>Stop</Text>
</TouchableOpacity>
<SafeAreaView style={styles.container}>
<ScrollView style={{ height: screenHeight, paddingBottom: 30, marginBottom: 30 }}>
<Text style={styles.title}>Exercise Details</Text>
<View style={styles.videoContainer}>
<Video
ref={videoRef}
source={{ uri: data.exercise_video_url }}
style={styles.video}
controls={true}
paused={videoPaused}
resizeMode="contain"
onLoad={handleLoad}
onBuffer={handleBuffer}
/>
{loading && <ActivityIndicator style={styles.loader} size="large" color="#0000ff" />}
</View>
<View style={styles.progressMainView}>
<CircleProgressBar percentage={(remainingTime / data.duration) * 100} />
<CircleProgressBar percentage={(remainingTime / (data.duration * 2)) * 100} />
<View style={styles.progressSecondView}>
<Text>Remaining</Text>
<Text>{remainingTime} seconds</Text>
</View>
</View>
<View style={styles.stepsContainer}>
<Text style={styles.stepsTitle}>Steps:</Text>
<View style={styles.stepsContent}>
{data.exer_steps.map((step, index) => (
<View key={index} style={styles.stepContainer}>
<Dot width={16} height={16} color={COLORS.primary} style={styles.dotIcon} />
<Text style={styles.stepItem}>{step.step}</Text>
<View style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'coloum', paddingHorizontal: 0}}>
{remainingTime > 0 &&
<View style={styles.buttonsContainer}>
<TouchableOpacity style={styles.button} onPress={videoPaused ? handlePlay : handlePause}>
<Text style={styles.buttonText}>{videoPaused ? 'Play' : 'Pause'}</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonRed} onPress={moveToNext}>
<Text style={styles.buttonText}>Stop</Text>
</TouchableOpacity>
</View>
}
{(remainingTime <= 0 || completeStatus == true) &&
<View style={styles.loginBtnWrapper}>
<LinearGradient
colors={[COLORS.gradientForm, COLORS.bgColor]}
style={styles.linearGradient}
start={{ y: 0.0, x: 0.0 }}
end={{ y: 1.0, x: 0.0 }}>
{/******************** LOGIN BUTTON *********************/}
<TouchableOpacity activeOpacity={0.7} style={styles.loginBtn} onPress={moveToNext}>
<Text style={styles.loginText}>Move To Next</Text>
</TouchableOpacity>
</LinearGradient>
</View>
))}
}
</View>
<Text style={styles.title}>Exercise Preview</Text>
<View style={styles.cameraContainer}>
<Camera
ref={cameraRef}
style={styles.camera}
device={device}
isActive={true}
video={true}
audio={true}
ratio="16:9"
/>
</View>
</View>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
width: '100%',
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 20,
marginTop: 10,
textAlign: 'center',
},
videoContainer: {
......@@ -112,9 +200,8 @@ const styles = StyleSheet.create({
aspectRatio: 16 / 9,
justifyContent: 'center',
alignItems: 'center',
marginTop: 40,
marginTop: 10,
position: 'relative',
top: '25%',
},
video: {
width: '100%',
......@@ -133,10 +220,22 @@ const styles = StyleSheet.create({
paddingBottom: 10,
},
button: {
backgroundColor: '#2196F3',
padding: 10,
borderRadius: 50,
marginHorizontal: 5,
backgroundColor: COLORS.primary,
justifyContent: 'center',
alignItems: 'center',
width: 80, // Adjust width and height as needed
height: 80,
borderRadius: 40, // Make the radius half of the width/height to make it circular
marginRight: 10
},
buttonRed: {
backgroundColor: COLORS.warning,
justifyContent: 'center',
alignItems: 'center',
width: 80, // Adjust width and height as needed
height: 80,
borderRadius: 40, // Make the radius half of the width/height to make it circular
marginRight: 10
},
buttonText: {
color: 'white',
......@@ -145,7 +244,7 @@ const styles = StyleSheet.create({
progressMainView: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
justifyContent: 'space-around',
shadowColor: '#000',
shadowOffset: {
width: 2,
......@@ -155,9 +254,9 @@ const styles = StyleSheet.create({
shadowRadius: 3.84,
elevation: 5,
backgroundColor: COLORS.white,
marginHorizontal: 20,
marginHorizontal: 60,
borderRadius: 15,
marginTop: 10,
marginTop: 20,
paddingVertical: 10,
},
progressSecondView: {
......@@ -179,9 +278,8 @@ const styles = StyleSheet.create({
flexDirection: 'column',
},
stepContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
dotIcon: {
......@@ -197,6 +295,56 @@ const styles = StyleSheet.create({
backgroundColor: 'black',
marginHorizontal: 5,
},
cameraContainer: {
display: 'flex',
width: width,
marginTop: 5,
justifyContent: 'center',
alignItems: 'center'
},
camera: {
width: cameraWidth,
height: cameraHeight,
justifyContent: 'flex-end',
alignItems: 'center',
},
// Login Btn Styles
loginBtnWrapper: {
height: 55,
marginTop: 25,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.4,
shadowRadius: 3,
elevation: 5,
width: "80%",
marginLeft: "10%",
flexDirection: 'row',
marginLeft: -10
},
linearGradient: {
width: '100%',
borderRadius: 50,
},
loginBtn: {
textAlign: 'center',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: 55,
},
loginText: {
color: COLORS.white,
fontSize: 16,
fontWeight: '400',
},
horizontalFlatList: {
flexDirection: 'row',
flexWrap: 'wrap',
},
});
export default ExerciseView;
......@@ -280,15 +428,15 @@ export default ExerciseView;
// </View>
// </View>
// <View style={styles.stepsContainer}>
// <Text style={styles.stepsTitle}>Steps:</Text>
// {data.exer_steps.map((step, index) => (
// <View key={index} style={styles.stepContainer}>
// {index !== 0 && <View style={styles.line} />}
// <Dot width={16} height={16} color={COLORS.primary} style={styles.dotIcon} />
// {/* {index < data.exer_steps.length - 1 && <View style={styles.line}></View>} */}
// <Text style={styles.stepItem}>{step.step}</Text>
// </View>
// ))}
// <Text style={styles.stepsTitle}>Steps:</Text>
// {data.exer_steps.map((step, index) => (
// <View key={index} style={styles.stepContainer}>
// {index !== 0 && <View style={styles.line} />}
// <Dot width={16} height={16} color={COLORS.primary} style={styles.dotIcon} />
// {/* {index < data.exer_steps.length - 1 && <View style={styles.line}></View>} */}
// <Text style={styles.stepItem}>{step.step}</Text>
// </View>
// ))}
// </View>
// </View>
......@@ -699,3 +847,36 @@ export default ExerciseView;
// });
// export default ExerciseView;
{/* <FlatList
data={[...data.exer_steps, { isCamera: true }]} // Adding a placeholder for the camera view
renderItem={({ item, index }) => (
item.isCamera ? (
<View style={styles.cameraContainer}>
<Camera
ref={cameraRef}
style={styles.camera}
device={device}
isActive={true}
video={true}
audio={true}
ratio="16:9"
/>
</View>
) : (
<View style={{ marginHorizontal: 5 }}>
{data.exer_steps.map((step, index) => (
<View key={index} style={styles.stepContainer}>
<Dot width={16} height={16} color={COLORS.primary} style={styles.dotIcon} />
<Text style={styles.stepItem}>{step.step}</Text>
</View>
))}
</View>
)
)}
keyExtractor={(item, index) => index.toString()}
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.horizontalFlatList}
/> */}
\ No newline at end of file
import React, { useEffect, useState } from 'react';
import { TextInput, View, SafeAreaView, KeyboardAvoidingView, TouchableOpacity, Text, Modal, StyleSheet, ScrollView, ToastAndroid, Image} from 'react-native';
import { TextInput, View, SafeAreaView, KeyboardAvoidingView, TouchableOpacity, Text, Modal, StyleSheet, ScrollView, ToastAndroid, Image } from 'react-native';
import { Formik } from 'formik';
import CheckBox from '@react-native-community/checkbox';
import LinearGradient from 'react-native-linear-gradient';
import { COLORS, IMGS, ROUTES } from '../../../constants';
import Button from '../../../components/Button';
import { meternalHealthPredict, addInitialExercises } from '../../../services/exercises/index';
import { meternalHealthPredict, addInitialExercises, updateDeviceStatus } from '../../../services/exercises/index';
import AsyncStorage from '@react-native-async-storage/async-storage';
import database from '@react-native-firebase/database';
import Dot from '../../../assets/icons/dot.svg';
......@@ -20,34 +20,50 @@ const HealthFormExercise = (props) => {
const [initialBodyTemp, setInitialBodyTemp] = useState();
const [initialHeartRate, setInitialHeartRate] = useState();
const [dataArray, setDataArray] = useState(null);
const [isWearbleDevice, setIsWearbleDevice] = useState(false);
const [wearableModalVisible, setWearableModalVisible] = useState(false);
useEffect(() => {
// Reference to your Firebase Realtime Database
const databaseRef = database().ref('test');
ToastAndroid.show('Data reading on device !', ToastAndroid.SHORT);
// Attach an asynchronous listener to read the data at our reference
const onDataChange = (snapshot) => {
const data = snapshot.val();
setDataArray(data);
console.log("dada", data)
};
if (isWearbleDevice) {
// Reference to your Firebase Realtime Database
const databaseRef = database().ref('test');
ToastAndroid.show('Data reading on device !', ToastAndroid.SHORT);
databaseRef.on('value', onDataChange);
// Attach an asynchronous listener to read the data at our reference
const onDataChange = (snapshot) => {
const data = snapshot.val();
setDataArray(data);
console.log("data", data);
};
updateDeviceState()
databaseRef.on('value', onDataChange);
// Detach the listener when component unmounts
return () => {
databaseRef.off('value', onDataChange);
};
}, []); // Empty dependency array to run the effect only once
const onSubmit = async (values) => {
// Detach the listener when component unmounts or when isWearableDevice changes
return () => {
databaseRef.off('value', onDataChange);
};
}
}, [isWearbleDevice]);
const updateDeviceState = async () => {
let userDataString = await AsyncStorage.getItem('userData');
let userData = JSON.parse(userDataString);
console.log(userData)
let respond = await meternalHealthPredict(userData.age, values.SystolicBP, values.DiastolicBP, values.Blood_glucose, values.BodyTemp, values.HeartRate);
let deviceStatus = isWearbleDevice;
await updateDeviceStatus(userData._id, deviceStatus);
}
if (respond.data.prediction) {
const onSubmit = async (values) => {
let userDataString = await AsyncStorage.getItem('userData');
let userData = JSON.parse(userDataString);
console.log(values)
let respond = await meternalHealthPredict(userData.age, values.SystolicBP, values.DiastolicBP, values.Blood_glucose, values.BodyTemp, values.HeartRate);
console.log(respond)
if (respond) {
ToastAndroid.show('Prediction getting successfully !', ToastAndroid.SHORT);
//0:"high risk",1:"low risk",2:"mid risk"
let prediction = respond.data.prediction === "high risk" ? 0 : respond.data.prediction === "low risk" ? 1 : respond.data.prediction === "mid risk" ? 2 : null;
let predictionStatus = respond.data.prediction === "high risk" ? 20 : respond.data.prediction === "low risk" ? 0 : respond.data.prediction === "mid risk" ? 10 : null;
......@@ -59,7 +75,7 @@ const HealthFormExercise = (props) => {
if (responds.data) {
try {
await AsyncStorage.setItem('userData', JSON.stringify(userData));
navigation.navigate(ROUTES.EXERCISE_MAIN_MENU)
navigation.navigate(ROUTES.EXERCISE_MAIN_NEW_MENU)
ToastAndroid.show('userData updated successfully !', ToastAndroid.SHORT);
} catch (error) {
ToastAndroid.show('Error updating userData !', ToastAndroid.SHORT);
......@@ -76,7 +92,7 @@ const HealthFormExercise = (props) => {
return (
<SafeAreaView >
<Formik
initialValues={{ SystolicBP: '', DiastolicBP: '', Blood_glucose: '', BodyTemp: `${dataArray?.temp}` || '', HeartRate: `${dataArray?.bpm}` || '' }}
initialValues={{ SystolicBP: '', DiastolicBP: '', Blood_glucose: '', BodyTemp: isWearbleDevice ? `${dataArray?.temp}` : '', HeartRate: isWearbleDevice ? `${dataArray?.bpm}` : '' }}
onSubmit={values => onSubmit(values)}
enableReinitialize={true}
>
......@@ -110,20 +126,54 @@ const HealthFormExercise = (props) => {
//borderRadius style will help us make the Round Shape Image
style={{ width: 72, height: 100, borderRadius: 20, paddingVertical: 10, paddingHorizontal: 10, marginLeft: 20, marginTop: 10 }}
/>
<Image
<Image
source={require("../../../assets/glucose.jpg")}
//borderRadius style will help us make the Round Shape Image
style={{ width: 72, height: 100, borderRadius: 20, paddingVertical: 10, paddingHorizontal: 10, marginLeft: 20, marginTop: 10 }}
/>
</View>
<View style={Styles.closeDiv}>
<TouchableOpacity onPress={() => setModalVisible(false)}>
<TouchableOpacity onPress={() => { setModalVisible(false); setWearableModalVisible(true) }}>
<Text style={Styles.closeButton}>Close</Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
<Modal
animationType="slide"
transparent={true}
visible={wearableModalVisible}
onRequestClose={() => {
setWearableModalVisible(!wearableModalVisible);
}}
>
<View style={Styles.centeredView}>
<View style={Styles.modalView}>
<Text>Do you have a wearable device?</Text>
<View style={Styles.buttonRow}>
<TouchableOpacity
onPress={() => {
setIsWearbleDevice(true);
setWearableModalVisible(false);
}}
>
<Text style={Styles.closeButton}>Yes</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
setIsWearbleDevice(false)
setWearableModalVisible(false);
}}
>
<Text style={Styles.closeNewButton}>No</Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
<Text style={Styles.textInputLabel}>SystolicBP (mmHg)</Text>
<View style={Styles.inputBox}>
......@@ -237,6 +287,13 @@ const Styles = StyleSheet.create({
fontSize: 18,
fontWeight: 'bold',
},
closeNewButton: {
marginTop: 10,
color: COLORS.danger,
textAlign: 'center',
fontSize: 18,
fontWeight: 'bold',
},
submitButton: {
backgroundColor: '#1899D6',
borderRadius: 10, // Adjust the border radius as needed
......@@ -354,8 +411,17 @@ const Styles = StyleSheet.create({
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignItems:"center",
alignItems: "center",
width: "100%"
},
buttonRow: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
width: '100%',
marginTop: 10,
gap: 20
}
});
......@@ -9,7 +9,8 @@ import {
Image,
View,
ScrollView,
Button
Button,
ActivityIndicator
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import Logo from '../../../assets/icons/progress.svg';
......@@ -20,26 +21,6 @@ import { getAllExerciseDay } from '../../../services/exercises/index';
import AsyncStorage from '@react-native-async-storage/async-storage';
const moment = require('moment');
// import Button from '../../../components/Button';
// import Carousel from 'react-native-snap-carousel-v4';
// const carouselRef = useRef(null);
// const sliderrenderItem = ({ item, index }) => {
// return (
// <View style={{
// backgroundColor: 'floralwhite',
// borderRadius: 5,
// height: 250,
// padding: 50,
// marginLeft: 25,
// marginRight: 25,
// }}>
// <Text style={{ fontSize: 30 }}>{item.title}</Text>
// <Text>{item.text}</Text>
// </View>
// );
// };
const Item = ({ item, onPress, backgroundColor, textColor }) => (
<TouchableOpacity onPress={onPress} style={[styles.item, { backgroundColor, flexDirection: "row", width: '100%' }]}>
<Image
......@@ -58,6 +39,7 @@ const Item = ({ item, onPress, backgroundColor, textColor }) => (
);
const MainMenuExercise = (props) => {
const [loading, setLoading] = useState(true);
const { navigation } = props;
const [selectedId, setSelectedId] = useState(null);
const [exerciseDataArray, setExerciseData] = useState();
......@@ -99,6 +81,7 @@ const MainMenuExercise = (props) => {
};
const retriveExerciseList = async () => {
setLoading(true)
let userDataString = await AsyncStorage.getItem('userData');
let userData = JSON.parse(userDataString);
let todayDate = moment().format();
......@@ -113,7 +96,9 @@ const MainMenuExercise = (props) => {
if (todayDateByFormat === "Friday" || todayDateByFormat === "Saturday" || todayDateByFormat === "Sunday") {
dataNum = 3;
}
console.log("data",userData._id, dataNum)
let exerciseData = await getAllExerciseDay(userData._id, dataNum);
console.log("dAT",exerciseData.data.data)
let dataArray = exerciseData.data.data;
if (dataArray.length > 0) {
let exerciseModifiedAarray = [];
......@@ -147,12 +132,15 @@ const MainMenuExercise = (props) => {
}
setExerciseData(exerciseModifiedAarray);
setLoading(false)
console.log("new data ",exerciseModifiedAarray )
}
}
useEffect(() => {
retriveExerciseList()
setSelectedId(null)
}, [])
return (
......@@ -170,8 +158,9 @@ const MainMenuExercise = (props) => {
renderItem={renderItem}
keyExtractor={item => item._id}
extraData={selectedId}
style={{ marginBottom: 20 }}
style={{ marginBottom: 20}}
/>
{loading && <ActivityIndicator style={styles.loader} size="large" color="#0000ff" />}
</ScrollView>
<Text style={styles.topText}>Progress</Text>
<View style={styles.progressMainView}>
......@@ -279,6 +268,12 @@ const styles = StyleSheet.create({
marginVertical: 5,
marginHorizontal: 16,
},
loader: {
position: 'absolute',
top: '50%',
left: '50%',
transform: [{ translateX: -25 }, { translateY: -25 }],
},
title: {
fontSize: 14,
},
......
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import {
ImageBackground,
Text,
View,
StyleSheet,
TouchableOpacity,
} from 'react-native';
import {IMGS, ROUTES} from '../../../constants';
const ChooseGame = ({navigation, route}) => {
const {predictedGameLevel} = route.params;
const navigateBasedOnGameAndLevel = gameSelected => {
const gameLevelRoutes =
gameSelected === 'MommysSweetMatch'
? {
0: ROUTES.GameLevel1,
1: ROUTES.GameLevel0,
2: ROUTES.GameLevel1,
3: ROUTES.GameLevel2,
4: ROUTES.GameLevel3,
5: ROUTES.GameLevel4,
6: ROUTES.GameLevel5,
7: ROUTES.GameLevel6,
8: ROUTES.GameLevel3,
9: ROUTES.GameLevel4,
}
: {
0: ROUTES.PuzzleGame02Level03,
1: ROUTES.Game02Level01,
2: ROUTES.CravingsPuzzleGame02Level02,
3: ROUTES.PuzzleGame02Level03,
4: ROUTES.Game02Level04,
5: ROUTES.Game02Level05,
6: ROUTES.Game02Level06,
7: ROUTES.Game02Level07,
8: ROUTES.Game02Level04,
9: ROUTES.Game02Level06,
};
const routeName = gameLevelRoutes[predictedGameLevel];
if (routeName) {
navigation.navigate(routeName);
} else {
console.error('Unexpected prediction value:', predictedGameLevel);
}
};
return (
<>
<View style={styles.bottomView}>
<View style={{padding: 25}}>
<View style={{marginTop: 40}}>
<TouchableOpacity
style={{
backgroundColor: '#260B8C',
height: 300,
marginBottom: 20,
alignItems: 'center',
marginHorizontal: 10,
borderRadius: 24,
width: 340,
}}
onPress={() => navigateBasedOnGameAndLevel('MommysSweetMatch')}>
<View style={styles.container}>
<View style={styles.imageContainer}>
<ImageBackground
source={IMGS.game_img_3}
style={styles.backgroundImage}
resizeMode="cover">
<View style={styles.box}></View>
<Text
bold
medium
style={{
color: 'black',
fontSize: 25,
marginTop: -45,
marginLeft: 20,
fontWeight: 'bold',
}}>
Mommy's Sweet Match
</Text>
</ImageBackground>
</View>
</View>
</TouchableOpacity>
</View>
<View style={{marginTop: 35}}>
<TouchableOpacity
style={{
backgroundColor: '#260B8C',
height: 300,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 10,
borderRadius: 24,
width: 340,
}}
onPress={() => navigateBasedOnGameAndLevel('BumpBoutique')}>
<ImageBackground
source={IMGS.game_img_4}
style={styles.backgroundImage}
resizeMode="cover">
<View style={styles.box}></View>
<Text
bold
medium
center
style={{
color: 'black',
fontSize: 25,
marginTop: -45,
marginLeft: 20,
fontWeight: 'bold',
}}>
Bump Boutique
</Text>
</ImageBackground>
</TouchableOpacity>
</View>
</View>
</View>
</>
);
};
const styles = StyleSheet.create({
brandViewText: {
color: '#FFFFFF',
fontSize: 40,
},
bottomView: {
flex: 1.5,
backgroundColor: '#FFFFFF',
},
backgroundImage: {
flex: 1,
width: 340,
height: 300,
borderRadius: 50,
},
imageContainer: {
borderRadius: 24,
overflow: 'hidden',
width: '100%',
height: '100%',
},
box: {
backgroundColor: 'white',
height: 50,
marginTop: 250,
opacity: 0.5,
},
});
export default ChooseGame;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, ROUTES} from '../../../constants';
const GameLevelPage = ({route, navigation}) => {
const {predictedGameLevel} = route.params;
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text
style={{
color: '#ffffff',
fontSize: predictedGameLevel === 0 ? 20 : 100,
fontWeight: 'bold',
}}>
{predictedGameLevel === 0 ? 'No Depression' : predictedGameLevel}
</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => {
if (predictedGameLevel === 0) {
navigation.navigate(ROUTES.GAME_WELCOME);
} else {
navigation.navigate(ROUTES.CHOOSE_GAME, {predictedGameLevel});
}
}}>
<Text style={styles.buttonText}>
{predictedGameLevel === 0 ? 'Exit' : 'Choose a Game'}
</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default GameLevelPage;
/* eslint-disable react-native/no-inline-styles */
import React, {useState} from 'react';
import {
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
ScrollView,
} from 'react-native';
import {ROUTES, COLORS} from '../../../constants';
import LinearGradient from 'react-native-linear-gradient';
const MainDetailsForm = ({navigation}) => {
const [maritalStatus, setMaritalStatus] = useState('single');
const [familyBackground, setFamilyBackground] = useState('normal');
const [age, setAge] = useState('');
const [previousChildBirthExperiences, setPreviousChildBirthExperiences] =
useState('');
const [ageError, setAgeError] = useState('');
const [childBirthError, setChildBirthError] = useState('');
const handleValidation = () => {
let valid = true;
if (age.trim() === '') {
setAgeError('Age is required');
valid = false;
} else {
setAgeError('');
}
if (previousChildBirthExperiences.trim() === '') {
setChildBirthError('Number of previous child births is required');
valid = false;
} else {
setChildBirthError('');
}
return valid;
};
const maritalStatusOptions = [
{
key: 'single',
text: 'Single',
selected: maritalStatus === 'single',
},
{
key: 'married',
text: 'Married',
selected: maritalStatus === 'married',
},
{
key: 'divorced',
text: 'Divorced',
selected: maritalStatus === 'divorced',
},
];
const familyBackgroundOptions = [
{
key: 'normal',
text: 'Normal',
selected: familyBackground === 'normal',
},
{
key: 'bad',
text: 'Bad',
selected: familyBackground === 'bad',
},
{
key: 'good',
text: 'Good',
selected: familyBackground === 'good',
},
];
const handleMaritalStatusSelect = key => {
setMaritalStatus(key);
};
const handleFamilyBackgroundSelect = key => {
setFamilyBackground(key);
};
const handleNext = () => {
if (handleValidation()) {
navigation.navigate(ROUTES.GAME_QUIZ_IN_ENGLISH, {
formData: {
age: age,
marital_status_divorced: maritalStatus === 'divorced' ? 1 : 0,
marital_status_married: maritalStatus === 'married' ? 1 : 0,
marital_status_single: maritalStatus === 'single' ? 1 : 0,
family_background_bad: familyBackground === 'bad' ? 1 : 0,
family_background_good: familyBackground === 'good' ? 1 : 0,
family_background_normal: familyBackground === 'normal' ? 1 : 0,
previous_child_birth_experiences: previousChildBirthExperiences,
},
});
}
};
return (
<>
<ScrollView
style={styles.scrollContainer}
contentContainerStyle={styles.contentContainer}>
<LinearGradient
style={{
flex: 1,
width: '100%',
height: '100%',
}}
colors={[COLORS.light_purple, COLORS.white, COLORS.rose]}>
<View style={{padding: 25}}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
}}>
<Text
style={{
color: COLORS.black,
fontSize: 20,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 40,
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
}}>
Please answer for this questions
</Text>
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 1,
marginBottom: 20,
color: COLORS.black,
}}>
Your Age:
</Text>
<TextInput
style={{
backgroundColor: '#ffffff',
borderRadius: 15,
height: 48,
marginBottom: 10,
marginTop: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.46,
shadowRadius: 11.14,
fontSize: 13,
color: COLORS.black,
elevation: 17,
}}
onChangeText={text => {
setAge(text);
if (text.trim() !== '') {
setAgeError('');
}
}}
keyboardType="numeric" // Set keyboardType appropriately
value={age}
/>
{!!ageError && <Text style={styles.errorText}>{ageError}</Text>}
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
Marital Status:{' '}
</Text>
<View style={styles.radioContainer}>
{maritalStatusOptions.map(item => (
<View key={item.key} style={styles.radioButtonContainer}>
<TouchableOpacity
style={styles.circle}
onPress={() => handleMaritalStatusSelect(item.key)}>
{item.selected ? (
<View style={styles.checkedCircle} />
) : null}
</TouchableOpacity>
<Text style={styles.radioText}>{item.text}</Text>
</View>
))}
</View>
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
Current Situation of Family Background (Financial / Economic/
Partner's Supportness):
</Text>
<View style={styles.radioContainer}>
{familyBackgroundOptions.map(item => (
<View key={item.key} style={styles.radioButtonContainer}>
<TouchableOpacity
style={styles.circle}
onPress={() => handleFamilyBackgroundSelect(item.key)}>
{item.selected ? (
<View style={styles.checkedCircle} />
) : null}
</TouchableOpacity>
<Text style={styles.radioText}>{item.text}</Text>
</View>
))}
</View>
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
No of Previous Child Births:
</Text>
<TextInput
style={{
backgroundColor: '#ffffff',
borderRadius: 15,
height: 48,
marginBottom: 10,
marginTop: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.46,
shadowRadius: 11.14,
fontSize: 13,
color: COLORS.black,
elevation: 17,
}}
keyboardType="number-pad"
onChangeText={text => {
setPreviousChildBirthExperiences(text);
if (text.trim() !== '') {
setChildBirthError('');
}
}}
value={previousChildBirthExperiences}
/>
{!!childBirthError && (
<Text style={styles.errorText}>{childBirthError}</Text>
)}
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
Experience of Previous Child Birth:
</Text>
<TextInput
style={{
backgroundColor: '#ffffff',
borderRadius: 15,
height: 48,
marginBottom: 10,
marginTop: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.46,
shadowRadius: 11.14,
fontSize: 13,
color: COLORS.black,
elevation: 17,
}}
/>
</View>
<View style={{marginTop: 55}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
marginBottom: 50,
justifyContent: 'center',
alignItems: 'center',
elevation: 10,
borderRadius: 14,
width: '100%',
}}
onPress={handleNext}>
<Text
bold
medium
center
style={{
color: COLORS.white,
fontSize: 20,
fontWeight: 700,
}}>
Next
</Text>
</TouchableOpacity>
</View>
</View>
</LinearGradient>
</ScrollView>
</>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
contentContainer: {
paddingBottom: 40, // Adds padding at the bottom
},
brandViewText: {
color: '#FFFFFF',
fontSize: 40,
fontWeight: 'bold',
},
bottomView: {
flex: 1,
height: 860,
backgroundColor: COLORS.purple,
},
radioContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
marginTop: 10,
},
radioButtonContainer: {
flexDirection: 'row',
alignItems: 'center',
},
circle: {
height: 20,
width: 20,
borderRadius: 10,
borderWidth: 1,
borderColor: '#ACACAC',
alignItems: 'center',
justifyContent: 'center',
marginHorizontal: 10,
},
checkedCircle: {
width: 14,
height: 14,
borderRadius: 7,
backgroundColor: '#794F9B',
},
radioText: {
marginLeft: 5,
color: COLORS.black,
},
container: {
flex: 1,
},
errorText: {
color: 'red',
},
});
export default MainDetailsForm;
/* eslint-disable react-native/no-inline-styles */
import React, {useState} from 'react';
import {
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
ScrollView,
} from 'react-native';
import {ROUTES, COLORS} from '../../../constants';
import LinearGradient from 'react-native-linear-gradient';
const MainDetailsFormInSinhala = ({navigation}) => {
const [maritalStatus, setMaritalStatus] = useState('single');
const [familyBackground, setFamilyBackground] = useState('normal');
const [age, setAge] = useState('');
const [previousChildBirthExperiences, setPreviousChildBirthExperiences] =
useState('');
const [ageError, setAgeError] = useState('');
const [childBirthError, setChildBirthError] = useState('');
const handleValidation = () => {
let valid = true;
if (age.trim() === '') {
setAgeError('වයස අනිවාර්ය වේ');
valid = false;
} else {
setAgeError('');
}
if (previousChildBirthExperiences.trim() === '') {
setChildBirthError('පෙර දරු උපත් සංඛ්‍යාව අනිවාර්ය වේ.');
valid = false;
} else {
setChildBirthError('');
}
return valid;
};
const maritalStatusOptions = [
{
key: 'single',
text: 'අවිවාහක',
selected: maritalStatus === 'single',
},
{
key: 'married',
text: 'විවාහක',
selected: maritalStatus === 'married',
},
{
key: 'divorced',
text: 'වෙන්වී සිටී',
selected: maritalStatus === 'divorced',
},
];
const familyBackgroundOptions = [
{
key: 'normal',
text: 'සාමාන්‍යයි',
selected: familyBackground === 'normal',
},
{
key: 'bad',
text: 'නරකයි',
selected: familyBackground === 'bad',
},
{
key: 'good',
text: 'හොඳයි',
selected: familyBackground === 'good',
},
];
const handleMaritalStatusSelect = key => {
setMaritalStatus(key);
};
const handleFamilyBackgroundSelect = key => {
setFamilyBackground(key);
};
const handleNext = () => {
if (handleValidation()) {
navigation.navigate(ROUTES.GAME_QUIZ_IN_SINHALA, {
formData: {
age: age,
marital_status_divorced: maritalStatus === 'divorced' ? 1 : 0,
marital_status_married: maritalStatus === 'married' ? 1 : 0,
marital_status_single: maritalStatus === 'single' ? 1 : 0,
family_background_bad: familyBackground === 'bad' ? 1 : 0,
family_background_good: familyBackground === 'good' ? 1 : 0,
family_background_normal: familyBackground === 'normal' ? 1 : 0,
previous_child_birth_experiences: previousChildBirthExperiences,
},
});
}
};
return (
<>
<ScrollView
style={styles.scrollContainer}
contentContainerStyle={styles.contentContainer}>
<LinearGradient
style={{
flex: 1,
width: '100%',
height: '100%',
}}
colors={[COLORS.light_purple, COLORS.white, COLORS.rose]}>
<View style={{padding: 25}}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
}}>
<Text
style={{
color: COLORS.black,
fontSize: 17,
fontWeight: 'bold',
marginTop: 40,
marginBottom: 40,
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
}}>
කරුණාකර මෙම ප්‍රශ්න සඳහා පිළිතුරු සපයන්න
</Text>
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
ඔබගේ වයස:
</Text>
<TextInput
style={{
backgroundColor: '#ffffff',
borderRadius: 15,
height: 48,
marginBottom: 10,
marginTop: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.46,
shadowRadius: 11.14,
fontSize: 13,
color: COLORS.black,
elevation: 17,
}}
onChangeText={text => {
setAge(text);
if (text.trim() !== '') {
setAgeError('');
}
}}
keyboardType="numeric" // Set keyboardType appropriately
value={age}
required
/>
{!!ageError && <Text style={styles.errorText}>{ageError}</Text>}
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
විවාහක/අවිවාහක බව:{' '}
</Text>
<View style={styles.radioContainer}>
{maritalStatusOptions.map(item => (
<View key={item.key} style={styles.radioButtonContainer}>
<TouchableOpacity
style={styles.circle}
onPress={() => handleMaritalStatusSelect(item.key)}>
{item.selected ? (
<View style={styles.checkedCircle} />
) : null}
</TouchableOpacity>
<Text style={styles.radioText}>{item.text}</Text>
</View>
))}
</View>
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
වත්මන් පවුල් පසුබිම් තත්ත්වය (මූල්‍යමය / ආර්ථිකමය / හවුල්කරුගේ
සහාය):
</Text>
<View style={styles.radioContainer}>
{familyBackgroundOptions.map(item => (
<View key={item.key} style={styles.radioButtonContainer}>
<TouchableOpacity
style={styles.circle}
onPress={() => handleFamilyBackgroundSelect(item.key)}>
{item.selected ? (
<View style={styles.checkedCircle} />
) : null}
</TouchableOpacity>
<Text style={styles.radioText}>{item.text}</Text>
</View>
))}
</View>
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
පෙර දරු උපත් සංඛ්‍යාව:
</Text>
<TextInput
style={{
backgroundColor: '#ffffff',
borderRadius: 15,
height: 48,
marginBottom: 10,
marginTop: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.46,
shadowRadius: 11.14,
fontSize: 13,
color: COLORS.black,
elevation: 17,
}}
keyboardType="number-pad"
onChangeText={text => {
setPreviousChildBirthExperiences(text);
if (text.trim() !== '') {
setChildBirthError('');
}
}}
value={previousChildBirthExperiences}
/>
{!!childBirthError && (
<Text style={styles.errorText}>{childBirthError}</Text>
)}
</View>
<View style={{marginTop: 15}}>
<Text
semi
style={{
fontSize: 15,
fontWeight: 'bold',
marginTop: 20,
marginBottom: 20,
color: COLORS.black,
}}>
පෙර දරු උපත පිළිබඳ අත්දැකීම්:
</Text>
<TextInput
style={{
backgroundColor: '#ffffff',
borderRadius: 15,
height: 48,
marginBottom: 10,
marginTop: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.46,
shadowRadius: 11.14,
fontSize: 13,
color: COLORS.black,
elevation: 17,
}}
// keyboardType="number-pad"
// onChangeText={text => setPreviousChildBirthExperiences(text)} // Use setAge for the age field // Set keyboardType appropriately
// value={previousChildBirthExperiences}
/>
</View>
<View style={{marginTop: 35}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
marginBottom: 50,
justifyContent: 'center',
alignItems: 'center',
elevation: 10,
borderRadius: 14,
width: '100%',
}}
onPress={handleNext}>
<Text
bold
medium
center
style={{
color: COLORS.white,
fontSize: 20,
}}>
Next
</Text>
</TouchableOpacity>
</View>
</View>
</LinearGradient>
</ScrollView>
</>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
contentContainer: {
paddingBottom: 40, // Adds padding at the bottom
},
brandViewText: {
color: '#FFFFFF',
fontSize: 40,
fontWeight: 'bold',
},
bottomView: {
flex: 1,
height: 860,
backgroundColor: COLORS.purple,
},
radioContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
marginTop: 10,
},
radioButtonContainer: {
flexDirection: 'row',
alignItems: 'center',
},
circle: {
height: 20,
width: 20,
borderRadius: 10,
borderWidth: 1,
borderColor: '#ACACAC',
alignItems: 'center',
justifyContent: 'center',
marginHorizontal: 10,
},
checkedCircle: {
width: 14,
height: 14,
borderRadius: 7,
backgroundColor: '#794F9B',
},
radioText: {
marginLeft: 5,
color: COLORS.black,
},
container: {
flex: 1,
},
errorText: {
color: 'red',
},
});
export default MainDetailsFormInSinhala;
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import {
ImageBackground,
Text,
View,
StyleSheet,
TouchableOpacity,
} from 'react-native';
import {COLORS, IMGS, ROUTES} from '../../../constants';
const MentalWellBeingTypes = ({navigation, route}) => {
const {predictedGameLevel} = route.params;
return (
<>
<View style={styles.bottomView}>
<View style={{padding: 25}}>
<View style={{marginTop: 40}}>
<TouchableOpacity
style={{
backgroundColor: '#260B8C',
height: 400,
marginBottom: 20,
alignItems: 'center',
marginHorizontal: 10,
borderRadius: 24,
width: 350,
}}>
<View style={styles.container}>
<View style={styles.imageContainer}>
<ImageBackground
source={IMGS.well_being}
style={styles.backgroundImage}
resizeMode="cover"></ImageBackground>
</View>
<View style={styles.box}></View>
<Text
bold
medium
style={{
color: 'black',
fontSize: 16,
marginTop: -50,
// marginLeft: 20,
fontWeight: 'bold',
textAlign: 'center',
}}>
Playing games can contribute to making you happy, perhaps even
without therapy.
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => {
navigation.navigate(ROUTES.GameLevelPage, {
predictedGameLevel,
});
}}>
<Text bold medium center style={styles.buttonText}>
Check Your Gaming Level
</Text>
</TouchableOpacity>
</View>
</View>
</View>
</>
);
};
const styles = StyleSheet.create({
brandViewText: {
color: '#FFFFFF',
fontSize: 40,
},
bottomView: {
flex: 1.5,
backgroundColor: COLORS.blue,
},
backgroundImage: {
flex: 1,
width: 350,
height: 400,
borderRadius: 50,
},
imageContainer: {
borderRadius: 24,
overflow: 'hidden',
width: '100%',
height: '100%',
},
box: {
backgroundColor: 'white',
height: 70,
marginTop: -38,
opacity: 0.5,
},
button: {
backgroundColor: COLORS.dark,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 350,
height: 50,
marginTop: 190,
},
buttonText: {
color: 'white',
fontWeight: 'bold',
fontSize: 17,
},
});
export default MentalWellBeingTypes;
/* eslint-disable react-native/no-inline-styles */
import React, {useEffect, useState} from 'react';
import {
View,
StyleSheet,
TouchableOpacity,
Text,
ActivityIndicator,
ScrollView,
} from 'react-native';
import axios from 'axios';
import {useNavigation} from '@react-navigation/native';
import {COLORS, ROUTES} from '../../../constants';
import RadioButton from '../../../components/RadioButton';
import LinearGradient from 'react-native-linear-gradient';
const QuestionInEnglishPage = ({navigation, route}) => {
const {formData} = route.params;
const [questions, setQuestions] = useState([]);
const [questionIndex, setQuestionIndex] = useState(0);
const [selectedAnswerIndices, setSelectedAnswerIndices] = useState(
new Array(questions.length).fill(null),
);
const [totalScore, setTotalScore] = useState(0);
const [isLoading, setIsLoading] = useState(true);
const setSelectedAnswer = (optionIndex, questionIndex) => {
const newSelectedAnswerIndices = [...selectedAnswerIndices];
newSelectedAnswerIndices[questionIndex] = optionIndex;
setSelectedAnswerIndices(newSelectedAnswerIndices);
// Calculate the total score based on the selected answer indices
let newTotalScore = 0;
for (let i = 0; i < selectedAnswerIndices.length; i++) {
const selectedOptionIndex = selectedAnswerIndices[i];
if (selectedOptionIndex !== null) {
newTotalScore += questions[i].scores[selectedOptionIndex];
}
}
setTotalScore(newTotalScore);
};
useEffect(() => {
loadData();
}, []);
const loadData = () => {
axios
.get('http://emidwife-api.onrender.com/api/quiz/all_english')
.then(response => {
setQuestions(response.data.data);
setIsLoading(false);
})
.catch(error => {
console.error(error);
2;
// Ensure loading is set to false even if there's an error
setIsLoading(false);
});
};
const handleNext = () => {
if (questionIndex < questions.length - 2) {
setQuestionIndex(questionIndex + 2);
}
};
const handlePrevious = () => {
if (questionIndex > 0) {
setQuestionIndex(questionIndex - 2);
}
};
const isOnFirstQuestions = questionIndex === 0;
const isOnLastQuestions = questionIndex >= questions.length - 2;
// Handle navigation to the "Quiz Score" page and pass the totalScore as a parameter
const handleNavigationToQuizScore = () => {
// Create a new object that includes all the formData fields and adds the totalScore as depression_level
const updatedFormData = {
...formData,
depression_level: totalScore,
};
// Navigate to the QUIZ_SCORE page, passing the updated formData
navigation.navigate(ROUTES.QUIZ_SCORE, {
depression_level: totalScore, // You can still pass totalScore separately if needed
formData: updatedFormData,
});
};
return (
<>
{isLoading ? (
<View style={styles.loaderContainer}>
<ActivityIndicator size={150} color={COLORS.dark_purple} />
</View>
) : (
<ScrollView
style={styles.scrollContainer}
contentContainerStyle={styles.contentContainer}>
<LinearGradient
style={{
flex: 1,
width: '100%',
height: '100%',
}}
colors={[COLORS.white, '#FDCEDF']}>
{questions
.slice(questionIndex, questionIndex + 2)
.map((question, index) => (
<View style={{padding: 18, marginTop: 42}} key={question._id}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
color: COLORS.pastal_blue,
fontSize: 22,
fontWeight: 'bold',
}}>
Question {questionIndex + index + 1}
</Text>
</View>
<View
style={{
backgroundColor: 'white',
borderColor: COLORS.pink,
borderWidth: 3,
borderRadius: 17,
marginTop: 5,
padding: 12,
}}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
color: 'black',
fontSize: 15,
fontWeight: 'bold',
marginTop: 10,
}}>
{question.question}
</Text>
</View>
<View
style={{
marginTop: 10,
gap: 3,
marginBottom: 5,
color: 'black',
marginRight: 25,
}}>
<RadioButton
label={questions[questionIndex + index].answers[0]}
selected={
selectedAnswerIndices[questionIndex + index] === 0
}
onPress={() =>
setSelectedAnswer(0, questionIndex + index)
}
value={3}
/>
<RadioButton
label={questions[questionIndex + index].answers[1]}
selected={
selectedAnswerIndices[questionIndex + index] === 1
}
onPress={() =>
setSelectedAnswer(1, questionIndex + index)
}
value={2}
/>
<RadioButton
label={questions[questionIndex + index].answers[2]}
selected={
selectedAnswerIndices[questionIndex + index] === 2
}
onPress={() =>
setSelectedAnswer(2, questionIndex + index)
}
value={1}
/>
<RadioButton
textColor="black"
label={questions[questionIndex + index].answers[3]}
selected={
selectedAnswerIndices[questionIndex + index] === 3
}
onPress={() =>
setSelectedAnswer(3, questionIndex + index)
}
value={0}
/>
</View>
</View>
</View>
))}
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 50,
marginBottom: 100,
}}>
{!isOnFirstQuestions && (
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 20,
borderRadius: 16,
width: 140,
elevation: 10,
}}
onPress={handlePrevious}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 20,
fontWeight: 'bold',
}}>
Back
</Text>
</TouchableOpacity>
)}
{!isOnLastQuestions && (
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: isOnFirstQuestions ? 240 : 20,
borderRadius: 16,
width: 140,
elevation: 10,
}}
onPress={handleNext}>
<Text
bold
medium
center
style={{
color: 'white',
fontWeight: 'bold',
fontSize: 20,
}}>
Next
</Text>
</TouchableOpacity>
)}
{isOnLastQuestions && (
<TouchableOpacity
style={{
backgroundColor: '#DE3163',
height: 50,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 20,
borderRadius: 16,
width: 150,
elevation: 10,
}}
onPress={handleNavigationToQuizScore}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 20,
fontWeight: 'bold',
}}>
Submit
</Text>
</TouchableOpacity>
)}
</View>
</LinearGradient>
</ScrollView>
)}
</>
);
};
export default QuestionInEnglishPage;
const styles = StyleSheet.create({
brandViewText: {
fontSize: 40,
fontWeight: 'bold',
},
bottomView: {
flex: 1.5,
},
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
scrollContainer: {
flexGrow: 1,
},
contentContainer: {
paddingBottom: 40, // Adds padding at the bottom
},
});
/* eslint-disable react-native/no-inline-styles */
import React, {useEffect, useState} from 'react';
import {
View,
StyleSheet,
TouchableOpacity,
Text,
ActivityIndicator,
ScrollView,
} from 'react-native';
import axios from 'axios';
import {useNavigation} from '@react-navigation/native';
import {COLORS, ROUTES} from '../../../constants';
import RadioButton from '../../../components/RadioButton';
import LinearGradient from 'react-native-linear-gradient';
const QuestionInSinhalaPage = ({navigation, route}) => {
const [questions, setQuestions] = useState([]);
const [questionIndex, setQuestionIndex] = useState(0);
const [selectedAnswerIndices, setSelectedAnswerIndices] = useState(
new Array(questions.length).fill(null),
);
const [totalScore, setTotalScore] = useState(0);
const [isLoading, setIsLoading] = useState(true);
const {formData} = route.params;
const setSelectedAnswer = (optionIndex, questionIndex) => {
const newSelectedAnswerIndices = [...selectedAnswerIndices];
newSelectedAnswerIndices[questionIndex] = optionIndex;
setSelectedAnswerIndices(newSelectedAnswerIndices);
// Calculate the total score based on the selected answer indices
let newTotalScore = 0;
for (let i = 0; i < selectedAnswerIndices.length; i++) {
const selectedOptionIndex = selectedAnswerIndices[i];
if (selectedOptionIndex !== null) {
newTotalScore += questions[i].scores[selectedOptionIndex];
}
}
setTotalScore(newTotalScore);
};
useEffect(() => {
loadData();
}, []);
const loadData = () => {
axios
.get('http://emidwife-api.onrender.com/api/quiz/all_sinhala')
.then(response => {
setQuestions(response.data.data);
setIsLoading(false);
})
.catch(error => {
console.error(error);
setIsLoading(false); // Ensure loading is set to false even if there's an error
});
};
const handleNext = () => {
if (questionIndex < questions.length - 2) {
setQuestionIndex(questionIndex + 2);
}
};
const handlePrevious = () => {
if (questionIndex > 0) {
setQuestionIndex(questionIndex - 2);
}
};
const isOnFirstQuestions = questionIndex === 0;
const isOnLastQuestions = questionIndex >= questions.length - 2;
// Handle navigation to the "Quiz Score" page and pass the totalScore as a parameter
const handleNavigationToQuizScore = () => {
const updatedFormData = {
...formData,
depression_level: totalScore,
};
// Navigate to the QUIZ_SCORE page, passing the updated formData
navigation.navigate(ROUTES.QUIZ_SCORE, {
depression_level: totalScore, // You can still pass totalScore separately if needed
formData: updatedFormData,
});
};
return (
<>
{isLoading ? (
<View style={styles.loaderContainer}>
<ActivityIndicator size={150} color={COLORS.dark_purple} />
</View>
) : (
<ScrollView
style={styles.scrollContainer}
contentContainerStyle={styles.contentContainer}>
<LinearGradient
style={{
flex: 1,
width: '100%',
height: '100%',
}}
colors={[COLORS.white, '#FDCEDF']}>
{questions
.slice(questionIndex, questionIndex + 2)
.map((question, index) => (
<View style={{padding: 18, marginTop: 42}} key={question._id}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
color: COLORS.pastal_blue,
fontSize: 22,
fontWeight: 'bold',
}}>
ප්‍රශ්නය {questionIndex + index + 1}
</Text>
</View>
<View
style={{
backgroundColor: 'white',
borderColor: COLORS.pink,
borderWidth: 3,
borderRadius: 17,
marginTop: 5,
padding: 12,
}}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
color: 'black',
fontSize: 15,
fontWeight: 'bold',
marginTop: 10,
}}>
{question.question}
</Text>
</View>
<View
style={{
marginTop: 1,
gap: 3,
marginBottom: 1,
color: 'black',
marginRight: 25,
}}>
<RadioButton
label={questions[questionIndex + index].answers[0]}
selected={
selectedAnswerIndices[questionIndex + index] === 0
}
onPress={() =>
setSelectedAnswer(0, questionIndex + index)
}
value={3}
/>
<RadioButton
label={questions[questionIndex + index].answers[1]}
selected={
selectedAnswerIndices[questionIndex + index] === 1
}
onPress={() =>
setSelectedAnswer(1, questionIndex + index)
}
value={2}
/>
<RadioButton
label={questions[questionIndex + index].answers[2]}
selected={
selectedAnswerIndices[questionIndex + index] === 2
}
onPress={() =>
setSelectedAnswer(2, questionIndex + index)
}
value={1}
/>
<RadioButton
textColor="black"
label={questions[questionIndex + index].answers[3]}
selected={
selectedAnswerIndices[questionIndex + index] === 3
}
onPress={() =>
setSelectedAnswer(3, questionIndex + index)
}
value={0}
/>
</View>
</View>
</View>
))}
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 50,
marginBottom: 100,
}}>
{!isOnFirstQuestions && (
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 20,
borderRadius: 16,
width: 140,
elevation: 10,
}}
onPress={handlePrevious}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 20,
fontWeight: 'bold',
}}>
ආපසු
</Text>
</TouchableOpacity>
)}
{!isOnLastQuestions && (
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: isOnFirstQuestions ? 240 : 20,
borderRadius: 16,
width: 140,
elevation: 10,
}}
onPress={handleNext}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 20,
fontWeight: 'bold',
}}>
ඊළඟ
</Text>
</TouchableOpacity>
)}
{isOnLastQuestions && (
<TouchableOpacity
style={{
backgroundColor: '#DE3163',
height: 50,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 20,
borderRadius: 16,
width: 150,
elevation: 10,
}}
onPress={handleNavigationToQuizScore}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 20,
fontWeight: 'bold',
}}>
ස්ථිර කරන්න
</Text>
</TouchableOpacity>
)}
</View>
</LinearGradient>
</ScrollView>
)}
</>
);
};
export default QuestionInSinhalaPage;
const styles = StyleSheet.create({
brandViewText: {
color: '#FFFFFF',
fontSize: 40,
fontWeight: 'bold',
},
bottomView: {
flex: 1.5,
backgroundColor: '#FFFFFF',
},
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
scrollContainer: {
flexGrow: 1,
},
contentContainer: {
paddingBottom: 40, // Adds padding at the bottom
},
});
/* eslint-disable react-native/no-inline-styles */
/* eslint-disable react/self-closing-comp */
import React from 'react';
import {
Text,
ImageBackground,
View,
StyleSheet,
TouchableOpacity,
} from 'react-native';
import {COLORS, ROUTES, IMGS} from '../../../constants';
const QuizOptionsPage = ({navigation}) => {
return (
<>
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<ImageBackground
source={IMGS.motherWithMidWife}
style={styles.backgroundImage}
resizeMode="cover"></ImageBackground>
</View>
<View style={styles.bottomView}>
<View style={{padding: 25}}>
<View
style={{
alignItems: 'center',
textAlign: 'center',
}}>
<Text
style={{
color: COLORS.navyBlue,
fontSize: 22,
fontWeight: 'bold',
marginBottom: 20,
fontFamily: 'monospace',
textAlign: 'center',
}}>
{' '}
We can improve your mental well-being...
</Text>
</View>
<View
style={{
alignItems: 'center',
padding: 10,
}}>
<Text
style={{
color: 'black',
fontSize: 18,
fontWeight: 'bold',
fontFamily: 'monospace',
textAlign: 'center',
}}>
Try with Us & Have a fun
</Text>
</View>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
color: 'black',
fontSize: 16,
fontWeight: 'bold',
marginTop: 20,
textAlign: 'center',
fontFamily: 'monospace',
}}>
Please give answers for this small questionnaire
</Text>
</View>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
color: 'black',
fontSize: 16,
fontWeight: 'bold',
marginTop: 30,
textAlign: 'center',
fontFamily: 'monospace',
}}>
Select Your Prefered Option to Answer
</Text>
</View>
<View style={{marginTop: 40}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: '100%',
elevation: 10,
}}
onPress={() => navigation.navigate(ROUTES.GAME_MAIN_DETAILS)}>
<Text
medium
center
style={{color: 'white', fontSize: 20, fontWeight: 'bold'}}>
English
</Text>
</TouchableOpacity>
</View>
<View style={{marginTop: 7}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.pastal_blue,
height: 50,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: '100%',
elevation: 10,
}}
onPress={() =>
navigation.navigate(ROUTES.MainDetailsFormInSinhala)
}>
<Text
medium
center
style={{color: 'white', fontSize: 20, fontWeight: 'bold'}}>
සිංහල
</Text>
</TouchableOpacity>
</View>
</View>
</View>
</>
);
};
const styles = StyleSheet.create({
brandViewText: {
color: '#F7A4A4',
fontSize: 40,
fontWeight: 'bold',
},
bottomView: {
flex: 2,
backgroundColor: '#FFC0D9',
},
backgroundImage: {
flex: 1,
width: 350,
height: 400,
borderRadius: 50,
},
});
export default QuizOptionsPage;
import React, {useState, useEffect} from 'react';
import {
View,
StyleSheet,
TouchableOpacity,
ImageBackground,
Text,
ActivityIndicator,
} from 'react-native';
import {COLORS, IMGS, ROUTES} from '../../../constants';
import {gameLevelPredict} from '../../../services/games';
const QuizScoreDisplayPage = ({route, navigation}) => {
const {formData} = route.params || {
formData: {},
};
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// Simulate a loading process, e.g., fetching data
const timer = setTimeout(() => {
setIsLoading(false);
}, 2000); // 2000 milliseconds = 2 seconds
return () => clearTimeout(timer); // Clean up the timer
}, []);
const handleChooseGamePress = async () => {
let musicFields = {
music_name_a: 0,
music_name_b: 0,
music_name_c: 0,
music_name_d: 0,
music_name_e: 0,
music_name_f: 0,
};
// Generate a random index to set one music name field to 1
const musicKeys = Object.keys(musicFields);
const randomIndex = Math.floor(Math.random() * musicKeys.length);
musicFields[musicKeys[randomIndex]] = 1;
try {
const response = await gameLevelPredict(
formData.age,
formData.depression_level,
formData.previous_child_birth_experiences,
formData.marital_status_divorced,
formData.marital_status_married,
formData.marital_status_single,
formData.family_background_bad,
formData.family_background_good,
formData.family_background_normal,
musicFields.music_name_a,
musicFields.music_name_b,
musicFields.music_name_c,
musicFields.music_name_d,
musicFields.music_name_e,
musicFields.music_name_f,
);
console.log(response.data.prediction, 'response.data.prediction');
if (response && response.data && response.data.prediction) {
console.log('API call successful with response:', response.data);
const predictedGameLevel = parseInt(
response.data.prediction.match(/\d+/)[0],
10,
);
navigation.navigate(ROUTES.MentalWellBeingTypes, {predictedGameLevel});
} else {
console.error('API call failed with response:', response.data);
}
} catch (error) {
console.error('API call encountered an error:', error);
}
};
return (
<>
{isLoading ? (
<View style={styles.loaderContainer}>
<ActivityIndicator size={150} color={COLORS.dark_purple} />
</View>
) : (
<ImageBackground
source={IMGS.game_img_5}
style={styles.backgroundImage}
resizeMode="cover">
<View style={styles.container}>
<Text style={styles.mainText}>Your Mental Well-Being</Text>
<View style={styles.mainCircle}>
<View style={styles.circle}>
<Text style={styles.scoreText}>
{formData.depression_level}/30
</Text>
</View>
</View>
<View style={styles.bottomContainer}>
<TouchableOpacity
style={styles.button}
onPress={handleChooseGamePress}>
<Text bold medium center style={styles.buttonText}>
Let's Improve Mental Well-Being
</Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
)}
</>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
height: 50,
},
backgroundImage: {
flex: 1,
width: '79%',
height: '80%',
},
circle: {
width: 180,
height: 180,
borderRadius: 100,
backgroundColor: '#FF9494',
alignItems: 'center',
justifyContent: 'center',
marginTop: 3,
},
mainCircle: {
width: 210,
height: 210,
borderRadius: 125,
backgroundColor: '#FFD1D1',
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#DE3163',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 1.84,
elevation: 5,
marginTop: 330,
marginLeft: 210,
},
scoreText: {
color: '#fff',
fontSize: 40,
},
mainText: {
color: '#000',
fontSize: 22,
marginBottom: 30,
fontWeight: 'bold',
justifyContent: 'center',
textAlign: 'center',
display: 'flex',
marginTop: 22,
},
button: {
backgroundColor: '#1572A1',
height: 50,
marginBottom: 90,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 160,
borderRadius: 14,
width: 350,
marginLeft: 250,
elevation: 10,
},
buttonText: {
color: 'white',
fontWeight: 'bold',
fontSize: 17,
},
bottomContainer: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
backgroundColor: '#9AD0EC',
borderTopLeftRadius: 65,
borderTopRightRadius: 165,
width: 500,
},
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default QuizScoreDisplayPage;
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import {Image, TouchableOpacity, Text, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../constants';
const WelcomePageGame = ({navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[COLORS.purple_new, COLORS.white, COLORS.purple]}>
<View>
<View>
<Image
source={IMGS.game_img_1}
style={{
height: 340,
width: 190,
borderRadius: 20,
position: 'absolute',
top: 2,
left: 2,
transform: [
{translateX: 50},
{translateY: 50},
{rotate: '-15deg'},
],
}}
/>
</View>
<View
style={{
paddingHorizontal: 22,
position: 'absolute',
top: 390,
width: '100%',
}}>
<Text
style={{
fontSize: 48,
color: COLORS.black,
fontWeight: 'bold',
}}>
Let's Get
</Text>
<Text
style={{
fontSize: 48,
color: COLORS.black,
fontWeight: 'bold',
}}>
Started...
</Text>
<View style={{marginVertical: 20}}>
<Text
style={{
fontSize: 16,
color: COLORS.black,
fontWeight: 'bold',
marginVertical: 20,
}}>
Enjoy every single moment.
</Text>
<Text
style={{
fontSize: 16,
color: COLORS.black,
fontWeight: 'bold',
}}>
Taking care of your mental helath is an act of self-love
</Text>
</View>
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.purple_new,
borderColor: COLORS.purple_new,
height: 50,
marginBottom: 70,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: '100%',
zIndex: 3,
elevation: 10,
}}
onPress={() => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS)}>
<Text
medium
center
style={{
color: 'white',
fontSize: 24,
fontWeight: 'bold',
}}>
Let Us Help You
</Text>
</TouchableOpacity>
</View>
</View>
</View>
</LinearGradient>
);
};
export default WelcomePageGame;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Alert,
Button,
ImageBackground,
} from 'react-native';
import {IMGS, ROUTES, COLORS} from '../../../../constants';
import Sound from 'react-native-sound';
const BoardSize = 3;
const CandyTypes = ['🤰', '🍼', '👶'];
const GameLevel0 = ({navigation}) => {
const [board, setBoard] = useState(createBoard());
const [score, setScore] = useState(0);
const [timeLeft, setTimeLeft] = useState(20);
const [selectedCandy, setSelectedCandy] = useState(null);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_a.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const resetGame = () => {
setBoard(createBoard());
// setScore(0);
// setTimeLeft(60); // Reset time to 60 seconds
setSelectedCandy(null);
};
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft(prev => (prev > 0 ? prev - 1 : 0));
}, 1000);
return () => clearInterval(timer);
}, []);
useEffect(() => {
if (timeLeft === 0 && score >= 25) {
Alert.alert(
'Congratulations 🥳🥳',
`Time is up! You win!
`,
[
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Level03);
},
},
],
);
} else if (timeLeft === 0 && score < 25) {
Alert.alert(
'Game Over',
`Time is up! You lose!
`,
[
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
},
},
],
);
}
}, [timeLeft, score, navigation]);
function createBoard() {
const newBoard = [];
for (let row = 0; row < BoardSize; row++) {
const newRow = [];
for (let col = 0; col < BoardSize; col++) {
newRow.push(CandyTypes[Math.floor(Math.random() * CandyTypes.length)]);
}
newBoard.push(newRow);
}
return newBoard;
}
function handlePress(row, col) {
if (selectedCandy) {
const [selectedRow, selectedCol] = selectedCandy;
const dx = Math.abs(selectedRow - row);
const dy = Math.abs(selectedCol - col);
if ((dx === 1 && dy === 0) || (dx === 0 && dy === 1)) {
// Adjacent candy selected
const newBoard = JSON.parse(JSON.stringify(board)); // Deep clone the board
[newBoard[selectedRow][selectedCol], newBoard[row][col]] = [
newBoard[row][col],
newBoard[selectedRow][selectedCol],
];
if (checkForMatch(newBoard)) {
setBoard(newBoard);
}
}
setSelectedCandy(null);
} else {
setSelectedCandy([row, col]);
}
}
function isBoardClear() {
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize; col++) {
if (board[row][col] !== null) {
return false;
}
}
}
return true;
}
function checkForMatch(board) {
const toClear = [];
// Check for horizontal matches
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize - 2; col++) {
const candy = board[row][col];
if (
candy &&
candy === board[row][col + 1] &&
candy === board[row][col + 2]
) {
toClear.push([row, col], [row, col + 1], [row, col + 2]);
}
}
}
// Check for vertical matches
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize - 2; row++) {
const candy = board[row][col];
if (
candy &&
candy === board[row + 1][col] &&
candy === board[row + 2][col]
) {
toClear.push([row, col], [row + 1, col], [row + 2, col]);
}
}
}
if (toClear.length === 0) return false; // No matches found
// Clear matched candies
let points = 0;
toClear.forEach(([row, col]) => {
if (board[row][col] !== null) {
points += 5; // Assuming each candy gives 5 points
board[row][col] = null;
}
});
setScore(prevScore => prevScore + points);
// Make candies fall down
for (let col = 0; col < BoardSize; col++) {
let shift = 0;
for (let row = BoardSize - 1; row >= 0; row--) {
if (board[row][col] === null) {
shift++;
} else if (shift > 0) {
board[row + shift][col] = board[row][col];
board[row][col] = null;
}
}
}
// Refill the board
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize; row++) {
if (board[row][col] === null) {
board[row][col] =
CandyTypes[Math.floor(Math.random() * CandyTypes.length)];
}
}
}
return true; // Matches were found and cleared
}
return (
<ImageBackground
source={IMGS.game_img_6}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginBottom: 40,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 12,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<Button
title="Refresh"
onPress={resetGame}
color="#097969"
style={{marginBottom: 10}}
/>
<Text style={styles.text}>Winning Score: 25</Text>
<Text style={styles.text}>Score: {score}</Text>
<Text style={styles.text}>Time Left: {timeLeft}s</Text>
<View style={styles.board}>
{board.map((row, rowIndex) => (
<View key={rowIndex} style={styles.row}>
{row.map((candy, colIndex) => (
<TouchableOpacity
key={colIndex}
style={styles.candy}
onPress={() => handlePress(rowIndex, colIndex)}>
<Text style={styles.candyText}>{candy}</Text>
</TouchableOpacity>
))}
</View>
))}
</View>
<View style={{marginTop: 90}}>
<TouchableOpacity
style={{
backgroundColor: '#804674',
height: 50,
marginBottom: 60,
justifyContent: 'center',
alignItems: 'center',
// marginHorizontal: 25,
borderRadius: 16,
width: 320,
}}
onPress={() => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS)}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 22,
fontWeight: 'bold',
}}>
Exit
</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
board: {
width: 250,
height: 250,
backgroundColor: '#CCCCFF',
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
// borderRadius: 25,
},
row: {
flex: 1,
flexDirection: 'row',
},
candy: {
flex: 1,
aspectRatio: 1,
justifyContent: 'center',
alignItems: 'center',
borderColor: 'white',
borderWidth: 1,
borderRadius: 4,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 2,
},
candyText: {
fontSize: 30,
textAlign: 'center',
textAlignVertical: 'center',
includeFontPadding: false,
flex: 1,
},
text: {
color: 'black',
marginBottom: 5,
fontWeight: 'bold',
fontSize: 16,
},
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default GameLevel0;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Alert,
Button,
ImageBackground,
} from 'react-native';
import {IMGS, ROUTES, COLORS} from '../../../../constants';
import Sound from 'react-native-sound';
const BoardSize = 8;
const CandyTypes = ['🤰', '🥦', '🐶', '🍧', '🍉', '🍄', '🍬', '👶', '🚫'];
const InitialTime = 80;
const levels = [
{
board: createBoard(),
winningScore: 50,
},
{
board: createBoard(),
winningScore: 60,
},
{
board: createBoard(),
winningScore: 80,
},
];
function createBoard() {
const newBoard = [];
for (let row = 0; row < BoardSize; row++) {
const newRow = [];
for (let col = 0; col < BoardSize; col++) {
newRow.push(CandyTypes[Math.floor(Math.random() * CandyTypes.length)]);
}
newBoard.push(newRow);
}
return newBoard;
}
const CandyCrushGameLevel04 = ({navigation}) => {
const [currentLevel, setCurrentLevel] = useState(0);
const [board, setBoard] = useState(levels[currentLevel].board);
const [score, setScore] = useState(0);
const [timeLeft, setTimeLeft] = useState(InitialTime);
const [selectedCandy, setSelectedCandy] = useState(null);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_e.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft(prev => (prev > 0 ? prev - 1 : 0));
}, 1000);
return () => clearInterval(timer);
}, []);
useEffect(() => {
if (timeLeft === 0) {
Alert.alert(
`${
score >= levels[currentLevel].winningScore
? 'Congratulations 🥳🥳'
: 'Game Over'
}`,
`Time is up! You ${
score >= levels[currentLevel].winningScore ? 'win!' : 'lose!'
}`,
);
resetGame();
}
}, [timeLeft]);
const resetGame = () => {
setBoard(createBoard());
setSelectedCandy(null);
};
const nextLevel = () => {
if (score >= levels[currentLevel].winningScore) {
if (currentLevel < levels.length - 1) {
Alert.alert(
'Congratulations 🥳🥳',
"You've reached the winning score! Moving on to the next level!",
);
setCurrentLevel(currentLevel + 1);
setBoard(levels[currentLevel + 1].board);
setScore(0);
setTimeLeft(InitialTime);
} else {
Alert.alert('Congratulations 🥳🥳', "You've completed all levels!", [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Level06);
},
},
]);
backgroundMusic.current.setVolume(0.0);
resetGame();
}
} else {
Alert.alert(
'Sorry!',
'You need to reach the winning score to advance to the next level.',
[
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
},
},
],
);
}
};
useEffect(() => {
if (score >= levels[currentLevel].winningScore) {
nextLevel();
}
}, [score]);
function createBoard() {
const newBoard = [];
for (let row = 0; row < BoardSize; row++) {
const newRow = [];
for (let col = 0; col < BoardSize; col++) {
newRow.push(CandyTypes[Math.floor(Math.random() * CandyTypes.length)]);
}
newBoard.push(newRow);
}
return newBoard;
}
const handlePress = (row, col) => {
if (board[row][col] === '🚫') return; // Prevent pressing the "🚫" emoji
if (selectedCandy) {
const [selectedRow, selectedCol] = selectedCandy;
const dx = Math.abs(selectedRow - row);
const dy = Math.abs(selectedCol - col);
if ((dx === 1 && dy === 0) || (dx === 0 && dy === 1)) {
// Adjacent candy selected
const newBoard = JSON.parse(JSON.stringify(board)); // Deep clone the board
[newBoard[selectedRow][selectedCol], newBoard[row][col]] = [
newBoard[row][col],
newBoard[selectedRow][selectedCol],
];
if (checkForMatch(newBoard)) {
setBoard(newBoard);
}
}
setSelectedCandy(null);
} else {
setSelectedCandy([row, col]);
}
};
function checkForMatch(board) {
const toClear = [];
// Check for horizontal matches
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize - 2; col++) {
const candy = board[row][col];
if (
candy &&
candy === board[row][col + 1] &&
candy === board[row][col + 2]
) {
toClear.push([row, col], [row, col + 1], [row, col + 2]);
}
}
}
// Check for vertical matches
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize - 2; row++) {
const candy = board[row][col];
if (
candy &&
candy === board[row + 1][col] &&
candy === board[row + 2][col]
) {
toClear.push([row, col], [row + 1, col], [row + 2, col]);
}
}
}
if (toClear.length === 0) return false; // No matches found
// Clear matched candies
let points = 0;
toClear.forEach(([row, col]) => {
if (board[row][col] !== null) {
points += 5; // Assuming each candy gives 5 points
board[row][col] = null;
}
});
setScore(prevScore => prevScore + points);
// Make candies fall down
for (let col = 0; col < BoardSize; col++) {
let shift = 0;
for (let row = BoardSize - 1; row >= 0; row--) {
if (board[row][col] === null) {
shift++;
} else if (shift > 0) {
board[row + shift][col] = board[row][col];
board[row][col] = null;
}
}
}
// Refill the board
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize; row++) {
if (board[row][col] === null) {
board[row][col] =
CandyTypes[Math.floor(Math.random() * CandyTypes.length)];
}
}
}
return true;
}
return (
<ImageBackground
source={IMGS.game_img_7}
style={styles.backgroundImage}
resizeMode="cover">
<View>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginBottom: 5,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
}}
onPress={toggleMute}>
<Text
medium
center
style={{
color: 'black',
fontSize: 30,
fontWeight: 'bold',
}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<Button
title="Refresh"
onPress={resetGame}
color="#702963"
sx={{marginBottom: 5}}
/>
<Text style={styles.text}>Level: {currentLevel + 1}</Text>
<Text style={styles.text}>
Winning Score: {levels[currentLevel].winningScore}
</Text>
<Text style={styles.text}>Score: {score}</Text>
<Text style={styles.text}>Time Left: {timeLeft}s</Text>
<Button
title="Next Level"
onPress={nextLevel}
color="#702963"
// style={{ marginBottom: 5, width: 100 }}
/>
<Text style={styles.text}> {''}</Text>
<View style={styles.board}>
{board.map((row, rowIndex) => (
<View key={rowIndex} style={styles.row}>
{row.map((candy, colIndex) => (
<TouchableOpacity
key={colIndex}
style={styles.candy}
onPress={() => handlePress(rowIndex, colIndex)}>
<Text style={styles.candyText}>{candy}</Text>
</TouchableOpacity>
))}
</View>
))}
</View>
<View>
<TouchableOpacity
style={{
backgroundColor: '#702963',
height: 50,
marginBottom: 60,
justifyContent: 'center',
alignItems: 'center',
// marginHorizontal: 25,
borderRadius: 16,
width: 320,
}}
onPress={() => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS)}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 22,
fontWeight: 'bold',
}}>
Exit
</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: 'black',
marginBottom: 5,
fontWeight: 'bold',
fontSize: 16,
},
board: {
width: 380,
height: 400,
backgroundColor: COLORS.navyBlue,
borderColor: 'white',
marginBottom: 40,
},
row: {
flex: 1,
flexDirection: 'row',
},
candy: {
flex: 1,
aspectRatio: 1,
justifyContent: 'center',
alignItems: 'center',
borderColor: 'white',
borderWidth: 1,
borderRadius: 4,
},
candyText: {
fontSize: 30,
},
});
export default CandyCrushGameLevel04;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Alert,
Button,
ImageBackground,
} from 'react-native';
import {IMGS, ROUTES, COLORS} from '../../../../constants';
import Sound from 'react-native-sound';
const BoardSize = 5;
const CandyTypes = ['🤰', '🍼', '🍀', '🧸', '🎈'];
const GameLevel1 = ({navigation}) => {
const [board, setBoard] = useState(createBoard());
const [score, setScore] = useState(0);
const [timeLeft, setTimeLeft] = useState(30);
const [selectedCandy, setSelectedCandy] = useState(null);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_b.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
// backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const resetGame = () => {
setBoard(createBoard());
// setScore(0);
// setTimeLeft(60); // Reset time to 60 seconds
setSelectedCandy(null);
};
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft(prev => (prev > 0 ? prev - 1 : 0));
}, 1000);
return () => clearInterval(timer);
}, []);
useEffect(() => {
if (timeLeft === 0 && score >= 50) {
Alert.alert(
'Congratulations 🥳🥳',
`Time is up! You win!
`,
[
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Level02);
},
},
],
);
backgroundMusic.current.setVolume(0.0);
} else if (timeLeft === 0 && score < 50) {
Alert.alert(
'Game Over',
`Time is up! You lose!
`,
[
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
},
},
],
);
}
}, [timeLeft, score, navigation]);
function createBoard() {
const newBoard = [];
for (let row = 0; row < BoardSize; row++) {
const newRow = [];
for (let col = 0; col < BoardSize; col++) {
newRow.push(CandyTypes[Math.floor(Math.random() * CandyTypes.length)]);
}
newBoard.push(newRow);
}
return newBoard;
}
function handlePress(row, col) {
if (selectedCandy) {
const [selectedRow, selectedCol] = selectedCandy;
const dx = Math.abs(selectedRow - row);
const dy = Math.abs(selectedCol - col);
if ((dx === 1 && dy === 0) || (dx === 0 && dy === 1)) {
// Adjacent candy selected
const newBoard = JSON.parse(JSON.stringify(board)); // Deep clone the board
[newBoard[selectedRow][selectedCol], newBoard[row][col]] = [
newBoard[row][col],
newBoard[selectedRow][selectedCol],
];
if (checkForMatch(newBoard)) {
setBoard(newBoard);
}
}
setSelectedCandy(null);
} else {
setSelectedCandy([row, col]);
}
}
function isBoardClear() {
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize; col++) {
if (board[row][col] !== null) {
return false;
}
}
}
return true;
}
function checkForMatch(board) {
const toClear = [];
// Check for horizontal matches
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize - 2; col++) {
const candy = board[row][col];
if (
candy &&
candy === board[row][col + 1] &&
candy === board[row][col + 2]
) {
toClear.push([row, col], [row, col + 1], [row, col + 2]);
}
}
}
// Check for vertical matches
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize - 2; row++) {
const candy = board[row][col];
if (
candy &&
candy === board[row + 1][col] &&
candy === board[row + 2][col]
) {
toClear.push([row, col], [row + 1, col], [row + 2, col]);
}
}
}
if (toClear.length === 0) return false; // No matches found
// Clear matched candies
let points = 0;
toClear.forEach(([row, col]) => {
if (board[row][col] !== null) {
points += 5; // Assuming each candy gives 5 points
board[row][col] = null;
}
});
setScore(prevScore => prevScore + points);
// Make candies fall down
for (let col = 0; col < BoardSize; col++) {
let shift = 0;
for (let row = BoardSize - 1; row >= 0; row--) {
if (board[row][col] === null) {
shift++;
} else if (shift > 0) {
board[row + shift][col] = board[row][col];
board[row][col] = null;
}
}
}
// Refill the board
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize; row++) {
if (board[row][col] === null) {
board[row][col] =
CandyTypes[Math.floor(Math.random() * CandyTypes.length)];
}
}
}
return true; // Matches were found and cleared
}
return (
<ImageBackground
source={IMGS.game_img_6}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginBottom: 40,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 12,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<Button
title="Refresh"
onPress={resetGame}
color="#097969"
style={{marginBottom: 10}}
/>
<Text style={styles.text}>Winning Score: 50</Text>
<Text style={styles.text}>Score: {score}</Text>
<Text style={styles.text}>Time Left: {timeLeft}s</Text>
<View style={styles.board}>
{board.map((row, rowIndex) => (
<View key={rowIndex} style={styles.row}>
{row.map((candy, colIndex) => (
<TouchableOpacity
key={colIndex}
style={styles.candy}
onPress={() => handlePress(rowIndex, colIndex)}>
<Text style={styles.candyText}>{candy}</Text>
</TouchableOpacity>
))}
</View>
))}
</View>
<View style={{marginTop: 50}}>
<TouchableOpacity
style={{
backgroundColor: '#804674',
height: 50,
marginBottom: 60,
justifyContent: 'center',
alignItems: 'center',
// marginHorizontal: 25,
borderRadius: 16,
width: 320,
}}
onPress={() => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS)}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 22,
fontWeight: 'bold',
}}>
Exit
</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
board: {
width: 350,
height: 350,
backgroundColor: '#F33A6A',
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
// borderRadius: 25,
},
row: {
flex: 1,
flexDirection: 'row',
},
candy: {
flex: 1,
aspectRatio: 1,
justifyContent: 'center',
alignItems: 'center',
borderColor: 'white',
borderWidth: 1,
borderRadius: 4,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 2,
},
candyText: {
fontSize: 30,
textAlign: 'center',
textAlignVertical: 'center',
includeFontPadding: false,
flex: 1,
},
text: {
color: 'black',
marginBottom: 5,
fontWeight: 'bold',
fontSize: 16,
},
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default GameLevel1;
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Alert,
Button,
ImageBackground,
} from 'react-native';
import {IMGS, ROUTES, COLORS} from '../../../../constants';
import Sound from 'react-native-sound';
const BoardSize = 7; // Increased board size
const CandyTypes = ['🤰', '🍼', '🌼', '🧸', '🤱', '🍇', '🍬']; // Increased candy types
const WinningScore = 100;
const CandyCrushGameLevel02 = ({navigation}) => {
const [board, setBoard] = useState(createBoard());
const [score, setScore] = useState(0);
const [timeLeft, setTimeLeft] = useState(50);
const [selectedCandy, setSelectedCandy] = useState(null);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_c.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
// backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const resetGame = () => {
setBoard(createBoard());
// setScore(0);
// setTimeLeft(60); // Reset time to 60 seconds
setSelectedCandy(null);
};
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft(prev => (prev > 0 ? prev - 1 : 0));
}, 1000);
return () => clearInterval(timer);
}, []);
useEffect(() => {
if (timeLeft === 0 && score >= 55) {
Alert.alert(
'Congratulations 🥳🥳',
`Time is up! You win!
`,
[
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Level03);
},
},
],
);
backgroundMusic.current.setVolume(0.0);
} else if (timeLeft === 0 && score < 55) {
Alert.alert(
'Game Over',
`Time is up! You lose!
`,
[
{
text: 'OK',
onPress: () => {
// Navigate to different screens based on the score
// if (score >= 50) {
// navigation.navigate("GameLevel03");
// } else {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
// }
},
},
],
);
}
}, [timeLeft, score, navigation]);
function createBoard() {
const newBoard = [];
for (let row = 0; row < BoardSize; row++) {
const newRow = [];
for (let col = 0; col < BoardSize; col++) {
newRow.push(CandyTypes[Math.floor(Math.random() * CandyTypes.length)]);
}
newBoard.push(newRow);
}
return newBoard;
}
function handlePress(row, col) {
if (selectedCandy) {
const [selectedRow, selectedCol] = selectedCandy;
const dx = Math.abs(selectedRow - row);
const dy = Math.abs(selectedCol - col);
if ((dx === 1 && dy === 0) || (dx === 0 && dy === 1)) {
// Adjacent candy selected
const newBoard = JSON.parse(JSON.stringify(board)); // Deep clone the board
[newBoard[selectedRow][selectedCol], newBoard[row][col]] = [
newBoard[row][col],
newBoard[selectedRow][selectedCol],
];
if (checkForMatch(newBoard)) {
setBoard(newBoard);
}
}
setSelectedCandy(null);
} else {
setSelectedCandy([row, col]);
}
}
function isBoardClear() {
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize; col++) {
if (board[row][col] !== null) {
return false;
}
}
}
return true;
}
function checkForMatch(board) {
const toClear = [];
// Check for horizontal matches
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize - 2; col++) {
const candy = board[row][col];
if (
candy &&
candy === board[row][col + 1] &&
candy === board[row][col + 2]
) {
toClear.push([row, col], [row, col + 1], [row, col + 2]);
}
}
}
// Check for vertical matches
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize - 2; row++) {
const candy = board[row][col];
if (
candy &&
candy === board[row + 1][col] &&
candy === board[row + 2][col]
) {
toClear.push([row, col], [row + 1, col], [row + 2, col]);
}
}
}
if (toClear.length === 0) return false; // No matches found
// Clear matched candies
let points = 0;
toClear.forEach(([row, col]) => {
if (board[row][col] !== null) {
points += 5; // Assuming each candy gives 5 points
board[row][col] = null;
}
});
setScore(prevScore => prevScore + points);
// Make candies fall down
for (let col = 0; col < BoardSize; col++) {
let shift = 0;
for (let row = BoardSize - 1; row >= 0; row--) {
if (board[row][col] === null) {
shift++;
} else if (shift > 0) {
board[row + shift][col] = board[row][col];
board[row][col] = null;
}
}
}
// Refill the board
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize; row++) {
if (board[row][col] === null) {
board[row][col] =
CandyTypes[Math.floor(Math.random() * CandyTypes.length)];
}
}
}
return true; // Matches were found and cleared
}
return (
<ImageBackground
source={IMGS.game_img_7}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginBottom: 40,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 12,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<Button
title="Refresh"
onPress={resetGame}
color="#DE3163"
style={{marginBottom: 10}}
/>
<Text style={styles.text}>Winning Score: 55</Text>
<Text style={styles.text}>Score: {score}</Text>
<Text style={styles.text}>Time Left: {timeLeft}s</Text>
<View style={styles.board}>
{board.map((row, rowIndex) => (
<View key={rowIndex} style={styles.row}>
{row.map((candy, colIndex) => (
<TouchableOpacity
key={colIndex}
style={styles.candy}
onPress={() => handlePress(rowIndex, colIndex)}>
<Text style={styles.candyText}>{candy}</Text>
</TouchableOpacity>
))}
</View>
))}
</View>
<View style={{marginTop: 90}}>
<TouchableOpacity
style={{
backgroundColor: '#DE3163',
height: 50,
marginBottom: 60,
justifyContent: 'center',
alignItems: 'center',
// marginHorizontal: 25,
borderRadius: 16,
width: 320,
}}
onPress={() => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS)}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 22,
fontWeight: 'bold',
}}>
Exit
</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
board: {
width: 380, // Adjusted according to the new board size
height: 400, // Adjusted according to the new board size
backgroundColor: '#097969',
borderColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
candy: {
flex: 1,
aspectRatio: 1,
justifyContent: 'center',
alignItems: 'center',
borderColor: 'white',
borderWidth: 1,
borderRadius: 4,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 2,
},
candyText: {
fontSize: 30,
textAlign: 'center',
textAlignVertical: 'center',
includeFontPadding: false,
flex: 1,
},
text: {
color: 'black',
marginBottom: 5,
fontWeight: 'bold',
fontSize: 16,
},
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default CandyCrushGameLevel02;
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Alert,
Button,
ImageBackground,
} from 'react-native';
import {IMGS, ROUTES, COLORS} from '../../../../constants';
import Sound from 'react-native-sound';
const BoardSize = 8;
const CandyTypes = ['🤰', '🥦', '🐶', '🍧', '🍉', '🍄', '🍬', '👶', '🚫'];
const WinningScore = 75;
const InitialTime = 60;
const CandyCrushGameLevel03 = ({navigation}) => {
const [board, setBoard] = useState(createBoard());
const [score, setScore] = useState(0);
const [timeLeft, setTimeLeft] = useState(60);
const [selectedCandy, setSelectedCandy] = useState(null);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_d.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft(prev => (prev > 0 ? prev - 1 : 0));
}, 1000);
return () => clearInterval(timer);
}, []);
useEffect(() => {
if (timeLeft === 0 && score >= 75) {
Alert.alert(
'Congratulations 🥳🥳',
`Time is up! You win!
`,
[
{
text: 'OK',
onPress: () => {
// Navigate to different screens based on the score
// if (score >= 50) {
navigation.navigate(ROUTES.Level04);
// } else {
// navigation.navigate("Candy Crush");
// }
},
},
],
);
backgroundMusic.current.setVolume(0.0);
} else if (timeLeft === 0 && score < 75) {
Alert.alert(
'Game Over',
`Time is up! You lose!
`,
[
{
text: 'OK',
onPress: () => {
// Navigate to different screens based on the score
// if (score >= 50) {
// navigation.navigate("GameLevel03");
// } else {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
// }
},
},
],
);
}
}, [timeLeft, score, navigation]);
function createBoard() {
const newBoard = [];
for (let row = 0; row < BoardSize; row++) {
const newRow = [];
for (let col = 0; col < BoardSize; col++) {
newRow.push(CandyTypes[Math.floor(Math.random() * CandyTypes.length)]);
}
newBoard.push(newRow);
}
return newBoard;
}
const resetGame = () => {
setBoard(createBoard());
// setScore(0);
// setTimeLeft(InitialTime);
setSelectedCandy(null);
};
const handlePress = (row, col) => {
if (board[row][col] === '🚫') return; // Prevent pressing the "🚫" emoji
if (selectedCandy) {
const [selectedRow, selectedCol] = selectedCandy;
const dx = Math.abs(selectedRow - row);
const dy = Math.abs(selectedCol - col);
if ((dx === 1 && dy === 0) || (dx === 0 && dy === 1)) {
// Adjacent candy selected
const newBoard = JSON.parse(JSON.stringify(board)); // Deep clone the board
[newBoard[selectedRow][selectedCol], newBoard[row][col]] = [
newBoard[row][col],
newBoard[selectedRow][selectedCol],
];
if (checkForMatch(newBoard)) {
setBoard(newBoard);
}
}
setSelectedCandy(null);
} else {
setSelectedCandy([row, col]);
}
};
function checkForMatch(board) {
const toClear = [];
// Check for horizontal matches
for (let row = 0; row < BoardSize; row++) {
for (let col = 0; col < BoardSize - 2; col++) {
const candy = board[row][col];
if (
candy &&
candy === board[row][col + 1] &&
candy === board[row][col + 2]
) {
toClear.push([row, col], [row, col + 1], [row, col + 2]);
}
}
}
// Check for vertical matches
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize - 2; row++) {
const candy = board[row][col];
if (
candy &&
candy === board[row + 1][col] &&
candy === board[row + 2][col]
) {
toClear.push([row, col], [row + 1, col], [row + 2, col]);
}
}
}
if (toClear.length === 0) return false; // No matches found
// Clear matched candies
let points = 0;
toClear.forEach(([row, col]) => {
if (board[row][col] !== null) {
points += 5; // Assuming each candy gives 5 points
board[row][col] = null;
}
});
setScore(prevScore => prevScore + points);
// Make candies fall down
for (let col = 0; col < BoardSize; col++) {
let shift = 0;
for (let row = BoardSize - 1; row >= 0; row--) {
if (board[row][col] === null) {
shift++;
} else if (shift > 0) {
board[row + shift][col] = board[row][col];
board[row][col] = null;
}
}
}
// Refill the board
for (let col = 0; col < BoardSize; col++) {
for (let row = 0; row < BoardSize; row++) {
if (board[row][col] === null) {
board[row][col] =
CandyTypes[Math.floor(Math.random() * CandyTypes.length)];
}
}
}
return true; // Matches were found and cleared
}
return (
<ImageBackground
source={IMGS.game_img_8}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginBottom: 40,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 12,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<Button title="Refresh" onPress={resetGame} color="#702963" />
<Text style={styles.text}>Winning Score: 75</Text>
<Text style={styles.text}>Score: {score}</Text>
<Text style={styles.text}>Time Left: {timeLeft}s</Text>
<View style={styles.board}>
{board.map((row, rowIndex) => (
<View key={rowIndex} style={styles.row}>
{row.map((candy, colIndex) => (
<TouchableOpacity
key={colIndex}
style={styles.candy}
onPress={() => handlePress(rowIndex, colIndex)}>
<Text style={styles.candyText}>{candy}</Text>
</TouchableOpacity>
))}
</View>
))}
</View>
<View style={{marginTop: 60}}>
<TouchableOpacity
style={{
backgroundColor: '#702963',
height: 50,
marginBottom: 60,
justifyContent: 'center',
alignItems: 'center',
// marginHorizontal: 25,
borderRadius: 16,
width: 320,
}}
onPress={() => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS)}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 22,
fontWeight: 'bold',
}}>
Exit
</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: 'black',
marginBottom: 5,
fontWeight: 'bold',
fontSize: 16,
},
board: {
width: 380,
height: 400,
backgroundColor: '#191970',
borderColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
candy: {
flex: 1,
aspectRatio: 1,
justifyContent: 'center',
alignItems: 'center',
borderColor: 'white',
borderWidth: 1,
borderRadius: 4,
},
candyText: {
fontSize: 30,
},
});
export default CandyCrushGameLevel03;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
Image,
StyleSheet,
Alert,
ImageBackground,
} from 'react-native';
import {IMGS, COLORS, ROUTES} from '../../../../constants';
import Sound from 'react-native-sound';
const rockImage = IMGS.game_img_10;
const paperImage = IMGS.game_img_11;
const scissorsImage = IMGS.game_img_12;
const choices = {
rock: rockImage,
paper: paperImage,
scissors: scissorsImage,
};
const getChoiceImage = choice => {
return choices[choice];
};
const GameLevel5 = ({navigation}) => {
const [playerChoice, setPlayerChoice] = useState(null);
const [computerChoice, setComputerChoice] = useState(null);
const [result, setResult] = useState('');
const [points, setPoints] = useState(0);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_f.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
useEffect(() => {
if (points >= 200) {
Alert.alert('Congratulations 🥳🥳', 'You have won the game!', [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Level06);
},
},
]);
setPoints(0);
backgroundMusic.current.setVolume(0.0);
}
}, [points]);
const play = choice => {
const computer = getRandomChoice();
const result = getWinner(choice, computer);
setPlayerChoice(choice);
setComputerChoice(computer);
setResult(result);
if (result === 'You Win!') {
setPoints(currentPoints => {
const updatedPoints = currentPoints + 10;
return updatedPoints;
});
}
};
useEffect(() => {
console.log(`Points updated: ${points}`);
}, [points]);
const getRandomChoice = () => {
const keys = Object.keys(choices);
const randomIndex = Math.floor(Math.random() * keys.length);
return keys[randomIndex];
};
const getWinner = (player, computer) => {
if (player === computer) return 'Draw';
if (
(player === 'rock' && computer === 'scissors') ||
(player === 'paper' && computer === 'rock') ||
(player === 'scissors' && computer === 'paper')
) {
return 'You Win!';
} else {
return 'Computer Wins!';
}
};
return (
<ImageBackground
source={IMGS.game_img_9}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 10}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginBottom: 2,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
// marginTop: 4,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<Text style={styles.headerText}>Rock Paper Scissors</Text>
<View style={styles.new}>
<Text style={styles.resultText}>Result: {result ? result : '-'}</Text>
<Text style={styles.pointsText}>Points: {points}</Text>
</View>
<View colors={['#9D50BB', '#6E48AA']} style={styles.gradient}>
<View style={styles.resultContainer}>
<View style={styles.circle}>
<Text style={styles.playerText}>Computer</Text>
{computerChoice && (
<Image
source={getChoiceImage(computerChoice)}
style={styles.choiceImage}
/>
)}
</View>
<Text style={styles.resultText}>VS</Text>
<View style={styles.circle}>
<Text style={styles.playerText}>You</Text>
{playerChoice && (
<Image
source={getChoiceImage(playerChoice)}
style={styles.choiceImage}
/>
)}
</View>
</View>
<View style={styles.choicesContainer}>
<View style={styles.square}>
<TouchableOpacity
onPress={() => play('rock')}
style={styles.choiceButton}>
<Image source={rockImage} style={styles.choiceImage} />
</TouchableOpacity>
</View>
<View style={styles.square}>
<TouchableOpacity
onPress={() => play('paper')}
style={styles.choiceButton}>
<Image source={paperImage} style={styles.choiceImage} />
</TouchableOpacity>
</View>
<View style={styles.square}>
<TouchableOpacity
onPress={() => play('scissors')}
style={styles.choiceButton}>
<Image source={scissorsImage} style={styles.choiceImage} />
</TouchableOpacity>
</View>
</View>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
gradient: {
flex: 1,
alignItems: 'center',
justifyContent: 'space-around',
padding: 30,
// backgroundColor: 'black',
},
headerText: {
fontSize: 30,
color: '#9400D3',
fontWeight: 'bold',
// marginTop: 3,
marginBottom: 20,
},
choicesContainer: {
flexDirection: 'row',
alignItems: 'center',
},
choiceButton: {
margin: 10,
padding: 10,
},
choiceImage: {
width: 100,
height: 100,
},
resultContainer: {
alignItems: 'center',
justifyContent: 'center',
},
resultText: {
fontSize: 24,
color: 'black',
fontWeight: 'bold',
marginTop: 1,
},
playerText: {
fontSize: 16,
color: 'white',
fontWeight: 'bold',
marginTop: 20,
marginBottom: 15,
},
pointsText: {
fontSize: 20,
fontWeight: 'bold',
color: 'black', // Make sure this color is visible on your background
// add other styles to position your points text if necessary
},
circle: {
width: 160,
height: 160,
borderRadius: 105,
backgroundColor: '#553C8B',
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#6F2DA8',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 1.84,
elevation: 5,
},
square: {
width: 100,
height: 100,
borderRadius: 20,
backgroundColor: '#CCC1FF',
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#CCCCFF',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 2,
elevation: 5,
marginRight: 10,
marginBottom: 42,
marginTop: 22,
},
mainsquare: {
width: 200,
height: 250,
borderRadius: 20,
backgroundColor: '#E8ADAA',
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#CCCCFF',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 2,
elevation: 5,
},
new: {
backgroundColor: '#F6A7BA',
width: '80%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: 100,
borderRadius: 30,
},
});
export default GameLevel5;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
Image,
StyleSheet,
Alert,
ImageBackground,
} from 'react-native';
import {IMGS, ROUTES, COLORS} from '../../../../constants';
import Sound from 'react-native-sound';
const babyImage = IMGS.game_img_13;
const cartImage = IMGS.game_img_14;
const shoes = IMGS.game_img_16;
const cloth = IMGS.game_img_17;
const choices = {
babyImage: babyImage,
cartImage: cartImage,
shoes: shoes,
cloth: cloth,
};
const getChoiceImage = choice => {
return choices[choice];
};
const GameLevel6 = () => {
const [playerChoice, setPlayerChoice] = useState(null);
const [computerChoice, setComputerChoice] = useState(null);
const [computerChoice2, setComputerChoice2] = useState(null);
const [computerChoice3, setComputerChoice3] = useState(null);
const [result, setResult] = useState('');
const [points, setPoints] = useState(0);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_f.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
useEffect(() => {
if (points >= 200) {
Alert.alert('Congratulations 🥳🥳', 'You have won the game!');
setPoints(0);
backgroundMusic.current.setVolume(0.0);
}
}, [points]);
const play = choice => {
const computer = getRandomChoice();
const computerChoice2 = getRandomChoice();
const computerChoice3 = getRandomChoice();
const result = getWinner(
choice,
computer,
computerChoice2,
computerChoice3,
);
setPlayerChoice(choice);
setComputerChoice(computer);
setComputerChoice2(computerChoice2);
setComputerChoice3(computerChoice3);
setResult(result);
if (result === 'You Win!') {
setPoints(currentPoints => {
const updatedPoints = currentPoints + 10;
return updatedPoints;
});
}
};
useEffect(() => {
console.log(`Points updated: ${points}`);
}, [points]);
const getRandomChoice = () => {
const keys = Object.keys(choices);
const randomIndex = Math.floor(Math.random() * keys.length);
return keys[randomIndex];
};
const getWinner = (player, computer1, computer2, computer3) => {
const choices = [player, computer1, computer2, computer3];
const winConditions = {
babyImage: 'babyImage',
cartImage: 'cartImage',
shoes: 'shoes',
cloth: 'cloth',
};
let playerWins = 0;
let computerWins = {computer1: 0, computer2: 0, computer3: 0};
choices.forEach((choice, index) => {
for (let i = 0; i < choices.length; i++) {
if (i !== index) {
if (winConditions[choice] === choices[i]) {
if (index === 0) {
playerWins += 1;
} else {
computerWins[`computer${index}`] += 1;
}
}
}
}
});
// Evaluate overall result
if (playerWins > 0) {
return 'You Win!';
} else if (Object.values(computerWins).some(val => val > 0)) {
return 'Computer Wins!';
} else {
return 'Draw';
}
};
return (
<ImageBackground
source={IMGS.game_img_15}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 10}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
// marginBottom: 2,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<View colors={['#9D50BB', '#6E48AA']} style={styles.gradient}>
{/* <Text style={styles.headerText}>Rock Paper Scissors</Text> */}
<View style={styles.resultContainer}>
<View style={styles.rowContainer}>
<View style={styles.circle}>
<Text style={styles.playerText}>Player 01</Text>
{computerChoice && (
<Image
source={getChoiceImage(computerChoice)}
style={styles.selectImage}
/>
)}
</View>
<View style={styles.circle}>
<Text style={styles.playerText}>Player 02</Text>
{playerChoice && (
<Image
source={getChoiceImage(computerChoice2)}
style={styles.selectImage}
/>
)}
</View>
</View>
<Text style={styles.resultText}>VS</Text>
<View style={styles.rowContainer}>
<View style={styles.circle}>
<Text style={styles.playerText}>Player 03</Text>
{playerChoice && (
<Image
source={getChoiceImage(computerChoice3)}
style={styles.selectImage}
/>
)}
</View>
<View style={styles.circle}>
<Text style={styles.playerText}>You</Text>
{playerChoice && (
<Image
source={getChoiceImage(playerChoice)}
style={styles.selectImage}
/>
)}
</View>
</View>
<Text style={styles.resultText}>Result: {result}</Text>
<Text style={styles.pointsText}>Points: {points}</Text>
</View>
<View style={styles.choicesContainer}>
<View style={styles.square}>
<TouchableOpacity
onPress={() => play('babyImage')}
style={styles.choiceButton}>
<Image source={babyImage} style={styles.choiceImage} />
</TouchableOpacity>
</View>
<View style={styles.square}>
<TouchableOpacity
onPress={() => play('cart')}
style={styles.choiceButton}>
<Image source={cartImage} style={styles.choiceImage} />
</TouchableOpacity>
</View>
<View style={styles.square}>
<TouchableOpacity
onPress={() => play('cloth')}
style={styles.choiceButton}>
<Image source={cloth} style={styles.choiceImage} />
</TouchableOpacity>
</View>
<View style={styles.square}>
<TouchableOpacity
onPress={() => play('shoes')}
style={styles.choiceButton}>
<Image source={shoes} style={styles.choiceImage} />
</TouchableOpacity>
</View>
</View>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
gradient: {
flex: 1,
alignItems: 'center',
justifyContent: 'space-around',
padding: 10,
},
headerText: {
fontSize: 30,
color: '#9400D3',
fontWeight: 'bold',
marginTop: 10,
},
choicesContainer: {
flexDirection: 'row',
alignItems: 'center',
},
rowContainer: {
flexDirection: 'row',
alignItems: 'center',
},
choiceButton: {
margin: 10,
padding: 10,
},
choiceImage: {
width: 60,
height: 60,
},
selectImage: {
width: 100,
height: 100,
},
resultContainer: {
alignItems: 'center',
justifyContent: 'center',
},
resultText: {
fontSize: 24,
color: 'black',
fontWeight: 'bold',
marginTop: 10,
},
playerText: {
fontSize: 16,
color: 'white',
fontWeight: 'bold',
marginTop: 20,
marginBottom: 15,
},
pointsText: {
fontSize: 20,
fontWeight: 'bold',
color: 'black', // Make sure this color is visible on your background
// add other styles to position your points text if necessary
},
circle: {
width: 160,
height: 170,
borderRadius: 85,
backgroundColor: '#000033',
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#6F2DA8',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 1.84,
elevation: 5,
margin: 20,
},
square: {
width: 80,
height: 80,
borderRadius: 20,
backgroundColor: '#54BAB9',
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#CCCCFF',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 2,
elevation: 5,
gap: 85,
margin: 7,
marginBottom: 56,
},
mainsquare: {
width: 200,
height: 250,
borderRadius: 20,
backgroundColor: '#E8ADAA',
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#CCCCFF',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 2,
elevation: 5,
},
});
export default GameLevel6;
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import {
ScrollView,
ImageBackground,
Text,
View,
StyleSheet,
TouchableOpacity,
} from 'react-native';
import {ROUTES, COLORS} from '../../../../constants';
import LinearGradient from 'react-native-linear-gradient';
const Level01InstructionsPage = ({navigation}) => {
return (
<>
<ScrollView style={styles.container}>
<LinearGradient
style={{
flex: 1,
}}
colors={[COLORS.white, COLORS.light_purple]}>
{/* <View style={{ backgroundColor: "#FFDFDD", height: '100%' }}> */}
<View style={{padding: 25}}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
}}>
<Text
style={{
display: 'flex',
color: '#000080',
fontSize: 28,
fontWeight: 'bold',
marginBottom: 25,
marginTop: 35,
}}>
INSTRUCTIONS
</Text>
</View>
<View
style={{
justifyContent: 'center',
padding: 10,
}}>
<Text
style={{
color: 'black',
fontSize: 16,
// fontWeight: "bold",
textAlign: 'justify',
marginTop: 30,
}}>
01. You can match same candy types more than three.
</Text>
<Text
style={{
color: 'black',
fontSize: 16,
// fontWeight: "bold",
textAlign: 'justify',
marginTop: 20,
}}>
02. After matching same type candy types, those are removed.
</Text>
<Text
style={{
color: 'black',
fontSize: 16,
// fontWeight: "bold",
textAlign: 'justify',
marginTop: 20,
}}>
03. According to your matching, you can get a score for that.
</Text>
<Text
style={{
color: 'black',
fontSize: 16,
// fontWeight: "bold",
textAlign: 'justify',
marginTop: 20,
}}>
04. You can get an any score in the give time period.
</Text>
<Text
style={{
color: 'black',
fontSize: 16,
// fontWeight: "bold",
textAlign: 'justify',
marginTop: 20,
}}>
05. The game will be given winning score automatically.
</Text>
<Text
style={{
color: 'black',
fontSize: 16,
// fontWeight: "bold",
textAlign: 'justify',
marginTop: 20,
}}>
06. If you get a highest score more than winning score, You can
win the game.
</Text>
<Text
style={{
color: 'black',
fontSize: 16,
// fontWeight: "bold",
textAlign: 'justify',
marginTop: 20,
}}>
07. If you cannot find same cand types, you can click refresh
button to refresh the board. (Your score and remaining time
period will not change.)
</Text>
</View>
<View style={{marginTop: 40}}>
<TouchableOpacity
style={{
backgroundColor: '#A685E2',
height: 50,
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
// marginHorizontal: 25,
borderRadius: 16,
width: '100%',
}}
onPress={() => navigation.navigate(ROUTES.GameLevel0)}>
<Text
bold
medium
center
style={{
color: 'white',
fontSize: 22,
fontWeight: 'bold',
}}>
Play
</Text>
</TouchableOpacity>
</View>
{/* </View> */}
</View>
</LinearGradient>
</ScrollView>
</>
);
};
const styles = StyleSheet.create({
brandViewText: {
color: '#F5A8A8',
fontSize: 40,
fontWeight: 'bold',
},
});
export default Level01InstructionsPage;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Level01 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>1</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.GameLevel0)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Level01;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Level02 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>2</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.GameLevel1)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Level02;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Level03 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>3</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.GameLevel2)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Level03;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Level04 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>5</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.GameLevel4)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Level04;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
import GameLevel5 from '../GameLevel5';
const Level05 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>4</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.GameLevel3)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Level05;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Level06 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>3</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.GameLevel3)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Level06;
/* eslint-disable prettier/prettier */
/* eslint-disable react-native/no-inline-styles */
// Import statements
import React, {useState, useRef, useEffect} from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Image,
Alert,
ScrollView,
} from 'react-native';
import {COLORS, IMGS, ROUTES} from '../../../../constants';
import Sound from 'react-native-sound';
const Game02Level01 = ({navigation, route}) => {
const [budget, setBudget] = useState(5000); // Starting budget
const [collectedItems, setCollectedItems] = useState([]);
const [healthyCost, setHealthyCost] = useState(0);
const [unhealthyCost, setUnhealthyCost] = useState(0);
const cartIcon = IMGS.game_img_18;
const [cartVisible, setCartVisible] = useState(false);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_a.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const openCart = () => {
setCartVisible(true);
};
// Dummy data for items
const items = [
{
id: 1,
name: 'Spinach',
cost: 150,
type: 'healthy',
image: IMGS.game_img_19,
},
{
id: 2,
name: 'Candy',
cost: 150,
type: 'unhealthy',
image: IMGS.game_img_20,
},
{
id: 3,
name: 'Carrot',
cost: 250,
type: 'healthy',
image: IMGS.game_img_21,
},
{
id: 4,
name: 'French Fries',
cost: 140,
type: 'unhealthy',
image: IMGS.game_img_22,
},
{
id: 5,
name: 'Tomato',
cost: 130,
type: 'healthy',
image: IMGS.game_img_23,
},
{
id: 6,
name: 'Doughnut',
cost: 100,
type: 'unhealthy',
image: IMGS.game_img_24,
},
{
id: 7,
name: 'Fruits',
cost: 250,
type: 'healthy',
image: IMGS.game_img_25,
},
{
id: 8,
name: 'Eggs',
cost: 80,
type: 'healthy',
image: IMGS.game_img_26,
},
{
id: 9,
name: 'Milk',
cost: 200,
type: 'healthy',
image: IMGS.game_img_27,
},
{
id: 10,
name: 'Water',
cost: 150,
type: 'healthy',
image: IMGS.game_img_28,
},
{
id: 11,
name: 'Hot dogs',
cost: 150,
type: 'unhealthy',
image: IMGS.game_img_29,
},
{
id: 12,
name: 'Oats',
cost: 300,
type: 'healthy',
image: IMGS.game_img_30,
},
];
const collectItem = item => {
if (budget - item.cost >= 0) {
setBudget(budget - item.cost);
setCollectedItems([...collectedItems, item]);
if (item.type === 'healthy') {
setHealthyCost(prevCost => prevCost + item.cost);
} else {
setUnhealthyCost(prevCost => prevCost + item.cost);
}
// Use a setTimeout to ensure state updates have been applied before check
setTimeout(() => {
if (unhealthyCost + item.cost > 2000) { // ensure the current cost is added to total for the check
Alert.alert('Game lost!', 'Choose healthier foods. 🍇🍌🍉🥬🥕🍒',
[
{
text: 'OK',
onPress: () => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS),
},
]);
} else if (healthyCost + item.cost > 2000) { // ensure the current cost is added to total for the check
Alert.alert('Game won!', 'Congratulations! You have made healthy choices.',
[
{
text: 'OK',
onPress: () => navigation.navigate(ROUTES.Game02ProgressLevel03),
},
]);
backgroundMusic.current.setVolume(0.0);
}
}, 0);
} else {
Alert.alert('Not enough budget', 'Please try to manage your budget better.',
[
{
text: 'OK',
onPress: () => navigation.navigate(ROUTES.CHOOSE_GAME),
},
]);
}
};
return (
<ScrollView style={styles.container}>
<View style={styles.rack}>
<View style={styles.mainSquare}>
<View style={styles.main}>
<Text style={styles.budgetText}>Budget: Rs:{budget}</Text>
</View>
<View>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 50,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.itemsContainer}>
{items.map(item => (
<TouchableOpacity
key={item.id}
style={styles.item}
onPress={() => collectItem(item)}>
<Image source={item.image} style={styles.itemImage} />
<Text style={styles.itemText}>{item.name}</Text>
<Text style={styles.itemText}>Rs:{item.cost}</Text>
</TouchableOpacity>
))}
</View>
<View style={styles.two}>
<View style={styles.one}>
<Text style={styles.budgetText}>
Healthy Foods Cost: Rs:{healthyCost}
</Text>
</View>
<View style={styles.one}>
<Text style={styles.budgetText}>
Unhealthy Foods Cost: Rs:{unhealthyCost}
</Text>
</View>
</View>
<View>
<TouchableOpacity onPress={openCart} style={styles.cartIconContainer}>
<Image source={cartIcon} style={styles.cartIcon} />
<View style={styles.cartItemCountContainer}>
<Text style={styles.cartItemCountText}>
{collectedItems.length}
</Text>
</View>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f0f0f0',
},
rack: {
padding: 20,
backgroundColor: '#380000',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
height: 844,
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
budgetText: {
display: 'flex',
justifyContent: 'center',
color: 'white',
alignItems: 'center',
margin: 10,
},
itemsContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-around',
},
item: {
width: '20%',
padding: 6,
margin: '1%',
borderWidth: 1,
borderColor: '#ccc',
backgroundColor: '#fff',
borderRadius: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.22,
shadowRadius: 2.22,
elevation: 3,
alignItems: 'center',
},
itemImage: {
width: 50,
height: 50,
marginBottom: 5,
},
main: {
width: 180,
height: 40,
marginBottom: 1,
backgroundColor: '#6633CC',
borderRadius: 10,
justifyContent: 'center',
display: 'flex',
alignContent: 'flex-start',
marginTop: 8,
},
mainSquare: {
width: '100%',
height: 60,
marginBottom: 10,
display: 'flex',
alignContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-around',
},
one: {
width: 250,
height: 40,
marginBottom: 15,
backgroundColor: '#FF3399',
borderRadius: 10,
justifyContent: 'center',
display: 'flex',
alignContent: 'center',
},
two: {
width: 130,
height: 30,
margin: 5,
borderRadius: 10,
marginLeft: 70,
flexDirection: 'column',
alignItems: 'center',
},
cartIconContainer: {
position: 'absolute',
top: 10,
right: 50,
zIndex: 1,
},
cartIcon: {
width: 230,
height: 230,
// marginTop: 1,
left: 50,
},
cartItemCountContainer: {
position: 'absolute',
right: 130,
top: 83,
backgroundColor: '#666699',
borderRadius: 45,
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
zIndex: 1,
},
cartItemCountText: {
color: 'white',
},
itemText: {
color: 'black',
},
});
export default Game02Level01;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
ScrollView,
Alert,
Image,
Button,
} from 'react-native';
import {COLORS, IMGS, ROUTES} from '../../../../constants';
import Sound from 'react-native-sound';
// Dummy data for baby gear items
const babyGearItems = [
{id: 1, image: IMGS.game_img_38, cost: 1200, essential: false},
{id: 2, image: IMGS.game_img_32, cost: 500, essential: true},
{id: 3, image: IMGS.game_img_31, cost: 800, essential: true},
{id: 4, image: IMGS.game_img_34, cost: 200, essential: true},
{id: 5, image: IMGS.game_img_37, cost: 350, essential: false},
{id: 6, image: IMGS.game_img_36, cost: 200, essential: true},
{id: 7, image: IMGS.game_img_35, cost: 450, essential: true},
{id: 8, image: IMGS.game_img_33, cost: 700, essential: true},
{id: 9, image: IMGS.game_img_39, cost: 900, essential: false},
{id: 10, image: IMGS.game_img_40, cost: 300, essential: true},
{id: 11, image: IMGS.game_img_41, cost: 950, essential: false},
{id: 12, image: IMGS.game_img_42, cost: 150, essential: true},
];
const CravingsPuzzleGame02Level02 = ({navigation}) => {
const initialBudget = 10000;
const [budget, setBudget] = useState(10000); // Starting budget
const [purchasedItems, setPurchasedItems] = useState([]);
const cartIcon = IMGS.game_img_18;
const [cartVisible, setCartVisible] = useState(false);
const [healthyCost, setHealthyCost] = useState(0);
const [unhealthyCost, setUnhealthyCost] = useState(0);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_b.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
// backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const openCart = () => {
setCartVisible(true);
};
const resetGame = () => {
setBudget(initialBudget); // Reset budget to initial
setPurchasedItems([]); // Clear purchased items
setHealthyCost(0); // Reset healthy cost counter
setUnhealthyCost(0); // Reset unhealthy cost counter
};
const purchaseItem = item => {
// Check if the budget allows for the purchase
if (budget - item.cost >= 0) {
// Update the budget and purchased items
setBudget(budget - item.cost);
setPurchasedItems([...purchasedItems, item]);
// Update the cost tracking based on whether the item is essential
if (item.essential === true) {
setHealthyCost(prevCost => prevCost + item.cost);
} else {
setUnhealthyCost(prevCost => prevCost + item.cost);
}
// Delay is unnecessary, so directly execute the checks
if (unhealthyCost + item.cost > 2000) {
Alert.alert('Game lost!', 'Choose essential items!', [
{
text: 'OK',
onPress: () => navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS),
},
]);
} else if (healthyCost + item.cost > 2000) {
Alert.alert('Game won!', 'Congratulations!', [
{
text: 'OK',
onPress: () => navigation.navigate(ROUTES.Game02ProgressLevel06),
},
]);
backgroundMusic.current.setVolume(0.0);
}
} else {
Alert.alert('Not enough budget');
}
};
return (
<ScrollView style={styles.container}>
<View style={styles.mainSquare}>
<View style={styles.budgetContainer}>
<Text style={styles.budgetText}>Budget: Rs {budget}</Text>
<Button title="Refresh" onPress={resetGame} color="#DE3163" />
</View>
<View>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 50,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
</View>
<Text style={styles.new}>Select necessary items for a baby</Text>
<View style={styles.itemsContainer}>
{babyGearItems.map(item => (
<TouchableOpacity
key={item.id}
style={styles.item}
onPress={() => purchaseItem(item)}>
<Image source={item.image} style={styles.itemImage} />
<Text style={styles.itemText}>Rs {item.cost}</Text>
</TouchableOpacity>
))}
<View style={styles.two}>
<View style={styles.one}>
<Text style={styles.budgetNewText}>
Healthy Foods Cost: Rs:{healthyCost}
</Text>
</View>
<View style={styles.one}>
<Text style={styles.budgetNewText}>
Unhealthy Foods Cost: Rs:{unhealthyCost}
</Text>
</View>
</View>
<View>
<TouchableOpacity onPress={openCart} style={styles.cartIconContainer}>
<Image source={cartIcon} style={styles.cartIcon} />
<View style={styles.cartItemCountContainer}>
<Text style={styles.cartItemCountText}>
{purchasedItems.length}
</Text>
</View>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
budgetText: {
fontSize: 18,
fontWeight: 'bold',
backgroundColor: 'black',
color: 'white',
padding: 10,
width: 200,
marginRight: 10,
marginTop: 2,
},
new: {
fontSize: 15,
fontWeight: 'bold',
backgroundColor: '#6633CC',
color: 'white',
padding: 5,
},
itemsContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-around',
backgroundColor: '#380000',
height: 800,
},
budgetContainer: {
flexDirection: 'row',
// flexWrap: 'wrap',
// justifyContent: 'space-around',
},
itemImage: {
width: 60,
height: 70,
marginBottom: 5,
},
item: {
width: '20%',
height: '15%',
backgroundColor: '#f9f9f9',
padding: 8,
alignItems: 'center',
margin: 5,
borderRadius: 10,
shadowColor: '#000',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
itemText: {
fontSize: 14,
color: 'black',
},
cartIconContainer: {
position: 'absolute',
top: 50,
right: 1,
zIndex: 1,
},
cartIcon: {
width: 230,
height: 230,
// marginTop: 10,
// left: 50,
},
cartItemCountContainer: {
position: 'absolute',
// right: 130,
top: 82,
backgroundColor: '#666699',
borderRadius: 45,
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
zIndex: 1,
},
cartItemCountText: {
color: 'white',
},
one: {
width: 250,
height: 50,
// marginBottom: 15,
// backgroundColor: '#FF3399',
// borderRadius: 10,
justifyContent: 'center',
display: 'flex',
alignContent: 'center',
},
mainSquare: {
width: '100%',
height: 60,
marginBottom: 10,
display: 'flex',
alignContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-around',
marginTop: 5,
},
budgetNewText: {
fontSize: 15,
fontWeight: 'bold',
backgroundColor: 'rgba(255, 255, 255, 0.5)',
color: 'black',
padding: 10,
width: 280,
zIndex: 2,
marginTop: 2,
borderRadius: 10,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
});
export default CravingsPuzzleGame02Level02;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Alert,
} from 'react-native';
import {IMGS, ROUTES, COLORS} from '../../../../constants';
import Sound from 'react-native-sound';
// A simple array of names, meanings, and origins for demonstration
const namesData = [
{name: 'Yasas', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Sama', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Dilshan', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Poorna', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Parami', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Randi', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Isura', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Devin', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Lili', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Ann', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Amara', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Kisuri', meaning: 'Fame, Glory', origin: 'Sinhalese'},
{name: 'Ashan', meaning: 'Eternal, Immortal', origin: 'Sinhalese'},
{name: 'Nirmala', meaning: 'Pure, Clean', origin: 'Sinhalese'},
{name: 'Tharaka', meaning: 'Star', origin: 'Sinhalese'},
{
name: 'Lakshmi',
meaning: 'Fortune, Wealth',
origin: 'Sinhalese/Tamil',
},
{
name: 'Anjali',
meaning: 'Gift, Offering',
origin: 'Sinhalese/Tamil',
},
{name: 'Kumara', meaning: 'Prince', origin: 'Sinhalese'},
{name: 'Suren', meaning: 'Wise', origin: 'Tamil'},
{name: 'Vihanga', meaning: 'Bird', origin: 'Sinhalese'},
{name: 'Aruni', meaning: 'Dawn', origin: 'Sinhalese'},
{name: 'Bhagya', meaning: 'Luck, Fortune', origin: 'Sinhalese'},
{name: 'Ruwan', meaning: 'Gold', origin: 'Sinhalese'},
{name: 'Nilani', meaning: 'Moon', origin: 'Tamil'},
{name: 'Asha', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Malsha', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Kasuni', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Kasun', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Avarjana', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Nadeesha', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Nimesha', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Mihiranga', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Maheshika', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Sasvi', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Sameera', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Budara', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Vinuki', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Kyron', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Ramesh', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Hansa', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Hansi', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Nipun', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Dinithi', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Geethmi', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Chathuni', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Mahela', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Ravindu', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Sahan', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Tharushi', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Sanduni', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Sachini', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Pawani', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Pasan', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Kumari', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Kasun', meaning: 'Moon', origin: 'Sinhalese'},
{name: 'Nila', meaning: 'Moon', origin: 'Tamil'},
{name: 'Mohomad', meaning: 'Moon', origin: 'Tamil'},
{name: 'Kathrina', meaning: 'Moon', origin: 'Tamil'},
{name: 'Umar', meaning: 'Moon', origin: 'Tamil'},
{name: 'Fathima', meaning: 'Moon', origin: 'Tamil'},
];
const PuzzleGame02Level03 = ({navigation}) => {
const letters = [
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
];
const [guess, setGuess] = useState([]);
const [nameInfo, setNameInfo] = useState(null);
const babyImage = IMGS.game_img_13;
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_c.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
// backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const checkGuess = () => {
const guessString = guess.join('');
const nameEntry = namesData.find(
entry => entry.name.toLowerCase() === guessString.toLowerCase(),
);
if (nameEntry) {
setNameInfo(nameEntry);
Alert.alert('Correct!', `You've guessed a name: ${nameEntry.name}`, [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Game02ProgressLevel01);
},
},
]);
backgroundMusic.current.setVolume(0.0);
setGuess([]);
} else {
Alert.alert('Try Again', "That's not a match. Keep trying!");
setGuess([]);
setNameInfo(null);
}
};
const addLetterToGuess = letter => {
setGuess([...guess, letter]);
};
const resetGame = () => {
setGuess([]);
setNameInfo(null);
};
return (
<View style={styles.container}>
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginBottom: 10,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
// marginTop: 1,
marginLeft: 300,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<Text style={styles.instructions}>Suggest a name for your baby!</Text>
<View>
<Image source={babyImage} style={styles.babyImage} />
</View>
<TouchableOpacity onPress={resetGame} style={styles.button}>
<Text style={styles.buttonText}>Refresh</Text>
</TouchableOpacity>
<View style={styles.itemcContainer}>
<View style={styles.lettersContainer}>
{letters.map((letter, index) => (
<TouchableOpacity
key={index}
style={styles.letterBox}
onPress={() => addLetterToGuess(letter)}>
<Text style={styles.letterText}>{letter}</Text>
</TouchableOpacity>
))}
</View>
</View>
<Text style={styles.guessText}>Current Guess</Text>
<View style={styles.currentGuess}>
<Text style={styles.guessText}>{guess.join('')}</Text>
</View>
<TouchableOpacity onPress={checkGuess} style={styles.button}>
<Text style={styles.buttonText}>Submit Guess</Text>
</TouchableOpacity>
{nameInfo && (
<View style={styles.infoContainer}>
<Text style={styles.nameText}>Name: {nameInfo.name}</Text>
{/* <Text style={styles.detailText}>Meaning: {nameInfo.meaning}</Text> */}
<Text style={styles.detailText}>Origin: {nameInfo.origin}</Text>
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
backgroundColor: '#32AFA9',
},
itemcContainer: {
alignItems: 'center',
justifyContent: 'center',
// padding: 2,
// backgroundColor: '#33CCCC',
},
instructions: {
marginBottom: 5,
fontSize: 22,
color: 'black',
fontWeight: 'bold',
},
input: {
borderWidth: 1,
borderColor: '#ddd',
width: '80%',
padding: 10,
marginBottom: 20,
color: 'black',
},
button: {
backgroundColor: '#660033',
padding: 10,
borderRadius: 5,
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
},
infoContainer: {
marginTop: 20,
marginBottom: 70,
},
nameText: {
fontSize: 20,
fontWeight: 'bold',
color: 'black',
marginBottom: 10,
},
detailText: {
fontSize: 16,
color: 'black',
fontWeight: 'bold',
},
lettersContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
marginBottom: 20,
},
letterBox: {
width: 40,
height: 45,
backgroundColor: '#003366',
justifyContent: 'center',
alignItems: 'center',
margin: 5,
borderRadius: 5,
},
letterText: {
fontSize: 20,
fontWeight: 'bold',
color: 'white',
},
guessText: {
fontSize: 20,
marginBottom: 10,
fontWeight: 'bold',
color: '#CC0066',
},
currentGuess: {
fontSize: 16,
fontWeight: 'bold',
borderColor: 'blue',
},
babyImage: {
width: 80,
height: 100,
marginBottom: 10,
marginTop: 5,
},
});
export default PuzzleGame02Level03;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
Alert,
StyleSheet,
Image,
ImageBackground,
} from 'react-native';
import {IMGS, COLORS, ROUTES} from '../../../../constants';
import Sound from 'react-native-sound';
const gridSize = 5; // 5x5 grid
const initialBoard = Array(gridSize).fill(Array(gridSize).fill(null)); // Create a 5x5 grid
const Game02Level04 = ({navigation}) => {
const [playerPosition, setPlayerPosition] = useState({x: 0, y: 0});
const player = IMGS.game_img_43;
const [collectedItems, setCollectedItems] = useState([]);
const [babyItems, setBabyItems] = useState([
{x: 2, y: 3, type: 'babyItem', image: IMGS.game_img_17},
{x: 0, y: 4, type: 'babyItem', image: IMGS.game_img_36},
]);
const [ladyItems, setLadyItems] = useState([
{x: 1, y: 1, type: 'ladyItem', image: IMGS.game_img_37},
{x: 4, y: 2, type: 'ladyItem', image: IMGS.game_img_39},
]);
const [selectedCandy, setSelectedCandy] = useState(null);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_d.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const movePlayer = direction => {
let newX = playerPosition.x;
let newY = playerPosition.y;
switch (direction) {
case 'up':
newY = Math.max(0, playerPosition.y - 1);
break;
case 'down':
newY = Math.min(gridSize - 1, playerPosition.y + 1);
break;
case 'left':
newX = Math.max(0, playerPosition.x - 1);
break;
case 'right':
newX = Math.min(gridSize - 1, playerPosition.x + 1);
break;
}
setPlayerPosition({x: newX, y: newY});
checkForItem(newX, newY);
};
const checkForItem = (x, y) => {
const foundBabyItemIndex = babyItems.findIndex(
item => item.x === x && item.y === y,
);
const foundLadyItem = ladyItems.find(item => item.x === x && item.y === y);
if (foundBabyItemIndex !== -1) {
// Update the collected items and perform checks inside the update callback
setCollectedItems(currentItems => {
const updatedItems = [...currentItems, `${x},${y}`];
// Remove the found baby item from the array to prevent recounting
const newBabyItems = [...babyItems];
newBabyItems.splice(foundBabyItemIndex, 1);
setBabyItems(newBabyItems);
// Check if the last baby item has been collected
if (updatedItems.length >= 2) {
// This is the last item; show only the congratulations message
Alert.alert('Congratulations 🥳🥳! You won the game.', '', [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Game02ProgressLevel02);
backgroundMusic.current.setVolume(0.0);
},
},
]);
} else {
// Not the last item, show the generic good job message
Alert.alert('Good job!', 'You found a baby item!');
}
return updatedItems;
});
} else if (foundLadyItem) {
Alert.alert('Oops!', "This is a lady's item. Try again!", [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
},
},
]);
}
};
const resetGame = () => {
setPlayerPosition({x: 0, y: 0}); // Reset player position to the starting point
setCollectedItems([]); // Clear collected items
};
return (
<ImageBackground
source={IMGS.game_img_44}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginLeft: 300,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 8,
}}
onPress={toggleMute}>
<Text
medium
center
style={{
color: 'black',
fontSize: 30,
fontWeight: 'bold',
}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<View style={styles.container}>
<Text style={styles.mainText}>Select Suitable Baby Items</Text>
<View style={styles.gameBoard}>
{initialBoard.map((row, rowIndex) => (
<View key={`row-${rowIndex}`} style={styles.row}>
{row.map((cell, cellIndex) => (
<View key={`cell-${cellIndex}`} style={styles.cell}>
{playerPosition.x === cellIndex &&
playerPosition.y === rowIndex && (
<Image source={player} style={styles.playerImage} />
)}
{babyItems.concat(ladyItems).map((item, index) => {
const itemKey = `${item.x},${item.y}`;
if (
item.x === cellIndex &&
item.y === rowIndex &&
!collectedItems.includes(itemKey)
) {
return (
<Image
key={index}
source={item.image}
style={styles.itemImage}
/>
);
}
return null;
})}
</View>
))}
</View>
))}
</View>
{/* Up Button */}
<TouchableOpacity
onPress={() => movePlayer('up')}
style={[styles.button, styles.buttonUp]}>
<Text style={styles.buttonText}>🔼</Text>
</TouchableOpacity>
<View style={styles.controls}>
<TouchableOpacity
onPress={() => movePlayer('right')}
style={[styles.button, styles.buttonLeft]}>
<Text style={styles.buttonText}>▶️</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => movePlayer('left')}
style={[styles.button, styles.buttonRight]}>
<Text style={styles.buttonText}>◀️</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => movePlayer('down')}
style={[styles.button, styles.buttonDown]}>
<Text style={styles.buttonText}>🔽</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
gameBoard: {
width: 350,
height: 350,
borderWidth: 2,
marginBottom: 20,
backgroundColor: '#354259',
borderColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
cell: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
alignItems: 'center',
justifyContent: 'center',
},
player: {
backgroundColor: '#add8e6',
},
controls: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '50%',
},
button: {
padding: 10,
backgroundColor: '#056676',
borderRadius: 5,
},
playerImage: {
width: '100%', // Adjust as needed
height: '100%', // Adjust as needed
resizeMode: 'contain', // This ensures the image scales correctly within the cell
},
itemImage: {
width: '80%', // Adjust based on your cell size
height: '80%',
resizeMode: 'contain',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontWeight: 'bold',
marginBottom: 35,
fontSize: 22,
backgroundColor: '#990033',
width: '100%',
padding: 15,
borderRadius: 20,
},
buttonUp: {
top: 1,
},
buttonLeft: {
left: 130,
},
buttonRight: {
right: 130,
},
buttonDown: {
bottom: 1,
},
});
export default Game02Level04;
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
Alert,
StyleSheet,
Image,
ImageBackground,
} from 'react-native';
import {IMGS, COLORS, ROUTES} from '../../../../constants';
import Sound from 'react-native-sound';
const gridSize = 7;
const initialBoard = Array(gridSize).fill(Array(gridSize).fill(null)); // Create a 5x5 grid
const Game02Level05 = ({navigation}) => {
const [playerPosition, setPlayerPosition] = useState({x: 0, y: 0});
const player = IMGS.game_img_43;
const [collectedItems, setCollectedItems] = useState([]);
const [babyItems, setBabyItems] = useState([
{x: 2, y: 3, type: 'babyItem', image: IMGS.game_img_17},
{x: 0, y: 4, type: 'babyItem', image: IMGS.game_img_36},
{x: 5, y: 6, type: 'babyItem', image: IMGS.game_img_16},
]);
const [ladyItems, setLadyItems] = useState([
{x: 1, y: 1, type: 'ladyItem', image: IMGS.game_img_37},
{x: 4, y: 4, type: 'ladyItem', image: IMGS.game_img_39},
{x: 6, y: 1, type: 'ladyItem', image: IMGS.game_img_38},
]);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_e.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const movePlayer = direction => {
let newX = playerPosition.x;
let newY = playerPosition.y;
switch (direction) {
case 'up':
newY = Math.max(0, playerPosition.y - 1);
break;
case 'down':
newY = Math.min(gridSize - 1, playerPosition.y + 1);
break;
case 'left':
newX = Math.max(0, playerPosition.x - 1);
break;
case 'right':
newX = Math.min(gridSize - 1, playerPosition.x + 1);
break;
}
setPlayerPosition({x: newX, y: newY});
checkForItem(newX, newY);
};
const checkForItem = (x, y) => {
const foundBabyItemIndex = babyItems.findIndex(
item => item.x === x && item.y === y,
);
const foundLadyItem = ladyItems.find(item => item.x === x && item.y === y);
if (foundBabyItemIndex !== -1) {
// Prepare the updated list of baby items by removing the found item
const newBabyItems = [...babyItems];
newBabyItems.splice(foundBabyItemIndex, 1);
// Update the collected items state
setCollectedItems(currentItems => {
const updatedItems = [...currentItems, `${x},${y}`];
// Check if all baby items have been collected (assuming total items needed to win is 3)
if (updatedItems.length === 3) {
// Show only the congratulations message when the last item is collected
Alert.alert('Congratulations 🥳🥳! You won the game!', '', [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Game02ProgressLevel04);
backgroundMusic.current.setVolume(0.0);
},
},
]);
} else {
// Show this alert if there are still items left to collect
Alert.alert('Good job!', 'You found a baby item!');
}
return updatedItems;
});
// Update the baby items array state
setBabyItems(newBabyItems);
} else if (foundLadyItem) {
Alert.alert('Oops!', "This is a lady's item. Try again!", [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
},
},
]);
}
};
const resetGame = () => {
setPlayerPosition({x: 0, y: 0});
setCollectedItems([]);
};
return (
<ImageBackground
source={IMGS.game_img_45}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginLeft: 300,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 8,
}}
onPress={toggleMute}>
<Text
medium
center
style={{
color: 'black',
fontSize: 30,
fontWeight: 'bold',
}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<View style={styles.container}>
<Text style={styles.mainText}>Select Suitable Baby Items</Text>
<View style={styles.gameBoard}>
{initialBoard.map((row, rowIndex) => (
<View key={`row-${rowIndex}`} style={styles.row}>
{row.map((cell, cellIndex) => (
<View key={`cell-${cellIndex}`} style={styles.cell}>
{playerPosition.x === cellIndex &&
playerPosition.y === rowIndex && (
<Image source={player} style={styles.playerImage} />
)}
{babyItems.concat(ladyItems).map((item, index) => {
const itemKey = `${item.x},${item.y}`;
if (
item.x === cellIndex &&
item.y === rowIndex &&
!collectedItems.includes(itemKey)
) {
return (
<Image
key={index}
source={item.image}
style={styles.itemImage}
/>
);
}
return null;
})}
</View>
))}
</View>
))}
</View>
{/* Up Button */}
<TouchableOpacity
onPress={() => movePlayer('up')}
style={[styles.button, styles.buttonUp]}>
<Text style={styles.buttonText}>🔼</Text>
</TouchableOpacity>
<View style={styles.controls}>
<TouchableOpacity
onPress={() => movePlayer('right')}
style={[styles.button, styles.buttonLeft]}>
<Text style={styles.buttonText}>▶️</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => movePlayer('left')}
style={[styles.button, styles.buttonRight]}>
<Text style={styles.buttonText}>◀️</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => movePlayer('down')}
style={[styles.button, styles.buttonDown]}>
<Text style={styles.buttonText}>🔽</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
gameBoard: {
width: 370,
height: 370,
borderWidth: 2,
marginBottom: 20,
backgroundColor: '#003333',
borderColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
cell: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
alignItems: 'center',
justifyContent: 'center',
},
player: {
backgroundColor: '#add8e6',
},
controls: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '50%',
},
button: {
padding: 10,
backgroundColor: '#046582',
borderRadius: 5,
},
playerImage: {
width: '100%', // Adjust as needed
height: '100%', // Adjust as needed
resizeMode: 'contain', // This ensures the image scales correctly within the cell
},
itemImage: {
width: '80%', // Adjust based on your cell size
height: '80%',
resizeMode: 'contain',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontWeight: 'bold',
marginBottom: 35,
fontSize: 22,
backgroundColor: '#990033',
width: '100%',
padding: 15,
borderRadius: 20,
},
buttonUp: {
top: 1,
},
buttonLeft: {
left: 140,
},
buttonRight: {
right: 140,
},
buttonDown: {
bottom: 1,
},
});
export default Game02Level05;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
Alert,
StyleSheet,
Image,
ImageBackground,
} from 'react-native';
import {IMGS, COLORS, ROUTES} from '../../../../constants';
import Sound from 'react-native-sound';
const gridSize = 7;
const initialBoard = Array(gridSize).fill(Array(gridSize).fill(null)); // Create a 5x5 grid
const Game02Level06 = ({navigation}) => {
const [playerPosition, setPlayerPosition] = useState({x: 0, y: 0});
const player = IMGS.game_img_43;
const [collectedItems, setCollectedItems] = useState([]);
const [babyItems, setBabyItems] = useState([
{x: 2, y: 3, type: 'babyItem', image: IMGS.game_img_17},
{x: 0, y: 4, type: 'babyItem', image: IMGS.game_img_36},
{x: 5, y: 6, type: 'babyItem', image: IMGS.game_img_16},
{x: 3, y: 0, type: 'babyItem', image: IMGS.game_img_33},
]);
const [ladyItems, setLadyItems] = useState([
{x: 1, y: 1, type: 'ladyItem', image: IMGS.game_img_24},
{x: 4, y: 4, type: 'ladyItem', image: IMGS.game_img_39},
{x: 6, y: 1, type: 'ladyItem', image: IMGS.game_img_38},
{x: 2, y: 5, type: 'ladyItem', image: IMGS.game_img_29},
]);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_e.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
// Release the audio player resource when the component unmounts
return () => backgroundMusic.current.release();
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const movePlayer = direction => {
let newX = playerPosition.x;
let newY = playerPosition.y;
switch (direction) {
case 'up':
newY = Math.max(0, playerPosition.y - 1);
break;
case 'down':
newY = Math.min(gridSize - 1, playerPosition.y + 1);
break;
case 'left':
newX = Math.max(0, playerPosition.x - 1);
break;
case 'right':
newX = Math.min(gridSize - 1, playerPosition.x + 1);
break;
}
setPlayerPosition({x: newX, y: newY});
checkForItem(newX, newY);
};
const checkForItem = (x, y) => {
const foundBabyItemIndex = babyItems.findIndex(
item => item.x === x && item.y === y,
);
const foundLadyItem = ladyItems.find(item => item.x === x && item.y === y);
if (foundBabyItemIndex !== -1) {
// Remove the found baby item from the array to prevent recounting
const newBabyItems = [...babyItems];
newBabyItems.splice(foundBabyItemIndex, 1);
setBabyItems(newBabyItems);
// Use position as a unique identifier and update the collected items
setCollectedItems(currentItems => {
const updatedItems = [...currentItems, `${x},${y}`];
// Check if all baby items have been collected
if (updatedItems.length >= 4) {
Alert.alert('Congratulations 🥳🥳!', 'You won the game.', [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Game02ProgressLevel05);
},
},
]);
backgroundMusic.current.setVolume(0.0);
} else {
Alert.alert('Good job!', 'You found a baby item!');
}
return updatedItems;
});
} else if (foundLadyItem) {
Alert.alert('Oops!', "This is a lady's item. Try again!", [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
},
},
]);
}
};
return (
<ImageBackground
source={IMGS.game_img_45}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginLeft: 300,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 8,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<View style={styles.container}>
<Text style={styles.mainText}>Select Suitable Baby Items</Text>
<View style={styles.gameBoard}>
{initialBoard.map((row, rowIndex) => (
<View key={`row-${rowIndex}`} style={styles.row}>
{row.map((cell, cellIndex) => (
<View key={`cell-${cellIndex}`} style={styles.cell}>
{playerPosition.x === cellIndex &&
playerPosition.y === rowIndex && (
<Image source={player} style={styles.playerImage} />
)}
{babyItems.concat(ladyItems).map((item, index) => {
const itemKey = `${item.x},${item.y}`;
if (
item.x === cellIndex &&
item.y === rowIndex &&
!collectedItems.includes(itemKey)
) {
return (
<Image
key={index}
source={item.image}
style={styles.itemImage}
/>
);
}
return null;
})}
</View>
))}
</View>
))}
</View>
{/* Up Button */}
<TouchableOpacity
onPress={() => movePlayer('up')}
style={[styles.button, styles.buttonUp]}>
<Text style={styles.buttonText}>🔼</Text>
</TouchableOpacity>
<View style={styles.controls}>
<TouchableOpacity
onPress={() => movePlayer('right')}
style={[styles.button, styles.buttonLeft]}>
<Text style={styles.buttonText}>▶️</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => movePlayer('left')}
style={[styles.button, styles.buttonRight]}>
<Text style={styles.buttonText}>◀️</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => movePlayer('down')}
style={[styles.button, styles.buttonDown]}>
<Text style={styles.buttonText}>🔽</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
gameBoard: {
width: 370,
height: 370,
borderWidth: 2,
marginBottom: 20,
backgroundColor: '#003333',
borderColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
cell: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
alignItems: 'center',
justifyContent: 'center',
},
player: {
backgroundColor: '#add8e6',
},
controls: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '50%',
},
button: {
padding: 10,
backgroundColor: '#554994',
borderRadius: 5,
},
playerImage: {
width: '100%', // Adjust as needed
height: '100%', // Adjust as needed
resizeMode: 'contain', // This ensures the image scales correctly within the cell
},
itemImage: {
width: '80%', // Adjust based on your cell size
height: '80%',
resizeMode: 'contain',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontWeight: 'bold',
marginBottom: 35,
fontSize: 22,
backgroundColor: '#990033',
width: '100%',
padding: 15,
borderRadius: 20,
},
buttonUp: {
top: 1,
},
buttonLeft: {
left: 130,
},
buttonRight: {
right: 130,
},
buttonDown: {
bottom: 1,
},
});
export default Game02Level06;
/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect, useRef} from 'react';
import {
View,
Text,
TouchableOpacity,
Alert,
StyleSheet,
Image,
ImageBackground,
} from 'react-native';
import {IMGS, COLORS, ROUTES} from '../../../../constants';
import Sound from 'react-native-sound';
const gridSize = 9;
const initialBoard = Array(gridSize).fill(Array(gridSize).fill(null)); // Create a 5x5 grid
const Game02Level07 = ({navigation}) => {
const [playerPosition, setPlayerPosition] = useState({x: 0, y: 0});
const player = IMGS.game_img_43;
const [collectedItems, setCollectedItems] = useState([]);
const [babyItems, setBabyItems] = useState([
{x: 3, y: 7, type: 'babyItem', image: IMGS.game_img_17},
{x: 8, y: 4, type: 'babyItem', image: IMGS.game_img_36},
{x: 1, y: 2, type: 'babyItem', image: IMGS.game_img_16},
{x: 4, y: 0, type: 'babyItem', image: IMGS.game_img_33},
]);
const [ladyItems, setLadyItems] = useState([
{x: 8, y: 1, type: 'ladyItem', image: IMGS.game_img_24},
{x: 4, y: 3, type: 'ladyItem', image: IMGS.game_img_39},
{x: 6, y: 1, type: 'ladyItem', image: IMGS.game_img_38},
{x: 2, y: 7, type: 'ladyItem', image: IMGS.game_img_29},
]);
const backgroundMusic = useRef(null);
const [isMuted, setIsMuted] = useState(false);
useEffect(() => {
backgroundMusic.current = new Sound(
require('../../../../assets/audios/music_name_e.mp3'),
error => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Play the music as soon as the component mounts and loop indefinitely
backgroundMusic.current.play();
backgroundMusic.current.setNumberOfLoops(-1);
},
);
return () => backgroundMusic.current.release(); // Release the audio player resource when the component unmounts
}, []);
const toggleMute = () => {
setIsMuted(!isMuted);
// Make sure backgroundMusic.current is not null
if (backgroundMusic.current) {
if (isMuted) {
backgroundMusic.current.setVolume(1.0);
} else {
backgroundMusic.current.setVolume(0.0);
}
}
};
const movePlayer = direction => {
let newX = playerPosition.x;
let newY = playerPosition.y;
switch (direction) {
case 'up':
newY = Math.max(0, playerPosition.y - 1);
break;
case 'down':
newY = Math.min(gridSize - 1, playerPosition.y + 1);
break;
case 'left':
newX = Math.max(0, playerPosition.x - 1);
break;
case 'right':
newX = Math.min(gridSize - 1, playerPosition.x + 1);
break;
}
setPlayerPosition({x: newX, y: newY});
checkForItem(newX, newY);
};
const checkForItem = (x, y) => {
const foundBabyItemIndex = babyItems.findIndex(
item => item.x === x && item.y === y,
);
const foundLadyItem = ladyItems.find(item => item.x === x && item.y === y);
if (foundBabyItemIndex !== -1) {
// Use position as a unique identifier and update the collected items
setCollectedItems(currentItems => {
const updatedItems = [...currentItems, `${x},${y}`];
// Remove the found baby item from the array to prevent recounting
const newBabyItems = [...babyItems];
newBabyItems.splice(foundBabyItemIndex, 1);
setBabyItems(newBabyItems);
// Check if all baby items have been collected (assuming total items needed to win is 3)
if (updatedItems.length >= 4) {
// Only show the congratulations message when the last item is collected
Alert.alert('Congratulations 🥳🥳! You won the game.', '', [
{
text: 'OK',
onPress: () => {
navigation.navigate(ROUTES.Game02ProgressLevel02);
backgroundMusic.current.setVolume(0.0);
},
},
]);
} else {
// This alert is for collecting but not finishing the game
Alert.alert('Good job!', 'You found a baby item!');
}
return updatedItems;
});
} else if (foundLadyItem) {
Alert.alert('Oops!', "This is a lady's item. Try again!", [
{
text: 'OK',
// onPress: () => {
// navigation.navigate(ROUTES.GAME_QUIZ_OPTIONS);
// },
},
]);
}
};
return (
<ImageBackground
source={IMGS.game_img_45}
style={styles.backgroundImage}
resizeMode="cover">
<View style={{marginTop: 1}}>
<TouchableOpacity
style={{
backgroundColor: COLORS.white,
borderColor: COLORS.white,
height: 60,
marginLeft: 300,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 14,
width: 50,
marginTop: 8,
}}
onPress={toggleMute}>
<Text
medium
center
style={{color: 'black', fontSize: 30, fontWeight: 'bold'}}>
{isMuted ? '🔇' : '🔊'}
</Text>
</TouchableOpacity>
</View>
<View style={styles.container}>
<Text style={styles.mainText}>Select Suitable Baby Items</Text>
<View style={styles.gameBoard}>
{initialBoard.map((row, rowIndex) => (
<View key={`row-${rowIndex}`} style={styles.row}>
{row.map((cell, cellIndex) => (
<View key={`cell-${cellIndex}`} style={styles.cell}>
{playerPosition.x === cellIndex &&
playerPosition.y === rowIndex && (
<Image source={player} style={styles.playerImage} />
)}
{babyItems.concat(ladyItems).map((item, index) => {
const itemKey = `${item.x},${item.y}`;
if (
item.x === cellIndex &&
item.y === rowIndex &&
!collectedItems.includes(itemKey)
) {
return (
<Image
key={index}
source={item.image}
style={styles.itemImage}
/>
);
}
return null;
})}
</View>
))}
</View>
))}
</View>
{/* Up Button */}
<TouchableOpacity
onPress={() => movePlayer('up')}
style={[styles.button, styles.buttonUp]}>
<Text style={styles.buttonText}>🔼</Text>
</TouchableOpacity>
<View style={styles.controls}>
<TouchableOpacity
onPress={() => movePlayer('right')}
style={[styles.button, styles.buttonLeft]}>
<Text style={styles.buttonText}>▶️</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => movePlayer('left')}
style={[styles.button, styles.buttonRight]}>
<Text style={styles.buttonText}>◀️</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => movePlayer('down')}
style={[styles.button, styles.buttonDown]}>
<Text style={styles.buttonText}>🔽</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
};
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
gameBoard: {
width: 360,
height: 400,
borderWidth: 2,
marginBottom: 5,
backgroundColor: '#003333',
borderColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
cell: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
alignItems: 'center',
justifyContent: 'center',
},
player: {
backgroundColor: '#add8e6',
},
controls: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '50%',
},
button: {
padding: 10,
backgroundColor: '#056676',
borderRadius: 5,
},
playerImage: {
width: '100%', // Adjust as needed
height: '100%', // Adjust as needed
resizeMode: 'contain', // This ensures the image scales correctly within the cell
},
itemImage: {
width: '80%', // Adjust based on your cell size
height: '80%',
resizeMode: 'contain',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontWeight: 'bold',
marginBottom: 25,
fontSize: 22,
backgroundColor: '#990033',
width: '100%',
padding: 10,
borderRadius: 20,
},
buttonUp: {
top: 1,
},
buttonLeft: {
left: 130,
},
buttonRight: {
right: 130,
},
buttonDown: {
bottom: 1,
},
});
export default Game02Level07;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Game02ProgressLevel01 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>1</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.Game02Level01)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Game02ProgressLevel01;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Game02ProgressLevel02 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>2</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() =>
navigation.navigate(ROUTES.CravingsPuzzleGame02Level02)
}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Game02ProgressLevel02;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Game02ProgressLevel03 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>3</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.PuzzleGame02Level03)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Game02ProgressLevel03;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Game02ProgressLevel04 = ({route, navigation}) => {
// const {predictedGameLevel} = route.params;
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>4</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.Game02Level04)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Game02ProgressLevel04;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Game02ProgressLevel05 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>5</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.Game02Level05)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Game02ProgressLevel05;
import React from 'react';
import {View, StyleSheet, TouchableOpacity, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../../../constants';
const Game02ProgressLevel06 = ({route, navigation}) => {
return (
<LinearGradient
style={{
flex: 1,
}}
colors={[
'#D9EDBF',
'#FFD3B5',
COLORS.white,
'#E8D3FF',
'#DAF1F9',
'#F6DFEB',
]}
start={{x: 0.0, y: 0.0}}
end={{x: 1.0, y: 1.0}}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Text style={styles.mainText}>Your Gaming Level</Text>
</View>
<View style={styles.diamondContainer}>
<View style={styles.innerCircle}>
<Text style={styles.scoreText}>7</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={() => navigation.navigate(ROUTES.Game02Level07)}>
<Text style={styles.buttonText}>Choose a Game</Text>
</TouchableOpacity>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
gradientBackground: {
flex: 1,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
diamondContainer: {
width: 250,
height: 250,
transform: [{rotate: '45deg'}],
backgroundColor: '#e76f51',
alignItems: 'center',
justifyContent: 'center',
elevation: 10,
borderRadius: 20,
},
innerCircle: {
width: 180,
height: 180,
borderRadius: 90,
backgroundColor: '#f4a261',
alignItems: 'center',
justifyContent: 'center',
transform: [{rotate: '-45deg'}],
elevation: 50,
},
scoreText: {
color: '#ffffff',
fontSize: 100,
fontWeight: 'bold',
},
mainText: {
color: 'white',
fontSize: 25,
fontWeight: 'bold',
position: 'absolute',
},
button: {
backgroundColor: '#f4a261',
top: 150,
borderRadius: 10,
elevation: 5,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 50,
},
buttonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
mainContainer: {
elevation: 80,
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
backgroundColor: '#f4a261',
height: 50,
width: '100%',
bottom: 200,
},
});
export default Game02ProgressLevel06;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374532/3D/wfu4pr9phnadjqargex4.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Shoulder pain | උරහිස් වේදනාව' },
{ key: 'symptom3', text: 'Upper Abdominal pain | ඉහළ උදරයේ වේදනාව' },
{ key: 'symptom4', text: 'Lower Abdomen pain | පහළ උදරයේ වේදනාව' },
],
[
{ key: 'symptom5', text: 'Swollen Ankle pain | ඉදිමුණු වළලුකර වේදනාව' },
{ key: 'symptom6', text: 'Leg joint pain | පාදයේ සන්ධි වේදනාව' },
{ key: 'symptom7', text: 'Thigh muscle pain | කලවා මාංශ පේශි වේදනාව' },
{ key: 'symptom8', text: 'Groin pain | ඉකිලි වේදනාව' },
{ key: 'symptom9', text: 'Breast Pain |පියයුරු වේදනාව'},
{ key: 'symptom10', text: 'Side muscle pain | පැත්තේ මාංශ පේශි වේදනාව'},
],
[
{ key: 'symptom11', text: 'Upper arm pain | ඉහළ අතේ වේදනාව' },
{ key: 'symptom12', text: 'Heart burn | හදවත දැවෙනවා' },
{ key: 'symptom13', text: 'Mouth and Nose ulcer’s | මුඛයේ සහ නාසයේ වණ'},
{ key: 'symptom14', text: 'Back Pain |පිටුපස මාංශ පේශි වේදනාව'},
],
// Add more groups as needed
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom12', 'symptom5', 'symptom4','symptom10', 'symptom8', 'symptom6'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_INFO);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Discoid Additional Symptoms </Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.white,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: '#11324D', // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false,
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374537/3D/ulxecngohldnmcizzrej.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Shoulder pain |උරහිස් වේදනාව'},
{ key: 'symptom3', text: 'Swelling in the hands | අත්වල ඉදිමීම'},
],
[ { key: 'symptom4', text: 'Change in vision | ඇස් පෙනීම වෙනස් වීම'},
{ key: 'symptom5', text: 'Shortness in breath | හුස්ම හිරවීම'},
{ key: 'symptom6', text: 'Upper Abdominal pain | ඉහළ උදරයේ වේදනාව'},
],
[
{ key: 'symptom7', text: 'Swelling in joints | සන්ධි ඉදිමීම'},
{ key: 'symptom8', text: 'Back Pain | පිටුපස වේදනාව'},
{ key: 'symptom9', text: 'Side muscle pain | පැත්තේ මාංශ පේශි වේදනාව'},
],
// Add more groups as needed
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom3', 'symptom4', 'symptom7','symptom9'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_INFO);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Patechiae Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374525/3D/tu1jhgaa6hvcyby5zybr.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Sore throat | උගුරේ අමාරුව'},
{ key: 'symptom3', text: 'Swelling in joints | සන්ධි ඉදිමීම'},
],
[
{ key: 'symptom5', text: 'Shortness in breath | හුස්ම හිරවීම'},
{ key: 'symptom6', text: 'Large mouth ulcers | මුඛයේ විශාල වණ'},
{ key: 'symptom4', text: 'Weight loss | බර අඩුවීම '},
],
// Add more groups as needed
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom3', 'symptom5', 'symptom4'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_INFO);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Cytomegalovirus Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374517/3D/q2zk6ka9aqamthwgn1vv.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Sore throat | උගුරේ අමාරුව'},
{ key: 'symptom3', text: 'Pain around genitals | ලිංගික අවයව වටා වේදනාව'},
{ key: 'symptom5', text: 'Pain in urination | මුත්රා කිරීමේදී වේදනාව'},
],
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom3', 'symptom5'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_INFO);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Herpes Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374529/3D/ri0w5kgmpchajypa7xfb.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Rash is intensely itchy | කුෂ්ඨ කැසීම'},
],
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Pupp Hives Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={() => navigation.navigate(ROUTES.SKIN_INFO)}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374540/3D/biile6hyrj1aiqvyvedi.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Enlarge lymph nodes | විශාල වසා ගැටිති'},
{ key: 'symptom2', text: 'Sharp pain under armpits | කිහිලි යට තියුණු වේදනාව'},
],
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom1', 'symptom2'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_INFO);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Melanoma Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState } from 'react';
import { View, StyleSheet, Text, TouchableOpacity, ScrollView, Image } from 'react-native';
// import Video from 'react-native-video'; // or any other audio player you prefer
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { COLORS, IMGS, ROUTES } from '../../../constants';
import Button from '../../../components/Button';
import Video from 'react-native-video';
const RiskEvaluationScreen = ({ navigation }) => {
const [audioPaused, setAudioPaused] = useState(true);
// Function to handle the continuation to the next screen
const handleContinue = () => {
// navigation.navigate('NextScreenRoute');
};
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Risk evaluation</Text>
<Text style={styles.descriptionText}>
Your Condition Risk Level: High,Low will be displayed below
</Text>
<Text style={styles.subTopicText}>Why High Risk ?</Text>
<View style={styles.audioPlayerContainer}>
{/* <Video
source={require("./skinassets/pause.png")}
style={styles.audioPlayer}
controls={true}
audioOnly={true}
resizeMode="cover" // Cover the audio's aspect ratio
paused={audioPaused}
repeat={true}
onLoad={() => setAudioPaused(false)}
/> */}
</View>
<Image style={styles.babyImage} source={IMGS.sk_14} />
<View style={styles.resultBox}>
<Text style={styles.resultText}>High Risk</Text>
</View>
</View>
<View style={styles.bottomContainer}>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={() => navigation.navigate(ROUTES.SKIN_INFO)}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
topContainer: {
flex: 3,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
container: {
flex: 1,
backgroundColor: COLORS.white,
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 16,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
},
videoPlayer: {
width: '90%',
alignSelf: 'center',
height: 200, // Adjust the height as needed
marginBottom: 20,
},
checkboxContainer: {
margin: 20,
padding: 20,
backgroundColor: COLORS.lightBlue, // Use a light pastel blue color
borderRadius: 25,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:20,
alignItems: 'center',
backgroundColor: '#EF9595',
borderTopRightRadius: 75,
borderTopLeftRadius: 75,
},
nextButton: {
width: '80%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
resultText: {
fontSize: 18,
fontWeight: 'bold',
color: '#EF9595',
textAlign: 'center',
},
resultBox: {
borderWidth: 2,
borderColor: '#EF9595',
borderRadius: 10,
paddingVertical: 25,
paddingHorizontal: 40,
backgroundColor: COLORS.white, // Set the background color to white
shadowColor: "#000", // Shadow color for iOS and also works as elevation shadow color in Android
shadowOffset: {
width: 0,
height: 2, // Shadow offset for iOS
},
shadowOpacity: 0.25, // Shadow opacity for iOS
shadowRadius: 3.84, // Shadow radius for iOS
elevation: 5, // Elevation for Android
alignSelf: 'center',
marginTop: 148, // Adjust the margin to fit your layout
marginLeft:20
},
audioPlayerContainer: {
width: '90%',
height: 50, // Set a fixed height for the audio player container
alignSelf: 'center',
justifyContent: 'center',
marginTop: 20, // Space between the text and the player
},
audioPlayer: {
width: '100%', // Fill the container width
height: '100%', // Fill the container height
// Add more styles as needed
},
babyImage: {
position: 'absolute', // Use absolute positioning
width: 200,
height: 100,
resizeMode: 'contain',
bottom: 70, // Adjust this value based on the height of your result box + desired gap
alignSelf: 'center', // Center the image horizontally
marginLeft:40,
marginRight:100,
},
});
export default RiskEvaluationScreen;
import React, { useState } from 'react';
import { View, StyleSheet, Image, TouchableOpacity, PermissionsAndroid, Text, ScrollView } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { COLORS, IMGS, ROUTES } from '../../../constants';
import Button from '../../../components/Button';
import axios from 'axios'; // Import Axios
const Camera = ({ navigation }) => {
const [cameraPhoto, setCameraPhoto] = useState();
const [galleryPhoto, setGalleryPhoto] = useState();
const REACT_APP_API_URL='https://us-central1-skin-condition-detection.cloudfunctions.net/predict';
const [prediction, setPrediction] = useState(null);
const [photo, setPhoto] = useState(null);
let options = {
saveToPhotos: true,
mediaType: 'photo',
};
const openCamera = async () => {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
const result = await launchCamera(options);
if (result.assets) {
setPhoto(result.assets[0].uri);
submitPhoto(result.assets[0].uri);
}
}
};
const openGallery = async () => {
const result = await launchImageLibrary(options);
if (result.assets) {
setPhoto(result.assets[0].uri);
submitPhoto(result.assets[0].uri);
}
};
const submitPhoto = async (photoUri) => {
try {
const formData = new FormData();
formData.append('file', {
uri: photoUri,
type: 'image/jpeg',
name: 'photo.jpg',
});
const response = await axios.post(REACT_APP_API_URL, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
if (response.status === 200) {
setPrediction(response.data); // Set prediction state with the received data
} else {
console.error('Error:', response.status);
}
} catch (error) {
console.error('Error:', error);
}
};
const handleContinue = () => {
let route; // Variable to store the route name
// Check the class and assign the route accordingly
if (prediction && prediction.class) {
switch (prediction.class) {
case 'Discoid':
route = ROUTES.SKIN_VIDEO;
break;
case 'Herpes HPV':
route = ROUTES.SKIN_VIDEO5;
break;
case 'Maculopapular':
route = ROUTES.SKIN_VIDEO2;
break;
case 'Melanoma':
route = ROUTES.SKIN_VIDEO3;
break;
case 'patechiae':
route = ROUTES.SKIN_VIDEO4;
break;
case 'PUPP Hives':
route = ROUTES.SKIN_VIDEO1;
break;
default:
route = ROUTES.SKIN_VIDEO1; // Define this route in your ROUTES constant
}
navigation.navigate(route);
} else {
// Handle the scenario where prediction or prediction.class is undefined
// Maybe navigate to an error page or show an alert
console.log("No valid prediction available.");
// navigation.navigate(ROUTES.DEFAULT_ROUTE); // Example fallback
}
};
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Skin Diagnostic Photo Upload</Text>
<Image style={styles.babyImage} source={IMGS.sk_1} />
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={openGallery} style={[styles.button, styles.buttonLeft]}>
<Image source={IMGS.sk_3} style={styles.buttonImage} />
</TouchableOpacity>
<TouchableOpacity onPress={openCamera} style={[styles.button, styles.buttonRight]}>
<Image source={IMGS.sk_2} style={styles.buttonImage} />
</TouchableOpacity>
</View>
{photo && (
<View style={styles.photoContainer}>
<Image source={{ uri: photo }} style={styles.photo} />
</View>
)}
</View>
<Text style={styles.descriptionText}>'Use phone camera or select a photo from the gallery that clearly shows your skin.'</Text>
<View style={styles.bottomContainer}>
{!prediction && (
<>
<Text style={styles.resultsHeading}>Results will appear below</Text>
</>
)}
{prediction && (
<View style={styles.predictionContainer}>
<Text style={styles.predictionText}>Predicted Class: {prediction.class}</Text>
<Text style={styles.predictionText}>Confidence: {prediction.confidence}</Text>
</View>
)}
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleContinue}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
predictionText: {
fontSize: 16,
color: '#000', // Text color
textAlign: 'center',
marginBottom: 5, // Space between text lines
},
topContainer: {
flex: 3,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
buttonContainer: {
flexDirection: 'row',
marginTop: -26,
alignSelf: 'center', // Center the button container
borderRadius: 30,
overflow: 'hidden',
maxWidth: 300, // Set the max width for the container
borderWidth: 1, // Border for the whole container
borderColor: COLORS.blue, // Color of the container border and the separator line
},
button: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 10,
backgroundColor: COLORS.white, // White background for the buttons
// Adding border only for the right button to act as the line separator
},
buttonImage: {
width: 50, // Adjust as necessary for your design
height: 50, // Adjust as necessary for your design
resizeMode: 'contain',
},
buttonLeft: {
borderTopLeftRadius: 30, // Rounded left-top edge
borderBottomLeftRadius: 30, // Rounded left-bottom edge
borderRightWidth: 1, // Separator line
borderColor: COLORS.lightGray, // Color of the separator line
},
buttonRight: {
borderTopRightRadius: 30, // Rounded right-top edge
borderBottomRightRadius: 30, // Rounded right-bottom edge
},
babyImage: {
width: 100,
height: 100,
resizeMode: 'contain',
marginVertical: 20,
},
topicText: {
fontSize: 22,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginBottom: 20,
},
descriptionText: {
fontSize: 16,
textAlign: 'center',
marginHorizontal: 10,
marginBottom: -10,
marginTop:-40
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 75,
borderTopLeftRadius: 75,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
photoContainer: {
elevation: 4, // Android shadow
shadowColor: '#000', // iOS shadow
shadowOffset: { width: 0, height: 2 }, // iOS shadow
shadowOpacity: 0.1, // iOS shadow
shadowRadius: 2, // iOS shadow
borderRadius: 10,
marginTop: 20,
marginBottom: 20,
},
photo: {
width: 100,
height: 100,
borderRadius: 10,
},
predictionContainer: {
width: '80%',
backgroundColor: COLORS.white, // White background for the prediction box
borderRadius: 10,
padding: 15,
marginVertical: 20, // Adjust as needed
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
// Add shadows if you like for better visual separation
elevation: 4, // Android shadow
shadowColor: '#000', // iOS shadow
shadowOffset: { width: 0, height: 2 }, // iOS shadow
shadowOpacity: 0.1, // iOS shadow
shadowRadius: 2, // iOS shadow
},
resultsHeading: {
fontSize: 16,
color: '#000',
fontWeight: 'bold',
padding: 10,
textAlign: 'center',
marginBottom: 100,
marginLeft:0
},
resultImage: {
width: 100, // Set your desired width
height: 100, // Set your desired height
alignSelf: 'center',
marginVertical: 20, // Adjust margin as needed
},
});
export default Camera;
// import React from 'react';
// import { SafeAreaView, StyleSheet, Text, View } from 'react-native';
// const WelcomeExercise = () => {
// return (
// <View >
// <Text>Register</Text>
// </View>
// );
// };
// export default WelcomeExercise;
import { View, Text, Pressable, Image, StyleSheet } from 'react-native'
import React from 'react'
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../constants';
import Button from '../../../components/Button';
const WelcomeExercise = ({ navigation }) => {
return (
<LinearGradient
style={styles.linearGradient}
colors={['#F1F0E8', '#96B6C5']}
>
<View style={styles.container}>
{/* Floating images with white borders */}
<Image source={IMGS.sk_5} style={styles.image1} />
<Image source={IMGS.sk_7} style={styles.image2} />
<Image source={IMGS.sk_8} style={styles.image3} />
<Image source={IMGS.sk_9} style={styles.image4} />
{/* Content */}
<View style={{
paddingHorizontal: 22,
position: "absolute",
top: 370,
width: "100%"
}}>
<Text style={{
fontSize: 50,
// fontWeight: 800,
color: COLORS.white
}}>Let's Get</Text>
<Text style={{
fontSize: 46,
// fontWeight: 800,
color: COLORS.white
}}>Started</Text>
<View style={{ marginVertical: 22 }}>
<Text style={{
fontSize: 16,
color: COLORS.white,
marginVertical: 4
}}>Reveal Your Skin's Story </Text>
<Text style={{
fontSize: 16,
color: COLORS.white,
}}>Your Skin, Your Health, Your App.</Text>
</View>
<Button
title="Start Today"
style={{
marginTop: 12,
width: "100%",
marginTop:43
}}
onPress={() => navigation.navigate(ROUTES.SKIN_UPLOAD)}
/>
{/* ... rest of your content */}
</View>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
linearGradient: {
flex: 1,
},
container: {
flex: 1,
},
image1: {
height: 100,
width: 100,
borderRadius: 20,
position: 'absolute',
top: -20,
transform: [
{ translateX: 20 },
{ translateY: 50 },
{ rotate: '-15deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
image2: {
height: 100,
width: 100,
borderRadius: 20,
position: 'absolute',
top: -20,
left: 200,
transform: [
{ translateX: 50 },
{ translateY: 50 },
{ rotate: '-5deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
image3: {
width: 100,
height: 100,
borderRadius: 20,
position: 'absolute',
top: 130,
left: -30,
transform: [
{ translateX: 50 },
{ translateY: 50 },
{ rotate: '15deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
image4: {
height: 150,
width: 150,
borderRadius: 20,
position: 'absolute',
top: 140,
left: 140,
transform: [
{ translateX: 50 },
{ translateY: 50 },
{ rotate: '-15deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
// ... rest of your styles
});
export default WelcomeExercise;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const Additionalinformation = ({ navigation }) => {
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715862352/AI/f0hccwonitbowttquawo.mp4";
const videoRef = useRef(null);
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const ContactCard = ({ name, title, phone, email }) => (
<View style={styles.contactCard}>
<Text style={styles.contactName}>{name}</Text>
<Text style={styles.contactTitle}>{title}</Text>
<View style={styles.contactSpace} />
<TouchableOpacity onPress={() => Linking.openURL(`tel:${phone}`)}>
<Image source={require('./skinassets/calling.png')} style={styles.contactIcon} />
<Text style={styles.contactInfo}>Phone: {phone}</Text>
</TouchableOpacity>
<Image source={require('./skinassets/email.png')} style={styles.contactIcon} />
<TouchableOpacity onPress={() => Linking.openURL(`mailto:${email}`)}>
<Text style={styles.contactInfo}>Email: {email}</Text>
</TouchableOpacity>
</View>
);
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Discoid Additional Information</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Please play the video
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/vector2.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<Text style={styles.dscriptionText}>
Click below to explore informative videos on this condition from trusted YouTube sources.
Remember, these videos are for educational purposes only. If you came this far,
you need medical advice immediately consult a professional. Thank you for prioritizing your health.
</Text>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://youtu.be/sbrNx78JSV0?si=OsHd9sft8jDg1O1j')}>
<Image
source={require('./skinassets/youtube.png')}
style={styles.buttonIcon}
/>
<Text style={styles.orButtonText}>Click here to view video</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://youtu.be/T9WQvX3W92A?si=dw7MhHk7TOpquJx_')}>
<Image
source={require('./skinassets/youtube.png')}
style={styles.buttonIcon}
/>
<Text style={styles.orButtonText}>Click here to view video</Text>
</TouchableOpacity>
</View>
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/Vectorw.png')} // Make sure the path is correct
style={styles.qrCodeImage1}
/>
<Text style={styles.dscriptionText}>
වැඩිදුර මග පෙන්වීම සහ සහාය සඳහා කරුණාකර යෙදුමේ ලැයිස්තුගත කර ඇති චර්ම රෝග විශේෂඥයින් වෙත සම්බන්ධ වන්න.
</Text>
<Text style={styles.dscriptionText}>
Please reach out to the dermatologists listed in the app for further guidance and assistance.
</Text>
<ContactCard
name="Neville Bassnayake"
title="Dermatologist"
phone="+94 759509725"
email="Nevillebassn@gmail.com"
/>
<ContactCard
name="Sandhya Hemamali"
title="Dermatologist"
phone="+94 773910789"
email="Sandhyahe@gmail.com"
/>
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={() => navigation.navigate(ROUTES.SKIN_WELCOME)}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.white,
fontWeight: 'bold',
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: '#11324D', // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#316B83', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '98%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.45,
shadowRadius: 8.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 30,
backgroundColor: COLORS.white,
marginBottom: 40,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 10,
marginTop:50
},
qrCodeImage: {
width: 250, // Adjust size as needed
height: 200, // Adjust size as needed
},
qrCodeImage1:{
width: 200, // Adjust size as needed
height: 200,
},
orButton: {
marginTop: 30,
backgroundColor:'#5F939A',
padding: 10,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'left',
flexDirection: 'row', // Align icon and text in a row
width: '100%', // Make the button wider
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.20,
shadowRadius: 4.65,
elevation: 12,
},
orButtonText: {
color: COLORS.white,
fontSize: 16,
marginLeft: 10, // Give some space after the icon
},
buttonIcon: {
width: 30,
height: 30,
marginLeft:10
},
dscriptionText: {
fontSize: 14,
textAlign: 'center',
color: COLORS.darkGray,
marginTop: 20,
marginBottom: 20,
},
contactCard: {
backgroundColor: '#5F939A',
padding: 15,
borderRadius:20,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.30,
shadowRadius: 4.65,
elevation: 8,
width: '110%',
marginVertical: 10,
alignItems: 'left',
},
contactName: {
fontSize: 18,
fontWeight: 'bold',
color: COLORS.white,
},
contactTitle: {
fontSize: 16,
color: COLORS.white,
},
contactInfo: {
fontSize: 14,
color: COLORS.white,
},
contactSpace: {
height: 10, // Space between title and contact info
},
contactIcon: {
width: 16,
height: 16,
marginRight: 8,
},
// ... possibly other styles
});
export default Additionalinformation;
\ No newline at end of file
import axios from "axios";
const BASE_PATH = 'http://10.0.2.2:8070/api/mother';
import axios from 'axios';
const BASE_PATH = 'https://emidwife-api.onrender.com/api/mother';
import AsyncStorage from '@react-native-async-storage/async-storage';
//signIn API Call
export let signin = async (email, password) => {
try {
let value = await axios.post(BASE_PATH + '/login', {
email: email,
password: password,
})
console.log("data1", value.data)
if (value.data.success === true) {
await AsyncStorage.setItem('userData', JSON.stringify(value.data.data));
console.log("data")
}
return value;
} catch (error) {
return error
try {
let value = await axios.post(BASE_PATH + '/login', {
email: email,
password: password,
});
console.log('data1', value.data);
if (value.data.success === true) {
await AsyncStorage.setItem('userData', JSON.stringify(value.data.data));
console.log('data');
}
}
return value;
} catch (error) {
return error;
}
};
//signIn API Call
export let signup = async (name, password, email, age, week) => {
try {
let value = await axios.post(BASE_PATH + '/add_mother', {
name: name,
password: password,
email: email,
age: age,
week: week,
})
console.log("data1", value.data)
if (value.data.success === true) {
await AsyncStorage.setItem('userData', JSON.stringify(value.data.data));
console.log("data")
}
return value;
} catch (error) {
return error
try {
let value = await axios.post(BASE_PATH + '/add_mother', {
name: name,
password: password,
email: email,
age: age,
week: week,
});
console.log('data1', value.data);
if (value.data.success === true) {
await AsyncStorage.setItem('userData', JSON.stringify(value.data.data));
console.log('data');
}
}
\ No newline at end of file
return value;
} catch (error) {
return error;
}
};
import axios from "axios";
const BASE_PATH = 'http://139.162.3.203:8010';
const BASE_PATH2 = 'http://139.162.3.203:8070/api/mother';
let BASE_PATH = 'http://16.170.242.186:8080';
let BASE_PATH2 = 'https://emidwife-api.onrender.com/api/mother';
import AsyncStorage from '@react-native-async-storage/async-storage';
//initialize payment API Call
export let meternalHealthPredict = async (Age,SystolicBP, DiastolicBP, Blood_glucose, BodyTemp, HeartRate) => {
try {
let value = await axios.post(BASE_PATH + '/predict', {
......@@ -22,7 +21,6 @@ export let meternalHealthPredict = async (Age,SystolicBP, DiastolicBP, Blood_glu
}
//initialize payment API Call
export let addInitialExercises = async (id, riskLevel) => {
try {
let value = await axios.post(BASE_PATH2 + '/initial_exercises', {
......@@ -36,9 +34,9 @@ export let addInitialExercises = async (id, riskLevel) => {
}
//initialize payment API Call
export let getAllExerciseDay = async (id, dateNum) => {
try {
console.log("id", id)
let value = await axios.post(BASE_PATH2 + '/get_all_exercise_day', {
_id: id,
day: dateNum
......@@ -47,4 +45,16 @@ export let getAllExerciseDay = async (id, dateNum) => {
} catch (error) {
return error
}
}
export let updateDeviceStatus = async (id, deviceStatus) => {
try {
let value = await axios.post(BASE_PATH2 + '/update_device_status', {
_id: id,
deviceStatus: deviceStatus
})
return value;
} catch (error) {
return error
}
}
\ No newline at end of file
import axios from 'axios';
// const BASE_PATH = 'http://10.0.2.2:8000';
const BASE_PATH = 'http://172.104.34.100:8000';
import AsyncStorage from '@react-native-async-storage/async-storage';
//initialize payment API Call
export let gameLevelPredict = async (
age,
depression_level,
previous_child_birth_experiences,
marital_status_divorced,
marital_status_married,
marital_status_single,
family_background_bad,
family_background_good,
family_background_normal,
music_name_a,
music_name_b,
music_name_c,
music_name_d,
music_name_e,
music_name_f,
) => {
try {
let value = await axios.post(BASE_PATH + '/predict/', {
age: age,
depression_level: depression_level,
previous_child_birth_experiences: previous_child_birth_experiences,
marital_status_divorced: marital_status_divorced,
marital_status_married: marital_status_married,
marital_status_single: marital_status_single,
family_background_bad: family_background_bad,
family_background_good: family_background_good,
family_background_normal: family_background_normal,
music_name_a: music_name_a,
music_name_b: music_name_b,
music_name_c: music_name_c,
music_name_d: music_name_d,
music_name_e: music_name_e,
music_name_f: music_name_f,
});
return value;
} catch (error) {
return error;
}
};
......@@ -23,7 +23,7 @@
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz"
integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.0", "@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.13.16", "@babel/core@^7.20.0", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.8.0":
"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.0", "@babel/core@^7.21.3", "@babel/core@^7.23.9":
version "7.24.5"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz"
integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==
......@@ -44,7 +44,7 @@
json5 "^2.2.3"
semver "^6.3.1"
"@babel/eslint-parser@^7.12.0", "@babel/eslint-parser@^7.20.0":
"@babel/eslint-parser@^7.20.0":
version "7.24.5"
resolved "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.5.tgz"
integrity sha512-gsUcqS/fPlgAw1kOtpss7uhY6E9SFFANQ6EFX5GTvzUwaV0+sGaZWk6xq22MOdeT9wfxyokW3ceCUvOiRtZciQ==
......@@ -536,7 +536,7 @@
"@babel/helper-create-regexp-features-plugin" "^7.18.6"
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-transform-arrow-functions@^7.0.0", "@babel/plugin-transform-arrow-functions@^7.0.0-0", "@babel/plugin-transform-arrow-functions@^7.24.1":
"@babel/plugin-transform-arrow-functions@^7.0.0", "@babel/plugin-transform-arrow-functions@^7.24.1":
version "7.24.1"
resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz"
integrity sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==
......@@ -766,7 +766,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.24.0"
"@babel/plugin-transform-nullish-coalescing-operator@^7.0.0-0", "@babel/plugin-transform-nullish-coalescing-operator@^7.24.1":
"@babel/plugin-transform-nullish-coalescing-operator@^7.24.1":
version "7.24.1"
resolved "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz"
integrity sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==
......@@ -808,7 +808,7 @@
"@babel/helper-plugin-utils" "^7.24.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
"@babel/plugin-transform-optional-chaining@^7.0.0-0", "@babel/plugin-transform-optional-chaining@^7.24.1", "@babel/plugin-transform-optional-chaining@^7.24.5":
"@babel/plugin-transform-optional-chaining@^7.24.1", "@babel/plugin-transform-optional-chaining@^7.24.5":
version "7.24.5"
resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz"
integrity sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==
......@@ -908,7 +908,7 @@
babel-plugin-polyfill-regenerator "^0.6.1"
semver "^6.3.1"
"@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.0.0-0", "@babel/plugin-transform-shorthand-properties@^7.24.1":
"@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.24.1":
version "7.24.1"
resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz"
integrity sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==
......@@ -930,7 +930,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.24.0"
"@babel/plugin-transform-template-literals@^7.0.0-0", "@babel/plugin-transform-template-literals@^7.24.1":
"@babel/plugin-transform-template-literals@^7.24.1":
version "7.24.1"
resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz"
integrity sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==
......@@ -985,7 +985,7 @@
"@babel/helper-create-regexp-features-plugin" "^7.22.15"
"@babel/helper-plugin-utils" "^7.24.0"
"@babel/preset-env@^7.1.6", "@babel/preset-env@^7.20.0":
"@babel/preset-env@^7.20.0":
version "7.24.5"
resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz"
integrity sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==
......@@ -1090,7 +1090,7 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
"@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.16.7":
"@babel/preset-typescript@^7.13.0":
version "7.24.1"
resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz"
integrity sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==
......@@ -1709,7 +1709,7 @@
prompts "^2.4.2"
semver "^7.5.2"
"@react-native-firebase/app@^19.2.2", "@react-native-firebase/app@19.2.2":
"@react-native-firebase/app@^19.2.2":
version "19.2.2"
resolved "https://registry.npmjs.org/@react-native-firebase/app/-/app-19.2.2.tgz"
integrity sha512-yucIZT/n567XH+gU8Qf/Z8Awtrc0dadu0LYDJU/dq228DwoQa8xyCoDqXqVM2Ppj9R8csQ+ga4VdMYBSHblYQw==
......@@ -1937,7 +1937,7 @@
resolved "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.30.tgz"
integrity sha512-plhc8UvCZs0UkV+sI+3bisIyn78wz9O/BiWZXpounu72k/R/Sj5PuZYFJ1fi6psvriUveMCGh4LeZckAZu2qiQ==
"@react-navigation/native@^6.0.0", "@react-navigation/native@^6.1.17":
"@react-navigation/native@^6.1.17":
version "6.1.17"
resolved "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.17.tgz"
integrity sha512-mer3OvfwWOHoUSMJyLa4vnBH3zpFmCwuzrBPlw7feXklurr/ZDiLjLxUScOot6jLRMz/67GyilEYMmP99LL0RQ==
......@@ -2061,7 +2061,7 @@
"@svgr/babel-plugin-transform-react-native-svg" "8.1.0"
"@svgr/babel-plugin-transform-svg-component" "8.0.0"
"@svgr/core@*", "@svgr/core@^8.1.0":
"@svgr/core@^8.1.0":
version "8.1.0"
resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz"
integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==
......@@ -2244,7 +2244,7 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^5.0.0", "@typescript-eslint/eslint-plugin@^5.57.1":
"@typescript-eslint/eslint-plugin@^5.57.1":
version "5.62.0"
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz"
integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==
......@@ -2260,7 +2260,7 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.57.1":
"@typescript-eslint/parser@^5.57.1":
version "5.62.0"
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz"
integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==
......@@ -2363,7 +2363,7 @@ acorn-jsx@^5.3.2:
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.8.2, acorn@^8.9.0:
acorn@^8.8.2, acorn@^8.9.0:
version "8.11.3"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
......@@ -2728,7 +2728,7 @@ braces@^3.0.2:
dependencies:
fill-range "^7.0.1"
browserslist@^4.22.2, browserslist@^4.23.0, "browserslist@>= 4.21.0":
browserslist@^4.22.2, browserslist@^4.23.0:
version "4.23.0"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz"
integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==
......@@ -3311,7 +3311,17 @@ deepmerge@^2.1.1:
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz"
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
deepmerge@^4.2.2, deepmerge@^4.3.0, deepmerge@^4.3.1:
deepmerge@^4.2.2:
version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
deepmerge@^4.3.0:
version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
deepmerge@^4.3.1:
version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
......@@ -3478,7 +3488,7 @@ encodeurl@~1.0.2:
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
encoding@^0.1.0, encoding@^0.1.11:
encoding@^0.1.11:
version "0.1.13"
resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz"
integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
......@@ -3770,7 +3780,7 @@ eslint-visitor-keys@^3.4.3:
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint@*, "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.5.0 || ^8.0.0 || ^9.0.0", eslint@^8.1.0, eslint@^8.19.0, eslint@>=4.19.1, eslint@>=7.0.0, eslint@>=7.28.0, eslint@>=8:
eslint@^8.19.0:
version "8.57.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz"
integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==
......@@ -4999,7 +5009,7 @@ jest-resolve-dependencies@^29.7.0:
jest-regex-util "^29.6.3"
jest-snapshot "^29.7.0"
jest-resolve@*, jest-resolve@^29.7.0:
jest-resolve@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz"
integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==
......@@ -6240,7 +6250,7 @@ prettier-linter-helpers@^1.0.0:
dependencies:
fast-diff "^1.1.2"
prettier@>=2, prettier@>=2.0.0, prettier@2.8.8:
prettier@2.8.8:
version "2.8.8"
resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz"
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
......@@ -6378,22 +6388,7 @@ react-freeze@^1.0.0:
resolved "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz"
integrity sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==
"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
react-is@^16.13.0:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^16.7.0:
"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^16.13.0, react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
......@@ -6403,6 +6398,16 @@ react-is@^17.0.1:
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-is@^18.0.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
react-is@^18.2.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
react-native-circular-progress-indicator@^4.4.2:
version "4.4.2"
resolved "https://registry.npmjs.org/react-native-circular-progress-indicator/-/react-native-circular-progress-indicator-4.4.2.tgz"
......@@ -6417,7 +6422,7 @@ react-native-circular-progress@^1.4.0:
dependencies:
prop-types "^15.8.1"
react-native-gesture-handler@*, react-native-gesture-handler@^2.16.2, "react-native-gesture-handler@>= 1.0.0":
react-native-gesture-handler@^2.16.2:
version "2.16.2"
resolved "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.16.2.tgz"
integrity sha512-vGFlrDKlmyI+BT+FemqVxmvO7nqxU33cgXVsn6IKAFishvlG3oV2Ds67D5nPkHMea8T+s1IcuMm0bF8ntZtAyg==
......@@ -6428,6 +6433,11 @@ react-native-gesture-handler@*, react-native-gesture-handler@^2.16.2, "react-nat
lodash "^4.17.21"
prop-types "^15.7.2"
react-native-image-picker@^7.1.1:
version "7.1.2"
resolved "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-7.1.2.tgz"
integrity sha512-b5y5nP60RIPxlAXlptn2QwlIuZWCUDWa/YPUVjgHc0Ih60mRiOg1PSzf0IjHSLeOZShCpirpvSPGnDExIpTRUg==
react-native-linear-gradient@^2.8.3:
version "2.8.3"
resolved "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz"
......@@ -6441,20 +6451,6 @@ react-native-progress-circle-gradient@^1.2.1:
"@shopify/react-native-skia" "^0.1.191"
color-interpolate "^1.0.5"
react-native-reanimated@>=2.0.0, react-native-reanimated@>=2.2.0:
version "3.11.0"
resolved "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.11.0.tgz"
integrity sha512-BNw/XDgUfs8UhfY1X6IniU8kWpnotWGyt8qmQviaHisTi5lvwnaOdXQKfN1KGONx6ekdFRHRP5EFwLi0UajwKA==
dependencies:
"@babel/plugin-transform-arrow-functions" "^7.0.0-0"
"@babel/plugin-transform-nullish-coalescing-operator" "^7.0.0-0"
"@babel/plugin-transform-optional-chaining" "^7.0.0-0"
"@babel/plugin-transform-shorthand-properties" "^7.0.0-0"
"@babel/plugin-transform-template-literals" "^7.0.0-0"
"@babel/preset-typescript" "^7.16.7"
convert-source-map "^2.0.0"
invariant "^2.2.4"
react-native-redash@*:
version "18.1.3"
resolved "https://registry.npmjs.org/react-native-redash/-/react-native-redash-18.1.3.tgz"
......@@ -6464,12 +6460,12 @@ react-native-redash@*:
normalize-svg-path "^1.0.1"
parse-svg-path "^0.1.2"
react-native-safe-area-context@^4.10.1, "react-native-safe-area-context@>= 3.0.0":
react-native-safe-area-context@^4.10.1:
version "4.10.1"
resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.1.tgz"
integrity sha512-w8tCuowDorUkPoWPXmhqosovBr33YsukkwYCDERZFHAxIkx6qBadYxfeoaJ91nCQKjkNzGrK5qhoNOeSIcYSpA==
react-native-screens@^3.31.1, "react-native-screens@>= 3.0.0":
react-native-screens@^3.31.1:
version "3.31.1"
resolved "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.31.1.tgz"
integrity sha512-8fRW362pfZ9y4rS8KY5P3DFScrmwo/vu1RrRMMx0PNHbeC9TLq0Kw1ubD83591yz64gLNHFLTVkTJmWeWCXKtQ==
......@@ -6485,6 +6481,11 @@ react-native-snap-carousel-v4@^1.0.1:
"@types/react-addons-shallow-compare" "^0.14.22"
react-addons-shallow-compare "15.6.2"
react-native-sound@^0.11.2:
version "0.11.2"
resolved "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.11.2.tgz"
integrity sha512-LmGc8lgOK3qecYMVQpyHvww/C+wgT6sWeMpVbOe4NCRGC2yKd4fo4U0KBUo9PO7AqKESO3I/2GZg1/C0+bwiiA==
react-native-svg-transformer@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/react-native-svg-transformer/-/react-native-svg-transformer-1.3.0.tgz"
......@@ -6495,7 +6496,7 @@ react-native-svg-transformer@^1.3.0:
"@svgr/plugin-svgo" "^8.1.0"
path-dirname "^1.0.2"
react-native-svg@^15.2.0, react-native-svg@>=12.0.0, react-native-svg@>=12.1.1, react-native-svg@>=7.0.0:
react-native-svg@^15.2.0:
version "15.2.0"
resolved "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.2.0.tgz"
integrity sha512-R0E6IhcJfVLsL0lRmnUSm72QO+mTqcAOM5Jb8FVGxJqX3NfJMlMP0YyvcajZiaRR8CqQUpEoqrY25eyZb006kw==
......@@ -6526,7 +6527,7 @@ react-native-vision-camera@^3.9.1:
resolved "https://registry.npmjs.org/react-native-vision-camera/-/react-native-vision-camera-3.9.2.tgz"
integrity sha512-watHRWbeH7CBYq/5sPj2fpZj87V8J5nGdmYO61aYsDLuJ2Pkij7anAzBf8B8oZiyoSUuYpAzX4lIIi+LjWVedA==
react-native@*, "react-native@^0.0.0-0 || >=0.60 <1.0", "react-native@>= 0.62", react-native@>=0.50.0, react-native@>=0.58.0, react-native@>=0.59.0, react-native@>=0.64, react-native@0.73.6:
react-native@0.73.6:
version "0.73.6"
resolved "https://registry.npmjs.org/react-native/-/react-native-0.73.6.tgz"
integrity sha512-oqmZe8D2/VolIzSPZw+oUd6j/bEmeRHwsLn1xLA5wllEYsZ5zNuMsDus235ONOnCRwexqof/J3aztyQswSmiaA==
......@@ -6605,7 +6606,7 @@ react-test-renderer@18.2.0:
react-shallow-renderer "^16.15.0"
scheduler "^0.23.0"
react@*, "react@^16.0.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, react@>=16.0.0, react@>=16.8, react@>=16.8.0, react@>=17.0.0, react@>=18.0, react@18.2.0:
react@18.2.0:
version "18.2.0"
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
......@@ -7496,7 +7497,7 @@ typed-array-length@^1.0.6:
is-typed-array "^1.1.13"
possible-typed-array-names "^1.0.0"
"typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=4.9.5, typescript@5.0.4:
typescript@5.0.4:
version "5.0.4"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz"
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment