diff --git a/.gitignore b/.gitignore index a77e3e4..d72792c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ # dependencies -/img \ No newline at end of file +/img + +/mobile \ No newline at end of file diff --git a/README.md b/README.md index b5be6b3..537b11f 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@

🚀 Tecnologias   |    - 🖥️ Projeto   |    + 🖥️ Projeto   |    🔨 Backend   |    🌐 Frontend   |    📱 Mobile   |    😉 Como contribuir   |   
⚙️ Como executar   |    🧾 Licença   |    - 🧑 Autor + 🧑 Autor


@@ -61,10 +61,10 @@ O Projeto Be The Hero tem como objetivo conectar pessoas com vontade de ajudar c - +## 📱 Mobile +

+ Backend Photo +

## ⚙️ Como Executar diff --git a/assets/mobile.png b/assets/mobile.png new file mode 100644 index 0000000..10a72dc Binary files /dev/null and b/assets/mobile.png differ diff --git a/mobile/.expo-shared/assets.json b/mobile/.expo-shared/assets.json new file mode 100644 index 0000000..17ad228 --- /dev/null +++ b/mobile/.expo-shared/assets.json @@ -0,0 +1,4 @@ +{ + "f9155ac790fd02fadcdeca367b02581c04a353aa6d5aa84409a59f6804c87acd": true, + "89ed26367cdb9b771858e026f2eb95bfdb90e5ae943e716575327ec325f39c44": true +} \ No newline at end of file diff --git a/mobile/.gitignore b/mobile/.gitignore new file mode 100644 index 0000000..c409cf6 --- /dev/null +++ b/mobile/.gitignore @@ -0,0 +1,14 @@ +node_modules/**/* +.expo/* +npm-debug.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +web-build/ +web-report/ + +# macOS +.DS_Store diff --git a/mobile/App.js b/mobile/App.js new file mode 100644 index 0000000..cf82084 --- /dev/null +++ b/mobile/App.js @@ -0,0 +1,11 @@ +import'intl' +import 'intl/locale-data/jsonp/pt-BR' +import React from 'react'; +import Routes from './src/routes'; + +export default function App() { + return ( + + ); +} + diff --git a/mobile/app.json b/mobile/app.json new file mode 100644 index 0000000..d5e10df --- /dev/null +++ b/mobile/app.json @@ -0,0 +1,30 @@ +{ + "expo": { + "name": "Be The Hero", + "slug": "bethehero", + "privacy": "public", + "sdkVersion": "36.0.0", + "platforms": [ + "ios", + "android", + "web" + ], + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "splash": { + "image": "./assets/splash.png", + "resizeMode": "contain", + "backgroundColor": "#e02041" + }, + "updates": { + "fallbackToCacheTimeout": 0 + }, + "assetBundlePatterns": [ + "**/*" + ], + "ios": { + "supportsTablet": true + } + } +} diff --git a/mobile/assets/icon.png b/mobile/assets/icon.png new file mode 100644 index 0000000..9bcbd0d Binary files /dev/null and b/mobile/assets/icon.png differ diff --git a/mobile/assets/splash.png b/mobile/assets/splash.png new file mode 100644 index 0000000..7d5fe26 Binary files /dev/null and b/mobile/assets/splash.png differ diff --git a/mobile/babel.config.js b/mobile/babel.config.js new file mode 100644 index 0000000..2900afe --- /dev/null +++ b/mobile/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function(api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + }; +}; diff --git a/mobile/package.json b/mobile/package.json new file mode 100644 index 0000000..2ce5529 --- /dev/null +++ b/mobile/package.json @@ -0,0 +1,33 @@ +{ + "main": "node_modules/expo/AppEntry.js", + "scripts": { + "start": "expo start", + "android": "expo start --android", + "ios": "expo start --ios", + "web": "expo start --web", + "eject": "expo eject" + }, + "dependencies": { + "@react-native-community/masked-view": "0.1.5", + "@react-navigation/native": "^5.1.3", + "@react-navigation/stack": "^5.2.7", + "axios": "^0.19.2", + "expo": "~36.0.0", + "expo-constants": "^9.0.0", + "expo-mail-composer": "~8.0.0", + "intl": "^1.2.5", + "react": "~16.9.0", + "react-dom": "~16.9.0", + "react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz", + "react-native-gesture-handler": "~1.5.0", + "react-native-reanimated": "~1.4.0", + "react-native-safe-area-context": "0.6.0", + "react-native-screens": "2.0.0-alpha.12", + "react-native-web": "~0.11.7" + }, + "devDependencies": { + "babel-preset-expo": "~8.0.0", + "@babel/core": "^7.0.0" + }, + "private": true +} diff --git a/mobile/src/assets/logo.png b/mobile/src/assets/logo.png new file mode 100644 index 0000000..bca15bd Binary files /dev/null and b/mobile/src/assets/logo.png differ diff --git a/mobile/src/assets/logo@2x.png b/mobile/src/assets/logo@2x.png new file mode 100644 index 0000000..d950e5c Binary files /dev/null and b/mobile/src/assets/logo@2x.png differ diff --git a/mobile/src/assets/logo@3x.png b/mobile/src/assets/logo@3x.png new file mode 100644 index 0000000..6e1fd30 Binary files /dev/null and b/mobile/src/assets/logo@3x.png differ diff --git a/mobile/src/pages/detail/index.js b/mobile/src/pages/detail/index.js new file mode 100644 index 0000000..2563a29 --- /dev/null +++ b/mobile/src/pages/detail/index.js @@ -0,0 +1,80 @@ +import React from 'react' +import { Feather } from '@expo/vector-icons' +import { useNavigation, useRoute } from '@react-navigation/native' +import { View, Text, Image, TouchableOpacity, Linking } from 'react-native' +import * as MailComposer from 'expo-mail-composer' + + +import logoImg from '../../assets/logo.png' + +import styles from './style' + + +export default function Detail() { + const navigation = useNavigation() + const route = useRoute() + + const incident = route.params.incident + const message = `Ola ${incident.name}, estou entrando em contato pois gostaria de ajudar no caso "${incident.title}" com o valor de ${ Intl.NumberFormat('pt-BR', {style: 'currency',currency: 'BRL' }).format(incident.value)}` + function navigateBack() { + navigation.goBack() + } + + function sendMail() { + MailComposer.composeAsync({ + subject: `Heroi do caso: ${incident.title}`, + recipients: [incident.email], + body: message + }) + } + function sendWhatsapp() { + Linking.openURL(`whatsapp://send?phone=55${incident.whatsapp}&text=${message}`) + } + + return ( + + + + + + + + + + ONG: + {incident.name} ({incident.city}/{incident.uf}) + + Caso: + {incident.description} + + Valor: + { + Intl.NumberFormat('pt-BR', { + style: 'currency', + currency: 'BRL' + }).format(incident.value)} + + + + + Salve o dia! + Seja o heroi desse caso. + + + Entre em contato + + + + Whatsapp + + + + E-mail + + + + + + + ) +} \ No newline at end of file diff --git a/mobile/src/pages/detail/style.js b/mobile/src/pages/detail/style.js new file mode 100644 index 0000000..ba03b59 --- /dev/null +++ b/mobile/src/pages/detail/style.js @@ -0,0 +1,70 @@ +import { StyleSheet } from 'react-native' +import Constants from 'expo-constants' + +export default StyleSheet.create({ + container:{ + flex: 1, + paddingHorizontal: 24, + paddingTop: Constants.statusBarHeight +20 + }, + header:{ + flexDirection:'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + incident: { + padding: 24, + borderRadius: 8, + backgroundColor: '#fff', + marginBottom: 16, + marginTop: 48 + }, + incidentProperty: { + fontSize: 14, + color: '#41414d', + fontWeight: 'bold', + marginTop: 24 + }, + incidentValue: { + marginTop:8, + fontSize: 15, + + color: '#737380' + }, + contactBox:{ + padding: 24, + borderRadius: 8, + backgroundColor: '#fff', + marginBottom: 16, + }, + heroTitle:{ + fontWeight:'bold', + fontSize:20, + color: '#13131a', + lineHeight:30, + }, + heroDescription:{ + fontSize: 15, + color: '#737380', + marginTop: 16, + }, + actions:{ + marginTop:16, + flexDirection: 'row', + justifyContent: 'space-between' + }, + action: { + backgroundColor: "#e02041", + borderRadius: 8, + height: 50, + width: '48%', + justifyContent: 'center', + alignItems: 'center', + }, + actionText:{ + color: '#fff', + fontSize: 15, + fontWeight: 'bold' + } + +}) \ No newline at end of file diff --git a/mobile/src/pages/incidents/index.js b/mobile/src/pages/incidents/index.js new file mode 100644 index 0000000..738e6df --- /dev/null +++ b/mobile/src/pages/incidents/index.js @@ -0,0 +1,100 @@ +import React, { useState, useEffect } from "react"; +import { Feather } from "@expo/vector-icons"; +import { useNavigation } from "@react-navigation/native"; +import { View, FlatList, Image, Text, TouchableOpacity } from "react-native"; +import logoImg from "../../assets/logo.png"; +import styles from "./style"; +import api from "../../services/api"; + +export default function Incidents() { + const [Incidents, setIncidents] = useState([]); + const [total,setTotal] = useState(0) + const [page, setPage] = useState(1) + const [loading, setLoading]= useState(false) + + + + + + + const navigation = useNavigation(); + + function navigateToDetail(incident) { + navigation.navigate("Detail",{ incident }); + } + + async function loadIncidents() { + if(loading){ + return + } + if(total>0 && Incidents.length === total){ + return + } + setLoading(true) + + const response = await api.get("incidents",{ + params: {page} + }); + + setIncidents([...Incidents,...response.data]); + setTotal(response.headers['x-total-count']) + setPage(page+1) + setLoading(false) + } + + useEffect(() => { + loadIncidents(); + }, []); + + return ( + + + + + total de {total} casos. + + + Bem-vindo! + + Escolha um dos casos abaixo e salve o dia + + + String(incident.id)} + showsVerticalScrollIndicator={false} + onEndReached={loadIncidents} + onEndReachedThreshold={0.2} + + renderItem={({ item: incident }) => ( + + + ONG: + {incident.name} + + Caso: + {incident.description} + + Valor: + { + Intl.NumberFormat('pt-BR',{ + style:'currency', + currency:'BRL' + }).format(incident.value)} + + + navigateToDetail(incident)} + > + Ver mais detalhes + + + + + )} + /> + + ); +} diff --git a/mobile/src/pages/incidents/style.js b/mobile/src/pages/incidents/style.js new file mode 100644 index 0000000..55a9db9 --- /dev/null +++ b/mobile/src/pages/incidents/style.js @@ -0,0 +1,70 @@ +import { StyleSheet } from 'react-native' +import Constants from 'expo-constants' + +export default StyleSheet.create( + { + container: { + flex: 1, + paddingHorizontal: 24, + paddingTop: Constants.statusBarHeight + 20 + }, + header: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center' + + }, + headerText: { + fontSize: 15, + color: '#737380' + }, + headerTextBold: { + fontWeight: 'bold' + }, + title: { + fontSize: 30, + marginBottom: 16, + marginTop: 48, + color: '#13131a', + fontWeight: 'bold' + }, + description: { + fontSize: 16, + lineHeight: 24, + color: '#737380' + + }, + incidentList: { + marginTop: 32, + }, + incident: { + padding: 24, + borderRadius: 8, + backgroundColor: '#fff', + marginBottom: 16, + }, + incidentProperty: { + fontSize: 14, + color: '#41414d', + fontWeight: 'bold' + }, + incidentValue: { + marginTop:8, + fontSize: 15, + marginBottom:24, + color: '#737380' + }, + detailButton:{ + flexDirection: 'row', + justifyContent: 'space-between', + alignItems : 'center' + }, + detailButtonText:{ + color: '#e02041', + fontSize: 15, + fontWeight: 'bold', + + } + + + }) \ No newline at end of file diff --git a/mobile/src/routes.js b/mobile/src/routes.js new file mode 100644 index 0000000..8ba3586 --- /dev/null +++ b/mobile/src/routes.js @@ -0,0 +1,19 @@ +import React from 'react' +import {NavigationContainer} from '@react-navigation/native' +import {createStackNavigator} from '@react-navigation/stack' + +const Appstack = createStackNavigator() + +import Incidents from './pages/incidents' +import Detail from './pages/detail' + +export default function Routes(){ + return( + + + + + + + ) +} \ No newline at end of file diff --git a/mobile/src/services/api.js b/mobile/src/services/api.js new file mode 100644 index 0000000..f1297c2 --- /dev/null +++ b/mobile/src/services/api.js @@ -0,0 +1,7 @@ +import axios from 'axios' + +const api = axios.create({ + baseURL:'http://192.168.143.10:3333' +}) + +export default api \ No newline at end of file