How to display custom alert before login(navigate to other page) - javascript

Hello guys i have a project made with react, node, express, and mysql. I have a problem, in this project user can register and login. In the login page i want to display snackbar with material ui after user succeed login. But the problem is user will redirecting to ("/home) without displaying the snackbar first. I want to make the snackbar appear for like 3second and after that the user will go to the next page.
This is the code, problem occur in login function :
const Login = () => {
let navigate = useNavigate();
Axios.defaults.withCredentials = true;
const { emailLog, setEmailLog } = useContext(EmailUser);
const [ passwordLog, setPasswordLog ] = useState("");
const { loginStatus, setLoginStatus } = useContext(LoginStatus);
const [ showSuccess, setShowSuccess ] = React.useState(false);
const [ showWarning, setShowWarning ] = React.useState(false);
const handleNotShowSuccess = (event, reason) => {
if (reason === 'clickaway') {
return;
}
setShowSuccess(false);
};
const handleNotShowWarning= (event, reason) => {
if (reason === 'clickaway') {
return;
}
setShowWarning(false);
};
const [ passwordType, setPasswordType] = useState(false);
const TogglePassword = () => {
setPasswordType(!passwordType);
}
Axios.defaults.withCredentials = true;
const login = (e) => {
e.preventDefault()
Axios.post("http://localhost:3001/login" , {
email: emailLog,
password: passwordLog
}).then((response)=> {
if(response.data.message) {
setShowWarning(true)
} else{
setLoginStatus(response.data[0].email);
setShowSuccess(true);
navigate("/home");
}
})
}
useEffect(() => {
Axios.get('http://localhost:3001/login').then((response)=> {
if(response.data.loggedIn === true) {
setLoginStatus(response.data.email[0].email)
}
})
}, [])
return (
<div>
<Stack spacing={2} sx={{ width: '100%' }}>
<Snackbar open={showSuccess} autoHideDuration={6000} onClose={handleNotShowSuccess}>
<Alert onClose={handleNotShowSuccess} severity="success" sx={{ width: '100%' }}>
Logging in
</Alert>
</Snackbar>
<Snackbar open={showWarning} autoHideDuration={6000} onClose={handleNotShowWarning}>
<Alert onClose={handleNotShowWarning} severity="warning" sx={{ width: '100%' }}>
User does not exist
</Alert>
</Snackbar>
</Stack>
<div className="wrapper">
<div className="img">
<img src={userNoBg} alt="background profile"/>
</div>
<div className="login-content">
<div className='loginForm'>
<img src={user} alt="default avatar profile" />
<h2 className="title">Welcome</h2>
<div className="input-div one">
<div className="icon">
<i className="fas fa-user"><GrMail /></i>
</div>
<div className="div">
<input type="email" name="emailLogin" className="input" placeholder='Email' required
onChange={(e)=> {
setEmailLog(e.target.value)
}}/>
</div>
</div>
<div className="input-div pass">
<div onClick={TogglePassword} className="icon">
{passwordType ? <i className="fas fa-lock"><MdVisibility /></i> : <i className="fas fa-lock"><MdVisibilityOff /></i>}
</div>
<div className="div">
<input type={passwordType ? "text" : "password"} className="input" placeholder='Password' required
onChange={(e)=> {
setPasswordLog(e.target.value)
}}/>
</div>
</div>
Don't have an account ?
<button type='submit' className='btnLogin' onClick={login}>Login</button>
</div>
</div>
</div>
</div>
)
}
export default Login

Maybe I'm misunderstanding, but could you not wrap the navigate call in a setTimeout?
setLoginStatus(response.data[0].email);
setShowSuccess(true);
setTimeout(() => navigate("/home"), 3000);

Related

react-paypal-js not changing currency

function App() {
return (
<PayPalScriptProvider
options={{
"client-id": process.env.REACT_APP_PAYPAL_CLIENT_ID,
currency: "PHP",
}}
>
<Router>
<div className="app">
<Routes>
<Route path="/" element={<LandingPage />}></Route>
<Route path="/admin" element={<Admin />}></Route>
</Routes>
</div>
</Router>
</PayPalScriptProvider>
);
}
I specified the currency in the properties of paypal script provider but it's still in usd
Purchase Image showing USD
What should I do to change the currency of it to Philippine Peso
Here is the link of the npm package that i used:
https://www.npmjs.com/package/#paypal/react-paypal-js
Whole Code
import "./App.css";
import { useState, useRef, useEffect } from "react";
import Dropzone from "react-dropzone";
import { PayPalButtons, PayPalScriptProvider } from "#paypal/react-paypal-js";
import {
arrayUnion,
collection,
deleteDoc,
doc,
onSnapshot,
orderBy,
query,
serverTimestamp,
setDoc,
updateDoc,
} from "firebase/firestore";
import { db, storage } from "./firebase.js";
import { v4 as uuidv4 } from "uuid";
import { getDownloadURL, ref, uploadString } from "firebase/storage";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import thanks from "./Images/thanks.png";
function PaypalCheckoutButton(props) {
const [error, setError] = useState(null);
const handleApprove = (orderID) => {
props.completeOrder();
};
if (error) {
alert(error);
}
return (
<div style={{ marginTop: "1rem" }}>
<PayPalButtons
createOrder={(data, actions) => {
return actions.order.create({
purchase_units: [
{
description: props.product.description,
amount: {
currency_code: "PHP",
value: props.product.price,
},
},
],
});
}}
onApprove={async (data, action) => {
const order = await action.order.capture();
console.log("order", order);
handleApprove(data.orderID);
}}
onCancel={() => {}}
onError={(err) => {
setError(err);
console.log("Paypal Checkout Error", err);
}}
/>
</div>
);
}
function Step1(props) {
const [isGift, setIsGift] = useState(null);
const [message, setMessage] = useState("");
function newKeychain() {
setIsGift(null);
props.setOrders((currentOrders) => [
{ image: props.image, message: message },
...currentOrders,
]);
props.setImage(null);
}
function handleShowButton() {
if (isGift === false) {
return props.image;
} else if (isGift === true) {
return props.image && message !== "";
}
}
return (
<div
className="step1 step"
style={isGift === true ? { marginTop: "5rem" } : {}}
>
{isGift === null && (
<>
<h1 className="title">Choose what type of keychain</h1>
<div className="purchaseTypeSection">
<div
className="formyself purchaseType"
onClick={() => setIsGift(false)}
>
<h2>Standard</h2>
<p className="keychainTypeDescription">
Perfect for personal use
</p>
<h2 className="price">₱69</h2>
</div>
<div className="gift purchaseType" onClick={() => setIsGift(true)}>
<h2>With Message</h2>
<p className="keychainTypeDescription">
Perfect for gifts to your love ones
</p>
<h2 className="price">₱99</h2>
</div>
</div>
</>
)}
{isGift !== null && (
<>
<h1 className="title">Choose your image</h1>
<Dropzone
onDrop={(acceptedFiles) =>
props.setImage(() => {
if (!acceptedFiles[0]) {
return null;
}
var fr = new FileReader();
fr.onload = function () {
props.setImage(fr.result);
};
fr.readAsDataURL(acceptedFiles[0]);
})
}
multiple={false}
accept={{ "image/jpeg": [".png", ".jpg"] }}
>
{({ getRootProps, getInputProps }) => (
<section>
<div
{...getRootProps()}
style={props.image ? { padding: "0 !important" } : {}}
>
<input {...getInputProps()} />
{props.image ? (
<img
className="drop__image"
src={props.image}
alt="Your Keychain"
/>
) : (
<h3 className="drop__text">
Drag your image here, or click to select a file
</h3>
)}
</div>
</section>
)}
</Dropzone>
{isGift === true && (
<textarea
className="messageInput largeInput"
maxLength={100}
placeholder="Enter your message to your special someone here"
value={message}
onChange={(e) => setMessage(e.target.value)}
></textarea>
)}
<div className="step1Buttons">
<button
className="step1Button"
onClick={() => {
setIsGift(null);
props.setImage(null);
}}
>
Go back
</button>
{handleShowButton() && (
<>
<button className="step1Button" onClick={newKeychain}>
Create Another Keychain
</button>
<button
className="step1Button"
onClick={() => {
newKeychain();
props.setStep((step) => step + 1);
}}
>
Next
</button>
</>
)}
</div>
</>
)}
</div>
);
}
function Step2(props) {
function completed() {
return (
props.customerName !== "" &&
props.customerNumber > 0 &&
props.customerAddress !== ""
);
}
return (
<div className="step2 step center">
<div className="question center">
<h3>Let us know who will we deliver it to</h3>
<input
placeholder="Enter your name"
value={props.customerName}
onChange={(e) => props.setCustomerName(e.target.value)}
></input>
</div>
<div className="question center">
<h3>For us to give you infomations about the delivery and package</h3>
<input
type="number"
placeholder="Enter your phone number"
value={props.customerNumber}
onChange={(e) => props.setCustomerNumber(e.target.value)}
></input>
</div>
<div className="question center">
<h3>Let us know where to deliver</h3>
<textarea
className="largeInput locationInput"
placeholder="Enter your location"
value={props.customerAddress}
onChange={(e) => props.setCustomerAddress(e.target.value)}
></textarea>
</div>
<div className="step1Buttons">
<button
className="step1Button createAnother"
onClick={() => props.setStep((step) => step - 1)}
>
Go Back
</button>
<button
className="step1Button"
style={
completed()
? { backgroundColor: "#5c90a0", cursor: "pointer" }
: { backgroundColor: "#b5b5b5", cursor: "default" }
}
onClick={() => {
if (!completed()) {
return;
}
props.setStep((step) => step + 1);
}}
>
Next
</button>
</div>
</div>
);
}
function Step3(props) {
function getPrice() {
var p = 0;
props.orders.forEach((o) => {
if (o.message === "") {
p += 69;
} else {
p += 99;
}
});
return p;
}
function getDescription() {
var giftCount = 0;
var standardCount = 0;
props.orders.forEach((o) => {
if (o.message === "") {
standardCount += 1;
} else {
giftCount += 1;
}
});
return `${giftCount > 0 ? `${giftCount} Gift Keychain/s` : ""}${
giftCount * standardCount !== 0 ? " and " : ""
}${standardCount > 0 ? `${standardCount} Standard Keychain/s` : ""}`;
}
async function completeOrder(method) {
// get the order informations
// add it to the orders collection in firebase
const orderId = uuidv4();
await setDoc(doc(db, "orders", orderId), {
customerName: props.customerName,
customerNumber: props.customerNumber,
customerAddress: props.customerAddress,
timestamp: serverTimestamp(),
paymentMethod: method,
description: getDescription(),
price: getPrice(),
status: "toApprove",
});
for (let i = 0; i < props.orders.length; i++) {
let order = props.orders[i];
const fileRef = ref(storage, `orders/${orderId}`);
await uploadString(fileRef, order.image, "data_url").then(
async (snapshot) => {
const downloadUrl = await getDownloadURL(fileRef);
updateDoc(doc(db, "orders", orderId), {
orders: arrayUnion({
keychainImage: downloadUrl,
keychainMessage: order.message,
}),
});
}
);
}
props.setHasOrdered(true);
props.setOrders([]);
props.setCustomerName("");
props.setCustomerAddress("");
props.setCustomerNumber("");
props.setStep(1);
}
return (
<div className="step3 step">
<button
className="paymentMethod cod"
onClick={() => completeOrder("Cash On Delivery")}
>
Cash on Delivery
</button>
<h2 style={{ marginTop: "1rem" }}>Or</h2>
<PaypalCheckoutButton
completeOrder={() => completeOrder("Online")}
product={{ description: getDescription(), price: getPrice() }}
/>
</div>
);
}
function LandingPage(props) {
const [orders, setOrders] = useState([]);
const [customerName, setCustomerName] = useState("");
const [customerNumber, setCustomerNumber] = useState();
const [customerAddress, setCustomerAddress] = useState("");
const [step, setStep] = useState(1);
const [navbar, setNavbar] = useState(false);
const bottomRef = useRef();
const topRef = useRef();
const [image, setImage] = useState(null);
const changeBackground = () => {
setNavbar(window.scrollY > 0);
};
useEffect(() => {
window.addEventListener("scroll", changeBackground);
}, []);
function handleStepIndicator() {
if (step === 1) {
return "Step 1. Create your keychains";
} else if (step === 2) {
return "Step 2. Delivery Informations";
} else if (step === 3) {
return "Step 3. Payment Method";
}
}
const [hasOrdered, setHasOrdered] = useState(false);
return (
<>
{hasOrdered && (
<>
<div className="overlay" onClick={() => setHasOrdered(false)} />
<div className="purchaseModal">
<img src={thanks} alt="thanks" className="thanksImage"></img>
<h2>Thank you for your purchase</h2>
<p className="purchaseInfo">
We will inform you about the package via phone number that you
gave us
</p>
</div>
</>
)}
<div className="top" ref={topRef} style={{ marginTop: "-2rem" }} />
<section className="hero">
<div
className={`hero__navbar ${navbar && "active"}`}
onClick={() => {
topRef.current?.scrollIntoView({ behavior: "smooth" });
}}
>
<h2
className="hero__nav"
onClick={() => {
topRef.current?.scrollIntoView({ behavior: "smooth" });
}}
>
KEYCH
</h2>
</div>
<div className="hero__about">
<h1 className="hero__headline">BRING YOUR KEYCHAIN IDEAS TO LIFE</h1>
<p className="hero__support">
We make handmade and customized keychains using images that you like
</p>
</div>
<button
className="hero__cta"
onClick={() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
}}
>
<h3>Create Now</h3>
</button>
</section>
<section className="creation">
<h1 className="creation__stepIndicator">{handleStepIndicator()}</h1>
{step === 1 && (
<Step1
image={image}
setImage={setImage}
orders={orders}
setOrders={setOrders}
setStep={setStep}
/>
)}
{step === 2 && (
<Step2
customerName={customerName}
setCustomerName={setCustomerName}
customerNumber={customerNumber}
setCustomerNumber={setCustomerNumber}
customerAddress={customerAddress}
setCustomerAddress={setCustomerAddress}
setStep={setStep}
/>
)}
{step === 3 && (
<Step3
orders={orders}
setOrders={setOrders}
customerName={customerName}
customerAddress={customerAddress}
customerNumber={customerNumber}
setCustomerName={setCustomerName}
setCustomerAddress={setCustomerAddress}
setCustomerNumber={setCustomerNumber}
setHasOrdered={setHasOrdered}
setStep={setStep}
/>
)}
</section>
<div className="bottom" ref={bottomRef} />
</>
);
}
function OrderInfo(props) {
return (
<div className="orderInfo">
<div className="info__segment" style={{ marginBottom: "3rem" }}>
<h1>{props.id}</h1>
<h5>Order ID</h5>
</div>
{props.orders.map((o, i) => (
<div className="keychainInfo">
<h1>Keychain No. {i + 1}</h1>
<div className="info__segment">
<img
className="keychainImage"
src={o.keychainImage}
alt="keychainImage"
/>
<h5>Keychain Image</h5>
</div>
{o.keychainMessage && (
<div className="info__segment">
<h3 className="keychainMessage">{o.keychainMessage}</h3>
<h5>Keychain Message</h5>
</div>
)}
</div>
))}
<div className="customerInfo">
<div className="info__segment">
<h3 className="customerName">{props.customerName}</h3>
<h5>Customer Name</h5>
</div>
<div className="info__segment">
<h3 className="customerNumber">{props.customerNumber}</h3>
<h5>Customer Number</h5>
</div>
<div className="info__segment">
<h3 className="customerAddress">{props.customerAddress}</h3>
<h5>Customer Address</h5>
</div>
<div className="info__segment">
<h3 className="customerAddress">{props.paymentMethod}</h3>
<h5>Payment Method</h5>
</div>
<div className="info__segment">
<h3 className="totalPrice">₱ {props.price}</h3>
<h5>Total Price</h5>
</div>
</div>
</div>
);
}
function OrderManagement() {
const [orders, setOrders] = useState([]);
useEffect(
() =>
onSnapshot(
query(collection(db, "orders"), orderBy("timestamp", "desc")),
(snapshot) => {
setOrders(snapshot.docs);
}
),
[]
);
return (
<section className="orders">
<section className="toApprove orders__section">
<h1 className="segmentTitle">To Approve</h1>
{orders
.filter((o) => o.data().status === "toApprove")
.map((o) => (
<div className="toApproveOrder Order">
<OrderInfo
key={o.id}
orders={o.data().orders}
customerName={o.data().customerName}
customerAddress={o.data().customerAddress}
customerNumber={o.data().customerNumber}
price={o.data().price}
id={o.id}
paymentMethod={o.data().paymentMethod}
/>
<div className="toApproveControls controls">
<button
className="declineButton controlButton decline"
onClick={() => {
deleteDoc(doc(db, "orders", o.id));
}}
>
Decline
</button>
<button
className="approveButton controlButton"
onClick={() => {
updateDoc(doc(db, "orders", o.id), {
status: "toCreate",
});
}}
>
Approve
</button>
</div>
</div>
))}
</section>
<section className="toCreate orders__section">
<h1 className="segmentTitle">To Create</h1>
{orders
.filter((o) => o.data().status === "toCreate")
.map((o) => (
<div className="Order">
<OrderInfo
key={o.id}
orders={o.data().orders}
customerName={o.data().customerName}
customerAddress={o.data().customerAddress}
customerNumber={o.data().customerNumber}
price={o.data().price}
id={o.id}
paymentMethod={o.data().paymentMethod}
/>
<div className="controls">
<button
className="controlButton"
onClick={() => {
updateDoc(doc(db, "orders", o.id), {
status: "toShip",
});
}}
>
Ship Order
</button>
</div>
</div>
))}
</section>
<section className="toShip orders__section">
<h1 className="segmentTitle">To Ship</h1>
{orders
.filter((o) => o.data().status === "toShip")
.map((o) => (
<div className="Order">
<OrderInfo
key={o.id}
orders={o.data().orders}
customerName={o.data().customerName}
customerAddress={o.data().customerAddress}
customerNumber={o.data().customerNumber}
price={o.data().price}
id={o.id}
paymentMethod={o.data().paymentMethod}
/>
<div className="controls">
<button
className="controlButton"
onClick={() => {
deleteDoc(doc(db, "orders", o.id));
}}
>
Complete Order
</button>
</div>
</div>
))}
</section>
</section>
);
}
function Admin() {
const securityPassword = "Pogi Ni Vlad";
const [password, setPassword] = useState("");
return password === securityPassword ? (
<OrderManagement />
) : (
<section className="login">
<h1 className="title">Keych Admin Login</h1>
<div className="login__form">
<input
type="text"
className="form__pasword"
placeholder="Input password to enter: "
value={password}
onChange={(e) => setPassword(e.target.value)}
></input>
</div>
</section>
);
}
function App() {
return (
<PayPalScriptProvider
options={{
"client-id": process.env.REACT_APP_PAYPAL_CLIENT_ID,
currency: "PHP",
}}
>
<Router>
<div className="app">
<Routes>
<Route path="/" element={<LandingPage />}></Route>
<Route path="/admin" element={<Admin />}></Route>
</Routes>
</div>
</Router>
</PayPalScriptProvider>
);
}
export default App;
Where is the PayPalButtons component in the first code sample?
Consider using the full sample the package provides as a base. There's a currency variable set in two locations (line 10 and later within the PayPalScriptProvider) for whatever reason.

