diff --git a/.env.development b/.env.development index a88d9e6b..51e83319 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -EXPO_PUBLIC_API_URL=http://192.168.1.10 +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 c63f53df..24c541cd 100644 --- a/app.json +++ b/app.json @@ -41,14 +41,14 @@ "origin": false }, "eas": { - "projectId": "7b777975-c65a-4ae3-ab23-93691fd81c12" + "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 08f67133..8bd50bb4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,19 +19,20 @@ "expo": "^51.0.39", "expo-build-properties": "~0.12.5", "expo-constants": "~16.0.2", - "expo-dev-client": "~4.0.23", + "expo-dev-client": "~4.0.29", "expo-device": "~6.0.2", - "expo-image": "~1.12.13", + "expo-doctor": "^1.12.4", + "expo-image": "~1.13.0", "expo-image-picker": "~15.0.7", "expo-jwt": "^1.6.5", "expo-linking": "~6.3.1", - "expo-notifications": "~0.28.15", - "expo-router": "^3.5.23", - "expo-splash-screen": "~0.27.5", + "expo-notifications": "~0.28.19", + "expo-router": "~3.5.24", + "expo-splash-screen": "~0.27.7", "expo-status-bar": "~1.12.1", - "expo-updates": "~0.25.22", + "expo-updates": "~0.25.27", "jest": "^29.2.1", - "jest-expo": "~51.0.3", + "jest-expo": "~51.0.4", "jest-mock-extended": "^3.0.5", "jest-sonar": "^0.2.16", "jest-sonar-reporter": "^2.0.0", @@ -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" }, @@ -2585,49 +2584,6 @@ "xmlbuilder": "^14.0.0" } }, - "node_modules/@expo/cli/node_modules/@expo/prebuild-config": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-7.0.9.tgz", - "integrity": "sha512-9i6Cg7jInpnGEHN0jxnW0P+0BexnePiBzmbUvzSbRXpdXihYUX2AKMu73jgzxn5P1hXOSkzNS7umaY+BZ+aBag==", - "dependencies": { - "@expo/config": "~9.0.0-beta.0", - "@expo/config-plugins": "~8.0.8", - "@expo/config-types": "^51.0.3", - "@expo/image-utils": "^0.5.0", - "@expo/json-file": "^8.3.0", - "@react-native/normalize-colors": "0.74.85", - "debug": "^4.3.1", - "fs-extra": "^9.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.6.0", - "xml2js": "0.6.0" - }, - "peerDependencies": { - "expo-modules-autolinking": ">=0.8.1" - } - }, - "node_modules/@expo/cli/node_modules/@expo/prebuild-config/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@expo/cli/node_modules/@expo/prebuild-config/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/@expo/cli/node_modules/@expo/spawn-async": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz", @@ -2639,11 +2595,6 @@ "node": ">=12" } }, - "node_modules/@expo/cli/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==" - }, "node_modules/@expo/cli/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3892,16 +3843,17 @@ } }, "node_modules/@expo/prebuild-config": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-7.0.6.tgz", - "integrity": "sha512-Hts+iGBaG6OQ+N8IEMMgwQElzJeSTb7iUJ26xADEHkaexsucAK+V52dM8M4ceicvbZR9q8M+ebJEGj0MCNA3dQ==", + "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.0-beta.0", - "@expo/config-types": "^51.0.0-unreleased", + "@expo/config-plugins": "~8.0.8", + "@expo/config-types": "^51.0.3", "@expo/image-utils": "^0.5.0", "@expo/json-file": "^8.3.0", - "@react-native/normalize-colors": "0.74.84", + "@react-native/normalize-colors": "0.74.85", "debug": "^4.3.1", "fs-extra": "^9.0.0", "resolve-from": "^5.0.0", @@ -3916,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" } @@ -3924,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", @@ -3941,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", @@ -3955,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" } @@ -3963,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", @@ -3973,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" }, @@ -3984,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" }, @@ -3998,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" @@ -4013,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" }, @@ -4023,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" } @@ -4037,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", @@ -4051,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" } @@ -4059,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" }, @@ -4070,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" }, @@ -4081,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" }, @@ -4092,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" } @@ -4100,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", @@ -4113,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" } @@ -4121,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" }, @@ -4132,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" } @@ -7460,9 +7433,10 @@ "integrity": "sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA==" }, "node_modules/@react-native/normalize-colors": { - "version": "0.74.84", - "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.84.tgz", - "integrity": "sha512-Y5W6x8cC5RuakUcTVUFNAIhUZ/tYpuqHZlRBoAuakrTwVuoNHXfQki8lj1KsYU7rW6e3VWgdEx33AfOQpdNp6A==" + "version": "0.74.85", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz", + "integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==", + "license": "MIT" }, "node_modules/@react-native/virtualized-lists": { "version": "0.74.87", @@ -11997,13 +11971,14 @@ } }, "node_modules/expo-dev-client": { - "version": "4.0.23", - "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.23.tgz", - "integrity": "sha512-s0qTAxrvpztQUpi0WS/JKddon04jZqnAHcwiMsuDyt+VSqDL6VF3aZAGl8dI5ZEDsq/cT3jETyNxY8CMkvLmyA==", - "dependencies": { - "expo-dev-launcher": "4.0.25", - "expo-dev-menu": "5.0.19", - "expo-dev-menu-interface": "1.8.3", + "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", + "expo-dev-menu-interface": "1.8.4", "expo-manifests": "~0.14.0", "expo-updates-interface": "~0.16.2" }, @@ -12012,12 +11987,13 @@ } }, "node_modules/expo-dev-launcher": { - "version": "4.0.25", - "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.25.tgz", - "integrity": "sha512-uwdcQvBGMXl1WAlOg0Qb827xDogJcqSHKjIkB+YOPjUPdf9NsLN9AwUHZqIK1wOcmvi0pfgv1fPzTgoE9AwNcw==", + "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.19", + "expo-dev-menu": "5.0.23", "expo-manifests": "~0.14.0", "resolve-from": "^5.0.0", "semver": "^7.6.0" @@ -12030,6 +12006,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", @@ -12044,12 +12021,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" }, @@ -12058,11 +12037,12 @@ } }, "node_modules/expo-dev-menu": { - "version": "5.0.19", - "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.19.tgz", - "integrity": "sha512-C/ulbzfhcEsEk1X0gF3XaJPSwCZJqnHPpYqPGUf4xaXzk/TZpeMTqF6f3nfMyZjpj67L6DetvaJWv8jiDzZ/6Q==", + "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.3", + "expo-dev-menu-interface": "1.8.4", "semver": "^7.5.4" }, "peerDependencies": { @@ -12070,9 +12050,10 @@ } }, "node_modules/expo-dev-menu-interface": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.8.3.tgz", - "integrity": "sha512-QM0LRozeFT5Ek0N7XpV93M+HMdEKRLEOXn0aW5M3uoUlnqC1+PLtF3HMy3k3hMKTTE/kJ1y1Z7akH07T0lunCQ==", + "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": "*" } @@ -12081,6 +12062,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" }, @@ -12121,6 +12103,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", @@ -12146,9 +12137,10 @@ } }, "node_modules/expo-image": { - "version": "1.12.13", - "resolved": "https://registry.npmjs.org/expo-image/-/expo-image-1.12.13.tgz", - "integrity": "sha512-Dmuc5qmkIsl1nFj8C3Ux3wL2bN4QYW4dM9fkGA8kYiP5Fxf1lT36ldkHk2O2lPFRSFJDvLxT8Tz+7GTko5fzwQ==", + "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": "*" } @@ -12337,9 +12329,10 @@ } }, "node_modules/expo-notifications": { - "version": "0.28.15", - "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.28.15.tgz", - "integrity": "sha512-T303dw2akcG4w8HBKI7+Y1v5kFxYy53DjlBSLBMo5f22vnLTHWaa8oOhmpwGRGU4uiX56Bw4q0wywCTSgbEamQ==", + "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", @@ -12561,9 +12554,10 @@ } }, "node_modules/expo-router": { - "version": "3.5.23", - "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-3.5.23.tgz", - "integrity": "sha512-Re2kYcxov67hWrcjuu0+3ovsLxYn79PuX6hgtYN20MgigY5ttX79KOIBEVGTO3F3y9dxSrGHyy5Z14BcO+usGQ==", + "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", @@ -12571,7 +12565,7 @@ "@react-navigation/bottom-tabs": "~6.5.7", "@react-navigation/native": "~6.1.6", "@react-navigation/native-stack": "~6.9.12", - "expo-splash-screen": "0.27.5", + "expo-splash-screen": "0.27.7", "react-native-helmet-async": "2.0.4", "schema-utils": "^4.0.1" }, @@ -12647,11 +12641,12 @@ } }, "node_modules/expo-splash-screen": { - "version": "0.27.5", - "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.27.5.tgz", - "integrity": "sha512-9rdZuLkFCfgJBxrheUsOEOIW6Rp+9NVlpSE0hgXQwbTCLTncf00IHSE8/L2NbFyeDLNjof1yZBppaV7tXHRUzA==", + "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.6" + "@expo/prebuild-config": "7.0.9" }, "peerDependencies": { "expo": "*" @@ -12668,9 +12663,10 @@ "integrity": "sha512-R+gFGn0x5CWl4OVlk2j1bJTJIz4KO8mPoCHpRHmfqMjmrMvrOM0qQSY3V5NHXwp1yT/L2v8aUmFQsBRIdvi1XA==" }, "node_modules/expo-updates": { - "version": "0.25.22", - "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.25.22.tgz", - "integrity": "sha512-ebu+wPnISzJ/H70CFAJAybS4ZZrACxRbgr9SMqOI/h84CwXGmdxzLmgxoNhy5q/Fa1u7JBmSr6x9a7psBDT4Cw==", + "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", @@ -15191,9 +15187,10 @@ } }, "node_modules/jest-expo": { - "version": "51.0.3", - "resolved": "https://registry.npmjs.org/jest-expo/-/jest-expo-51.0.3.tgz", - "integrity": "sha512-r49OuS9X2S/dH+lSfNmarBS2L/tgvBhzOgKHYFyDJWo+Bb5uVs7Rg/GZal/RD/NDkKFJuByGAaW1F6zHYnjZnw==", + "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", @@ -17937,9 +17934,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": "*" } @@ -19437,6 +19435,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" }, @@ -19673,6 +19672,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", @@ -19732,6 +19732,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 0d28588a..8fc8bc07 100644 --- a/package.json +++ b/package.json @@ -26,19 +26,20 @@ "expo": "^51.0.39", "expo-build-properties": "~0.12.5", "expo-constants": "~16.0.2", - "expo-dev-client": "~4.0.23", + "expo-dev-client": "~4.0.29", "expo-device": "~6.0.2", - "expo-image": "~1.12.13", + "expo-doctor": "^1.12.4", + "expo-image": "~1.13.0", "expo-image-picker": "~15.0.7", "expo-jwt": "^1.6.5", "expo-linking": "~6.3.1", - "expo-notifications": "~0.28.15", - "expo-router": "^3.5.23", - "expo-splash-screen": "~0.27.5", + "expo-notifications": "~0.28.19", + "expo-router": "~3.5.24", + "expo-splash-screen": "~0.27.7", "expo-status-bar": "~1.12.1", - "expo-updates": "~0.25.22", + "expo-updates": "~0.25.27", "jest": "^29.2.1", - "jest-expo": "~51.0.3", + "jest-expo": "~51.0.4", "jest-mock-extended": "^3.0.5", "jest-sonar": "^0.2.16", "jest-sonar-reporter": "^2.0.0", @@ -53,6 +54,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", 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/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/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/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; +};