diff --git a/src/App.jsx b/src/App.jsx
index 129a9e7..d41fc7d 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -4,19 +4,72 @@ import Register from "./pages/Register";
import CreateNote from "./pages/CreateNote";
import ViewNotes from "./pages/ViewNotes";
import Navbar from "./components/Navbar";
+import ProtectedRoute from "./components/auth/ProtectedRoute";
+import CreateNoteForm from "./components/CreateNoteForm";
+import NoteCard from "./components/NoteCard";
+import { useEffect } from "react";
+import { checkAuthStatus } from "./store/slices/authSlice";
+import { useDispatch } from "react-redux";
+
+
const App = () => {
+
+
+ const dispatch = useDispatch();
+ // const { status } = useSelector((state) => state.auth);
+
+ useEffect(() => {
+ dispatch(checkAuthStatus());
+ }, [dispatch]);
+
+
return (
- } />
- } />
+ } />
+ } />
+
+
+
+
+
+
+
+ }
+ />
+
+
+
+
+ }
+ />
+
+
+
+
+ }
+ />
+
+
+
+
+ }
+ />
+
+
- } />
- } />
diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx
index 9bd2bc8..a52a6b8 100644
--- a/src/components/Navbar.jsx
+++ b/src/components/Navbar.jsx
@@ -46,7 +46,10 @@ const Navbar = () => {
Create
-
+
+ {isAuthenticated ? (
+ <>
+
{
Logout
-
+ >
+ ) : (
+ <>
{
Register
-
+ >
+ )}
+
diff --git a/src/components/auth/ProtectedRoute.jsx b/src/components/auth/ProtectedRoute.jsx
index 0c71b6c..9983573 100644
--- a/src/components/auth/ProtectedRoute.jsx
+++ b/src/components/auth/ProtectedRoute.jsx
@@ -17,9 +17,15 @@ const ProtectedRoute = ({ children, requireAuth }) => {
}
// TODO: If route requires authentication and user is not authenticated, redirect to login
+ if (requireAuth && !isAuthenticated) {
+ return < Navigate to ="/login" replace />;
+ }
//TODO: If route requires unauthenticated user and user is authenticated, redirect to notes
+ if (!requireAuth && isAuthenticated) {
+ return ;
+ }
// Otherwise, render the children
diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx
index 4f6d4f7..a0f0f80 100644
--- a/src/pages/Login.jsx
+++ b/src/pages/Login.jsx
@@ -1,4 +1,44 @@
+import React from "react";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { z } from "zod";
+import { useDispatch, useSelector } from "react-redux";
+import { useNavigate } from "react-router-dom";
+import { login } from "../store/slices/authSlice";
+import { loginSchema } from "../schema/authSchema";
+import { Link } from "react-router-dom";
+
+
const Login = () => {
+ const dispatch = useDispatch();
+ const { status, error } = useSelector((state) => state.auth);
+ const navigate = useNavigate();
+
+ //create react hook form
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ } = useForm({
+ resolver: zodResolver(loginSchema),
+ });
+
+
+ //create onSubmit function
+
+ const onSubmit = async (data) => {
+ try{
+ await dispatch(login(data)).unwrap();
+ navigate("/view-notes");
+
+ }catch (error){
+ console.log(error);
+ }
+};
+
+
+
+
return (
@@ -6,7 +46,7 @@ const Login = () => {
Login to Your Account
-
diff --git a/src/pages/Register.jsx b/src/pages/Register.jsx
index ba6f0bd..e26a086 100644
--- a/src/pages/Register.jsx
+++ b/src/pages/Register.jsx
@@ -1,4 +1,39 @@
+import React from "react";
+import { useForm } from "react-hook-form";
+import { useDispatch, useSelector } from "react-redux";
+import axios from "axios";
+import { useNavigate } from "react-router-dom";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { z } from "zod";
+import { registerUser } from "../store/slices/authSlice";
+import { registerSchema } from "../schema/authSchema";
+import { Link } from "react-router-dom";
+
const Register = () => {
+ const dispatch = useDispatch();
+ const { status, error } = useSelector((state) => state.auth);
+ const navigate = useNavigate();
+
+ //creat react hook form
+
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ } = useForm({
+ resolver: zodResolver(registerSchema),
+ });
+
+ //handle form submit
+ const onSubmit = async (data) => {
+ try {
+ await dispatch(registerUser(data)).unwrap();
+ navigate("/view-notes");
+ } catch (err) {
+ console.error("Failed to register:", err);
+ }
+ };
+
return (
@@ -6,7 +41,7 @@ const Register = () => {
Create an Account
-
diff --git a/src/store/slices/authSlice.js b/src/store/slices/authSlice.js
index 35778d0..d5e04a9 100644
--- a/src/store/slices/authSlice.js
+++ b/src/store/slices/authSlice.js
@@ -13,9 +13,20 @@ export const checkAuthStatus = createAsyncThunk(
// 1. Make a GET request to /auth/check
// 2. Return the response data
// 3. Handle errors appropriately
+
+ try{
+ const response = await axios.get(`${BASE_URL}/auth/check`);
+ return response.data
+
+ }catch(error) {
+ throw error;
+ }
+
}
);
+
+
// TODO: Implement login thunk
export const login = createAsyncThunk(
"auth/login",
@@ -24,17 +35,38 @@ export const login = createAsyncThunk(
// 1. Make a POST request to /auth/login with credentials
// 2. Return the response data
// 3. Handle errors appropriately
+ try{
+ const response = await axios.post(`${BASE_URL}/auth/login`, credentials);
+ return response.data
+
+ }catch(error){
+ if (error.response?.data?.error) {
+ throw new Error(error.response.data.error);
+ }
+ throw error;
+
+ }
}
);
// TODO: Implement register thunk
-export const register = createAsyncThunk(
+export const registerUser = createAsyncThunk(
"auth/register",
async (userData, { rejectWithValue }) => {
// TODO: Implement registration functionality
// 1. Make a POST request to /auth/register with userData
// 2. Return the response data
// 3. Handle errors appropriately
+
+ try{
+ const response = await axios.post(`${BASE_URL}/auth/register`, userData);
+ return response.data
+
+ }catch(error) {
+ throw error;
+ }
+
+
}
);
@@ -45,9 +77,29 @@ export const logout = createAsyncThunk(
// TODO: Implement logout functionality
// 1. Make a POST request to /auth/logout
// 2. Handle errors appropriately
+
+ try{
+ await axios.post(`${BASE_URL}/auth/logout`);
+
+ }catch(error) {
+ throw error;
+ }
+
}
);
+export const resetposssword = createAsyncThunk(
+ "auth/resetpassword",
+ async (email, { rejectWithValue }) => {
+ try{
+ const response = await axios.post(`${BASE_URL}/auth/reset-password`, {email});
+ return response.data
+ }catch(error) {
+ throw error;
+ }
+ }
+)
+
const initialState = {
user: null,
isAuthenticated: false,
@@ -64,11 +116,78 @@ const authSlice = createSlice({
},
},
extraReducers: (builder) => {
- builder;
+
// TODO: Add cases for checkAuthStatus
- // TODO: Add cases for login
- // TODO: Add cases for register
- // TODO: Add cases for logout
+ builder
+ // Check Auth Status
+ .addCase(checkAuthStatus.pending, (state) => {
+ state.status = "loading";
+ })
+ .addCase(checkAuthStatus.fulfilled, (state, action) => {
+ state.status = "succeeded";
+ state.user = action.payload;
+ state.isAuthenticated = true;
+ state.loading = false;
+ state.error = null;
+ })
+ .addCase(checkAuthStatus.rejected, (state, action) => {
+ state.status = "failed";
+ state.user = null;
+ state.isAuthenticated = false;
+ state.loading = false;
+ state.error = action.error.message;
+ })
+
+ // Login
+ .addCase(login.pending, (state) => {
+ state.status = "loading";
+ })
+ .addCase(login.fulfilled, (state, action) => {
+ state.status = "succeeded";
+ state.user = action.payload;
+ state.isAuthenticated = true;
+ state.loading = false;
+ state.error = null;
+ })
+ .addCase(login.rejected, (state, action) => {
+ state.status = "failed";
+ state.user = null;
+ state.isAuthenticated = false;
+ state.loading = false;
+ state.error = action.error.message;
+ })
+
+ // Register
+ .addCase(registerUser.pending, (state) => {
+ state.status = "loading";
+ state.error = null;
+ })
+ .addCase(registerUser.fulfilled, (state, action) => {
+ state.status = "succeeded";
+ state.user = action.payload;
+ state.isAuthenticated = true;
+ state.error = null;
+ })
+ .addCase(registerUser.rejected, (state, action) => {
+ state.status = "failed";
+ state.error = action.error.message;
+ })
+
+ // Logout
+ .addCase(logout.pending, (state) => {
+ state.status = "loading";
+ })
+ .addCase(logout.fulfilled, (state) => {
+ state.status = "succeeded";
+ state.user = null;
+ state.isAuthenticated = false;
+ state.loading = false;
+ state.error = null;
+ })
+ .addCase(logout.rejected, (state, action) => {
+ state.status = "failed";
+ state.error = action.error.message;
+ });
},
});