added Popup modal for login and signup page (#155)

This commit is contained in:
Anirban Pratihar 2022-05-21 20:48:26 +05:30 committed by GitHub
parent ef76047a10
commit 1b2006edcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 216 additions and 21 deletions

View File

@ -9,6 +9,9 @@ import Link from 'next/link'
import { useContext } from 'react'
import { useRouter } from 'next/router'
import {PopupMain} from "../Pop_up/Popup.jsx"
import style from "../../styles/popup_style.module.css"
function Login() {
const router = useRouter()
const user = useContext(UserContext)
@ -24,18 +27,31 @@ function Login() {
setUserData({ ...userData, [name]: value })
}
const handleLogin = (evt) => {
const handleLogin =async (evt) => {
evt.preventDefault()
user.login(userData)
await user.login(userData)
user.popupHandler(true)
}
// disable submit button is any input has not been filled
const disabledSubmitBtn = Object.values(userData).some((val) => val === '')
if (user.user) {
router.push('/dashboard')
setTimeout(() => {
router.push('/dashboard')
}, 4400);
}
return (
return <>
<div className={style["container-modal-main"]}>
{
(user.showPopUp) ? (user.user) ? <PopupMain message="Successfully Logged In" mode="accept" /> :
<PopupMain message="Invalid Credentials" mode="error" /> : ""
}
</div>
<LoginStyle>
<form className="form-wrapper" onSubmit={handleLogin}>
<p className="reg-title">Sign in</p>
@ -88,6 +104,7 @@ function Login() {
</p>
</form>
</LoginStyle>
)
</>
}
export default Login

View File

@ -0,0 +1,59 @@
import style from "../../styles/popup_style.module.css"
import { useRef,useState,useEffect,useCallback,useContext } from "react"
import UserAuth from '../../helpers/user/usercontext'
export const PopupMain = ({message,mode})=>{
const context = useContext(UserAuth)
const containerRef = useRef()
//* a state to trigger the exit animation for popup
const [unmount,setUnmount] = useState(false)
const cb = useCallback(()=>{
setTimeout(() => {
setUnmount(true)
}, 3500)
if(unmount){
const className = containerRef.current?.classList[0];
const cont = document.querySelector(`.${className}`)
cont.classList.add(`${style["container-exit"]}`)
setTimeout(() => {
//* No popup active currently
context.popupHandler(false)
// containerRef.current.remove()
},2000);
}
},[unmount])
useEffect(()=>{
cb()
},[cb])
return <>
<div className={style["container"]} ref={containerRef}>
<div className={style["text-container"]} style={{color:(mode== "accept")?"green":"red"}}>
{(mode == "accept")?<ion-icon name="checkmark-circle-outline" ></ion-icon> :<ion-icon name="alert-circle-outline" ></ion-icon>}
<h4>{message}</h4>
</div>
<div className={style["loading-bar"]}></div>
</div>
</>
}

View File

@ -6,6 +6,8 @@ import { useState, useContext } from 'react'
import { Link } from '@mui/material'
import UserAuth from 'helpers/user/usercontext'
import { useRouter } from 'next/router'
import {PopupMain} from "../Pop_up/Popup.jsx"
import style from "../../styles/popup_style.module.css"
function Reg() {
const router = useRouter()
@ -16,25 +18,39 @@ function Reg() {
password: '',
repassword: '',
})
const handleInput = (event) => {
const name = event.target.name
const value = event.target.value
setUserData({ ...userData, [name]: value })
}
const handleSubmit = (e) => {
const handleSubmit = async (e) => {
e.preventDefault()
setUserData(userData)
context.createAcc(userData)
await context.createAcc(userData)
context.popupHandler(true) //* state change to spwan a popUp
}
// disable submit button is any input has not been filled
const disabledSubmitBtn = Object.values(userData).some((val) => val === '')
if (context.user) {
router.push('/dashboard')
if (context.user ) {
setTimeout(() => {
router.push('/dashboard')
}, 4400);
}
return (
return <>
<div className={style["container-modal-main"]}>
{
(context.showPopUp) ? (context.user) ? <PopupMain message="Successfully Registered" mode="accept" /> :
<PopupMain message="Invalid Credentials" mode="error" /> : ""
}
</div>
<RegStyle>
<form onSubmit={handleSubmit} className="form-wrapper">
<p className="reg-title">Sign Up</p>
@ -115,6 +131,9 @@ function Reg() {
</p>
</form>
</RegStyle>
)
</>
}
export default Reg

View File

@ -32,6 +32,12 @@ const UserAuthProvider = ({ children }) => {
const [mode,setMode] = useState('light')
const [user, setUser] = useState(null)
const [jwt, setJwt] = useState(null)
const [showPopUp,setPopUp] = useState(false)
const popupHandler = (bool)=>{
setPopUp(bool)
}
const login = async ({ email, password }) => {
let login = true
await axios
@ -95,7 +101,7 @@ const UserAuthProvider = ({ children }) => {
setJwt(null)
storeJWT(null)
}
const context = { jwt, user, mode, login, logout, createAcc, handleLightMode, handleDarkMode,fetchUser }
const context = { jwt, user, mode, login, logout, createAcc, handleLightMode, handleDarkMode,fetchUser,popupHandler,showPopUp }
useEffect(() => {
let jwt = fetchJWT()
if (jwt) {

View File

@ -3,17 +3,23 @@ import '../styles/logostyles.css'
import '../styles/formStyles.css'
import '../styles/index.css'
import '../styles/404.css'
import UserAuthProvider from 'helpers/user/userState'
import Page from 'react-page-loading'
function MyApp({ Component, pageProps }) {
return (
return <>
<UserAuthProvider>
<Page loader={'bar'} color={'#03b1fc'} size={10}>
<Component {...pageProps} />
</Page>
</UserAuthProvider>
)
<script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script>
</>
}
export default MyApp

View File

@ -8,11 +8,14 @@ import UserAuth, { UserContext } from '../helpers/user/usercontext'
export default function signup() {
const { mode } = useContext(UserAuth)
return (
<div className={mode == 'light' ? 'flex-column' : 'dark-bg'}>
<NavBar />
<Reg />
<Footer />
</div>
)
return <>
<div className={mode == 'light' ? 'flex-column' : 'dark-bg'}>
<NavBar />
<Reg />
<Footer />
</div>
</>
}

View File

@ -0,0 +1,85 @@
.container-modal-main{
width: 20em;
position: absolute;
right: 0;
display: flex;
flex-direction: column-reverse;
justify-content: flex-start;
gap: 0.7em;
height: 100%;
z-index: 2;
}
.container{
width: 19em;
height: 3.9em;
box-shadow: -3px 0px 15px rgba(0, 0, 0, 0.459);
background: white;
/* left: 76%; */
transform: translateX(105%);
/* display: none; */
overflow: hidden;
animation: container 400ms ease-out 1 forwards ;
margin-bottom: 0.9em;
}
@keyframes container{
25%{
transform: translateX(-1.5%);
}
50%{
transform: translateX(-3%);
}
100%{
transform: translateX(-1.5%);
}
}
.container.container-exit{
transform: translateX(-1.5%);
animation: container-exit 400ms ease-out 1 forwards ;
}
@keyframes container-exit{
50%{
transform: translateX(-3%);
}
100%{
transform: translateX(108%);
}
}
.container .text-container{
padding: 0.9em 0.65em;
font-size: 1.2em;
font-family: sans-serif;
align-items: center;
display: flex;
gap: 0.6em;
}
.container .text-container ion-icon{
transform: translate(0);
font-size:1.2em;
}
.loading-bar{
background: rgb(222, 146, 4);
height: calc(3.5em - 2em);
transform-origin: left;
transform: scaleX(1);
animation: loading 3s 100ms linear 1 forwards ;
}
@keyframes loading{
100%{
transform: scaleX(0);
}
}