diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..62c89355
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.idea/
\ No newline at end of file
diff --git a/application/mobile/.env.example b/application/mobile/.env.example
new file mode 100644
index 00000000..ca9963a0
--- /dev/null
+++ b/application/mobile/.env.example
@@ -0,0 +1 @@
+VITE_API_URL=http://localhost:8080
\ No newline at end of file
diff --git a/application/mobile/.gitignore b/application/mobile/.gitignore
index 545942e1..318a7401 100644
--- a/application/mobile/.gitignore
+++ b/application/mobile/.gitignore
@@ -28,8 +28,9 @@ yarn-error.*
.DS_Store
*.pem
-# local env files
+# env files
.env*.local
+.env
# typescript
*.tsbuildinfo
diff --git a/application/mobile/App.js b/application/mobile/App.js
index 1a6fc5b7..dd236d0d 100644
--- a/application/mobile/App.js
+++ b/application/mobile/App.js
@@ -4,6 +4,8 @@ import LoginScreen from "./App/Screens/LoginScreen";
import RegisterScreen from "./App/Screens/RegisterScreen";
import FeedScreen from "./App/Screens/FeedScreen";
import ProfileScreen from "./App/Screens/ProfileScreen";
+import PostCreationScreen from "./App/Screens/PostCreationScreen";
+import SearchResultScreen from "./App/Screens/SearchResultScreen";
const Stack = createNativeStackNavigator();
@@ -31,6 +33,16 @@ export default function App() {
component={ProfileScreen}
options={{ headerShown: false }}
/>
+
+
);
diff --git a/application/mobile/App/Screens/FeedScreen.js b/application/mobile/App/Screens/FeedScreen.js
index ce0e913a..14939185 100644
--- a/application/mobile/App/Screens/FeedScreen.js
+++ b/application/mobile/App/Screens/FeedScreen.js
@@ -14,7 +14,7 @@ import {
import Icon from "react-native-vector-icons/Entypo";
import Post from "../components/Post";
-export default function FeedScreen({ navigation }) {
+export default function FeedScreen({ navigation, route }) {
const getPosts = () => {
return [
{
@@ -81,6 +81,8 @@ export default function FeedScreen({ navigation }) {
};
const [isMenuVisible, setIsMenuVisible] = useState(false);
+ const [text, setText] = useState("");
+ const [error, setError] = useState("");
const toggleMenu = () => {
console.log("Toggle menu");
@@ -88,10 +90,12 @@ export default function FeedScreen({ navigation }) {
};
const createPost = () => {
+ navigation.navigate("Post");
console.log("create post");
};
const viewProfile = () => {
console.log("view profile");
+ setIsMenuVisible(false);
navigation.navigate("Profile");
};
const settings = () => {
@@ -102,18 +106,26 @@ export default function FeedScreen({ navigation }) {
navigation.navigate("Login");
};
+ const search = () => {
+ navigation.navigate("Search", {
+ param: text,
+ authToken: route.params.accessToken,
+ });
+ };
+
return (
-
- Fanatic
-
-
-
+
+
+
+ appFanatic.
+
+
+
+
+
+
@@ -140,7 +152,12 @@ export default function FeedScreen({ navigation }) {
-
+
{
- console.log(email + " logged in with password " + password);
- navigation.navigate("Feed");
+ const userParams = {
+ email: email,
+ password: password,
+ };
+
+ axios
+ .post(`${VITE_API_URL}/api/v1/auth/authenticate`, userParams)
+ .then((response) => {
+ console.log(response.data);
+ navigation.navigate("Feed", {
+ email: email,
+ authToken: response.data.accessToken,
+ });
+ })
+ .catch((error) => {
+ setError("Incorrect e-mail or password!");
+ console.log(error.response.data);
+ console.log(error.response.status);
+ });
};
const onSignupClick = () => {
- console.log("sign up");
navigation.navigate("Register");
};
@@ -52,6 +71,7 @@ export default function LoginScreen({ navigation }) {
ref={ref_password}
/>
+ {error && {error}}
Log In
@@ -108,6 +128,10 @@ const styles = StyleSheet.create({
borderColor: "lightgrey",
fontSize: 15,
},
+ errorText: {
+ color: "red",
+ textAlign: "center",
+ },
buttonContainer: {
height: "10%",
width: "90%",
diff --git a/application/mobile/App/Screens/PostCreationScreen.js b/application/mobile/App/Screens/PostCreationScreen.js
new file mode 100644
index 00000000..97a9e258
--- /dev/null
+++ b/application/mobile/App/Screens/PostCreationScreen.js
@@ -0,0 +1,199 @@
+import React, { useState, useRef } from "react";
+import {
+ ImageBackground,
+ StyleSheet,
+ TextInput,
+ View,
+ Text,
+ TouchableOpacity,
+ StatusBar,
+ Dimensions,
+ Image,
+ Button,
+} from "react-native";
+import Icon from "react-native-vector-icons/Entypo";
+import axios from "axios";
+import AutoExpandingTextInput from "../components/AutoExpandingTextInput";
+import * as ImagePicker from 'expo-image-picker/src/ImagePicker';
+export default function PostCreationScreen({navigation}){
+ const profile = {
+ profilePhoto: require("../assets/dummy_pics/pp2.png"),
+ username: "james",
+ email: "james@gmail.com",
+ supportedTeam: "Fenerbahçe",
+ };
+ const[selectedImage, selectImage] = useState(null);
+ const[selectedCommunity, selectCommunity] = useState("");
+
+
+ const [isMenuVisible, setIsMenuVisible] = useState(false);
+
+ const toggleMenu = () => {
+ console.log("Toggle menu");
+ setIsMenuVisible(!isMenuVisible);
+ };
+
+ const createPost = () => {
+ navigation.navigate("Post");
+ console.log("create post");
+ };
+ const viewProfile = () => {
+ console.log("view profile");
+ setIsMenuVisible(false);
+ navigation.navigate("Profile");
+ };
+ const settings = () => {
+ console.log("settings");
+ };
+ const logout = () => {
+ console.log("logout");
+ navigation.navigate("Login");
+ };
+ const pickImage = async () => {
+ const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
+ if (permissionResult.granted === false) {
+ alert("Permission to access camera roll is required!");
+ return;
+ }
+ const pickerResult = await ImagePicker.launchImageLibraryAsync();
+ if (pickerResult.cancelled === true) {
+ return;
+ }
+
+
+ selectImage({ localUri: pickerResult.assets[0].uri });
+ }
+ const removeImage = () => {
+ selectImage(null);
+ }
+ const pickCommunity = (comm) =>{
+ selectCommunity(comm);
+ }
+ return(
+
+
+
+ Fanatic
+
+
+
+
+
+
+
+
+
+
+
+ {selectedImage !== null && (
+
+ )}
+
+
+
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ backgroundContainer: {
+ flex: 1,
+ backgroundColor: "white",
+ paddingTop: StatusBar.currentHeight,
+ justifyContent: "flex-start",
+ alignItems: "center",
+ minHeight: Math.round(Dimensions.get("window").height),
+ },
+ profilePic: {
+ flex: 1,
+ height: null,
+ width: null,
+ borderRadius: 100,
+ overflow: "hidden"
+ },
+ profilePicContainer: {
+ height: 50,
+ width: "10%",
+ marginRight: "2%",
+ },
+
+ headerContainer: {
+ marginTop: "5%",
+ flexDirection: "row",
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ header: {
+ color: "blue",
+ fontSize: 25,
+ fontWeight: "600",
+ },
+ headerMenuIcon: {
+ right: -100,
+ },
+ textInContainer: {
+ height: "5%",
+ width: "90%",
+ marginTop: "2%",
+ marginLeft: "5%",
+ marginBottom: "5%",
+ borderWidth: 2,
+ padding: 5,
+ borderRadius: 5,
+ borderColor: "#0001",
+ },
+ flatList: {
+ width: "90%",
+ marginTop: "5%",
+ },
+ modalContainer: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
+ },
+ closeButton: {
+ fontSize: 20,
+ color: "#fff",
+ padding: 10,
+ backgroundColor: "tomato",
+ borderRadius: 5,
+ flexDirection: "row",
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ menuItem: {
+ padding: 10,
+ borderBottomWidth: 1,
+ borderBottomColor: "#ccc",
+ backgroundColor: "white",
+ borderRadius: 5,
+ flexDirection: "row",
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ menuItemText: {
+ fontSize: 16,
+ paddingLeft: 4,
+ },
+ menuItemIcon: {
+ paddingHorizontal: 4,
+ },
+ interactionIcon:{
+ width: 70,
+ height: 70
+ },
+ imageSelect: {
+ width: 300,
+ height: 300,
+ resizeMode: 'contain',
+ },
+});
\ No newline at end of file
diff --git a/application/mobile/App/Screens/ProfileScreen.js b/application/mobile/App/Screens/ProfileScreen.js
index 4c578503..bc964f7d 100644
--- a/application/mobile/App/Screens/ProfileScreen.js
+++ b/application/mobile/App/Screens/ProfileScreen.js
@@ -6,120 +6,143 @@ import {
TextInput,
StatusBar,
Image,
- FlatList,
Dimensions,
TouchableOpacity,
Modal,
Button,
} from "react-native";
import Icon from "react-native-vector-icons/Entypo";
-export default function ProfileScreen({navigation}){
- const [isMenuVisible, setIsMenuVisible] = useState(false);
- const profile= {
- profilePhoto : require("../assets/dummy_pics/pp2.png"),
- username : "james",
- email : "james@gmail.com",
- supportedTeam : "Fenerbahçe"
- };
- const [newUsername, changeUsername] = useState(profile.username);
- const [newMail, changeMail] = useState(profile.email);
- const [newTeam, changeTeam] = useState(profile.supportedTeam);
-
- const onUsernameChange = (value) =>{
- changeUsername(value);
- }
- const onMailChange = (value) =>{
- changeMail(value);
- }
- const onTeamChange = (value) =>{
- changeTeam(value);
- }
+export default function ProfileScreen({ navigation }) {
+ const [isMenuVisible, setIsMenuVisible] = useState(false);
+ const profile = {
+ profilePhoto: require("../assets/dummy_pics/pp2.png"),
+ username: "james",
+ email: "james@gmail.com",
+ supportedTeam: "Fenerbahçe",
+ };
+ const [newUsername, changeUsername] = useState(profile.username);
+ const [newMail, changeMail] = useState(profile.email);
+ const [newTeam, changeTeam] = useState(profile.supportedTeam);
- const toggleMenu = () => {
- console.log("Toggle menu");
- setIsMenuVisible(!isMenuVisible);
- };
+ const onUsernameChange = (value) => {
+ changeUsername(value);
+ };
+ const onMailChange = (value) => {
+ changeMail(value);
+ };
+ const onTeamChange = (value) => {
+ changeTeam(value);
+ };
- const createPost = () => {
- console.log("create post");
- };
- const viewProfile = () => {
- console.log("view profile");
- navigation.navigate("Profile");
- };
- const settings = () => {
- console.log("settings");
- };
- const logout = () => {
- console.log("logout");
- navigation.navigate("Login");
- };
- const saveChanges = () => {
- console.log("Username: " + newUsername + "," + "E-mail: " + newMail + "," + "Team: "+ newTeam);
- navigation.navigate("Feed");
- }
- return(
-
-
-
- Fanatic
-
-
+ const toggleMenu = () => {
+ console.log("Toggle menu");
+ setIsMenuVisible(!isMenuVisible);
+ };
+
+ const createPost = () => {
+ console.log("create post");
+ };
+ const viewProfile = () => {
+ console.log("view profile");
+ navigation.navigate("Profile");
+ };
+ const settings = () => {
+ console.log("settings");
+ };
+ const logout = () => {
+ console.log("logout");
+ navigation.navigate("Login");
+ };
+ const saveChanges = () => {
+ console.log(
+ "Username: " +
+ newUsername +
+ "," +
+ "E-mail: " +
+ newMail +
+ "," +
+ "Team: " +
+ newTeam
+ );
+ navigation.navigate("Feed");
+ };
+ return (
+
+
+
+ Fanatic
+
+
+
+
+
+
+
+
+ Create Post
+
+
+
+ View Profile
+
+
+
+ Settings
+
+
+
+ Logout
+
+
+
+ Close
-
-
-
-
- Create Post
-
-
-
- View Profile
-
-
-
- Settings
-
-
-
- Logout
-
-
-
- Close
-
-
-
-
- Profile Details
-
-
-
-
-
- Username
-
-
-
- E-mail
-
-
-
- Supported Team
-
-
-
-
-
-
- );
+
+ Profile Details
+
+
+
+
+ Username
+
+
+
+ E-mail
+
+
+
+ Supported Team
+
+
+
+
+
+
+
+ );
}
const styles = StyleSheet.create({
@@ -194,4 +217,4 @@ const styles = StyleSheet.create({
menuItemIcon: {
paddingHorizontal: 4,
},
-});
\ No newline at end of file
+});
diff --git a/application/mobile/App/Screens/RegisterScreen.js b/application/mobile/App/Screens/RegisterScreen.js
index 2ba81401..a4870cea 100644
--- a/application/mobile/App/Screens/RegisterScreen.js
+++ b/application/mobile/App/Screens/RegisterScreen.js
@@ -7,21 +7,87 @@ import {
Text,
TouchableOpacity,
Dimensions,
+ Alert,
} from "react-native";
+import DropDownPicker from "react-native-dropdown-picker";
+import {VITE_API_URL} from "@env";
+import axios from "axios";
export default function RegisterScreen({ navigation }) {
const [email, setEmail] = useState("");
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [team, setTeam] = useState("");
+ const [error, setError] = useState("");
+
+ const [teamDropdownOpen, teamDropdownSetOpen] = useState(false);
+ const [teamDropdownValue, teamDropdownSetValue] = useState(null);
+ const [teamDropdownItems, teamDropdownSetItems] = useState([
+ { label: "Adana Demirspor", value: "Adana Demirspor" },
+ { label: "Alanyaspor", value: "Alanyaspor" },
+ { label: "Ankaragucu", value: "Ankaragucu" },
+ { label: "Antalyaspor", value: "Antalyaspor" },
+ { label: "Basaksehir", value: "Basaksehir" },
+ { label: "Besiktas", value: "Besiktas" },
+ { label: "Fatih Karagumruk", value: "Fatih Karagumruk" },
+ { label: "Fenerbahce", value: "Fenerbahce" },
+ { label: "Galatasaray", value: "Galatasaray" },
+ { label: "Gaziantep", value: "Gaziantep" },
+ { label: "Hatayspor", value: "Hatayspor" },
+ { label: "Istanbulspor", value: "Istanbulspor" },
+ { label: "Kasimpasa", value: "Kasimpasa" },
+ { label: "Kayserispor", value: "Kayserispor" },
+ { label: "Konyaspor", value: "Konyaspor" },
+ { label: "Pendikspor", value: "Pendikspor" },
+ { label: "Rizespor", value: "Rizespor" },
+ { label: "Samsunspor", value: "Samsunspor" },
+ { label: "Sivasspor", value: "Sivasspor" },
+ { label: "Trabzonspor", value: "Trabzonspor" },
+ ]);
+
+ let email_reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w\w+)+$/;
+ let username_password_reg = /^[A-Zığüçşa-z0-9]+$/;
const ref_username = useRef();
const ref_password = useRef();
const ref_team = useRef();
const onSignupClick = () => {
- console.log("sign up");
- navigation.navigate("Login");
+ if (email === "") {
+ setError("Email can not be left empty.");
+ } else if (email_reg.test(email) === false) {
+ setError("Email format is not valid.");
+ } else if (username === "") {
+ setError("Username can not be left empty.");
+ } else if (username_password_reg.test(username) === false) {
+ setError("Username must consist of only letters and numbers.");
+ } else if (password.length < 8) {
+ setError("Password should be at least 8 characters long.");
+ } else if (username_password_reg.test(password) === false) {
+ setError("Password must consist of only letters and numbers.");
+ } /*else if (team === "") {
+ setError("Team can not be left empty.");
+ }*/ else {
+ const userParams = {
+ firstName: username,
+ lastName: "",
+ email: email,
+ password: password,
+ };
+
+ axios
+ .post(`${VITE_API_URL}/api/v1/auth/register`, userParams)
+ .then((response) => {
+ console.log(response.data);
+ Alert.alert("", "Account is successfully created.", [
+ { text: "Ok", onPress: () => navigation.navigate("Login") },
+ ]);
+ })
+ .catch((error) => {
+ setError("Duplicate entry");
+ console.log(error);
+ });
+ }
};
return (
@@ -61,14 +127,17 @@ export default function RegisterScreen({ navigation }) {
onSubmitEditing={() => ref_team.current.focus()}
blurOnSubmit={false}
/>
-
+ {error && {error}}
Sign Up
@@ -118,6 +187,7 @@ const styles = StyleSheet.create({
borderRadius: 5,
borderColor: "lightgrey",
},
+ errorText: { color: "red", textAlign: "center" },
buttonContainer: {
height: "10%",
width: "90%",
diff --git a/application/mobile/App/Screens/SearchResultScreen.js b/application/mobile/App/Screens/SearchResultScreen.js
new file mode 100644
index 00000000..eff7d878
--- /dev/null
+++ b/application/mobile/App/Screens/SearchResultScreen.js
@@ -0,0 +1,96 @@
+import React, { useState, useRef } from "react";
+import {
+ Text,
+ View,
+ StyleSheet,
+ StatusBar,
+ Image,
+ FlatList,
+ Dimensions,
+} from "react-native";
+import axios from "axios";
+import Post from "../components/Post";
+import {VITE_API_URL} from "@env";
+
+export default function SearchResultScreen({ navigation, route }) {
+ const [error, setError] = useState();
+
+ const listSearchResults = () => {
+ console.log(route.params.param);
+ axios
+ .get(
+ `${VITE_API_URL}/api/v1/posts?param=` + route.params.param,
+ {
+ headers: { Authorization: `Bearer ${route.params.authToken}` },
+ }
+ )
+ .then((response) => {
+ console.log(response.data);
+ })
+ .catch((error) => {
+ setError("1");
+ console.log(error.response);
+ });
+
+ return [
+ { userId: 1, title: "galata", text: "galata", team: "galatasaray" },
+ ];
+ };
+
+ return (
+
+
+
+
+ appFanatic.
+
+
+ (
+
+ )}
+ style={styles.flatList}
+ />
+
+ );
+}
+
+const styles = StyleSheet.create({
+ backgroundContainer: {
+ flex: 1,
+ backgroundColor: "white",
+ paddingTop: StatusBar.currentHeight,
+ justifyContent: "flex-start",
+ alignItems: "center",
+ minHeight: Math.round(Dimensions.get("window").height),
+ },
+
+ headerContainer: {
+ marginTop: "5%",
+ flexDirection: "row",
+ justifyContent: "space-evenly",
+ alignItems: "center",
+ width: "90%",
+ },
+ logoContainer: {
+ height: "100%",
+ flexDirection: "row",
+ justifyContent: "center",
+ alignItems: "center",
+ marginHorizontal: "15%",
+ },
+ header: {
+ color: "blue",
+ fontSize: 25,
+ fontWeight: "600",
+ },
+ flatList: {
+ width: "90%",
+ marginTop: "5%",
+ },
+});
diff --git a/application/mobile/App/assets/community.png b/application/mobile/App/assets/community.png
new file mode 100644
index 00000000..236bf20c
Binary files /dev/null and b/application/mobile/App/assets/community.png differ
diff --git a/application/mobile/App/assets/image.png b/application/mobile/App/assets/image.png
new file mode 100644
index 00000000..53bc8846
Binary files /dev/null and b/application/mobile/App/assets/image.png differ
diff --git a/application/mobile/App/components/AutoExpandingTextInput.js b/application/mobile/App/components/AutoExpandingTextInput.js
new file mode 100644
index 00000000..71e44bbb
--- /dev/null
+++ b/application/mobile/App/components/AutoExpandingTextInput.js
@@ -0,0 +1,42 @@
+import React, { useState } from 'react';
+import { TextInput, View, StyleSheet } from 'react-native';
+
+const AutoExpandingTextInput = () => {
+ const [inputValue, setInputValue] = useState('');
+ const [inputHeight, setInputHeight] = useState(40);
+
+ const handleChangeText = (text) => {
+ setInputValue(text);
+ const lineCount = Math.ceil((text.length + 1) / 40);
+ setInputHeight(Math.max(40, lineCount * 40));
+ };
+
+ return (
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ padding: 10,
+ justifyContent: 'center',
+ },
+ input: {
+ borderWidth: 1,
+ borderColor: 'gray',
+ borderRadius: 5,
+ paddingHorizontal: 10,
+ fontSize: 16,
+ },
+});
+
+export default AutoExpandingTextInput;
diff --git a/application/mobile/App/components/Post.js b/application/mobile/App/components/Post.js
index ec60bd43..6ebaa74b 100644
--- a/application/mobile/App/components/Post.js
+++ b/application/mobile/App/components/Post.js
@@ -14,50 +14,47 @@ export default function Post(props) {
};
const [postLiked, changeLike] = useState(false);
const [postDisliked, changeDislike] = useState(false);
- const getLikeCount = () =>{
+ const getLikeCount = () => {
return 5;
};
- const getDislikeCount = () =>{
+ const getDislikeCount = () => {
return 5;
};
- const[likeCount, setLikeCount] = useState(getLikeCount());
- const[dislikeCount, setDislikeCount] = useState(getDislikeCount());
- const changeLikeCount = (change) =>{
+ const [likeCount, setLikeCount] = useState(getLikeCount());
+ const [dislikeCount, setDislikeCount] = useState(getDislikeCount());
+ const changeLikeCount = (change) => {
setLikeCount(likeCount + change);
- }
- const changeDislikeCount = (change) =>{
+ };
+ const changeDislikeCount = (change) => {
setDislikeCount(dislikeCount + change);
- }
-
- const likeClicked = () =>{
- if(postLiked){
+ };
+
+ const likeClicked = () => {
+ if (postLiked) {
changeLikeCount(-1);
changeLike(false);
return;
}
- if(postDisliked){
+ if (postDisliked) {
changeDislikeCount(-1);
changeDislike(false);
}
changeLikeCount(1);
changeLike(true);
-
- }
- const dislikeClicked = () =>{
- if(postDisliked){
+ };
+ const dislikeClicked = () => {
+ if (postDisliked) {
changeDislikeCount(-1);
changeDislike(false);
return;
}
- if(postLiked){
+ if (postLiked) {
changeLikeCount(-1);
changeLike(false);
}
changeDislikeCount(1);
changeDislike(true);
-
- }
-
+ };
return (
@@ -75,15 +72,28 @@ export default function Post(props) {
{props.text}
-
- {postLiked ? likeCount: "Like"}
+
+
+ {postLiked ? likeCount : "Like"}
+
-
- {postDisliked ? dislikeCount: "Dislike"}
+
+
+ {postDisliked ? dislikeCount : "Dislike"}
+
-
+
Comment
@@ -129,12 +139,12 @@ const styles = StyleSheet.create({
fontSize: 15,
},
rowContainer: {
- flex : 1,
- flexDirection : "row",
- marginRight: 20
+ flex: 1,
+ flexDirection: "row",
+ marginRight: 20,
},
- interactionIcon:{
+ interactionIcon: {
width: "50%",
- height: "200%"
+ height: "200%",
},
});
diff --git a/application/mobile/app.json b/application/mobile/app.json
index 6ab1b700..a6217215 100644
--- a/application/mobile/app.json
+++ b/application/mobile/app.json
@@ -1,13 +1,13 @@
{
"expo": {
- "name": "mobile",
- "slug": "mobile",
+ "name": "appFanatic",
+ "slug": "appFanatic",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./App/assets/icon.jpeg",
"userInterfaceStyle": "light",
"splash": {
- "image": "./App/assets/splash.png",
+ "image": "./App/assets/icon.jpeg",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
@@ -19,7 +19,7 @@
},
"android": {
"adaptiveIcon": {
- "foregroundImage": "./App/assets/adaptive-icon.png",
+ "foregroundImage": "./App/assets/icon.jpeg",
"backgroundColor": "#ffffff"
}
},
diff --git a/application/mobile/babel.config.js b/application/mobile/babel.config.js
index 2900afe9..28583dd8 100644
--- a/application/mobile/babel.config.js
+++ b/application/mobile/babel.config.js
@@ -2,5 +2,15 @@ module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
+ plugins: [
+ ["module:react-native-dotenv", {
+ "moduleName": "@env",
+ "path": ".env",
+ "blacklist": null,
+ "whitelist": null,
+ "safe": false,
+ "allowUndefined": true
+ }]
+ ]
};
};
diff --git a/application/mobile/package-lock.json b/application/mobile/package-lock.json
index a16d0bc4..c9bba86f 100644
--- a/application/mobile/package-lock.json
+++ b/application/mobile/package-lock.json
@@ -10,10 +10,14 @@
"dependencies": {
"@react-navigation/native": "^6.1.17",
"@react-navigation/native-stack": "^6.9.26",
+ "axios": "^1.6.8",
"expo": "~50.0.14",
+ "expo-image-picker": "~14.7.1",
"expo-status-bar": "~1.11.1",
"react": "18.2.0",
"react-native": "0.73.6",
+ "react-native-dotenv": "^3.4.11",
+ "react-native-dropdown-picker": "^5.4.6",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
"react-native-vector-icons": "^10.0.3"
@@ -6546,6 +6550,29 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/axios": {
+ "version": "1.6.8",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
+ "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/axios/node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/babel-core": {
"version": "7.0.0-bridge.0",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
@@ -8175,6 +8202,25 @@
"expo": "*"
}
},
+ "node_modules/expo-image-loader": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-4.6.0.tgz",
+ "integrity": "sha512-RHQTDak7/KyhWUxikn2yNzXL7i2cs16cMp6gEAgkHOjVhoCJQoOJ0Ljrt4cKQ3IowxgCuOrAgSUzGkqs7omj8Q==",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-image-picker": {
+ "version": "14.7.1",
+ "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-14.7.1.tgz",
+ "integrity": "sha512-ILQVOJgI3aEzrDmCFGDPtpAepYkn8mot8G7vfQ51BfFdQbzL6N3Wm1fS/ofdWlAZJl/qT2DwaIh5xYmf3SyGZA==",
+ "dependencies": {
+ "expo-image-loader": "~4.6.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-keep-awake": {
"version": "12.8.2",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-12.8.2.tgz",
@@ -8496,6 +8542,25 @@
"node": ">=0.4.0"
}
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fontfaceobserver": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
@@ -12141,6 +12206,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -12342,6 +12412,26 @@
"react": "18.2.0"
}
},
+ "node_modules/react-native-dotenv": {
+ "version": "3.4.11",
+ "resolved": "https://registry.npmjs.org/react-native-dotenv/-/react-native-dotenv-3.4.11.tgz",
+ "integrity": "sha512-6vnIE+WHABSeHCaYP6l3O1BOEhWxKH6nHAdV7n/wKn/sciZ64zPPp2NUdEUf1m7g4uuzlLbjgr+6uDt89q2DOg==",
+ "dependencies": {
+ "dotenv": "^16.4.5"
+ },
+ "peerDependencies": {
+ "@babel/runtime": "^7.20.6"
+ }
+ },
+ "node_modules/react-native-dropdown-picker": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/react-native-dropdown-picker/-/react-native-dropdown-picker-5.4.6.tgz",
+ "integrity": "sha512-T1XBHbE++M6aRU3wFYw3MvcOuabhWZ29RK/Ivdls2r1ZkZ62iEBZknLUPeVLMX3x6iUxj4Zgr3X2DGlEGXeHsA==",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/react-native-safe-area-context": {
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.8.2.tgz",
diff --git a/application/mobile/package.json b/application/mobile/package.json
index 3b190852..cd45cbfd 100644
--- a/application/mobile/package.json
+++ b/application/mobile/package.json
@@ -11,10 +11,14 @@
"dependencies": {
"@react-navigation/native": "^6.1.17",
"@react-navigation/native-stack": "^6.9.26",
+ "axios": "^1.6.8",
"expo": "~50.0.14",
+ "expo-image-picker": "~14.7.1",
"expo-status-bar": "~1.11.1",
"react": "18.2.0",
"react-native": "0.73.6",
+ "react-native-dotenv": "^3.4.11",
+ "react-native-dropdown-picker": "^5.4.6",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
"react-native-vector-icons": "^10.0.3"