2

I have a navbar with the usual login and sign-up buttons. When I click the relevant link, a modal with the form should pop-up allowing the user to login or sign-up. At the moment, neither of the pop-ups seem to work. I have been following React-Bootstrap Multiple Modal and have been using the chosen answer to try and implement the modals.

The handle functions are in my app.jsx:

import React, {useEffect, useState} from 'react'
import {useRouter} from 'next/router'
import {SessionProvider, useSession} from 'next-auth/react'
import {SSRProvider} from 'react-bootstrap'
import 'application.css';
import Navigation from "../components/Navigation";
import Login from "../components/Login";
import SideNav from "../components/SideNav";
import SignUp from "../components/SignUp";


function MyApp({Component, pageProps}) {
    let id = '';
    const [show, setShow] = useState(null)
    function handleClose() {
        setShow({show: id});
    }

    function handleShow(id) {
        setShow({show: id});
    }
    const [showSideBar, setShowSideBar] = useState(false)
    const toggleSideMenu = () => setShowSideBar((prev) => !prev);


    return (
        <SessionProvider session={pageProps.session}>
            <SSRProvider>
                <SideNav showSideBar={showSideBar} />
                <Navigation
                  handleShow={handleShow}
                  handleClose={handleClose}
                  toggleSideMenu={toggleSideMenu}
                />

                <Login
                  show={show}
                  handleShow={handleShow}
                  handleClose={handleClose}
                />

                <SignUp
                  show={show}
                  handleShow={handleShow}
                  handleClose={handleClose}
                />

                {Component.auth
                    ? <Auth><Component {...pageProps} /></Auth>
                    : <Component {...pageProps} />
                }
            </SSRProvider>
        </SessionProvider>
    )
}

function Auth({children}) {
    // @ts-ignore
    const [session, loading] = useSession()
    const isUser = !!session?.user
    const router = useRouter()

    useEffect(() => {
        if (loading) return // Do nothing while loading
        if (!isUser) router.push('/login')
        // If not authenticated, force log in
    }, [isUser, loading])

    if (isUser) {
        return children
    }

    // Session is being fetched, or no user.
    // If no user, useEffect() will redirect.
    return <div>Loading...</div>
}

export default MyApp

I pass the show, handleshow, handleclose to each component. In the navigation the buttons look like this:

<Nav.Link href="#" onClick={() => handleShow('login')}><FontAwesomeIcon icon={solid('sign-in-alt')}/><span>&nbsp;Login</span></Nav.Link>
<Nav.Link href="#" onClick={() => handleShow('signup')}><FontAwesomeIcon icon={solid('user-plus')}/><span>&nbsp;Sign up</span></Nav.Link>

And then finally, my Login.jsx with a modal:

import {getCsrfToken, signIn, useSession} from "next-auth/react";
import Router from "next/router";
import { Modal, CloseButton, Form } from 'react-bootstrap';
import Link from "next/link";
import { useState } from "react";

function Login({csrfToken, show, handleClose, handleShow, props}) {
  const [error, setError] = useState(false);

  //setShow(prev => !prev);


  const handleSubmit = async (e) => {
    e.preventDefault();

    const res = await signIn('credentials', {
      redirect: false,
      email: e.target.email1.value,
      password: e.target.password1.value,
      callbackUrl: `/dashboard`,
    });

    if (res?.error) {
      setError(true);
    } else {
      Router.push('/dashboard');
    }

  }

  return (
    <Modal show={show === "login"} onHide={handleClose} fade={false}>
      <Modal.Header className={"modal-dark bg-dark"}>
        <Modal.Title><h1>Log In</h1></Modal.Title>
        <CloseButton variant="white" onClick={handleClose}/>
      </Modal.Header>
      <Modal.Body className={"modal-dark bg-dark"}>
        <form noValidate onSubmit={(e) => handleSubmit(e)}>
          <input name="csrfToken" type="hidden" defaultValue={csrfToken}/>
          <Form.Group className="mt-3">
            <Form.Control
              id="email-address1"
              name="email1"
              type="email"
              autoComplete="email"
              required
              className=""
              placeholder="Email address"
            />
          </Form.Group>
          <Form.Group className="mt-3">
            <Form.Control
              id="password1"
              name="password1"
              type="password"
              autoComplete="current-password"
              required
              placeholder="Password"
            />
          </Form.Group>
          <button type={"submit"} className={"btn orange-button mt-3"}>Login</button>

          <div>
            or <Link href='/signup'>sign up</Link>
          </div>

          {error && <div className="bg-red-300 p-2 text-white rounded">Wrong email or password</div>}

        </form>

      </Modal.Body>
      <Modal.Footer className={"modal-dark bg-dark"}>
        <button onClick={handleClose}>
          Close
        </button>
      </Modal.Footer>
    </Modal>
  );
}

export default Login;

In the developer tools looking at the React components tab, it is sending the correct information.

React components tab

The props all seem to be there, the modal just doesn't seem to pop-up. Thanks

devon93
  • 165
  • 2
  • 11

0 Answers0