diff --git a/.env.development b/.env.development index 1b66607d..51e83319 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -EXPO_PUBLIC_API_URL=http://192.168.1.3 +EXPO_PUBLIC_API_URL=http://192.168.1.19 EXPO_PUBLIC_API_USUARIO_PORT=3001 EXPO_PUBLIC_API_FORUM_PORT=3002 EXPO_PUBLIC_API_SAUDE_PORT=3003 diff --git a/.gitignore b/.gitignore index 56471116..c02fdd80 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,44 @@ ios android /.idea -/reports \ No newline at end of file +/reports +# @generated expo-cli sync-b5df6a44d8735348b729920a7406b633cfb74d4c +# The following patterns were generated by expo-cli + +# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files + +# dependencies +node_modules/ + +# Expo +.expo/ +dist/ +web-build/ + +# Native +*.orig.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision + +# Metro +.metro-health-check* + +# debug +npm-debug.* +yarn-debug.* +yarn-error.* + +# macOS +.DS_Store +*.pem + +# local env files +.env*.local + +# typescript +*.tsbuildinfo + +# @end expo-cli \ No newline at end of file diff --git a/README.md b/README.md index 46c2e1d3..ca6f8af5 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ docker compose -f docker-compose.test.yml up ![IOS](https://github.com/fga-eps-mds/2023-2-GEROcuidado-Front/assets/51385738/1a9562d5-dec5-485d-999a-59f2f16e2427) ### Android ![Android](https://github.com/fga-eps-mds/2023-2-GEROcuidado-Front/assets/51385738/9a6d23c0-2f88-42de-ac26-719e6faa9fd3) -### 📝 Notes +### 📝 Notes. - [Expo Router: Docs](https://expo.github.io/router) - [Expo Router: Repo](https://github.com/expo/router) diff --git a/app.json b/app.json index be9572b7..24c541cd 100644 --- a/app.json +++ b/app.json @@ -41,14 +41,14 @@ "origin": false }, "eas": { - "projectId": "d0700b57-06bb-420d-b975-fcd5d3193360" + "projectId": "e30305f3-1909-4fb7-ad3d-41cd29eb1963" } }, "runtimeVersion": { "policy": "appVersion" }, "updates": { - "url": "https://u.expo.dev/7028a81c-adee-41de-91a7-b7e80535a448" + "url": "https://u.expo.dev/e30305f3-1909-4fb7-ad3d-41cd29eb1963" } } } diff --git a/eas.json b/eas.json index 15fdb4de..c5d14d44 100644 --- a/eas.json +++ b/eas.json @@ -7,17 +7,20 @@ "android": { "buildType": "apk", "developmentClient": true - } + }, + "channel": "development" }, "preview": { "android": { "buildType": "apk" - } + }, + "channel": "preview" }, "production": { "android": { "buildType": "app-bundle" - } + }, + "channel": "production" } }, "submit": { diff --git a/index.js b/index.js new file mode 100644 index 00000000..1d6e981e --- /dev/null +++ b/index.js @@ -0,0 +1,8 @@ +import { registerRootComponent } from 'expo'; + +import App from './App'; + +// registerRootComponent calls AppRegistry.registerComponent('main', () => App); +// It also ensures that whether you load the app in Expo Go or in a native build, +// the environment is set up appropriately +registerRootComponent(App); diff --git a/metro.config.js b/metro.config.js new file mode 100644 index 00000000..07c9fce6 --- /dev/null +++ b/metro.config.js @@ -0,0 +1,7 @@ +// Learn more https://docs.expo.io/guides/customizing-metro +const { getDefaultConfig } = require('expo/metro-config'); + +/** @type {import('expo/metro-config').MetroConfig} */ +const config = getDefaultConfig(__dirname); + +module.exports = config; diff --git a/package-lock.json b/package-lock.json index 21e72f0d..4c49c174 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "expo-constants": "~16.0.2", "expo-dev-client": "~4.0.29", "expo-device": "~6.0.2", + "expo-doctor": "^1.12.4", "expo-image": "~1.13.0", "expo-image-picker": "~15.0.7", "expo-jwt": "^1.6.5", @@ -46,6 +47,7 @@ "react-native-gesture-handler": "~2.16.1", "react-native-mask-input": "^1.2.3", "react-native-paper": "^5.11.2", + "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.5", "react-native-screens": "3.31.1", "react-native-swiper": "^1.6.0", @@ -1435,7 +1437,6 @@ "version": "7.22.11", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1517,7 +1518,6 @@ "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz", "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -1777,7 +1777,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3847,6 +3846,7 @@ "version": "7.0.9", "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-7.0.9.tgz", "integrity": "sha512-9i6Cg7jInpnGEHN0jxnW0P+0BexnePiBzmbUvzSbRXpdXihYUX2AKMu73jgzxn5P1hXOSkzNS7umaY+BZ+aBag==", + "license": "MIT", "dependencies": { "@expo/config": "~9.0.0-beta.0", "@expo/config-plugins": "~8.0.8", @@ -3868,6 +3868,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" } @@ -3876,6 +3877,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.5.1.tgz", "integrity": "sha512-U/GsFfFox88lXULmFJ9Shfl2aQGcwoKPF7fawSCLixIKtMCpsI+1r0h+5i0nQnmt9tHuzXZDL8+Dg1z6OhkI9A==", + "license": "MIT", "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", @@ -3893,6 +3895,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz", "integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==", + "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -3907,6 +3910,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -3915,6 +3919,7 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-8.3.3.tgz", "integrity": "sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A==", + "license": "MIT", "dependencies": { "@babel/code-frame": "~7.10.4", "json5": "^2.2.2", @@ -3925,6 +3930,7 @@ "version": "1.7.2", "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz", "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==", + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3" }, @@ -3936,6 +3942,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -3950,6 +3957,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3965,6 +3973,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -3975,12 +3984,14 @@ "node_modules/@expo/prebuild-config/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/@expo/prebuild-config/node_modules/crypto-random-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", "integrity": "sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==", + "license": "MIT", "engines": { "node": ">=4" } @@ -3989,6 +4000,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -4003,6 +4015,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -4011,6 +4024,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -4022,6 +4036,7 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4033,6 +4048,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4044,6 +4060,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", + "license": "MIT", "engines": { "node": ">=4" } @@ -4052,6 +4069,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", + "license": "MIT", "dependencies": { "temp-dir": "^1.0.0", "type-fest": "^0.3.1", @@ -4065,6 +4083,7 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=6" } @@ -4073,6 +4092,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", "integrity": "sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==", + "license": "MIT", "dependencies": { "crypto-random-string": "^1.0.0" }, @@ -4084,6 +4104,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -7414,7 +7435,8 @@ "node_modules/@react-native/normalize-colors": { "version": "0.74.85", "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz", - "integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==" + "integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==", + "license": "MIT" }, "node_modules/@react-native/virtualized-lists": { "version": "0.74.87", @@ -9237,6 +9259,156 @@ "node": ">=8" } }, + "node_modules/babel-plugin-react-compiler": { + "version": "0.0.0-experimental-592953e-20240517", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-0.0.0-experimental-592953e-20240517.tgz", + "integrity": "sha512-OjG1SVaeQZaJrqkMFJatg8W/MTow8Ak5rx2SI0ETQBO1XvOk/XZGMbltNCPdFJLKghBYoBjC+Y3Ap/Xr7B01mA==", + "dependencies": { + "@babel/generator": "7.2.0", + "@babel/types": "^7.19.0", + "chalk": "4", + "invariant": "^2.2.4", + "pretty-format": "^24", + "zod": "^3.22.4", + "zod-validation-error": "^2.1.0" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/@babel/generator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz", + "integrity": "sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg==", + "dependencies": { + "@babel/types": "^7.2.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/babel-plugin-react-compiler/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-plugin-react-compiler/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/babel-plugin-react-native-web": { "version": "0.19.13", "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.13.tgz", @@ -10733,6 +10905,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -11952,6 +12145,7 @@ "version": "4.0.29", "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.29.tgz", "integrity": "sha512-aANlw9dC4PJEPaRNpe+X5xwyYI+aCIcbZklAAsFlkv2/05gLrsvAFgmQpRtowAzF+VggHWde1eKUOeUccAYIEg==", + "license": "MIT", "dependencies": { "expo-dev-launcher": "4.0.29", "expo-dev-menu": "5.0.23", @@ -11967,6 +12161,7 @@ "version": "4.0.29", "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.29.tgz", "integrity": "sha512-0a0SL8mc4FrqPeGxJHe9kf0kG+Di+38Gd+HP5DEL9dcOa8m2qffKnk22UcyujCT6+Qk0OUK1s53nnfqFB26uVw==", + "license": "MIT", "dependencies": { "ajv": "8.11.0", "expo-dev-menu": "5.0.23", @@ -11982,6 +12177,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -11996,12 +12192,14 @@ "node_modules/expo-dev-launcher/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/expo-dev-launcher/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -12013,6 +12211,7 @@ "version": "5.0.23", "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.23.tgz", "integrity": "sha512-ztDvrSdFGkRbMoQlGLyKMS6CslMGylonVW4kQHUrBQApCL0c2NtRwLlr2bA1SXF0S7qYdPPg/ayLnj7DDR5X2w==", + "license": "MIT", "dependencies": { "expo-dev-menu-interface": "1.8.4", "semver": "^7.5.4" @@ -12025,6 +12224,7 @@ "version": "1.8.4", "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.8.4.tgz", "integrity": "sha512-FpYI57EUu9qTSOOi+FZJ58xkCGJK7QD0mTiXK/y1I8lRdZGjCmdBqVvC4dAx2GcbIT78EPxaVf4/90tK/KRK6A==", + "license": "MIT", "peerDependencies": { "expo": "*" } @@ -12033,6 +12233,7 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -12073,6 +12274,15 @@ "node": "*" } }, + "node_modules/expo-doctor": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/expo-doctor/-/expo-doctor-1.12.4.tgz", + "integrity": "sha512-WgA4ERef4183DZAkwr+w/mnQE+fIlpzybZEABjV7xauwKfp2Dp7hMAxe7ca30VgyYsLgxTPi8HKWpU5cgOI/Dg==", + "license": "MIT", + "bin": { + "expo-doctor": "build/index.js" + } + }, "node_modules/expo-eas-client": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/expo-eas-client/-/expo-eas-client-0.12.0.tgz", @@ -12101,6 +12311,7 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/expo-image/-/expo-image-1.13.0.tgz", "integrity": "sha512-0NLDcFmEn4Nh1sXeRvNzDHT+Fl6FXtTol6ki6kYYH0/iDeSFWyIy/Fek6kzDDYAmhipSMR7buPf7VVoHseTbAA==", + "license": "MIT", "peerDependencies": { "expo": "*" } @@ -12292,6 +12503,7 @@ "version": "0.28.19", "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.28.19.tgz", "integrity": "sha512-rKKTnVQQ9XNQyTNwKmI9OlchhVu0XOZfRpImMqPFCJg6IwECM1izdas2SLCbE/GApg2Tw3U5R2fd26OnCtUU/w==", + "license": "MIT", "dependencies": { "@expo/image-utils": "^0.5.0", "@ide/backoff": "^1.0.0", @@ -12516,6 +12728,7 @@ "version": "3.5.24", "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-3.5.24.tgz", "integrity": "sha512-wFi+PIUrOntF5cgg0PgBMlkxEZlWedIv5dWnPFEzN6Tr3A3bpsqdDLgOEIwvwd+pxn5DLzykTmg9EkQ1pPGspw==", + "license": "MIT", "dependencies": { "@expo/metro-runtime": "3.2.3", "@expo/server": "^0.4.0", @@ -12602,6 +12815,7 @@ "version": "0.27.7", "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.27.7.tgz", "integrity": "sha512-s+eGcG185878nixlrjhhLD6UDYrvoqBUaBkIEozBVWFg3pkdsKpONPiUAco4XR3h7I/9ODq4quN28RJLFO+s0Q==", + "license": "MIT", "dependencies": { "@expo/prebuild-config": "7.0.9" }, @@ -12623,6 +12837,7 @@ "version": "0.25.27", "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.25.27.tgz", "integrity": "sha512-1hyYZqBEXcAiEuSRPJ6dINTndGlWi6/bwlyYGjSnyoYfu/vzZQrJ+XA8JUP4EvJ3b0g8a0UOIjlDJ9ke9kMcfg==", + "license": "MIT", "dependencies": { "@expo/code-signing-certificates": "0.0.5", "@expo/config": "~9.0.0-beta.0", @@ -15146,6 +15361,7 @@ "version": "51.0.4", "resolved": "https://registry.npmjs.org/jest-expo/-/jest-expo-51.0.4.tgz", "integrity": "sha512-WmlR4rUur1TNF/F14brKCmPdX3TWf7Bno/6A1PuxnflN79LEIXpXuPKMlMWwCCChTohGB5FRniknRibblWu1ug==", + "license": "MIT", "dependencies": { "@expo/config": "~9.0.0-beta.0", "@expo/json-file": "^8.3.0", @@ -17889,9 +18105,10 @@ "dev": true }, "node_modules/moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", "engines": { "node": "*" } @@ -19389,6 +19606,7 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -19625,6 +19843,7 @@ "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==", + "license": "MIT", "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", @@ -19684,6 +19903,27 @@ "color-string": "^1.6.0" } }, + "node_modules/react-native-reanimated": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.10.1.tgz", + "integrity": "sha512-sfxg6vYphrDc/g4jf/7iJ7NRi+26z2+BszPmvmk0Vnrz6FL7HYljJqTf531F1x6tFmsf+FEAmuCtTUIXFLVo9w==", + "license": "MIT", + "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-safe-area-context": { "version": "4.10.5", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.5.tgz", diff --git a/package.json b/package.json index 242f5c70..8fc8bc07 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,12 @@ "@testing-library/jest-native": "^5.4.3", "axios": "^1.5.1", "date-fns": "^2.30.0", - "expo": "~51.0.39", + "expo": "^51.0.39", + "expo-build-properties": "~0.12.5", "expo-constants": "~16.0.2", "expo-dev-client": "~4.0.29", "expo-device": "~6.0.2", + "expo-doctor": "^1.12.4", "expo-image": "~1.13.0", "expo-image-picker": "~15.0.7", "expo-jwt": "^1.6.5", @@ -52,14 +54,14 @@ "react-native-gesture-handler": "~2.16.1", "react-native-mask-input": "^1.2.3", "react-native-paper": "^5.11.2", + "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.5", "react-native-screens": "3.31.1", "react-native-swiper": "^1.6.0", "react-native-toast-message": "^2.1.7", "react-native-vector-icons": "^10.0.0", "react-native-web": "~0.19.10", - "ts-jest": "^29.1.1", - "expo-build-properties": "~0.12.5" + "ts-jest": "^29.1.1" }, "devDependencies": { "@babel/core": "^7.24.0", diff --git a/src/app/components/CardEvento.tsx b/src/app/components/CardEvento.tsx new file mode 100644 index 00000000..e873dfcb --- /dev/null +++ b/src/app/components/CardEvento.tsx @@ -0,0 +1,128 @@ +import React, { useEffect, useState } from "react"; +import { View, Text, StyleSheet, Pressable, Dimensions } from "react-native"; +import Icon from "react-native-vector-icons/MaterialCommunityIcons"; +import { router } from "expo-router"; +import { IEvento } from "../interfaces/evento.interface"; +import { updateEvento } from "../services/evento.service" +import database from "../db"; +import { Collection } from "@nozbe/watermelondb"; +import Evento from "../model/Evento"; + +interface IProps { + item: IEvento; + index: number; + date: Date; + } + + export default function CardEvento({ item, index, date }: IProps) { + const dateString = date.toLocaleString("pt-BR", { + year: "numeric", + month: "2-digit", + day: "2-digit", + }); + + const [nameIcon, setnameIcon] = useState("view-grid-outline"); + const [check, setCheck] = useState(false); + const [time, setTime] = useState(""); + const [token, setToken] = useState(""); + const [timer, setTimer] = useState(null); + + + const editar = () => { + const evento = item as unknown as Evento; + const eventoAttributes = { + id: evento.id, + titulo: evento.titulo, + descricao: evento.descricao, + dataHora: evento.dataHora, + local: evento.local, + criadoEm: evento.createdAt, + atualizadoEm: evento.updatedAt, + }; + const params = { evento: JSON.stringify(eventoAttributes) }; + + router.push({ + pathname: "/private/pages/editarEvento", + params: params, + }); + }; + + const handleDataHora = () => { + const dateString = new Date(item.dataHora).toLocaleString("pt-BR", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + }); + + const [data, hora] = dateString.split(" "); + setTime(hora); + }; + + useEffect(() => handleDataHora(), []); + + return ( + <> + {time} + + + + + + {item.titulo} + {item.descricao} + + + + ); +} + +const styles = StyleSheet.create({ + hora: { + fontSize: 18, + fontWeight: "300", + marginLeft: 20, + marginTop: 10, + }, + + container: { + flexDirection: "row", + alignItems: "center", + width: Dimensions.get("window").width - 40, + marginRight: 20, + marginLeft: 20, + marginTop: 10, + marginBottom: 10, + shadowColor: "#000", + shadowOffset: { width: 3, height: 3 }, + shadowOpacity: 0.2, + shadowRadius: 4, + borderRadius: 4, + padding: 10, + paddingVertical: 5, + }, + texts: { + flexDirection: "column", + marginLeft: 10, + marginBottom: 8, + marginTop: 8, + marginRight: 8, + flex: 1, + }, + title: { + fontWeight: "500", + fontSize: 18, + }, + description: { + color: "#767676", + marginTop: 10, + }, + icon: {}, +}); diff --git a/src/app/components/ForgetButton.tsx b/src/app/components/ForgetButton.tsx new file mode 100644 index 00000000..585d1c23 --- /dev/null +++ b/src/app/components/ForgetButton.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import { ActivityIndicator, StyleSheet, Text } from "react-native"; +import { router } from "expo-router"; +import { View } from 'react-native'; + +interface Props { + title: string; + showLoading?: boolean; +} + +export default function ForgetButton({ + title, + showLoading, +}: Readonly) { + + const handlePress = () => { + router.push("/private/pages/esqueciSenha"); + }; + + return ( + + {showLoading ? ( + + ) : ( + + {title} + + )} + + ); +} + +const styles = StyleSheet.create({ + linkText: { + width: "40%", + color: "#2CCDB5", + maxWidth: 300, + textDecorationLine: "underline", + paddingVertical: 12, + paddingHorizontal: 18, + textAlign: "left", + borderRadius: 20, + }, + }); diff --git a/src/app/db/index.ts b/src/app/db/index.ts index ee34c1e4..9e263831 100644 --- a/src/app/db/index.ts +++ b/src/app/db/index.ts @@ -9,6 +9,7 @@ import Idoso from '../model/Idoso' import Rotina from '../model/Rotina' import Metrica from '../model/Metrica' import ValorMetrica from '../model/ValorMetrica' +import Evento from '../model/Evento' // import Post from './model/Post' // ⬅️ You'll import your Models here // First, create the adapter to the underlying database: @@ -31,7 +32,7 @@ const database = new Database({ adapter, modelClasses: [ // Post, // ⬅️ You'll add Models to Watermelon here - Usuario, Idoso, Rotina, Metrica, ValorMetrica + Usuario, Idoso, Rotina, Metrica, ValorMetrica, Evento ], }); diff --git a/src/app/db/migrations.ts b/src/app/db/migrations.ts index 14bbbc1b..1c83130b 100644 --- a/src/app/db/migrations.ts +++ b/src/app/db/migrations.ts @@ -5,7 +5,7 @@ import { tableSchema } from '@nozbe/watermelondb'; export default schemaMigrations({ migrations: [ { - toVersion: 3, + toVersion: 8, steps: [ // Passo para adicionar as colunas à tabela 'usuario' se elas ainda não existirem { @@ -67,11 +67,17 @@ export default schemaMigrations({ { type: 'create_table', schema: tableSchema({ - name: 'valor_metrica', + name: 'evento', columns: [ - { name: 'metrica_id', type: 'string', isIndexed: true }, - { name: 'valor', type: 'string' }, + { name: 'titulo', type: 'string' }, + { name: 'descricao', type: 'string' }, + { name: 'categoria', type: 'string' }, { name: 'dataHora', type: 'number' }, + { name: 'notificacao', type: 'boolean' }, + { name: 'token', type: 'string' }, + { name: 'idoso_id', type: 'string', isIndexed: true }, + { name: 'created_at', type: 'number' }, + { name: 'updated_at', type: 'number' }, ], }), }, diff --git a/src/app/db/schema.ts b/src/app/db/schema.ts index 3d8d7078..adf37b06 100644 --- a/src/app/db/schema.ts +++ b/src/app/db/schema.ts @@ -2,7 +2,7 @@ import { appSchema, tableSchema } from '@nozbe/watermelondb'; export default appSchema({ - version: 7, + version: 8, tables: [ tableSchema({ name: 'usuario', @@ -66,5 +66,19 @@ export default appSchema({ { name: 'updated_at', type: 'number' }, ], }), - ], -}); + tableSchema({ + name: 'evento', + columns: [ + { name: 'titulo', type: 'string' }, + { name: 'descricao', type: 'string' }, + { name: 'categoria', type: 'string' }, + { name: 'dataHora', type: 'number' }, + { name: 'notificacao', type: 'boolean' }, + { name: 'token', type: 'string' }, + { name: 'idoso_id', type: 'string', isIndexed: true }, + { name: 'created_at', type: 'number' }, + { name: 'updated_at', type: 'number' }, + ], + }), +], +}); \ No newline at end of file diff --git a/src/app/index.tsx b/src/app/index.tsx index 54a19e82..6e3ea05b 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -2,6 +2,8 @@ import { Image, StyleSheet, Text, View } from "react-native"; import LinkButton from "./components/LinkButton"; import React from "react"; +import 'react-native-gesture-handler'; +import Reanimated from 'react-native-reanimated'; export default function Home() { return ( @@ -9,7 +11,7 @@ export default function Home() { Seja um GEROcuidador! - + { + status: string; + message: string; + data: T; + } + \ No newline at end of file diff --git a/src/app/model/Evento.ts b/src/app/model/Evento.ts new file mode 100644 index 00000000..c341cc9a --- /dev/null +++ b/src/app/model/Evento.ts @@ -0,0 +1,26 @@ +import { Model } from "@nozbe/watermelondb"; +import { field, text, date, readonly, json, relation } from "@nozbe/watermelondb/decorators"; +import Idoso from "./Idoso"; + +const sanitizeStringArray = (rawParticipantes: any): string[] => { + return Array.isArray(rawParticipantes) ? rawParticipantes.map(String) : []; +}; + +export default class Evento extends Model { + static table = 'evento'; + + @text('titulo') titulo!: string; + @text('descricao') descricao!: string; + @date('dataHora') dataHora!: Date; + @text('categoria') categoria!: string; + @text('local') local!: string; + @json('participantes', sanitizeStringArray) participantes!: string[]; + + @readonly @date('created_at') createdAt!: Date; + @readonly @date('updated_at') updatedAt!: Date; + + @relation('idoso', 'idoso_id') idoso!: Idoso; + token: string | undefined; + notificacao!: boolean; + idIdoso: string | undefined; +} diff --git a/src/app/private/pages/cadastrarEvento.tsx b/src/app/private/pages/cadastrarEvento.tsx new file mode 100644 index 00000000..5f0fa97b --- /dev/null +++ b/src/app/private/pages/cadastrarEvento.tsx @@ -0,0 +1,408 @@ +import { + Pressable, + StyleSheet, + Text, + View, + TextInput, + Platform, + Switch, + } from "react-native"; + import React, { useEffect, useState } from "react"; + import { ScrollView } from "react-native"; + import Icon from "react-native-vector-icons/MaterialCommunityIcons"; + import { router } from "expo-router"; + import { SelectList } from "react-native-dropdown-select-list"; + import { ECategoriaRotina } from "../../interfaces/rotina.interface"; + import MaskInput, { Masks } from "react-native-mask-input"; + import MaskHour from "../../components/MaskHour"; + import Calendar from "react-native-vector-icons/Feather"; + import { postEvento } from "../../services/evento.service"; + import Toast from "react-native-toast-message"; + import AsyncStorage from "@react-native-async-storage/async-storage"; + import { IIdoso } from "../../interfaces/idoso.interface"; + import ErrorMessage from "../../components/ErrorMessage"; + import * as Notifications from "expo-notifications"; + import database from "../../db"; + import { Collection } from "@nozbe/watermelondb"; + import Evento from "../../model/Evento"; + import { handleNotificacao, validateFields } from "../../shared/helpers/useNotification"; + import CustomButton from "../../components/CustomButton"; + import WeekDays from "../../components/weekDay"; +import { Try } from "expo-router/build/views/Try"; + + interface IErrors { + titulo?: string; + data?: string; + hora?: string; + categoria?: string; + descricao?: string; + } + + export default function CadastrarEvento() { + const getInitialDateTime = (isData = true) => { + const today = new Date(); + const formattedDate = today.toLocaleDateString("pt-BR", { + hour: "2-digit", + minute: "2-digit", + }); + const formattedDateArray = formattedDate.split(" "); + return isData ? formattedDateArray[0] : formattedDateArray[1]; + }; + + const [idoso, setIdoso] = useState(); + const [titulo, setTitulo] = useState(""); + const [data, setData] = useState(getInitialDateTime()); + const [hora, setHora] = useState(getInitialDateTime(false)); + const [notificacao, setNotificacao] = useState(false); + const [expoToken, setExpoToken] = useState(""); + const [descricao, setDescricao] = useState(""); + const [categoria, setCategoria] = useState(null); + const [showLoading, setShowLoading] = useState(false); + const [erros, setErros] = useState({}); + const [showErrors, setShowErrors] = useState(false); + const [token, setToken] = useState(""); + const [dias, setDias] = useState([]); + + const getToken = () => { + AsyncStorage.getItem("token").then((response) => { + setToken(response as string); + }); + }; + + const getIdoso = () => { + AsyncStorage.getItem("idoso").then((idosoString) => { + if (idosoString) { + const idosoPayload = JSON.parse(idosoString) as IIdoso; + setIdoso(idosoPayload); + } + }); + }; + + const handleErrors = () => { + validateFields(titulo, data, hora, categoria, descricao, setErros); + }; + + const categorias = [ + { key: ECategoriaRotina.GERAL, value: ECategoriaRotina.GERAL }, + { key: ECategoriaRotina.MEDICAMENTO, value: ECategoriaRotina.MEDICAMENTO }, + { key: ECategoriaRotina.ALIMENTACAO, value: ECategoriaRotina.ALIMENTACAO }, + { key: ECategoriaRotina.EXERCICIOS, value: ECategoriaRotina.EXERCICIOS }, + ]; + + const getDateIsoString = () => { + const dateArray = data.split("/"); + return `${dateArray[2]}-${dateArray[1]}-${dateArray[0]}T${hora}:00.000`; + }; + + const salvarNoBancoLocal = async () => { + const eventoCollection = database.get('evento') as Collection; + + await database.write(async () => { + await eventoCollection.create((evento) => { + evento.titulo = titulo; + evento.descricao = descricao; + evento.categoria = String(categoria); + evento.dataHora = new Date(getDateIsoString()); + evento.token = token; + evento.notificacao = notificacao; + evento.idIdoso = idoso?.id; + }); + }); + console.log("Estado atual do banco:", await eventoCollection.query().fetch()); + } + + const salvar = async () => { + if (Object.keys(erros).length > 0) { + setShowErrors(true); + return; + } + + try { + setShowLoading(true); + await salvarNoBancoLocal(); + Toast.show({ + type: "success", + text1: "Sucesso!", + text2: "Evento criado", + }); + router.replace({ + pathname: "private/tabs/eventos", + }); + } catch (err) { + const error = err as { message: string }; + console.log(error); + Toast.show({ + type: "error", + text1: "Erro!", + text2: "Algo deu errado na criação do evento :(", + }); + } finally { + setShowLoading(false); + } + }; + + const goBack = () => { + router.push({ + pathname: "/private/tabs/eventos", + }); + }; + + useEffect(() => getIdoso(), []); + useEffect(() => getToken(), []); + useEffect(() => handleErrors(), [titulo, data, hora, categoria, descricao]); + useEffect(() => { + handleNotificacao(notificacao, setNotificacao, setExpoToken); + }, [notificacao]); + + return ( + + + + + + Novo evento + + + + + setTitulo(titulo)} + placeholder="Adicionar título" + placeholderTextColor={"#3D3D3D"} + style={styles.inputTitulo} + /> + + + + + + + + + + + + + + + setHora(hora)} + /> + + + + + + + + {(!categoria || categoria == ECategoriaRotina.GERAL) && ( + + )} + {categoria === ECategoriaRotina.ALIMENTACAO && ( + + )} + {categoria === ECategoriaRotina.MEDICAMENTO && ( + + )} + {categoria === ECategoriaRotina.EXERCICIOS && ( + + )} + + + + + + + + + Evento no(s) dia(s) + + + + + + + + + Ativar notificação + + + + + + + + + + + + + + + ); + } + + const styles = StyleSheet.create({ + notificacaoContainer: { + flexDirection: "row", + alignItems: "center", + width: "100%", + fontWeight: "700", + marginBottom: 20, + }, + notificacaoText: { + fontWeight: "600", + marginLeft: 7, + fontSize: 16, + color: "#616161", + }, + header: { + backgroundColor: "#2CCDB5", + height: 60, + flexDirection: "row", + alignItems: "center", + }, + tituloheader: { + fontWeight: "bold", + fontSize: 20, + color: "#fff", + }, + evento: { + flexDirection: "column", + borderRadius: 15, + backgroundColor: "white", + margin: 15, + padding: 15, + shadowColor: "#000", + shadowOffset: { width: 1, height: 1 }, + shadowOpacity: 0.3, + shadowRadius: 6, + alignItems: "center", + justifyContent: "center", + }, + titulo: { + width: "100%", + height: 60, + backgroundColor: "#F6F6F6", + borderRadius: 6, + justifyContent: "center", + paddingHorizontal: 15, + marginBottom: -20, + }, + inputTitulo: { + width: "100%", + fontSize: 18, + color: "#707070", + }, + erroTitulo: { + marginBottom: 30, + }, + dataHora: { + width: "100%", + height: 60, + backgroundColor: "#F6F6F6", + borderRadius: 6, + marginBottom: 0, + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 15, + }, + iconDataHora: { + marginRight: 10, + }, + textInput: { + width: "100%", + fontSize: 18, + color: "#707070", + }, + erro: { + marginBottom: 30, + }, + dropdown: { + borderRadius: 5, + borderWidth: 0, + height: 60, + marginBottom: -5, + }, + categoriaSelecionada: { + fontSize: 18, + color: "#707070", + }, + categoria: { + flexDirection: "row", + borderBottomWidth: 1, + width: 300, + alignItems: "baseline", + paddingBottom: 5, + }, + iconCategoria: { + marginRight: 10, + fontSize: 24, + color: "#707070", + }, + repete: { + marginBottom: 5, + }, + weekDays: { + marginBottom: 0, + }, + descricao: { + width: "100%", + marginBottom: 0, + }, + textInputDescription: { + padding: 10, + fontSize: 16, + color: "#707070", + textAlignVertical: "top", + backgroundColor: "#F6F6F6", + borderRadius: 6, + }, + linkButton: { + marginBottom: 30, + alignItems: "center", + }, + }); diff --git a/src/app/private/pages/editarEvento.tsx b/src/app/private/pages/editarEvento.tsx new file mode 100644 index 00000000..88af9135 --- /dev/null +++ b/src/app/private/pages/editarEvento.tsx @@ -0,0 +1,379 @@ +import { + ActivityIndicator, + Pressable, + StyleSheet, + Text, + View, + TextInput, + Platform, + Switch, + } from "react-native"; + import React, { useEffect, useState } from "react"; + import { ScrollView } from "react-native"; + import Icon from "react-native-vector-icons/MaterialCommunityIcons"; + import { router, useLocalSearchParams } from "expo-router"; + import WeekDays from "../../components/weekDay"; + import { SelectList } from "react-native-dropdown-select-list"; + import Calendar from "react-native-vector-icons/Feather"; + import CustomButton from "../../components/CustomButton"; + import MaskInput, { Masks } from "react-native-mask-input"; + import MaskHour from "../../components/MaskHour"; + import ErrorMessage from "../../components/ErrorMessage"; + import ModalConfirmation from "../../components/ModalConfirmation"; + import Toast from "react-native-toast-message"; + import database from "../../db"; + import { Collection } from "@nozbe/watermelondb"; + import Evento from "../../model/Evento"; + import { validateFields } from "../../shared/helpers/useNotification"; + + interface IErrors { + titulo?: string; + data?: string; + hora?: string; + local?: string; + descricao?: string; + } + + export default function EditarEvento() { + const { evento } = useLocalSearchParams(); + const params = JSON.parse(evento as string); + const [titulo, setTitulo] = useState(params.titulo); + const [local, setLocal] = useState(params.local); + const [descricao, setDescricao] = useState(params.descricao); + const [dias, setDias] = useState((params.dias || []).map(Number)); + const [data, setData] = useState(""); + const [hora, setHora] = useState(""); + const [notificacao, setNotificacao] = useState(String(params.notificacao) === "true"); + const [showLoading, setShowLoading] = useState(false); + const [erros, setErros] = useState({}); + const [showErrors, setShowErrors] = useState(false); + const [showLoadingApagar, setShowLoadingApagar] = useState(false); + const [modalVisible, setModalVisible] = useState(false); + + const handleDataHora = () => { + const dateString = new Date(params.dataHora).toLocaleString("pt-BR", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + }); + const [data, hora] = dateString.split(" "); + setData(data); + setHora(hora); + }; + + const handleErrors = () => { + validateFields(titulo, data, hora, local, descricao, setErros); + }; + + const getDateIsoString = (data: string, hora: string) => { + const dateArray = data.split("/"); + return `${dateArray[2]}-${dateArray[1]}-${dateArray[0]}T${hora}:00.000`; + }; + + const salvar = async () => { + if (Object.keys(erros).length > 0) { + setShowErrors(true); + return; + } + + try { + setShowLoading(true); + + const eventoCollection = database.get('evento') as Collection; + await database.write(async () => { + const evento = await eventoCollection.find(params.id); + + await evento.update(() => { + evento.titulo = titulo; + evento.dataHora = new Date(getDateIsoString(data, hora)); + evento.descricao = descricao; + evento.notificacao = notificacao; + }); + }); + + Toast.show({ + type: "success", + text1: "Sucesso!", + text2: "Evento atualizado com sucesso", + }); + + router.back(); + + } catch (err) { + console.log("Erro ao atualizar evento:", err); + Toast.show({ + type: "error", + text1: "Erro!", + text2: "Erro ao atualizar evento", + }); + } finally { + setShowLoading(false); + } + }; + + const apagarEvento = async () => { + setModalVisible(false); + setShowLoadingApagar(true); + + try { + const eventoCollection = database.get('evento') as Collection; + await database.write(async () => { + const evento = await eventoCollection.find(params.id); + await evento.destroyPermanently(); + }); + + router.replace("private/tabs/eventos"); + } catch (err) { + console.log("Erro ao apagar evento:", err); + } finally { + setShowLoadingApagar(false); + } + }; + + useEffect(() => handleDataHora(), []); + useEffect(() => handleErrors(), [titulo, data, hora, local, descricao]); + + const confirmation = () => { + setModalVisible(!modalVisible); + }; + + const closeModal = () => { + setModalVisible(false); + }; + + return ( + + + router.back()}> + + + Detalhes do evento + + + + {setTitulo(NewTitulo);}} + placeholder="Título do evento" + style={styles.inputTitulo} + /> + + + + + + + + + + + + + + + + Evento no(s) dia(s) + + + + + Ativar notificação + + + + + + {setDescricao(NewDescription);}} + placeholder="Descrição" + style={styles.textInputDescription} + multiline={true} + numberOfLines={4} + /> + + + + + + + + + {showLoadingApagar ? ( + + ) : ( + Apagar Evento + )} + + + + + + ); + } + + const styles = StyleSheet.create({ + header: { + backgroundColor: "#2CCDB5", + height: 60, + flexDirection: "row", + alignItems: "center", + }, + tituloheader: { + fontWeight: "bold", + color: "white", + fontSize: 20, + }, + Evento: { + borderRadius: 15, + backgroundColor: "white", + margin: 15, + padding: 15, + shadowColor: "#000", + shadowOffset: { width: 1, height: 1 }, + shadowOpacity: 0.3, + shadowRadius: 6, + alignItems: "center", + }, + titulo: { + flexDirection: "row", + marginTop: 10, + borderBottomWidth: 1, + borderBottomColor: "#333333", + paddingBottom: 5, + marginBottom: 1, + }, + inputTitulo: { + color: "black", + fontSize: 17, + textAlign: "center", + }, + dataHora: { + flexDirection: "row", + borderBottomWidth: 1, + borderBottomColor: "black", + paddingBottom: 5, + width: 300, + marginBottom: 1, + }, + iconDataHora: { + fontSize: 25, + opacity: 0.8, + }, + textInput: { + paddingLeft: 10, + color: "black", + fontSize: 17, + width: 280, + }, + categoria: { + flexDirection: "row", + borderBottomWidth: 1, + width: 300, + alignItems: "baseline", + paddingBottom: 5, + }, + iconCategoria: { + fontSize: 25, + opacity: 0.8, + }, + dropdown: { + borderWidth: 0, + paddingLeft: 10, + width: 280, + fontSize: 17, + }, + categoriaSelecionada: { + fontSize: 17, + color: "#3D3D3D", + }, + repete: { + alignSelf: "flex-start", + marginTop: 10, + fontSize: 17, + color: "#616161", + }, + weekDays: { + flexDirection: "row", + marginTop: 15, + marginBottom: 15, + }, + iconDesciption: { + width: "10%", + fontSize: 18, + }, + descricao: { + borderBottomWidth: 0, + borderBottomColor: "black", + paddingBottom: 5, + width: 300, + }, + textInputDescription: { + borderRadius: 10, + backgroundColor: "#F1F1F1", + fontSize: 17, + width: 300, + padding: 12, + }, + linkButton: { + marginTop: 20, + marginBottom: 40, + alignItems: "center", + width: 250, + }, + erroTitulo: { + marginBottom: 35, + }, + erro: { + marginBottom: 15, + alignSelf: "flex-start", + }, + apagar: { + color: "#FF7F7F", + alignSelf: "center", + fontSize: 18, + fontWeight: "600", + marginBottom: 25, + alignItems: "center", + }, + notificacaoContainer: { + flexDirection: "row", + alignItems: "center", + width: "100%", + fontWeight: "700", + marginBottom: 10, + }, + notificacaoText: { + fontWeight: "600", + marginLeft: 7, + fontSize: 16, + color: "#616161", + }, + }); + \ No newline at end of file diff --git a/src/app/private/pages/esqueciSenha.tsx b/src/app/private/pages/esqueciSenha.tsx new file mode 100644 index 00000000..57ad37c1 --- /dev/null +++ b/src/app/private/pages/esqueciSenha.tsx @@ -0,0 +1,103 @@ +import React, { useState } from "react"; +import { forgotPassword } from "../../services/user.service"; +import { Alert, Text, View, TextInput, StyleSheet, TouchableOpacity } from "react-native"; +import axios from 'axios'; +//import BackButton from "/components/BackButton.tsx"; Não consigo achar esse caminho, preciso fazer rodar... (é o botão q volta pra outra pag) + +export default function EsqueciSenha() { + const API_URL = process.env.EXPO_PUBLIC_API_URL; + const API_PORT = process.env.EXPO_PUBLIC_API_USUARIO_PORT; + const BASE_URL = `${API_URL}:${API_PORT}/api/usuario/esqueci-senha`; + const [email, setEmail] = useState(""); + + const handleRecuperarSenha = async () => { + if (!email) { + Alert.alert("Erro", "Por favor, insira um email válido."); + return; + } + try { + const response = await forgotPassword(email); + console.log("E-mail de recuperação enviado:", response); + } catch (error) { + console.error("Erro ao solicitar recuperação de senha:", error.message); + } + }; + return ( + + + {/* Logo deveria estar aqui, mas não consegui encaixá-la */} + + Esqueceu sua senha? + Calma, a GERO te ajuda!! + + + + + + + Recuperar senha + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: "center", + alignItems: "center", + backgroundColor: "#FFF", + padding: 16, + }, + logo: { + width: 280, + height: 90, + marginBottom: 40, + }, + title: { + fontSize: 28, + fontWeight: "300", + textAlign: "center", + marginBottom: 19, + }, + subtitle: { + fontSize: 18, + fontWeight: "300", + textAlign: "center", + marginBottom: 10, + }, + inputContainer: { + width: "90%", + maxWidth: 400, + borderBottomWidth: 1, + borderBottomColor: "#CCC", + marginBottom: 20, + }, + input: { + fontSize: 16, + paddingVertical: 8, + paddingHorizontal: 10, + color: "#333", + width: "100%", + }, + button: { + width: "90%", + maxWidth: 200, + backgroundColor: "#2CCDB5", + paddingVertical: 12, + borderRadius: 8, + alignItems: "center", + }, + buttonText: { + color: "#FFF", + fontSize: 16, + fontWeight: "600", + }, +}); diff --git a/src/app/private/tabs/_layout.tsx b/src/app/private/tabs/_layout.tsx index d4aee530..035754b5 100644 --- a/src/app/private/tabs/_layout.tsx +++ b/src/app/private/tabs/_layout.tsx @@ -41,6 +41,16 @@ export default function TabsLayout() { }} /> + { + return iconComponent(focused, size, "calendar"); + }, + }} + /> (); + const [user, setUser] = useState(); + const [eventos, setEventos] = useState([]); + const [loading, setLoading] = useState(true); + const [selectedDate, setSelectedDate] = useState(moment()); + const order: IOrder = { + field: "dataHora", + direction: "asc", + }; + + const datesWhitelist = [ + { + start: moment().clone().subtract(1, "y"), + end: moment().add(1, "y"), + }, + ]; + + const getIdoso = () => { + AsyncStorage.getItem("idoso").then((idosoString) => { + if (idosoString) { + const idosoPayload = JSON.parse(idosoString) as IIdoso; + setIdoso(idosoPayload); + } + }); + }; + + const novoEvento = () => { + router.push({ + pathname: "private/pages/cadastrarEvento", + }); + }; + + const handleUser = () => { + AsyncStorage.getItem("usuario").then((response) => { + const usuario = JSON.parse(response as string); + setUser(usuario); + }); + }; + + const getEventos = async () => { + if (!idoso || !selectedDate) return; + + setLoading(true); + + try { + const eventoCollection = database.get('evento') as Collection; + + // TODO: Consulta com defeito, arrumar um jeito de filtar com ela + /*const eventoFiltrados = await eventoCollection.query( + Q.where('idoso_id', idoso.id), + ).fetch();*/ + + const todosEventos = await eventoCollection.query().fetch(); + + const startOfDay = selectedDate.startOf('day').toISOString(); + const endOfDay = selectedDate.endOf('day').toISOString(); + + // Metodo menos eficiente, assim que resolvido deve ser descontinuado + const eventosFiltrados = todosEventos.filter(evento => { + const eventoDataHora = new Date(evento.dataHora).toISOString(); + return evento.idIdoso === idoso.id && eventoDataHora >= startOfDay && eventoDataHora <= endOfDay; + }); + + setEventos(eventosFiltrados); + } finally { + setLoading(false); + } + }; + + const markedDates = [ + { + date: moment(), + dots: [{ color: "#fff" }], + }, + ]; + + useEffect(() => handleUser(), []); + useEffect(() => getIdoso(), []); + useEffect(() => { + getEventos(); + }, + [idoso, selectedDate] + ); + + return ( + <> + {!user?.id && } + + {user?.id && !idoso?.id && } + + {user?.id && idoso?.id && ( + + + {getFoto(idoso?.foto)} + + {idoso?.nome} + + + + + + + + + + Novo Evento + + + {loading && ( + + )} + + {!loading && eventos.length > 0 && ( + + ( + + )} + estimatedItemSize={50} + /> + + )} + {eventos.length === 0 && ( + + {`Você ainda não tem nenhum evento cadastrado no dia ${moment( + selectedDate, + ).format("DD/MM")}`} + + )} + + )} + + ); +} + +const styles = StyleSheet.create({ + header: { + backgroundColor: "#2CCDB5", + width: "100%", + padding: 10, + flexDirection: "row", + alignItems: "center", + }, + fotoPerfil: { + width: 60, + aspectRatio: 1, + borderRadius: 100, + }, + Calendar: { + height: 80, + margin: 0, + backgroundColor: "#2CCDB5", + }, + nomeUsuario: { + color: "#FFFFFF", + fontSize: 16, + marginLeft: 20, + maxWidth: "75%", + }, + negrito: { + fontWeight: "bold", + }, + botaoCriarEvento: { + flexDirection: "row", + alignItems: "center", + backgroundColor: "#B4026D", + paddingHorizontal: 10, + paddingVertical: 5, + borderRadius: 10, + marginLeft: "auto", + marginRight: 10, + marginVertical: 10, + }, + textoBotaoCriarEvento: { + color: "white", + fontWeight: "600", + fontSize: 14, + marginLeft: 5, + }, + eventos: { + width: Dimensions.get("window").width, + height: Dimensions.get("window").height, + }, + semEventos: { + fontSize: 35, + opacity: 0.3, + textAlign: "center", + marginTop: "35%", + }, +}); diff --git a/src/app/public/cadastro.tsx b/src/app/public/cadastro.tsx index 946ef40d..23eaf9dc 100644 --- a/src/app/public/cadastro.tsx +++ b/src/app/public/cadastro.tsx @@ -209,6 +209,8 @@ export default function Cadastro() { style={styles.passwordInput} /> + + setEscondeSenha(!escondeSenha)} diff --git a/src/app/public/login.tsx b/src/app/public/login.tsx index 49381180..6e99cbf0 100644 --- a/src/app/public/login.tsx +++ b/src/app/public/login.tsx @@ -1,7 +1,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; import { router } from "expo-router"; import React, { useState, useEffect } from "react"; -import { Image, StyleSheet, Text, View, TextInput } from "react-native"; +import { Image, StyleSheet, Text, View, TextInput, Button } from "react-native"; import Toast from "react-native-toast-message"; import Icon from "react-native-vector-icons/MaterialCommunityIcons"; @@ -16,6 +16,7 @@ import database from "../db"; import { Collection, Q } from "@nozbe/watermelondb"; import { syncDatabaseWithServer } from "../services/watermelon.service"; import Usuario from "../model/Usuario"; +import ForgetButton from "../components/ForgetButton"; interface IErrors { email?: string; @@ -23,13 +24,16 @@ interface IErrors { } export default function Login() { + const API_URL = process.env.EXPO_PUBLIC_API_URL; + const API_PORT = process.env.EXPO_PUBLIC_API_USUARIO_PORT; + const BASE_URL = `${API_URL}:${API_PORT}/api/usuario`; const [email, setEmail] = useState(""); const [senha, setSenha] = useState(""); const [escondeSenha, setEscondeSenha] = useState(true); const [erros, setErros] = useState({}); const [showErrors, setShowErrors] = useState(false); const [showLoading, setShowLoading] = useState(false); - + const login = async () => { if (Object.keys(erros).length > 0) { setShowErrors(true); @@ -41,7 +45,7 @@ export default function Login() { try { setShowLoading(true); console.log("Iniciando o login..."); - + console.log(BASE_URL); const response = await loginUser(body); console.log("Resposta do login:", response); @@ -247,6 +251,7 @@ export default function Login() { name={escondeSenha ? "eye-outline" : "eye-off-outline"} size={20} /> + @@ -258,9 +263,16 @@ export default function Login() { showLoading={showLoading} /> + + + + - ); + ); } const styles = StyleSheet.create({ @@ -352,4 +364,11 @@ const styles = StyleSheet.create({ eye: { marginLeft: 100, }, + EsqueciButton: { + marginTop: 35, + alignItems: "center", + justifyContent: "center", // Adicionado para centralizar verticalmente + width: "100%", + flex: 1, + } }); \ No newline at end of file diff --git a/src/app/services/evento.service.ts b/src/app/services/evento.service.ts new file mode 100644 index 00000000..754e67ed --- /dev/null +++ b/src/app/services/evento.service.ts @@ -0,0 +1,103 @@ +import { IEvento, IEventoBody, IEventoFilter, IOrder } from "../interfaces/evento.interface"; +import { IResponse } from "../interfaces/response.interface"; + +const API_URL = process.env.EXPO_PUBLIC_API_URL; +const API_PORT = process.env.EXPO_PUBLIC_API_SAUDE_PORT; +const BASE_URL = `${API_URL}:${API_PORT}/api/saude/evento`; + +// Função para criar um evento +export const postEvento = async ( + body: IEventoBody, + token: string +): Promise> => { + const response = await fetch(BASE_URL, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify(body), + }); + + const json = await response.json(); + + if (response.status !== 201) { + throw new Error(json.message as string); + } + + return json; +}; + +// Função para listar todos os eventos +export const getAllEvento = async ( + filter: IEventoFilter, + order: IOrder +): Promise> => { + const params = `limit=20&offset=0&filter=${JSON.stringify( + filter + )}&order=${JSON.stringify(order)}`; + const response = await fetch(`${BASE_URL}?${params}`, { + method: "GET", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + }); + + const json = await response.json(); + + if (response.status !== 200) { + throw new Error(json.message as string); + } + + return json; +}; + +// Função para atualizar um evento +export const updateEvento = async ( + id: number, + body: Partial, + token: string +): Promise> => { + const response = await fetch(`${BASE_URL}/${id}`, { + method: "PATCH", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify(body), + }); + + const json = await response.json(); + + if (response.status !== 200) { + throw new Error(json.message as string); + } + + return json; +}; + +// Função para excluir um evento +export const deleteEvento = async ( + id: number, + token: string +): Promise> => { + const response = await fetch(`${BASE_URL}/${id}`, { + method: "DELETE", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + }); + + const json = await response.json(); + + if (response.status !== 200) { + throw new Error(json.message as string); + } + + return json; +}; diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts index 03122fdb..de4821b8 100644 --- a/src/app/services/user.service.ts +++ b/src/app/services/user.service.ts @@ -26,6 +26,28 @@ export const postUser = async ( return json; }; +export const forgotPassword = async ( + email: string, +): Promise> => { + const response = await fetch(`${BASE_URL}/esqueci-senha`, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify({ email }), + }); + + const json = await response.json(); + + if (response.status !== 200) { + throw new Error(json.message as string); + } + + return json; +}; + + export const updateUser = async ( id: number, body: Partial,