forked from fr/deguapp
		
	Added: fully working signin/signup system with routing
This commit is contained in:
		@@ -2,6 +2,7 @@
 | 
			
		||||
  "expo": {
 | 
			
		||||
    "name": "deguapp",
 | 
			
		||||
    "slug": "deguapp",
 | 
			
		||||
    "scheme": "deguapp",
 | 
			
		||||
    "version": "1.0.0",
 | 
			
		||||
    "orientation": "portrait",
 | 
			
		||||
    "icon": "./assets/icon.png",
 | 
			
		||||
@@ -25,6 +26,9 @@
 | 
			
		||||
    },
 | 
			
		||||
    "web": {
 | 
			
		||||
      "favicon": "./assets/favicon.png"
 | 
			
		||||
    }
 | 
			
		||||
    },
 | 
			
		||||
    "plugins": [
 | 
			
		||||
      "expo-router"
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								frontend/app/(app)/_layout.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								frontend/app/(app)/_layout.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import { Redirect, Stack } from "expo-router";
 | 
			
		||||
 | 
			
		||||
import { useAuth } from "../context/AuthContext";
 | 
			
		||||
import { View, Text } from "react-native";
 | 
			
		||||
 | 
			
		||||
export default function AppLayout() {
 | 
			
		||||
  const { authState } = useAuth();
 | 
			
		||||
 | 
			
		||||
  if (authState.authenticated === null) {
 | 
			
		||||
    // micro loading co neni skoro videt ale get the fuck out se uz neloguje
 | 
			
		||||
    return (
 | 
			
		||||
      <View>
 | 
			
		||||
        <Text>Loading...</Text>
 | 
			
		||||
      </View>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  if (!authState.authenticated) {
 | 
			
		||||
    console.log("get the fuck out");
 | 
			
		||||
    return <Redirect href="/login" />;
 | 
			
		||||
  }
 | 
			
		||||
  return <Stack />;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								frontend/app/(app)/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								frontend/app/(app)/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import { Text, View } from "react-native";
 | 
			
		||||
 | 
			
		||||
import { useAuth } from "../context/AuthContext";
 | 
			
		||||
 | 
			
		||||
export default function Index() {
 | 
			
		||||
  const { onLogout } = useAuth();
 | 
			
		||||
  const user = "debil"
 | 
			
		||||
  return (
 | 
			
		||||
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
 | 
			
		||||
      <Text>Welcome {user}</Text>
 | 
			
		||||
      <Text
 | 
			
		||||
        onPress={() => {
 | 
			
		||||
          // The `app/(app)/_layout.tsx` will redirect to the sign-in screen.
 | 
			
		||||
          onLogout();
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        Sign Out
 | 
			
		||||
      </Text>
 | 
			
		||||
    </View>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								frontend/app/_layout.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								frontend/app/_layout.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
import { Slot } from "expo-router";
 | 
			
		||||
import { AuthProvider } from "./context/AuthContext";
 | 
			
		||||
 | 
			
		||||
export default function Root() {
 | 
			
		||||
  return (
 | 
			
		||||
    <AuthProvider>
 | 
			
		||||
      <Slot />
 | 
			
		||||
    </AuthProvider>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								frontend/app/context/AuthContext.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								frontend/app/context/AuthContext.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
import { createContext, useContext, useEffect, useState } from "react";
 | 
			
		||||
import axios from "axios";
 | 
			
		||||
import storageUtil from "./storage";
 | 
			
		||||
 | 
			
		||||
const TOKEN_KEY = "my-jwt";
 | 
			
		||||
export const API_URL = "http://10.69.1.137:6060/api/v1";
 | 
			
		||||
const AuthContext = createContext(null);
 | 
			
		||||
 | 
			
		||||
export function useAuth() {
 | 
			
		||||
  const authContext = useContext(AuthContext);
 | 
			
		||||
  if (authContext === undefined) {
 | 
			
		||||
    throw new Error("Context is outside of provider");
 | 
			
		||||
  }
 | 
			
		||||
  return authContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function AuthProvider({ children }) {
 | 
			
		||||
  const [authState, setAuthState] = useState({
 | 
			
		||||
    token: null,
 | 
			
		||||
    authenticated: null,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    // tohle se zavola jen poprve pri startu appky
 | 
			
		||||
    async function loadToken() {
 | 
			
		||||
      const token = await storageUtil.getItem(TOKEN_KEY);
 | 
			
		||||
      console.log(`stored: ${token}`);
 | 
			
		||||
 | 
			
		||||
      if (token) {
 | 
			
		||||
        axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
 | 
			
		||||
 | 
			
		||||
        setAuthState({
 | 
			
		||||
          token: token,
 | 
			
		||||
          authenticated: true,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      setAuthState({
 | 
			
		||||
        authenticated: false,
 | 
			
		||||
        token: null,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    loadToken();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  async function register(username, email, password) {
 | 
			
		||||
    try {
 | 
			
		||||
      const res = await axios.post(`${API_URL}/auth/signup`, {
 | 
			
		||||
        username,
 | 
			
		||||
        email,
 | 
			
		||||
        password,
 | 
			
		||||
      });
 | 
			
		||||
      return res
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      return { error: true, msg: err.response.data};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function login(email, password) {
 | 
			
		||||
    try {
 | 
			
		||||
      const res = await axios.post(`${API_URL}/auth/signin`, {
 | 
			
		||||
        email,
 | 
			
		||||
        password,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      setAuthState({
 | 
			
		||||
        token: res.data.data.jwt,
 | 
			
		||||
        authenticated: true,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      //axios.defaults.headers.common[
 | 
			
		||||
      //  "Authorization"
 | 
			
		||||
      //] = `Bearer ${res.data.data.jwt}`;
 | 
			
		||||
 | 
			
		||||
      await storageUtil.setItem(TOKEN_KEY, res.data.data.jwt);
 | 
			
		||||
 | 
			
		||||
      return res
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      return { error: true, msg: err.res };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function logout() {
 | 
			
		||||
    await storageUtil.delItem(TOKEN_KEY);
 | 
			
		||||
 | 
			
		||||
    axios.defaults.headers.common["Authorization"] = "";
 | 
			
		||||
 | 
			
		||||
    setAuthState({
 | 
			
		||||
      token: null,
 | 
			
		||||
      authenticated: false,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const value = {
 | 
			
		||||
    onSignin: register,
 | 
			
		||||
    onLogin: login,
 | 
			
		||||
    onLogout: logout,
 | 
			
		||||
    authState,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								frontend/app/context/storage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								frontend/app/context/storage.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
import * as SecureStore from "expo-secure-store";
 | 
			
		||||
import { Platform } from "react-native";
 | 
			
		||||
import AsyncStorage from "@react-native-async-storage/async-storage";
 | 
			
		||||
 | 
			
		||||
const storageUtil = {
 | 
			
		||||
  setItem: async (k, v) => {
 | 
			
		||||
    if (Platform.OS === "web") {
 | 
			
		||||
      // web
 | 
			
		||||
      await AsyncStorage.setItem(k, v);
 | 
			
		||||
    } else {
 | 
			
		||||
      // mobile
 | 
			
		||||
      await SecureStore.setItemAsync(k, v.toString()); // v must be string,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  getItem: async (k) => {
 | 
			
		||||
    if (Platform.OS === "web") {
 | 
			
		||||
      // web
 | 
			
		||||
      return await AsyncStorage.getItem(k);
 | 
			
		||||
    } else {
 | 
			
		||||
      // mobile
 | 
			
		||||
      return await SecureStore.getItemAsync(k);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  delItem: async (k) => {
 | 
			
		||||
    if (Platform.OS === "web") {
 | 
			
		||||
      // web
 | 
			
		||||
      await AsyncStorage.removeItem(k);
 | 
			
		||||
    } else {
 | 
			
		||||
      // mobile
 | 
			
		||||
      await SecureStore.deleteItemAsync(k);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
export default storageUtil;
 | 
			
		||||
							
								
								
									
										6
									
								
								frontend/app/hooks/useIsAutheticated.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								frontend/app/hooks/useIsAutheticated.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
import { useAuth } from "../context/AuthContext";
 | 
			
		||||
 | 
			
		||||
export function useIsAutheticated() {
 | 
			
		||||
  const { authState } = useAuth();
 | 
			
		||||
  return authState.authenticated
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								frontend/app/index.js.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								frontend/app/index.js.old
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
import { Redirect, Link } from "expo-router";
 | 
			
		||||
import { Text, View } from "react-native";
 | 
			
		||||
import { AuthProvider } from "./context/AuthContext";
 | 
			
		||||
 | 
			
		||||
function HomePage() {
 | 
			
		||||
  return <Redirect href="/login" />;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default HomePage;
 | 
			
		||||
@@ -1,15 +1,26 @@
 | 
			
		||||
import {
 | 
			
		||||
  StyleSheet,
 | 
			
		||||
  TouchableOpacity,
 | 
			
		||||
  TextInput,
 | 
			
		||||
  View,
 | 
			
		||||
  Text,
 | 
			
		||||
  Image,
 | 
			
		||||
} from "react-native";
 | 
			
		||||
import { StyleSheet, TextInput, View, Text, Image } from "react-native";
 | 
			
		||||
import { useEffect, useState } from "react";
 | 
			
		||||
import { router } from "expo-router";
 | 
			
		||||
import Button from "../components/Button";
 | 
			
		||||
import { colors } from "../components/style";
 | 
			
		||||
 | 
			
		||||
export function LoginForm() {
 | 
			
		||||
import { useAuth } from "./context/AuthContext";
 | 
			
		||||
 | 
			
		||||
function LoginPage() {
 | 
			
		||||
  const [pass, setPass] = useState("");
 | 
			
		||||
  const [email, setEmail] = useState("");
 | 
			
		||||
  const { onLogin, authState } = useAuth();
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (authState.authenticated) {
 | 
			
		||||
      router.replace("/");
 | 
			
		||||
    }
 | 
			
		||||
  }, [authState.authenticated]);
 | 
			
		||||
 | 
			
		||||
  function login() {
 | 
			
		||||
    onLogin(email, pass);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <View style={styles.container}>
 | 
			
		||||
      <View style={styles.header}>
 | 
			
		||||
@@ -19,7 +30,6 @@ export function LoginForm() {
 | 
			
		||||
        />
 | 
			
		||||
        <Text style={styles.h1}>Please Log In</Text>
 | 
			
		||||
      </View>
 | 
			
		||||
 | 
			
		||||
      <View style={styles.form}>
 | 
			
		||||
        <TextInput
 | 
			
		||||
          style={styles.input}
 | 
			
		||||
@@ -30,6 +40,8 @@ export function LoginForm() {
 | 
			
		||||
          keyboardType="email-address"
 | 
			
		||||
          placeholderTextColor={"#aaaaaa"}
 | 
			
		||||
          returnKeyType="next"
 | 
			
		||||
          value={email}
 | 
			
		||||
          onChangeText={(text) => setEmail(text)}
 | 
			
		||||
        />
 | 
			
		||||
        <TextInput
 | 
			
		||||
          style={styles.input}
 | 
			
		||||
@@ -37,19 +49,21 @@ export function LoginForm() {
 | 
			
		||||
          placeholder="Enter your password"
 | 
			
		||||
          placeholderTextColor={"#aaaaaa"}
 | 
			
		||||
          returnKeyType="done"
 | 
			
		||||
          value={pass}
 | 
			
		||||
          onChangeText={(text) => setPass(text)}
 | 
			
		||||
        />
 | 
			
		||||
        <View style={styles.btnContainer}>
 | 
			
		||||
          <Button
 | 
			
		||||
            style={styles.button}
 | 
			
		||||
            title="Sign Up"
 | 
			
		||||
            color={colors.charcoal}
 | 
			
		||||
            onPress={() => alert("Signed In")}
 | 
			
		||||
            onPress={() => router.replace("/signup")}
 | 
			
		||||
          />
 | 
			
		||||
          <Button
 | 
			
		||||
            style={styles.button}
 | 
			
		||||
            title="Log In"
 | 
			
		||||
            color={colors.gold}
 | 
			
		||||
            onPress={() => alert("Logged In")}
 | 
			
		||||
            onPress={login}
 | 
			
		||||
          />
 | 
			
		||||
        </View>
 | 
			
		||||
      </View>
 | 
			
		||||
@@ -92,9 +106,12 @@ const styles = StyleSheet.create({
 | 
			
		||||
    borderWidth: 1,
 | 
			
		||||
    borderRadius: 5,
 | 
			
		||||
    padding: 10,
 | 
			
		||||
    color: "#fff",
 | 
			
		||||
  },
 | 
			
		||||
  btnContainer: {
 | 
			
		||||
    flexDirection: "row",
 | 
			
		||||
    gap: 5,
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default LoginPage;
 | 
			
		||||
							
								
								
									
										148
									
								
								frontend/app/signup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								frontend/app/signup.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
import { StyleSheet, TextInput, View, Text, Image } from "react-native";
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
import Button from "../components/Button";
 | 
			
		||||
import { colors } from "../components/style";
 | 
			
		||||
import { Link, router } from "expo-router";
 | 
			
		||||
 | 
			
		||||
import { useAuth } from "./context/AuthContext";
 | 
			
		||||
 | 
			
		||||
function SignupPage() {
 | 
			
		||||
  const [pass1, setPass1] = useState("");
 | 
			
		||||
  const [pass2, setPass2] = useState("");
 | 
			
		||||
  const [email, setEmail] = useState("");
 | 
			
		||||
  const [username, setUsername] = useState("");
 | 
			
		||||
  const { onSignin } = useAuth();
 | 
			
		||||
 | 
			
		||||
  async function signin() {
 | 
			
		||||
    if (pass1 == pass2) {
 | 
			
		||||
      const res = await onSignin(username, email, pass1);
 | 
			
		||||
      if (res.error) {
 | 
			
		||||
        if(res.msg.message == "validation error") {
 | 
			
		||||
          alert(res.msg.data.message);
 | 
			
		||||
        } else {
 | 
			
		||||
          alert(res.msg.message)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (!res.error) {
 | 
			
		||||
        alert("You have been successfully registered. Please Log In");
 | 
			
		||||
        router.replace("/login");
 | 
			
		||||
      }
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    alert("Passwords are not same!");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <View style={styles.container}>
 | 
			
		||||
      <View style={styles.header}>
 | 
			
		||||
        <Image
 | 
			
		||||
          source={require("../assets/deguapp_logo.png")}
 | 
			
		||||
          style={styles.logo}
 | 
			
		||||
        />
 | 
			
		||||
        <Text style={styles.h1}>Please Sign Up</Text>
 | 
			
		||||
      </View>
 | 
			
		||||
 | 
			
		||||
      <View style={styles.form}>
 | 
			
		||||
        <TextInput
 | 
			
		||||
          style={styles.input}
 | 
			
		||||
          placeholder="Enter your username"
 | 
			
		||||
          placeholderTextColor={"#aaaaaa"}
 | 
			
		||||
          returnKeyType="done"
 | 
			
		||||
          value={username}
 | 
			
		||||
          onChangeText={(username) => setUsername(username)}
 | 
			
		||||
        />
 | 
			
		||||
        <TextInput
 | 
			
		||||
          style={styles.input}
 | 
			
		||||
          placeholder="Enter your email"
 | 
			
		||||
          autoCapitalize="none"
 | 
			
		||||
          autoCompleteType="email"
 | 
			
		||||
          textContentType="emailAddress"
 | 
			
		||||
          keyboardType="email-address"
 | 
			
		||||
          placeholderTextColor={"#aaaaaa"}
 | 
			
		||||
          returnKeyType="next"
 | 
			
		||||
          value={email}
 | 
			
		||||
          onChangeText={(email) => setEmail(email)}
 | 
			
		||||
        />
 | 
			
		||||
        <TextInput
 | 
			
		||||
          style={styles.input}
 | 
			
		||||
          secureTextEntry={true}
 | 
			
		||||
          placeholder="Enter your password"
 | 
			
		||||
          placeholderTextColor={"#aaaaaa"}
 | 
			
		||||
          returnKeyType="done"
 | 
			
		||||
          value={pass1}
 | 
			
		||||
          onChangeText={(pass1) => setPass1(pass1)}
 | 
			
		||||
        />
 | 
			
		||||
        <TextInput
 | 
			
		||||
          style={styles.input}
 | 
			
		||||
          secureTextEntry={true}
 | 
			
		||||
          placeholder="Enter your password"
 | 
			
		||||
          placeholderTextColor={"#aaaaaa"}
 | 
			
		||||
          returnKeyType="done"
 | 
			
		||||
          value={pass2}
 | 
			
		||||
          onChangeText={(pass2) => setPass2(pass2)}
 | 
			
		||||
        />
 | 
			
		||||
        <Button
 | 
			
		||||
          style={styles.button}
 | 
			
		||||
          title="Sign Up"
 | 
			
		||||
          color={colors.gold}
 | 
			
		||||
          onPress={signin}
 | 
			
		||||
        />
 | 
			
		||||
        <Link href="/login" style={styles.a}>
 | 
			
		||||
          Already have an account? Log In!
 | 
			
		||||
        </Link>
 | 
			
		||||
      </View>
 | 
			
		||||
    </View>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const styles = StyleSheet.create({
 | 
			
		||||
  container: {
 | 
			
		||||
    width: "100%",
 | 
			
		||||
    height: "100%",
 | 
			
		||||
    backgroundColor: colors.dark,
 | 
			
		||||
  },
 | 
			
		||||
  form: {
 | 
			
		||||
    flex: 1,
 | 
			
		||||
    alignItems: "center",
 | 
			
		||||
    paddingTop: "10%",
 | 
			
		||||
    width: "100%",
 | 
			
		||||
    gap: 15,
 | 
			
		||||
  },
 | 
			
		||||
  h1: {
 | 
			
		||||
    color: "#FFF",
 | 
			
		||||
    fontSize: 30,
 | 
			
		||||
    textAlign: "center",
 | 
			
		||||
    paddingTop: "20%",
 | 
			
		||||
  },
 | 
			
		||||
  a: {
 | 
			
		||||
    color: "#FFF",
 | 
			
		||||
    fontSize: 12,
 | 
			
		||||
    fontStyle: "italic",
 | 
			
		||||
    textDecorationLine: "underline",
 | 
			
		||||
  },
 | 
			
		||||
  logo: {
 | 
			
		||||
    width: "80%",
 | 
			
		||||
    resizeMode: "contain",
 | 
			
		||||
  },
 | 
			
		||||
  header: {
 | 
			
		||||
    width: "100%",
 | 
			
		||||
    alignItems: "center",
 | 
			
		||||
    paddingTop: "20%",
 | 
			
		||||
  },
 | 
			
		||||
  input: {
 | 
			
		||||
    height: "auto",
 | 
			
		||||
    width: "60%",
 | 
			
		||||
    borderColor: "gray",
 | 
			
		||||
    borderWidth: 1,
 | 
			
		||||
    borderRadius: 5,
 | 
			
		||||
    padding: 10,
 | 
			
		||||
    color: "#fff",
 | 
			
		||||
  },
 | 
			
		||||
  btnContainer: {
 | 
			
		||||
    flexDirection: "row",
 | 
			
		||||
    gap: 5,
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default SignupPage;
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/deguapp_logo_v2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/assets/deguapp_logo_v2.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 79 KiB  | 
							
								
								
									
										772
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										772
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "deguapp",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "main": "node_modules/expo/AppEntry.js",
 | 
			
		||||
  "main": "expo-router/entry",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "start": "expo start",
 | 
			
		||||
    "android": "expo start --android",
 | 
			
		||||
@@ -9,13 +9,22 @@
 | 
			
		||||
    "web": "expo start --web"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@expo/metro-runtime": "~3.1.3",
 | 
			
		||||
    "@react-native-async-storage/async-storage": "^1.23.1",
 | 
			
		||||
    "@types/react": "~18.2.45",
 | 
			
		||||
    "axios": "^1.6.8",
 | 
			
		||||
    "expo": "~50.0.17",
 | 
			
		||||
    "expo-constants": "~15.4.6",
 | 
			
		||||
    "expo-linking": "~6.2.2",
 | 
			
		||||
    "expo-router": "~3.4.10",
 | 
			
		||||
    "expo-secure-store": "^12.8.1",
 | 
			
		||||
    "expo-status-bar": "~1.11.1",
 | 
			
		||||
    "react": "18.2.0",
 | 
			
		||||
    "react-native": "0.73.6",
 | 
			
		||||
    "react-native-web": "~0.19.6",
 | 
			
		||||
    "react-dom": "18.2.0",
 | 
			
		||||
    "@expo/metro-runtime": "~3.1.3"
 | 
			
		||||
    "react-native": "0.73.6",
 | 
			
		||||
    "react-native-safe-area-context": "4.8.2",
 | 
			
		||||
    "react-native-screens": "~3.29.0",
 | 
			
		||||
    "react-native-web": "~0.19.6"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@babel/core": "^7.20.0"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user