onChange Event not Triggered in React JS

export default function ActionRolesPage(props) {
const [authorities, setAuthorities] = useState([]);
const [name, setName] = useState("");
let list = [];
useEffect(() => {
getAuthorities();
}, []);
const getAuthorities = () => {
doGetAllAuthorities()
.then((res) => {
getValidatedData(res.data, "array").map((data) => (
list.push({ authority: data})
))
setAuthorities(list);
}).catch((e) => {
console.log(e);
})
}
const handleChange = (e) => {
console.log(e);
const { name, checked } = e.target
console.log(name,checked);
let tempUser = authorities.map((user) => (
user.authority === name ? { ...user, isChecked: checked } : user
));
setAuthorities(tempUser);
}
if(authorities.length){
console.log(authorities);
}
return (
<React.Fragment>
<Suspense fallback={<div>Loading....</div>}>
<div className="page-content">
<MetaTags>
<title>Add Role | IG One</title>
</MetaTags>
<Container fluid>
<Breadcrumb
title="Add Role"
breadcrumbItems={[{ title: "Settings" }, { title: "Roles" }, { title: "Add" }]}
/>
<Form onSubmit={handleSubmit}>
<Card>
<CardBody>
<Row className="mb-3">
<label
htmlFor="example-text-input"
className="col-md-2 col-form-label"
>
Name
</label>
<div className="col-md-8 mx-0">
<Input
className="form-control"
type="text"
name="name"
required
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name Of User "
/>
</div>
</Row>
<br></br>
<br></br>
<Row className="mb-3">
<CardTitle>
Authorities
</CardTitle>
<div className="col-md-2">
{
authorities.map((data,index) => (
<>
<div key={index} style={{ display: "flex" }}>
<div className='col-md-10 mx-0 mt-2'>
<Input type={"checkbox"}
checked={data?.isChecked || false}
name={data.authority}
onChange={(e) => console.log(e)}
className="form-control"
style={{ cursor: "pointer", paddingLeft: "1rem" }}
/></div>
<div>
<label style={{ cursor: "pointer" }} htmlFor={data.authority} className="col-md-50 col-form-label"> {data.authority}</label>
</div>
</div>
</>
))
}
</div>
</Row>
<Row className="d-flex justify-content-center mt-4">
<Button color="dark" type='submit' className="btn-xs" style={{ width: "40%", cursor: "pointer" }}
>
Add Role
</Button>
</Row>
</CardBody>
</Card>
</Form>
</Container>
</div>
</Suspense>
</React.Fragment>
)
}
Here is the whole code. I want to handle multiple checkboxes but onChange Event not triggered. There is a function handleChange it calls when onChange triggered but in my case there is no error seen in console as well as not display any event at console please resolve my doubt.
I also need to update the form getting respose from backend is checked authority name array How to handle checked state in checkbox.
If you have created a custom component for input, pass your onChange handler as prop and call inside the component as onChage event of <input> field. Or if you used any third-party lib, then you just need to pass a callback as prop. Otherwise Try this: <input> instead of <Input>
<input type={"checkbox"}
checked={data?.isChecked || false}
name={data.authority}
onChange={(e) => console.log(e)}
className="form-control"
style={{ cursor: "pointer", paddingLeft: "1rem" }}
/>

