Reputation: 31
I'm trying to create this sliding sign in /sign up portal but the original code was on Vanilla JS. The components seems unmounted on the Dom and the program is unable to find the Classlist by its id.I did few attempts on using Component did mount but it is throwing error, later I've found out that I am lacking understanding about Class vs function on react. componentDidMount()
seems to be only for Classes. Now I cant seem to find a valid solution for this. Also I might forget, when should I really need to use Classes vs functions in rendering a component? How can I prevent calling an unmounted element in the DOM if I use function instead of class?
This is the raw Html,css,vanilla js code for the portal.
const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('container');
signUpButton.addEventListener('click', () => {
container.classList.add("right-panel-active");
});
signInButton.addEventListener('click', () => {
container.classList.remove("right-panel-active");
});
@import url('https://fonts.googleapis.com/css?family=Montserrat:400,800');
* {
box-sizing: border-box;
}
body {
background: #f6f5f7;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-family: 'Montserrat', sans-serif;
height: 100vh;
margin: -20px 0 50px;
}
h1 {
font-weight: bold;
margin: 0;
}
h2 {
text-align: center;
}
p {
font-size: 14px;
font-weight: 100;
line-height: 20px;
letter-spacing: 0.5px;
margin: 20px 0 30px;
}
span {
font-size: 12px;
}
a {
color: #333;
font-size: 14px;
text-decoration: none;
margin: 15px 0;
}
button {
border-radius: 20px;
border: 1px solid #FF4B2B;
background-color: #FF4B2B;
color: #FFFFFF;
font-size: 12px;
font-weight: bold;
padding: 12px 45px;
letter-spacing: 1px;
text-transform: uppercase;
transition: transform 80ms ease-in;
}
button:active {
transform: scale(0.95);
}
button:focus {
outline: none;
}
button.ghost {
background-color: transparent;
border-color: #FFFFFF;
}
form {
background-color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 50px;
height: 100%;
text-align: center;
}
input {
background-color: #eee;
border: none;
padding: 12px 15px;
margin: 8px 0;
width: 100%;
}
.container {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 14px 28px rgba(0,0,0,0.25),
0 10px 10px rgba(0,0,0,0.22);
position: relative;
overflow: hidden;
width: 768px;
max-width: 100%;
min-height: 480px;
}
.form-container {
position: absolute;
top: 0;
height: 100%;
transition: all 0.6s ease-in-out;
}
.sign-in-container {
left: 0;
width: 50%;
z-index: 2;
}
.container.right-panel-active .sign-in-container {
transform: translateX(100%);
}
.sign-up-container {
left: 0;
width: 50%;
opacity: 0;
z-index: 1;
}
.container.right-panel-active .sign-up-container {
transform: translateX(100%);
opacity: 1;
z-index: 5;
animation: show 0.6s;
}
@keyframes show {
0%, 49.99% {
opacity: 0;
z-index: 1;
}
50%, 100% {
opacity: 1;
z-index: 5;
}
}
.overlay-container {
position: absolute;
top: 0;
left: 50%;
width: 50%;
height: 100%;
overflow: hidden;
transition: transform 0.6s ease-in-out;
z-index: 100;
}
.container.right-panel-active .overlay-container{
transform: translateX(-100%);
}
.overlay {
background: #FF416C;
background: -webkit-linear-gradient(to right, #FF4B2B, #FF416C);
background: linear-gradient(to right, #FF4B2B, #FF416C);
background-repeat: no-repeat;
background-size: cover;
background-position: 0 0;
color: #FFFFFF;
position: relative;
left: -100%;
height: 100%;
width: 200%;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
}
.container.right-panel-active .overlay {
transform: translateX(50%);
}
.overlay-panel {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 40px;
text-align: center;
top: 0;
height: 100%;
width: 50%;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
}
.overlay-left {
transform: translateX(-20%);
}
.container.right-panel-active .overlay-left {
transform: translateX(0);
}
.overlay-right {
right: 0;
transform: translateX(0);
}
.container.right-panel-active .overlay-right {
transform: translateX(20%);
}
.social-container {
margin: 20px 0;
}
.social-container a {
border: 1px solid #DDDDDD;
border-radius: 50%;
display: inline-flex;
justify-content: center;
align-items: center;
margin: 0 5px;
height: 40px;
width: 40px;
}
footer {
background-color: #222;
color: #fff;
font-size: 14px;
bottom: 0;
position: fixed;
left: 0;
right: 0;
text-align: center;
z-index: 999;
}
footer p {
margin: 10px 0;
}
footer i {
color: red;
}
footer a {
color: #3c97bf;
text-decoration: none;
}
<div class="container" id="container">
<div class="form-container sign-up-container">
<form action="#">
<h1>Create Account</h1>
<div class="social-container">
<a href="#" class="social"><i class="fab fa-facebook-f"></i></a>
<a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
<a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
</div>
<span>or use your email for registration</span>
<input type="text" placeholder="Name" />
<input type="email" placeholder="Email" />
<input type="password" placeholder="Password" />
<button>Sign Up</button>
</form>
</div>
<div class="form-container sign-in-container">
<form action="#">
<h1>Sign in</h1>
<div class="social-container">
<a href="#" class="social"><i class="fab fa-facebook-f"></i></a>
<a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
<a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
</div>
<span>or use your account</span>
<input type="email" placeholder="Email" />
<input type="password" placeholder="Password" />
<a href="#">Forgot your password?</a>
<button>Sign In</button>
</form>
</div>
<div class="overlay-container">
<div class="overlay">
<div class="overlay-panel overlay-left">
<h1>Welcome Back!</h1>
<p>To keep connected with us please login with your personal info</p>
<button class="ghost" id="signIn">Sign In</button>
</div>
<div class="overlay-panel overlay-right">
<h1>Hello, Friend!</h1>
<p>Enter your personal details and start journey with us</p>
<button class="ghost" id="signUp">Sign Up</button>
</div>
</div>
</div>
</div>
And this is my current Login.js for my portal on a function.
import React, { useState } from 'react';
import axios from 'axios';
import { setUserSession } from './Utils/Common';
import './Login.css';
function Login(props) {
const [loading, setLoading] = useState(false);
const username = useFormInput('');
const password = useFormInput('');
const [error, setError] = useState(null);
const handleLogin = () => {
setError(null);
setLoading(true);
axios.post('http://localhost:4000/users/signin', { username: username.value, password: password.value }).then(response => {
console.log(username, password);
setLoading(false);
setUserSession(response.data.token, response.data.user);
props.history.push('/dashboard');
}).catch(error => {
setLoading(false);
if (error.response.status === 401) setError(error.response.data.message);
else setError("Something went wrong. Please try again later.");
});
}
const Signup = () => {
setError(null);
setLoading(true);
props.history.push('/Signup');
}
return (
<div className='login-wrapper' >
<div className='user-wrapper'>
<h1>Library Management System</h1>
<br />
<h1>Login</h1>
<br /><br />
<div className="user-details">
<h3>Username</h3>
<img src={userlogo} className="login-logo-user" />
<input type="text" {...username} autoComplete="new-password" />
</div>
<div className="user-details">
<h3>Password</h3>
<img src={passwordlogo} className="login-logo-password"/>
<input type="password" {...password} autoComplete="new-password" />
</div>
{error && <><small style={{ color: 'red' }}>{error}</small><br /></>}<br />
<input type="button" value={loading ? 'Loading...' : 'Login'} onClick={handleLogin} disabled={loading} id='buttons'/>
<input type="button" value={loading ? 'Loading...' : 'Signup'} onClick={Signup} id='buttons'/>
<div className="forgot-password">
<h5>Forgot Password? Click <span id="forgot-password">here</span>.</h5>
</div>
</div>
<div className='logo-wrapper'>
<div className="logo-main">
<img src={librarylogo} id="mainlogo"/>
<h2>Library Management System v1.0</h2>
</div>
</div>
</div>
);
}
const useFormInput = initialValue => {
const [value, setValue] = useState(initialValue);
const handleChange = e => {
setValue(e.target.value);
}
return {
value,
onChange: handleChange
}
}
export default Login;
Is this correct by the way?
I am trying to convert this as well?
from this function.
function login(props) {
const [loading, setLoading] = useState(false);
const username = useFormInput('');
const password = useFormInput('');
const [error, setError] = useState(null);
}
into a class:
class Login extends React.Component{
constructor(props) {
super(props);
this.state = {
loading, setLoading : false,
username : useFormInput(''),
password : useFormInput(''),
error, setError = null
}
}
}
Upvotes: 1
Views: 128
Reputation: 31
I got it working now. Thanks for all the help.
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
setLoading: false,
email: props.email,
password: props.password,
error: null,
setError: null
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount(){
const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('container');
if (container){
console.log('loaded');
signUpButton.addEventListener('click', () => {
container.classList.add("right-panel-active");
});
signInButton.addEventListener('click', () => {
container.classList.remove("right-panel-active");
});
}
}
handleChange(event) {
this.setState({
[event.target.type]: event.target.value
});
}
handleSubmitSignIn(event) {
// alert('A name was submitted: ' + this.state.email + this.state.password);
event.preventDefault();
console.log(this.state.email);
console.log(this.state.password);
}
handleSubmitSignUp(event) {
// alert('A name was submitted: ' + this.state.email + this.state.password);
event.preventDefault();
console.log(this.state.email);
console.log(this.state.password);
}
render() {
return (
<div className="container" id="container">
<div className="form-container sign-up-container">
<form onSubmit={this.handleSubmitSignUp}>
<h1>Create Account</h1>
<div className="social-container">
<a href="#" className="social"><i className="fab fa-facebook-f"></i></a>
<a href="#" className="social"><i className="fab fa-google-plus-g"></i></a>
<a href="#" className="social"><i className="fab fa-linkedin-in"></i></a>
</div>
<span>or use your email for registration</span>
<input type="text" placeholder="Name" autoComplete="new-name" />
<input type="email" placeholder="Email" autoComplete="new-email" />
<input type="password" placeholder="Password" autoComplete="new-password" />
<input type="department" placeholder="Department" autoComplete="new-name" />
<input type="year" placeholder="Year" autoComplete="new-email" />
<input type="schoolId" placeholder="School Id No." autoComplete="new-password" />
<button>Sign Up</button>
</form>
</div>
<div className="form-container sign-in-container">
<form onSubmit={this.handleSubmitSignIn}>
<h1>Sign in</h1>
<div className="social-container">
<a href="#" className="social"><i className="fab fa-facebook-f"></i></a>
<a href="#" className="social"><i className="fab fa-google-plus-g"></i></a>
<a href="#" className="social"><i className="fab fa-linkedin-in"></i></a>
</div>
<span>or use your account</span>
<input type="email" placeholder="Email" value={this.state.email} autoComplete='new-email' onChange={this.handleChange}/>
<input type="password" placeholder="Password" value={this.state.password} autoComplete='new-password' onChange={this.handleChange}/>
<a href="#">Forgot your password?</a>
<button type='submit' >Sign In</button>
</form>
</div>
<div className="overlay-container">
<div className="overlay">
<div className="overlay-panel overlay-left">
<h1>Welcome Back!</h1>
<p>To keep connected with us please login with your personal info</p>
<button className="ghost" id="signIn">Sign In</button>
</div>
<div className="overlay-panel overlay-right">
<h1>Hello</h1>
<p>Enter your personal details and start journey with us</p>
<button className="ghost" id="signUp">Sign Up</button>
</div>
</div>
</div>
</div>
);
}
}
export default Login;
Upvotes: 1