Skip to content

Commit

Permalink
Mobile part
Browse files Browse the repository at this point in the history
  • Loading branch information
caiquejjx committed Mar 29, 2020
1 parent fe69f02 commit fc77698
Show file tree
Hide file tree
Showing 24 changed files with 5,987 additions and 14 deletions.
Binary file added assets-app-mobile/.DS_Store
Binary file not shown.
Binary file removed assets/heroes.png
Binary file not shown.
11 changes: 0 additions & 11 deletions assets/logo.svg

This file was deleted.

5 changes: 3 additions & 2 deletions backend/src/controllers/IncidentController.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = {

const [count] = await connection("incidents").count();
const incidents = await connection("incidents")
.join("ongs", "ongs_id", "=", "incidents.ong_id")
.join("ongs", "ongs.id", "=", "incidents.ong_id")
.limit(5)
.offset((page - 1) * 5)
.select([
Expand All @@ -31,7 +31,8 @@ module.exports = {
"ongs.uf"
]);

res.headers("X-Total-Count", count["count(*)"]);
res.header("X-Total-Count", count["count(*)"]);

return res.json(incidents);
},
async delete(req, res) {
Expand Down
Binary file modified backend/src/database/db.sqlite
Binary file not shown.
2 changes: 1 addition & 1 deletion backend/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ routes.get("/ongs", OngController.index);
routes.post("/ongs", OngController.create);

routes.post("/incidents", IncidentController.create);
routes.get("incidents", IncidentController.index);
routes.get("/incidents", IncidentController.index);
routes.delete("/incidents/:id", IncidentController.delete);

routes.get("/profile", ProfileController.index);
Expand Down
4 changes: 4 additions & 0 deletions mobile/.expo-shared/assets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"f9155ac790fd02fadcdeca367b02581c04a353aa6d5aa84409a59f6804c87acd": true,
"89ed26367cdb9b771858e026f2eb95bfdb90e5ae943e716575327ec325f39c44": true
}
14 changes: 14 additions & 0 deletions mobile/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
node_modules/**/*
.expo/*
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
web-report/

# macOS
.DS_Store
10 changes: 10 additions & 0 deletions mobile/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import "intl";
import "intl/locale-data/jsonp/pt-BR";

import React from "react";
import { StyleSheet, Text, View } from "react-native";
import Routes from "./src/routes";

export default function App() {
return <Routes />;
}
24 changes: 24 additions & 0 deletions mobile/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"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
}
}
}
Binary file added mobile/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mobile/assets/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions mobile/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
32 changes: 32 additions & 0 deletions mobile/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"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.8",
"axios": "^0.19.2",
"expo": "~36.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/core": "^7.0.0",
"babel-preset-expo": "~8.0.0"
},
"private": true
}
Binary file added mobile/src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mobile/src/assets/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mobile/src/assets/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions mobile/src/pages/Detail/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from "react";
import { View, TouchableOpacity, Image, Text, Linking } from "react-native";
import { Feather } from "@expo/vector-icons";
import { useNavigation, useRoute } from "@react-navigation/native";
import logoImg from "../../assets/logo.png";
import * as MailComposer from "expo-mail-composer";

import styles from "./styles";

export default function Details() {
const navigation = useNavigation();
const route = useRoute();

const incident = route.params.incident;
const message = `Olá ${
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: `Herói do caso: ${incident.title}`,
recipients: [incident.email],
body: message
});
}

function sendWhatsapp() {
Linking.openURL(
`whatsapp://send?phone=${incident.whatsapp}&text=${message}`
);
}
return (
<View style={styles.container}>
<View style={styles.header}>
<Image source={logoImg} />
<TouchableOpacity onPress={navigateBack}>
<Feather name="arrow-left" size={28} color="#e02041" />
</TouchableOpacity>
</View>
<View style={styles.incident}>
<Text style={[styles.incidentProperty, { marginTop: 0 }]}>ONG:</Text>
<Text style={styles.incidentValue}>
{incident.name} de {incident.city}/{incident.uf}
</Text>

<Text style={styles.incidentProperty}>CASO:</Text>
<Text style={styles.incidentValue}>{incident.title}</Text>

<Text style={styles.incidentProperty}>VALOR:</Text>
<Text style={styles.incidentValue}>
{Intl.NumberFormat("pt-BR", {
style: "currency",
currency: "BRL"
}).format(incident.value)}
</Text>
</View>

<View style={styles.contactBox}>
<Text style={styles.heroTitle}>Salve o dia!</Text>
<Text style={styles.heroTitle}>Seja o herói desse caso</Text>

<Text style={styles.heroDescription}>Entre em contato:</Text>

<View style={styles.actions}>
<TouchableOpacity style={styles.action} onPress={sendWhatsapp}>
<Text style={styles.actionText}>Whatsapp</Text>
</TouchableOpacity>

<TouchableOpacity style={styles.action} onPress={sendMail}>
<Text style={styles.actionText}>E-mail</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
78 changes: 78 additions & 0 deletions mobile/src/pages/Detail/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
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",
marginTop: 24,
fontWeight: "bold"
},

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: "#e02141",
borderRadius: 8,
height: 50,
width: "48%",
justifyContent: "center",
alignItems: "center"
},

actionText: {
color: "#FFF",
fontSize: 15,
fontWeight: "bold"
}
});
93 changes: 93 additions & 0 deletions mobile/src/pages/Incidents/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, { useEffect, useState } from "react";
import { Feather } from "@expo/vector-icons";
import { View, FlatList, Image, Text, TouchableOpacity } from "react-native";
import api from "../../services/api";
import logoImg from "../../assets/logo.png";
import { useNavigation } from "@react-navigation/native";
import styles from "./styles";

export default function Incident() {
const navigation = useNavigation();
const [incidents, setIncidents] = useState([]);
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);

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 (
<View style={styles.container}>
<View style={styles.header}>
<Image source={logoImg} />
<Text style={styles.headerText}>
Total de <Text style={styles.headerTextBold}>{total} casos</Text>
</Text>
</View>
<Text style={styles.title}>Bem-vindo!</Text>
<Text style={styles.description}>
Escolha um dos casos abaixo e salve o dia.
</Text>

<FlatList
sytle={styles.incidentList}
data={incidents}
keyExtractor={incidents => String(incidents.id)}
showsVerticalScrollIndicator={false}
onEndReached={loadIncidents}
onEndReachedThreshold={0.2}
renderItem={({ item: incidents }) => (
<View style={styles.incident}>
<Text style={styles.incidentProperty}>ONG:</Text>
<Text style={styles.incidentValue}>{incidents.name}</Text>

<Text style={styles.incidentProperty}>CASO:</Text>
<Text style={styles.incidentValue}>{incidents.title}</Text>

<Text style={styles.incidentProperty}>VALOR:</Text>
<Text style={styles.incidentValue}>
{Intl.NumberFormat("pt-BR", {
style: "currency",
currency: "BRL"
}).format(incidents.value)}
</Text>

<TouchableOpacity
style={styles.detailsButton}
onPress={() => navigateToDetail(incidents)}
>
<Text style={styles.detailsButtonText}>Ver mais detalhes</Text>
<Feather name="arrow-right" size={16} color="#E02041" />
</TouchableOpacity>
</View>
)}
/>
</View>
);
}
Loading

0 comments on commit fc77698

Please sign in to comment.