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> Login</span></Nav.Link>
<Nav.Link href="#" onClick={() => handleShow('signup')}><FontAwesomeIcon icon={solid('user-plus')}/><span> 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.
The props all seem to be there, the modal just doesn't seem to pop-up. Thanks