import React, { useState, useEffect } from "react"; import "./Forms.css"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import toast, { Toaster } from "react-hot-toast"; import { Link, useNavigate } from "react-router-dom"; import Tippy from "@tippyjs/react"; import "tippy.js/dist/tippy.css"; import { useDispatch } from "react-redux"; import { login } from "../../store/slices/authSlice"; // Define Zod schema for form validation const formSchema = z.object({ email: z.string().email({ message: "Invalid email format" }), password: z.string().min(6, { message: "Password must be at least 6 characters" }) }); const LoginForm = () => { const { register, handleSubmit, formState: { errors } } = useForm({ resolver: zodResolver(formSchema) }); const navigate = useNavigate(); const dispatch = useDispatch(); // TODO: Initialize a state variable to manage the loading indicator. // Explanation: Use the useState hook to create a variable (e.g., "isLoading") // that will be true when the login request is in progress and false otherwise. // Assignment 7: [Insert TODO for initializing loading state here] // Display validation errors sequentially via toast notifications useEffect(() => { const errorKeys = Object.keys(errors); errorKeys.forEach((key, index) => { setTimeout(() => { toast.error(errors[key].message); }, (index + 1) * 1000); }); }, [errors]); const onSubmit = async (data) => { // TODO: Set the loading state to true before sending the login request. // Explanation: Update the loading indicator to signal that the login process has started. try { // TODO: Send a POST request to the /api/login endpoint. // Explanation: // - Use the fetch API with method "POST". // - Include headers with "Content-Type": "application/json". // - Pass the form data as a JSON-stringified body. // TODO: Process the server response. // Explanation: // - If the response is successful (response.ok is true), parse the JSON, dispatch the login action, // display a success toast, and navigate to the account page. // - If not, parse the error message from the response and display it using toast.error. } catch (error) { // TODO: Catch any errors and display a generic error message. // Explanation: Log the error and use toast.error to notify the user of an error. } // TODO: Reset the loading state to false after the request completes. // Explanation: This ensures the UI is re-enabled regardless of success or failure. }; return (

Ravenous

Login

{/* TODO: Disable the submit button when the loading state is true and display appropriate button text. Explanation: When isLoading is true, the button should be disabled and show text like "Logging in...". Otherwise, it should display "Login". */} Create an Account
); }; export default LoginForm;