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
+
+
+
## ⚙️ 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