How to reset the Modal input states after clicking the modal close button in React?

After giving the input of mobile number when i close the modal, then again after clicking the Form Submit button, input box shows the previously entered number. I believe model captures the previous state by itself and i want to clear it whenever we open the modal.
After entering the OTP input in Modal, if we click on the Edit mobile number and when we again enter the input in mobile number, then previously entered OTP also shows up. I want to clear it after entering the new mobile number.
I have already tried setting the state to ("") on the onclick events but it doesn't help.
I could really use some help.
Code:
export default function Form() {
// form default hooks
const {register,handleSubmit, formState: { errors, isValid },} = useForm({mode: "onChange",criteriaMode: "all",});
const {register: register2,handleSubmit: handleSubmit2,formState: { errors: errors2 },} = useForm({mode: "onChange",});
const [verifyOTPFlag, setVerifyOTPFlag] = useState(true);
//modal hooks
const [mobileNumberInput, setMobileNumberInput] = useState(true);
const [postVerificationMessage, setPostVerificationMessage] = useState();
const [otpVerificationResult, setOtpVerificationResult] = useState(false);
const [show, setShow] = useState(false);
const [otpInput, setShowOtpInput] = useState(false);
const [number, setNumber] = useState("");
const [OTP, setOTP] = useState("");
const [counter, setCounter] = useState(59);
// post office and aadhar hooks
const [districtName, setDistrictName] = React.useState("");
const [stateName, setStateName] = React.useState("");
//-------------------------modal functionalities start-------------------------
const handleClose = () => {
setShow(false);
setShowOtpInput(false);};
const handleShow = () => {
setShow(true);};
const showOtpInput = () => {
getOTP(number);
setOTP("");
setShowOtpInput(true);
setMobileNumberInput(false);
setOtpVerificationResult(false);
};
const onSubmit = (data) => {
data["district"] = districtName;
data["state"] = stateName;
setMobileNumberInput(true);
setPostVerificationMessage("");
setNumber("");
if (verifyOTPFlag) {
if (isValid) {
setShow(true);
} else {}
}
};
const onSubmit2 = () => {
verifyOTP(OTP)
.then((resp) => {
alert("OTP verification Successful");
setPostVerificationMessage(<p className="text-danger">OTP verification Successful</p>);
setVerifyOTPFlag(false);
setOtpVerificationResult(true);
setShowOtpInput(false);
})
.catch((error) => {
setPostVerificationMessage(<p className="text-danger"> OTP verification Failed. Kindly enter the correct OTP</p> )
setOtpVerificationResult(true);
});};
const onClickEditMobileNo = () => {
setShowOtpInput(!otpInput);
setOtpVerificationResult("");
setOTP("");
setMobileNumberInput(true);
};
return (
<div>
<div className="form-group">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="container mt-2">
<label className="control-label">Full Name : </label>
<input
className="text-uppercase input-group input-group-lg form-control"
type="text"
name="username"
{...register("username", {
required: "Username is Required",
pattern: {
value: /^[a-zA-Z0-9\s,\'-\/:&]*$/,
message: "Entered value does not match valid name format",
},
})}
/>
<p className="errorMsg">{errors.username?.message}</p>
<label className="control-label">C/o : </label>
<input
className="text-uppercase input-group input-group-lg form-control"
type="text"
name="careof"
{...register("careof", {
required: "Name of c/o is Required",
pattern: {
value: /^[a-zA-Z0-9\s,\'-\/:&]*$/,
message: "Entered value does not match valid name format",
},
})}
/>
<p className="errorMsg">{errors.careof?.message}</p>
<label className="control-label">House No./Bldg./Apt : </label>
<input
className="text-uppercase input-group input-group-lg form-control"
type="text"
name="houseno"
{...register("houseno", {
required: "House number is Required",
})}
/>
<p className="errorMsg">{errors.houseno?.message}</p>
<div className="text-center">
<button
className="button btn-primary btn px-3 mr-1"
onClick={onSubmit}
>
Form Submit
</button>
</div>
</div>
</form>
<form onSubmit={handleSubmit2(onSubmit2)}>
{/* modal starts */}
<Modal show={show} onHide={handleClose} backdrop="static">
<Modal.Header
style={{
backgroundImage: "linear-gradient(180deg , #3f55c4 , #95a4f0",
}}
closeButton></Modal.Header>
<Collapse in={mobileNumberInput}>
<div
className="input-field-sb mt-4 ml-5"
style={{ width: "80%" }}
>
<input className="input-sb" maxLength="10" type="text" id="mobile"
// onChange={(e) => setNumber(e.target.value)}
{...register2("mobile", {
required: "Mobile number is Required",
pattern: {
value: /^[5-9]\d{9}$/,
message: "Entered value does not match valid name format",
},
onChange: (e) => setNumber(e.target.value),})}/>
<p className="errorMsg">{errors2.mobile?.message}</p>
<label className="label-sb" htmlFor="mobile">Enter Mobile Number: </label>
</div>
</Collapse>
<Modal.Body>
<Collapse in={otpInput}>
<div>
<div className="d-flex justify-content-center">
<p className="text-center"><strong>{" "} We sent you a code to verify your mobile number{" "}</strong>{" "}
<b className="text-danger">{number}</b>
<span className="mobile-text"> Enter your OTP code here</span>
</p>
</div>
<input className="input-sbj" maxLength="6" onChange={(e) => setOTP(e.target.value)}/>
</div>
</Collapse>
<Collapse in={otpVerificationResult}>
<div className="text-center">{postVerificationMessage}</div>
</Collapse>
<div className="d-flex justify-content-center col-md-12">
{otpInput ? (
<Button className="px-5 align-middle mt-4" variant="secondary" onClick={onSubmit2}>{" "} Verify</Button>) : (
<Button className="px-5 align-middle mt-4" variant="secondary"
onClick={errors2.mobile ? null : showOtpInput}>
{" "} Send OTP </Button>)}
</div>
<div className="row">
<div className={otpInput ? "col-sm-6" : "col-sm-6 d-none"}>
<a className="btn">Resend OTP in 00:{counter}</a>
</div>
<div
className={otpInput? "text-right col-sm-6": "text-right col-sm-6 d-none"}>
<a className="btn" onClick={onClickEditMobileNo}> Edit Mobile number </a>
</div>
</div>
</Modal.Body>
</Modal>
</form>
{/* modal ends */}
</div></div>);}
The easiest way would be just adding e.target.reset() in your onSubmit function.
const onSubmit = (data, e) => {
data["district"] = districtName;
data["state"] = stateName;
setMobileNumberInput(true);
setPostVerificationMessage("");
setNumber("");
e.target.reset();
if (verifyOTPFlag) {
if (isValid) {
setShow(true);
} else {}
}
};
also keep the setNumber("") like this. I think this will solve the problem.

How to clear the Modal states after closing it or before opening it again

After giving the input of mobile number when i close the modal, then again after clicking the Form Submit button, input box shows the previously entered number. I believe model captures the previous state by itself and i want to clear it whenever we open the modal.
After entering the OTP input in Modal, if we click on the Edit mobile number and when we again enter the input in mobile number, then previously entered OTP also shows up. I want to clear it after entering the new mobile number.
I have already tried setting the state to ("") on the onclick events but it doesn't help.
I could really use some help.
codesandbox
Code:
export default function Form() {
const {register,handleSubmit, formState: { errors, isValid },} = useForm({mode: "onChange",criteriaMode: "all",});
const {register: register2,handleSubmit: handleSubmit2,formState: { errors: errors2 },} = useForm({mode: "onChange",});
const [verifyOTPFlag, setVerifyOTPFlag] = useState(true);
//modal hooks
const [mobileNumberInput, setMobileNumberInput] = useState(true);
const [postVerificationMessage, setPostVerificationMessage] = useState();
const [otpVerificationResult, setOtpVerificationResult] = useState(false);
const [show, setShow] = useState(false);
const [otpInput, setShowOtpInput] = useState(false);
const [number, setNumber] = useState("");
const [OTP, setOTP] = useState("");
const [counter, setCounter] = useState(59);
// post office and aadhar hooks
const [districtName, setDistrictName] = React.useState("");
const [stateName, setStateName] = React.useState("");
//-------------------------modal functionalities start-------------------------
const handleClose = () => {
setShow(false);
setShowOtpInput(false);};
const handleShow = () => {
setShow(true);};
const showOtpInput = () => {
getOTP(number);
setOTP("");
setShowOtpInput(true);
setMobileNumberInput(false);
setOtpVerificationResult(false);
};
const onSubmit = (data) => {
data["district"] = districtName;
data["state"] = stateName;
setMobileNumberInput(true);
setPostVerificationMessage("");
setNumber("");
if (verifyOTPFlag) {
if (isValid) {
setShow(true);
} else {}
}
};
const onSubmit2 = () => {
verifyOTP(OTP)
.then((resp) => {
alert("OTP verification Successful");
setPostVerificationMessage(<p className="text-danger">OTP verification Successful</p>);
setVerifyOTPFlag(false);
setOtpVerificationResult(true);
setShowOtpInput(false);
})
.catch((error) => {
setPostVerificationMessage(<p className="text-danger"> OTP verification Failed. Kindly enter the correct OTP</p> )
setOtpVerificationResult(true);
});};
const onClickEditMobileNo = () => {
setShowOtpInput(!otpInput);
setOtpVerificationResult("");
setOTP("");
setMobileNumberInput(true);
};
return (
<div>
<div className="form-group">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="container mt-2">
<label className="control-label">Full Name : </label>
<input
className="text-uppercase input-group input-group-lg form-control"
type="text"
name="username"
{...register("username", {
required: "Username is Required",
pattern: {
value: /^[a-zA-Z0-9\s,\'-\/:&]*$/,
message: "Entered value does not match valid name format",
},
})}
/>
<p className="errorMsg">{errors.username?.message}</p>
<label className="control-label">C/o : </label>
<input
className="text-uppercase input-group input-group-lg form-control"
type="text"
name="careof"
{...register("careof", {
required: "Name of c/o is Required",
pattern: {
value: /^[a-zA-Z0-9\s,\'-\/:&]*$/,
message: "Entered value does not match valid name format",
},
})}
/>
<p className="errorMsg">{errors.careof?.message}</p>
<label className="control-label">House No./Bldg./Apt : </label>
<input
className="text-uppercase input-group input-group-lg form-control"
type="text"
name="houseno"
{...register("houseno", {
required: "House number is Required",
})}
/>
<p className="errorMsg">{errors.houseno?.message}</p>
<div className="text-center">
<button
className="button btn-primary btn px-3 mr-1"
onClick={onSubmit}
>
Form Submit
</button>
</div>
</div>
</form>
<form onSubmit={handleSubmit2(onSubmit2)}>
{/* modal starts */}
<Modal show={show} onHide={handleClose} backdrop="static">
<Modal.Header
style={{
backgroundImage: "linear-gradient(180deg , #3f55c4 , #95a4f0",
}}
closeButton></Modal.Header>
<Collapse in={mobileNumberInput}>
<div
className="input-field-sb mt-4 ml-5"
style={{ width: "80%" }}
>
<input className="input-sb" maxLength="10" type="text" id="mobile"
// onChange={(e) => setNumber(e.target.value)}
{...register2("mobile", {
required: "Mobile number is Required",
pattern: {
value: /^[5-9]\d{9}$/,
message: "Entered value does not match valid name format",
},
onChange: (e) => setNumber(e.target.value),})}/>
<p className="errorMsg">{errors2.mobile?.message}</p>
<label className="label-sb" htmlFor="mobile">Enter Mobile Number: </label>
</div>
</Collapse>
<Modal.Body>
<Collapse in={otpInput}>
<div>
<div className="d-flex justify-content-center">
<p className="text-center"><strong>{" "} We sent you a code to verify your mobile number{" "}</strong>{" "}
<b className="text-danger">{number}</b>
<span className="mobile-text"> Enter your OTP code here</span>
</p>
</div>
<input className="input-sbj" maxLength="6" onChange={(e) => setOTP(e.target.value)}/>
</div>
</Collapse>
<Collapse in={otpVerificationResult}>
<div className="text-center">{postVerificationMessage}</div>
</Collapse>
<div className="d-flex justify-content-center col-md-12">
{otpInput ? (
<Button className="px-5 align-middle mt-4" variant="secondary" onClick={onSubmit2}>{" "} Verify</Button>) : (
<Button className="px-5 align-middle mt-4" variant="secondary"
onClick={errors2.mobile ? null : showOtpInput}>
{" "} Send OTP </Button>)}
</div>
<div className="row">
<div className={otpInput ? "col-sm-6" : "col-sm-6 d-none"}>
<a className="btn">Resend OTP in 00:{counter}</a>
</div>
<div
className={otpInput? "text-right col-sm-6": "text-right col-sm-6 d-none"}>
<a className="btn" onClick={onClickEditMobileNo}> Edit Mobile number </a>
</div>
</div>
</Modal.Body>
</Modal>
</form>
{/* modal ends */}
</div></div>)
;}
when applying modal, generally you can use this approach.
when you submit, clear your modal fields states so it will be like it opened for the first time when you open it again.
you can do this for when you toggle or close.
this will mean that whenever you open the modal next time it will open with clean (empty or default) data.

Trying to switch between modal components using React

So I have a start page that gives options to open a login modal or sign up modal. However, once you are in the login modal I give an option so you can switch to sign up modal. However, I can't seem to get this to work. The one time I got it to work, the modal showed up in the wrong section of the screen since it was being opened in relation to the login modal and not the start page.
I am new to React so any insight would be appreciated. Should I use redux, since I can't pass props from child to parent. So that way when I return to start page I can rerender with info saying that I had clicked sign-up link on the login modal.
function LoginContent(props) {
const [ open, setOpen ] = useState(false)
const { show, closeModal } = props;
function handleSubmit(e){
e.preventDefault();
}
function handleSignUpButton(){
closeModal();
console.log(open)
setOpen(!false)
console.log(open)
}
//added so that the component doesn't get affected by parent css
//and is being rendered from the "modal-root" DOM node from the index.html file
return ReactDOM.createPortal(
<>
<div className={show ? "overlay" : "hide"} onClick={closeModal} />
<div className={show ? "modal" : "hide"}>
<button onClick={closeModal} id="close">X</button>
<div className="login_form">
<h1> Log in to Continue </h1>
<form onSubmit={handleSubmit}>
<input className="username" type='text' name='username' placeholder='Email Address' />
<input className="password" type='password' name='password' placeholder='password' />
<button className="login_button"> Sign In</button>
</form>
</div>
<div className="login_demo">
<h3 className="login_demo_pointer" type="submit">Demo Login</h3>
</div>
<hr />
<div className="login_switch">Don't have an account.
<button className="signup_link" onClick={handleSignUpButton}>Sign Up</button>
{open && <SignUpContent open={open} closeModal={closeModal} show={show} />} </div>
</div>
</>, document.getElementById("modal-root")
);
}
function Start() {
const history = useHistory();
const [showLogin, setLogin ] = useState(false);
const openModalLogin = () => setLogin(true);
const closeModalLogin = () => setLogin(false);
const [showSignUp, setShow ] = useState(false);
const openModalSignUp = () => setShow(true);
const closeModalSignUp = () => setShow(false);
return (
<div className="bodyStart">
<img src="https://i.imgur.com/5gjRSmB.gif" alt="" id="bg" />
<div className="start_logo">
<img src={require("../styling/logo.png")} alt="" onClick={() => {
history.push('/home')
history.go(0)}} className="logo" />
</div>
<div className="start">
<div className="start_heading">
<h2>Mother Nature is Calling.</h2>
<h4>Find a place to recharge and escape the day to day.</h4>
</div>
<div className="start_location">
<p>Where?</p>
<div className="start_input">
<input type="text" placeholder="anywhere" />
<ArrowForwardIcon onClick={() => {
history.push('/search')
history.go(0)}}
className="arrow" fontSize="large"/>
</div>
</div>
<div className="start_authentication">
<Button className="login"
variant="contained"
color="primary"
size="large"
onClick={() => openModalLogin()}> Login </Button>
{showLogin && <LoginContent closeModal={closeModalLogin} show={showLogin} />}
<Button className="signup"
variant="contained"
size="large"
onClick={()=> openModalSignUp()}> Sign-Up </Button>
{showSignUp && <SignUpContent closeModal={closeModalSignUp} show={showSignUp} />}
</div>
</div>
</div>
)
}
I have made similar modals with Material-UI. You can change loginOpen state and signupOpen states in modals. See codepen below
Codepen
const { useState } = React;
const { Button, Dialog, DialogTitle, DialogContent, DialogActions } = MaterialUI;
function LoginDialog(props) {
const { open, setLoginOpen, setSignupOpen } = props;
const switchSignup = (event) => {
setLoginOpen(false)
setSignupOpen(true)
}
return (
<Dialog aria-labelledby="simple-dialog-title" open={open}>
<DialogTitle id="simple-dialog-title">LOGIN</DialogTitle>
<DialogContent>If you don't have an account, press SIGNUP</DialogContent>
<DialogActions>
<Button onClick={(event) => {setLoginOpen(false)}}>CLOSE</Button>
<Button>LOGIN</Button>
<Button onClick={switchSignup}>SIGNUP</Button>
</DialogActions>
</Dialog>
);
}
function SignupDialog(props) {
const { open, setLoginOpen, setSignupOpen } = props;
const switchLogin = (event) => {
setSignupOpen(false)
setLoginOpen(true)
}
return (
<Dialog aria-labelledby="simple-dialog-title" open={open}>
<DialogTitle id="simple-dialog-title">SIGNUP</DialogTitle>
<DialogContent>If you have an account, press LOGIN</DialogContent>
<DialogActions>
<Button onClick={(event) => {setSignupOpen(false)}}>CLOSE</Button>
<Button>SIGNUP</Button>
<Button onClick={switchLogin}>LOGIN</Button>
</DialogActions>
</Dialog>
);
}
const App = () => {
const [loginOpen, setLoginOpen] = useState(false)
const [signupOpen, setSignupOpen] = useState(false)
const handleLogin = (event) => {
setLoginOpen(true)
}
const handleSignup = (event) => {
setSignupOpen(true)
}
return (
<div>
<Button variant='contained' color='primary' onClick={handleLogin} >
LOGIN
</Button>
<Button variant='outlined' color='primary' onClick={handleSignup} >
SIGNUP
</Button>
<LoginDialog open={loginOpen} setLoginOpen={setLoginOpen} setSignupOpen={setSignupOpen} />
<SignupDialog open={signupOpen} setLoginOpen={setLoginOpen} setSignupOpen={setSignupOpen} />
</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"));

Categories

Resources