updated register and login functionality
This commit is contained in:
parent
014ca66466
commit
4bad07751a
5 changed files with 133 additions and 20 deletions
|
@ -0,0 +1,28 @@
|
||||||
|
const mongoose = require("mongoose");
|
||||||
|
|
||||||
|
const todoSchema = new mongoose.Schema({
|
||||||
|
title:{
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
status:{
|
||||||
|
type: String,
|
||||||
|
enum: ["pending", "completed"],
|
||||||
|
default: "pending"
|
||||||
|
},
|
||||||
|
category:{
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
dueDate:{
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
createdAt:{
|
||||||
|
type: Date,
|
||||||
|
default: Date.now
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Todo= mongoose.model("Todo", todoSchema);
|
||||||
|
module.exports = Todo
|
|
@ -1,13 +1,42 @@
|
||||||
import { StyleSheet, Text, View, SafeAreaView, KeyboardAvoidingView, Image, TextInput, Pressable } from 'react-native'
|
import { StyleSheet, Text, View, SafeAreaView, KeyboardAvoidingView, Image, TextInput, Pressable } from 'react-native'
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { Fontisto } from '@expo/vector-icons';
|
import { Fontisto } from '@expo/vector-icons';
|
||||||
import { Entypo } from '@expo/vector-icons';
|
import { Entypo } from '@expo/vector-icons';
|
||||||
import { useRouter } from 'expo-router';
|
import { useRouter } from 'expo-router';
|
||||||
|
import axios from "axios";
|
||||||
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
|
|
||||||
const login = () => {
|
const login = () => {
|
||||||
|
const router = useRouter();
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const router = useRouter();
|
useEffect(() => {
|
||||||
|
const checkLoginStatus = async() => {
|
||||||
|
try {
|
||||||
|
const token = await AsyncStorage.getItem("authToken");
|
||||||
|
if(token){
|
||||||
|
router.replace("/(tabs)/home")
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
checkLoginStatus();
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
const user = {
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
};
|
||||||
|
axios.post("http://localhost:3030/login", user).then((res) => {
|
||||||
|
const token = res.data.token;
|
||||||
|
AsyncStorage.setItem("authToken", token);
|
||||||
|
router.replace("/(tabs)/home")
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={{flex:1, backgroundColor: "white", alignItems: "center", justifyContent:"center"}}>
|
<SafeAreaView style={{flex:1, backgroundColor: "white", alignItems: "center", justifyContent:"center"}}>
|
||||||
|
@ -35,12 +64,11 @@ const login = () => {
|
||||||
<Entypo name="key" size={16} color="#31363F" />
|
<Entypo name="key" size={16} color="#31363F" />
|
||||||
<TextInput value={password} onChangeText={(text) => setPassword(text)} secureTextEntry={true} style={{color: "#31363F", width:250, outlineStyle: 'none', marginVertical: 10, fontSize:email ? 14 : 14}} placeholder='Enter your password'/>
|
<TextInput value={password} onChangeText={(text) => setPassword(text)} secureTextEntry={true} style={{color: "#31363F", width:250, outlineStyle: 'none', marginVertical: 10, fontSize:email ? 14 : 14}} placeholder='Enter your password'/>
|
||||||
</View>
|
</View>
|
||||||
<View style={{flexDirection: "row", alignItems: "center", justifyContent:"space-between", marginTop:10}}>
|
<View style={{marginTop:10}}>
|
||||||
<Text style={{fontSize: 12}}>Keep me login</Text>
|
<Text style={{color: "#61677A", fontSize: 12 }}>Forgot password?</Text>
|
||||||
<Text style={{color: "#61677A", fontSize: 12}}>Forgot password?</Text>
|
|
||||||
</View>
|
</View>
|
||||||
<View style={{marginTop: 50}}/>
|
<View style={{marginTop: 50}}/>
|
||||||
<Pressable style={{backgroundColor: "#61677A", padding:10, borderRadius:5, alignItems: "center"}}>
|
<Pressable onPress={handleLogin} style={{backgroundColor: "#61677A", padding:10, borderRadius:5, alignItems: "center"}}>
|
||||||
<Text style={{color: "#D8D9DA", fontSize: 16, fontWeight: 600}}>Login</Text>
|
<Text style={{color: "#D8D9DA", fontSize: 16, fontWeight: 600}}>Login</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
<Pressable onPress={() => router.replace("/register")} style={{marginTop: 10}}>
|
<Pressable onPress={() => router.replace("/register")} style={{marginTop: 10}}>
|
||||||
|
|
|
@ -1,14 +1,35 @@
|
||||||
import { StyleSheet, Text, View, SafeAreaView, KeyboardAvoidingView, Image, TextInput, Pressable } from 'react-native'
|
import { StyleSheet, Text, View, SafeAreaView, KeyboardAvoidingView, Image, TextInput, Pressable, Alert } from 'react-native'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { Fontisto } from '@expo/vector-icons';
|
import { Fontisto } from '@expo/vector-icons';
|
||||||
import { Entypo } from '@expo/vector-icons';
|
import { Entypo } from '@expo/vector-icons';
|
||||||
|
import { AntDesign } from '@expo/vector-icons';
|
||||||
import { useRouter } from 'expo-router';
|
import { useRouter } from 'expo-router';
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
const register = () => {
|
const register = () => {
|
||||||
|
const [name, setName] = useState('');
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const handleRegister = () => {
|
||||||
|
const user = {
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
}
|
||||||
|
axios.post("http://localhost:3030/register", user).then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
Alert.alert("Registration succeeded!");
|
||||||
|
setEmail('');
|
||||||
|
setPassword('');
|
||||||
|
setName('');
|
||||||
|
}).catch((error) => {
|
||||||
|
Alert.alert("Registration failed!");
|
||||||
|
console.log("error", error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={{flex:1, backgroundColor: "white", alignItems: "center", justifyContent:"center"}}>
|
<SafeAreaView style={{flex:1, backgroundColor: "white", alignItems: "center", justifyContent:"center"}}>
|
||||||
<View>
|
<View>
|
||||||
|
@ -26,19 +47,28 @@ const register = () => {
|
||||||
<View style={{alignItems: "center"}}>
|
<View style={{alignItems: "center"}}>
|
||||||
<Text style={{fontSize: 16, fontWeight: 600, color: "black", marginTop: 20}}>Register</Text>
|
<Text style={{fontSize: 16, fontWeight: 600, color: "black", marginTop: 20}}>Register</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{marginTop: 50}}>
|
<View style={{marginTop: 50}}>
|
||||||
<View style={{flexDirection: "row", justifyContent: "center", alignItems: "center", gap:5, backgroundColor: "#EEEEEE", paddingHorizontal:10, borderRadius:5}}>
|
<View style={{flexDirection: "row", justifyContent: "center", alignItems: "center", gap:5, backgroundColor: "#EEEEEE", paddingHorizontal:10, borderRadius:5}}>
|
||||||
|
<AntDesign name="user" size={16} color="#31363F" />
|
||||||
|
<TextInput value={name} onChangeText={(text) => setName(text)} style={{color: "#31363F", width:250, outlineStyle: 'none', marginVertical: 10, fontSize:email ? 14 : 14}} placeholder='Username'/>
|
||||||
|
</View>
|
||||||
|
<View style={{flexDirection: "row", justifyContent: "center", alignItems: "center", gap:5, backgroundColor: "#EEEEEE", paddingHorizontal:10, borderRadius:5, marginTop: 10}}>
|
||||||
<Fontisto name="email" size={16} color="#31363F" />
|
<Fontisto name="email" size={16} color="#31363F" />
|
||||||
<TextInput value={email} onChangeText={(text) => setEmail(text)} style={{color: "#31363F", width:250, outlineStyle: 'none', marginVertical: 10, fontSize:email ? 14 : 14}} placeholder='Enter your email'/>
|
<TextInput value={email} onChangeText={(text) => setEmail(text)} style={{color: "#31363F", width:250, outlineStyle: 'none', marginVertical: 10, fontSize:email ? 14 : 14}} placeholder='Enter your email'/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{flexDirection: "row", justifyContent: "center", alignItems: "center", gap:5, backgroundColor: "#EEEEEE", paddingHorizontal:10, borderRadius:5, marginTop: 10}}>
|
<View style={{flexDirection: "row", justifyContent: "center", alignItems: "center", gap:5, backgroundColor: "#EEEEEE", paddingHorizontal:10, borderRadius:5, marginTop: 10}}>
|
||||||
<Entypo name="key" size={16} color="#31363F" />
|
<Entypo name="key" size={16} color="#31363F" />
|
||||||
<TextInput value={password} onChangeText={(text) => setPassword(text)} secureTextEntry={true} style={{color: "#31363F", width:250, outlineStyle: 'none', marginVertical: 10, fontSize:email ? 14 : 14}} placeholder='Enter your password'/>
|
<TextInput value={password} onChangeText={(text) => setPassword(text)} secureTextEntry={true} style={{color: "#31363F", width:250, outlineStyle: 'none', marginVertical: 10, fontSize:email ? 14 : 14}} placeholder='Enter your password'/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{marginTop: 50}}/>
|
<View style={{marginTop: 50}}/>
|
||||||
<Pressable style={{backgroundColor: "#61677A", padding:10, borderRadius:5, alignItems: "center"}}>
|
|
||||||
|
<Pressable onPress={handleRegister} style={{backgroundColor: "#61677A", padding:10, borderRadius:5, alignItems: "center"}}>
|
||||||
<Text style={{color: "#D8D9DA", fontSize: 16, fontWeight: 600}}>Register</Text>
|
<Text style={{color: "#D8D9DA", fontSize: 16, fontWeight: 600}}>Register</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
|
||||||
<Pressable onPress={() => router.replace("/login")} style={{marginTop: 10}}>
|
<Pressable onPress={() => router.replace("/login")} style={{marginTop: 10}}>
|
||||||
<Text style={{fontSize: 12, textAlign:"center"}}>Already have an account? <Text style={{fontWeight: 700}}>Login</Text></Text>
|
<Text style={{fontSize: 12, textAlign:"center"}}>Already have an account? <Text style={{fontWeight: 700}}>Login</Text></Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
import {Stack} from "expo-router";
|
import {Stack} from "expo-router";
|
||||||
|
import {ModalPortal} from "react-native-modals"
|
||||||
|
|
||||||
export default function Layout(){
|
export default function Layout(){
|
||||||
return(
|
return(
|
||||||
<Stack screenOptions={{headerShown:false}}>
|
<>
|
||||||
<Stack.Screen name="index"/>
|
<Stack screenOptions={{headerShown:false}}>
|
||||||
</Stack>
|
<Stack.Screen name="index"/>
|
||||||
|
</Stack>
|
||||||
|
<ModalPortal />
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
import { Image, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'
|
import { Image, Pressable, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native'
|
||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
import { AntDesign } from '@expo/vector-icons';
|
import { AntDesign } from '@expo/vector-icons';
|
||||||
|
import { BottomModal, ModalContent, ModalTitle, SlideAnimation } from 'react-native-modals';
|
||||||
|
|
||||||
const index = () => {
|
const index = () => {
|
||||||
const todo = [
|
const todo = [];
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const [addToDo, setAddToDo] = useState('');
|
||||||
|
|
||||||
];
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={{marginHorizontal:20, marginVertical:20, alignItems: "center", flexDirection: "row", gap: 10}}>
|
<View style={{marginHorizontal:20, marginVertical:20, alignItems: "center", flexDirection: "row", gap: 10}}>
|
||||||
|
@ -18,7 +20,7 @@ const index = () => {
|
||||||
<Pressable style={{backgroundColor: "#000000", paddingHorizontal:10, paddingVertical: 5, borderRadius:25, alignItems: "center", justifyContent: "center", marginRight: "auto"}}>
|
<Pressable style={{backgroundColor: "#000000", paddingHorizontal:10, paddingVertical: 5, borderRadius:25, alignItems: "center", justifyContent: "center", marginRight: "auto"}}>
|
||||||
<Text style={{color: "white", textAlign: "center"}}>Personal</Text>
|
<Text style={{color: "white", textAlign: "center"}}>Personal</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
<Pressable>
|
<Pressable onPress={() => setModalVisible(!modalVisible)}>
|
||||||
<AntDesign name="plus" size={24} color="black" />
|
<AntDesign name="plus" size={24} color="black" />
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</View>
|
</View>
|
||||||
|
@ -34,14 +36,35 @@ const index = () => {
|
||||||
uri:"./assets/images/to-do.png",
|
uri:"./assets/images/to-do.png",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Text style={{fontSize:16, fontWeight:600, marginTop: 20, textAlign:"center"}}>Hooray! No task for today</Text>
|
<Text style={{fontSize:16, fontWeight:600, marginTop: 20, textAlign:"center"}}>Hooray! There is no tasks</Text>
|
||||||
<Pressable style={{backgroundColor: "black", marginTop: 20, padding:5, borderRadius: 5}}>
|
<Pressable onPress={() => setModalVisible(!modalVisible)} style={{backgroundColor: "black", marginTop: 20, padding:5, borderRadius: 5}}>
|
||||||
<Text style={{fontSize:16, fontWeight:600, textAlign:"center", color: "white"}}>Add task <AntDesign name="plus" size={16} color="white" /></Text>
|
<Text style={{fontSize:14, fontWeight:600, textAlign:"center", color: "white"}}>Add task <AntDesign name="plus" size={16} color="white" /></Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
<BottomModal
|
||||||
|
onBackdropPress={() => setModalVisible(!modalVisible)}
|
||||||
|
onHardwareBackPress={() => setModalVisible(!modalVisible)}
|
||||||
|
swipeDirection={['up', 'down']}
|
||||||
|
swipeThreshold={200}
|
||||||
|
modalTitle={<ModalTitle title="Add Task"/>}
|
||||||
|
modalAnimation={
|
||||||
|
new SlideAnimation({
|
||||||
|
slideFrom: 'bottom',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
visible={modalVisible}
|
||||||
|
onTouchOutside={() => setModalVisible(!modalVisible)}
|
||||||
|
>
|
||||||
|
<ModalContent style={{width:"100%", height:200}}>
|
||||||
|
<View style={{marginTop: 10}}>
|
||||||
|
<TextInput value={addToDo} onChangeText={(text) => setAddToDo(text)} style={{padding:10, borderColor: "#61677A", borderRadius:5, borderWidth:1, flex:1, outlineStyle: 'none', color: "#31363F"}} placeholder='Add your new task'/>
|
||||||
|
</View>
|
||||||
|
</ModalContent>
|
||||||
|
</BottomModal>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue