My code keeps bringing torusPlugin is assigned a value but never used, LoggedInView is assigned a value but never used and I don't know where I went wrong. I have checked the code and the torusPlugin function was used, same with the loggedInView.
import { useEffect, useState } from "react";
import { Card, Form } from "react-bootstrap";
import { FaComment, FaRecycle, FaRetweet, FaThumbsUp } from "react-icons/fa";
import { Web3AuthCore } from "#web3auth/core";
import {
WALLET_ADAPTERS,
CHAIN_NAMESPACES,
SafeEventEmitterProvider,
} from "#web3auth/base";
import { OpenloginAdapter } from "#web3auth/openlogin-adapter";
import { TorusWalletConnectorPlugin } from "#web3auth/torus-wallet-connector-plugin";
import Twitter from "./twitter";
import RPC from "./evm";
import { APP_CONSTANTS } from "./constants";
import "./App.css";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
const clientId = APP_CONSTANTS.CLIENT_ID; // get from https://dashboard.web3auth.io
function App() {
const [web3auth, setWeb3auth] = useState<Web3AuthCore | null>(null);
const [provider, setProvider] = useState<SafeEventEmitterProvider | null>(
null
);
const [tweets, setTweets] = useState<Array<any> | null>(null);
const [comment, setComment] = useState<string | "">("");
const [userName, setUserName] = useState<string | "">("");
const [profileImage, setProfileImage] = useState<string | "">("");
const [newTweetName, setNewTweetName] = useState<string | "">("");
const [newTweetDescription, setNewTweetDescription] = useState<string | "">(
""
);
const refreshTime = APP_CONSTANTS.REACT_APP_REFRESH_TIMER * 1000
const [torusPlugin, setTorusPlugin] =
useState<TorusWalletConnectorPlugin | null>(null);
useEffect(() => {
const init = async () => {
try {
const web3auth = new Web3AuthCore({
clientId,
chainConfig: {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x13881",
rpcTarget: APP_CONSTANTS.RPC_TARGET, // This is the mainnet RPC we have added, please pass on your own endpoint while creating an app
},
});
const openloginAdapter = new OpenloginAdapter({
adapterSettings: {
clientId,
network: "testnet",
uxMode: "popup",
whiteLabel: {
name: "Twitter DApp",
logoLight: APP_CONSTANTS.APP_LOGO,
logoDark: APP_CONSTANTS.APP_LOGO,
defaultLanguage: "en",
dark: true, // whether to enable dark mode. defaultValue: false
},
loginConfig: {
// Add login configs corresponding to the providers on modal
// Twitter login
jwt: {
name: "Custom Auth Login",
verifier: APP_CONSTANTS.ADAPTER_TWITTER_CLIENT_VERIFIER, // Please create a verifier on the developer dashboard and pass the name here
typeOfLogin: "twitter", // Pass on the login provider of the verifier you've created
clientId: APP_CONSTANTS.ADAPTER_TWITTER_CLIENT_ID, // Pass on the clientId of the login provider here - Please note this differs from the Web3Auth ClientID. This is the JWT Client ID
},
// Add other login providers here
},
},
});
const torusPlugin = new TorusWalletConnectorPlugin({
torusWalletOpts: {},
walletInitOptions: {
whiteLabel: {
theme: { isDark: true, colors: { primary: "#ffffff" } },
logoDark:
"https://i.ibb.co/kDNCfC9/reshot-icon-wallet-9-H3-QMSDLFR.png",
logoLight:
"https://i.ibb.co/kDNCfC9/reshot-icon-wallet-9-H3-QMSDLFR.png",
},
useWalletConnect: true,
enableLogging: true,
},
});
await web3auth.addPlugin(torusPlugin);
setTorusPlugin(torusPlugin);
await web3auth.configureAdapter(openloginAdapter);
setWeb3auth(web3auth);
await web3auth.init();
if (web3auth.provider) {
await setProvider(web3auth.provider);
let user = await web3auth.getUserInfo();
console.log('user ', user)
if(user.name && user.name !== null && user.name !== " " && user.name !== "")
setUserName(user.name)
if(user.profileImage && user.profileImage !== null && user.profileImage !== " " && user.profileImage !== "")
setProfileImage(user.profileImage)
}
await fetchAllTweets();
//eslint-disable-next-line react-hooks/exhaustive-deps
} catch (error) {
console.error(error);
}
};
init();
}, []);
const logout = async () => {
if (!web3auth) {
console.log("web3auth not initialized yet");
return;
}
await web3auth.logout();
setProvider(null);
};
const login = async () => {
if (!web3auth) {
console.log("web3auth not initialized yet");
return;
}
const web3authProvider = await web3auth.connectTo(
WALLET_ADAPTERS.OPENLOGIN,
{
loginProvider: "jwt",
extraLoginOptions: {
domain: APP_CONSTANTS.AUTH0_DOMAIN, // Please append "https://" before your domain
verifierIdField: "sub",
},
}
);
setProvider(web3authProvider);
if(web3authProvider){
let user = await web3auth.getUserInfo();
if(user.name && user.name !== null && user.name !== " " && user.name !== "")
setUserName(user.name)
if(user.profileImage && user.profileImage !== null && user.profileImage !== " " && user.profileImage !== "")
setProfileImage(user.profileImage)
}
};
/*
const getAccounts = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const rpc = new RPC(provider);
const userAccount = await rpc.getAccounts();
return userAccount;
};
*/
const refresh = (e: any) => {
e.preventDefault();
fetchAllTweets();
};
const fetchAllTweets = async () => {
console.log("fetchalltweetsrunning");
if (!provider) {
console.log("provider not initialized yet");
return;
}
const rpc = new RPC(provider);
try {
let fetchedTweets = await rpc.getAllTweets();
let tweets = [...fetchedTweets];
setTweets(tweets.reverse());
} catch (error) {
console.log("error in fetching tweets", error);
}
};
const upVote = async (tweetIndex: any) => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
try {
const rpc = new RPC(provider);
await rpc.sendUpVoteTransaction(tweetIndex);
fetchAllTweets();
} catch (error) {
console.log("failed to execute upvote transaction", error);
}
};
const addNewTweet = (e: any) => {
e.preventDefault();
if (!provider) {
console.log("provider not initialized yet");
return;
}
try {
const rpc = new RPC(provider);
toast.success("Tweet added successfully", {
position: toast.POSITION.TOP_CENTER,
});
rpc.sendWriteTweetTransaction(newTweetName, newTweetDescription);
setTimeout(function () {
fetchAllTweets();
}, refreshTime);
fetchAllTweets();
} catch (error) {
toast.error("Something went wrong", {
position: toast.POSITION.TOP_LEFT,
});
console.log("failed to execute new tweet transaction", error);
}
};
const addComment = async (event: any, tweetIndex: any) => {
event.preventDefault();
if (!provider) {
console.log("provider not initialized yet");
return;
}
try {
const rpc = new RPC(provider);
toast.success("Comment added successfully - refresh after 30 sec", {
position: toast.POSITION.TOP_CENTER,
});
await rpc.sendAddCommentTransaction(tweetIndex, comment);
fetchAllTweets();
} catch (error) {
toast.error("Something went wrong", {
position: toast.POSITION.TOP_LEFT,
});
console.log("failed to execute add comment transaction", error);
}
};
// Event handlers
const handleCommentChange = async (event: any) => {
setComment(event.target.value);
};
const handleNewTweetNameChange = async (event: any) => {
setNewTweetName(event.target.value);
};
const handleNewTweetDescriptionChange = async (event: any) => {
setNewTweetDescription(event.target.value);
};
const loggedInView = (
<>
<button className="button" onClick={logout}>
Logout
</button>
<div>
<h1>New Tweet</h1>
<Card>
<Card.Body>
<Card.Title>What are you thinking? Tweet it out!</Card.Title>
<Card.Text></Card.Text>
<Form.Control
as="input"
onChange={handleNewTweetNameChange}
placeholder="Tweet Name"
/>
<br></br>
<br></br>
<Form.Control
as="textarea"
onChange={handleNewTweetDescriptionChange}
placeholder="Description"
/>
<br></br>
<FaRetweet onClick={addNewTweet} />
</Card.Body>
</Card>
</div>
<div>
<h1>
All Tweets <FaRecycle onClick={fetchAllTweets} />
</h1>
{(tweets || []).map((tweet: any, i) => (
<div key={i}>
<div>
<Card>
<Card.Body>
<Card.Title>
<FaThumbsUp onClick={(event) => upVote(i)} /> {tweet.name}
</Card.Title>
<p>Total Upvotes: {tweet.upvotes}</p>
<p>Tweeted by: {tweet.fromAddress}</p>
<Card.Text>{tweet.description}</Card.Text>
<div>
<h3>All Comments</h3>
{tweet.comments.map((comment: any, j: any) => (
<div key={j}>
Comment {j + 1}: {comment}
</div>
))}
<h3>New Comment</h3>
<span>
<Form.Control
as="input"
onChange={handleCommentChange}
placeholder="Your comment..."
/>
</span>
<span>
<FaComment onClick={(event) => addComment(event, i)} />
</span>
</div>
</Card.Body>
<a
href={
APP_CONSTANTS.OPENSEA_ASSETS_URL +
"/" +
APP_CONSTANTS.CONTRACT_ADDRESS +
"/" +
i
}
rel="opener"
>
Buy Now
</a>
</Card>
</div>
</div>
))}
</div>
<div></div>
<div id="console" style={{ whiteSpace: "pre-line" }}>
<p style={{ whiteSpace: "pre-line" }}></p>
</div>
</>
);
const unloggedInView = (
<>
<div className="login-account">
<button className="twitter-bg btn" onClick={login}>
<img src="images/twitter-white.png" alt=""></img>
Login to your Twitter account
</button>
</div>
</>
);
return (
<div className="grid">
{provider ? (
<Twitter
logoutButton={logout}
handleNewTweetDescriptionChange={handleNewTweetDescriptionChange}
handleNewTweetNameChange={handleNewTweetNameChange}
addNewTweet={addNewTweet}
fetchAllTweets={fetchAllTweets}
tweets={tweets}
upVote={upVote}
handleCommentChange={handleCommentChange}
addComment={addComment}
refresh={refresh}
username={userName}
profileimage={profileImage}
/>
) : (
unloggedInView
)}{" "}
<ToastContainer />
</div>
// <div className="grid">{provider
// ? loggedInView
// : unloggedInView}</div>
// {/* <div className="grid">{loggedInView}</div> */}
);
}
export default App;
enter image description here
this is a screenshot of my code terminal
You are actually not using torusPlugin (line 38 screenshot) anywhere. Inside your useEffect you created a new const torusPlugin and then you are calling that const instead of the [torusPlugin, ...] state you declared on line 38 of the screenshot. Try to differentiate your variables / constants names otherwise would be difficult for you to identify mistakes.
Related
Good morning. I am trying to integrate PayPal check out in my React app. Everything works fine except that the Paypal Checkout amount is not showing the same as the total cart amount. Checkout amount is fixed at $0.01 and not changing as cart amount changes. Please what could i be doing wrong ??? This is the code
#cart.js code
import React, { useContext, useState, useEffect } from "react";
import { GlobalState } from "../../../GlobalState";
import axios from "axios";
import PayPalButton from "./PaypalButton";
function Cart() {
const state = useContext(GlobalState);
const [cart, setCart] = state.userAPI.cart;
const [token] = state.token;
const [total, setTotal] = useState(0);
useEffect(() => {
const getTotal = () => {
const total = cart.reduce((prev, item) => {
return prev + item.price * item.quantity;
}, 0);
setTotal(total);
};
getTotal();
}, [cart]);
const addToCart = async () => {
await axios.patch(
"/user/addcart",
{ cart },
{
headers: { Authorization: token },
}
);
};
const increment = (id) => {
cart.forEach((item) => {
if (item._id === id) {
item.quantity += 1;
}
});
setCart([...cart]);
addToCart();
};
const decrement = (id) => {
cart.forEach((item) => {
if (item._id === id) {
item.quantity === 1 ? (item.quantity = 1) : (item.quantity -= 1);
}
});
setCart([...cart]);
addToCart();
};
const removeProduct = (id) => {
if (window.confirm("Do you want to delete this product?")) {
cart.forEach((item, index) => {
if (item._id === id) {
cart.splice(index, 1);
}
});
setCart([...cart]);
addToCart();
}
};
const tranSuccess = async (payment) => {
console.log(payment);
};
if (cart.length === 0)
return (
<h2 style={{ textAlign: "center", fontSize: "5rem" }}>Cart Empty</h2>
);
return (
<div>
{cart.map((product) => (
<div className="detail cart" key={product._id}>
<img src={product.images.url} alt="" />
<div className="box-detail">
<h2>{product.title}</h2>
<h3>${product.price * product.quantity}</h3>
<p>{product.description}</p>
<p>{product.content}</p>
<div className="amount">
<button onClick={() => decrement(product._id)}> - </button>
<span>{product.quantity}</span>
<button onClick={() => increment(product._id)}> + </button>
</div>
<div className="delete" onClick={() => removeProduct(product._id)}>
X
</div>
</div>
</div>
))}
<div className="total">
<h3>Total: $ {total}</h3>
<PayPalButton total={total} tranSuccess={tranSuccess} />
</div>
</div>
);
}
export default Cart;
PayPal button code
import React from "react";
import { PayPalScriptProvider, PayPalButtons } from "#paypal/react-paypal-js";
export default class PayPalButton extends React.Component {
render() {
const onSuccess = (payment) => {
console.log("The payment was succeeded!", payment);
this.props.tranSuccess(payment);
};
const onCancel = (data) => {
console.log("The payment was cancelled!", data);
};
const onError = (err) => {
console.log("Error!", err);
};
let env = "sandbox"; // you can set here to 'production' for production
let total = this.props.total;
let currency = "USD";
const client = {
sandbox:
"ARhnfWu_QrcGQa-PdvaY1RVriEmqGiSkfEWf-plauZQpQN_gyxaLjH9RXOhdQw7fxxxxxxxxxxxx",
production: "YOUR-PRODUCTION-APP-ID",
};
let style = {
size: "small",
color: "blue",
shape: "rect",
label: "checkout",
tagline: false,
};
return (
<PayPalScriptProvider
options={{
"client-id": "ARhnfWu_QrcGQa-PdvaY1RVriEmqGiSkfEWf-plauZQpQN_gyxaLjH9RXOhdQw7fxxxxxxxxxxxx",
}}
>
<PayPalButtons
env={env}
client={client}
commit={true}
total={total}
currency={currency}
onError={onError}
onSuccess={onSuccess}
onCancel={onCancel}
style={style}
/>
</PayPalScriptProvider>
);
}
}
I don't see a createOrder function anywhere. You need one, and it needs to invoke actions.order.create() with a JSON object that uses your total to set the amount.
See examples in the react-paypal-js storybook.
I am having issues trying to focus on a previous input once I delete out of the input that I am in. I have 6 inputs, all with a maxLength of 1. When I press the backspace key I would like to delete the value and move to the previous input. I have tried a variety of things but nothing seems to work how I need.
Here is my code
This is the Auth component which is passing props to verify (the page with the inputs)
const Auth = ({ sub }) => {
let params = useParams();
const navigate = useNavigate();
const [rec, setRec] = useState({
accept: false,
email: '',
phone: '',
pin: ['', '', '', '', '', '']
})
const onPaste = (event) => {
event.preventDefault()
const pasted = event.clipboardData.getData("text/plain")
setRec({ ...rec, pin: pasted.split("").slice(0, rec.pin.length) })
// target event last sibling
event.target.parentNode.lastChild.focus()
}
function update(event, index) {
event.preventDefault()
setRec({
...rec, pin: [
...rec.pin.slice(0, index),
event.target.value,
...rec.pin.slice(index + 1)
]
})
}
const handleFocus = (event) => {
if (event.target.nextSibling)
event.target.nextSibling.focus();
// if value is deleted, focus previous sibling
// if all siblings are empty, focus first sibling
if (event.target.value === '' && event.target.previousSibling === null)
event.target.parentNode.firstChild.focus()
}
const onKeyPress = (event) => {
// if backspace is clicked, go to previous input
if (event.key === 'Backspace' && event.target.value === '') {
event.target.previousSibling.focus()
}
}
const handleChange = (name, value) => {
if (name === 'mobile') name = 'phone'
const recState = {
...rec,
[name]: value,
}
setRec(recState)
}
const toggleAccept = () => {
if (!rec.accept) {
setRec({
...rec,
accept: true
});
} else {
setRec({
...rec,
accept: false
});
}
}
const handleSubmit = async () => {
const { accept, email, phone } = rec
if (params.method === 'email' && !email) return app.actions.setError('Enter an email')
else if (params.method !== 'email' && !phone) return app.actions.setError('Enter a phone number')
const send = params.method === 'email' ? { email } : { phone }
if (!accept) return app.actions.setError('Please accept the terms & conditions')
try {
await app.actions.setLoading(true)
// if there is already a user, just login, else create user first
await user.actions.login(send)
await app.actions.setLoading(false)
navigate(`/auth/verify/login/${params.method || 'phone'}`)
} catch (e) {
if (e.response && e.response.status === 404) {
// try join
await user.actions.join(send)
await app.actions.setLoading(false)
return navigate(`/auth/verify/join/${params.method || 'phone'}`)
}
await app.actions.setLoading(false)
await app.actions.setError(e)
}
}
const handleVerify = async ({ context, method }) => {
const { email, phone, pin } = rec
const joinPin = pin.join('');
if (method === 'email' && !email) return app.actions.setError('Enter an email')
else if (method !== 'email' && !phone) return app.actions.setError('Enter a phone number')
const send = method === 'email' ? { email } : { phone }
await app.actions.setError(null)
try {
await app.actions.setLoading(true)
if (context === 'login') {
await user.actions.loginVerify({
...send,
pin: joinPin,
})
} else {
await user.actions.verify({
...send,
pin: joinPin,
})
}
await app.actions.init()
await app.actions.setLoading(false)
navigate('/')
} catch (e) {
await app.actions.setLoading(false)
await app.actions.setError(e)
}
}
return (
<>
{sub ?
<Verify
context={params.context}
handleChange={handleChange}
handleFocus={handleFocus}
handleSubmit={() => handleVerify({ context: params.context, method: params.method })}
onKeyPress={onKeyPress}
method={params.method}
paste={onPaste}
update={update}
rec={rec} />
:
<Jogin
handleChange={handleChange}
handleSubmit={handleSubmit}
method={params.method}
toggleAccept={toggleAccept}
rec={rec} />
}
</>
)
}
export default Auth
and here is the verify component
import React from 'react'
import { onFormSubmit } from '../../utility/form'
import { Navigate, useNavigate } from 'react-router-dom'
import user from '../../model/user'
import app from '../../model/app'
const Verify = ({ handleSubmit, method, rec, paste, update, handleFocus, onKeyPress }) => {
const navigate = useNavigate();
const { email, phone } = rec
const send = method === 'email' ? { email: email } : { phone: phone }
const resendPin = async () => {
try {
await app.actions.setLoading(true)
// if there is already a user, just login, else create user first
await user.actions.login(send)
await app.actions.setLoading(false)
navigate(`/auth/verify/login/${method || 'phone'}`)
} catch (e) {
if (e.response && e.response.status === 404) {
// try join
await user.actions.join(send)
await app.actions.setLoading(false)
return navigate(`/auth/verify/join/${method || 'phone'}`)
}
await app.actions.setLoading(false)
await app.actions.setError(e)
}
}
const renderContent = () => {
const methodLabel = method === 'email' ? 'email address' : 'phone number'
return (
<>
<div id="back-grad" />
<div className="col-md-8">
<div className='verify-text-section'>
<p className="verify-text pb-5">
Enter the PIN number we just sent to your {methodLabel}.
</p>
</div>
<div className="flex">
{rec.pin.map((s, key) => (
<input key={key} className='code-input mr-2' value={s} maxLength='1' onPaste={(e) => paste(e)} onKeyDown={e => onKeyPress(e)} onInput={(e) => update(e, key)} onChange={(e) => handleFocus(e)} inputMode='numeric' autoFocus={key === 0} />
))}
</div>
<div className="verify-resend mt-3" onClick={resendPin}>Resend Code</div>
<div className="flex margin-set text-center">
<button className="btn btn-block text-white verify-btn">
<p className="verify-btn-text">VERIFY</p>
</button>
</div>
</div>
</>
)
}
return (
<>
{rec.email.length < 1 && rec.phone.length < 1 ? <Navigate to={'/auth'} />
:
<div className="d-flex align-items-center h-full">
<form className="container" onSubmit={e => onFormSubmit(e, handleSubmit)}>
<div className="row justify-content-center">
{renderContent()}
</div>
</form>
</div>
}
</>
)
}
export default Verify
any help is appreciated!
In ReactJs it works well.
import React, { useState, useEffect } from "react";
import { Snackbar } from "#material-ui/core";
import axios from "axios";
import { withTranslation } from "../../i18n";
import MuiAlert from "#material-ui/lab/Alert";
import sha512 from "crypto-js/sha512";
import { LoginEmailIn, LoginEmailOut } from "../../Types";
import { getTempUserUuid } from "../../util/Utility";
//import ReactPixel from "react-facebook-pixel";
import styles from "../../styles/LoginAndRegistration.module.css";
import {BEUrl} from "../../util/Utility"
function Alert(props: any) {
return <MuiAlert elevation={6} variant="filled" {...props} />;
}
function LoginWithEmail({ t },props: {
eventId: string;
trackUserInteractions:boolean;
eventName: string;
setLogin: (a:boolean)=> void;
}) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [alertOpen, setAlertOpen] = useState(false);
const [alertMessage, setAlertMessage] = useState("");
const [alertType, setAlertType] = useState("error");
const alertClose = (event: any, reason: any) => {
if (reason === "clickaway") {
return;
}
setAlertOpen(false);
};
const checkEmail = () => {
const regex = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (email === "") {
setAlertType("error");
setAlertMessage(t("Please enter your registered e-mail address"));
setAlertOpen(true);
return false;
} else if (!regex.test(email)) {
setAlertType("error");
setAlertMessage(t("The entered e-mail address is not valid"));
setAlertOpen(true);
return false;
} else return true;
};
const checkPassword = () => {
if (password === "") {
setAlertType("error");
setAlertMessage(t("Please enter your password"));
setAlertOpen(true);
return false;
} else return true;
};
const loginButtonPressed = () => {
if (checkEmail() && checkPassword()) {
const loginData: LoginEmailIn = {
email: email,
passwordHash: sha512(password).toString(),
tempUserId: getTempUserUuid(),
};
let url = BEUrl + "loginEmail";
axios({
method: "post",
url: url,
data: loginData,
headers: { "Content-Type": "application/json", crossDomain: true },
})
.then((resp: any) => {
const data: LoginEmailOut = resp.data;
if (!data.error) {
setAlertType("success");
setAlertMessage(t(`Successful login, Welcome ${data.userName!}`));
setAlertOpen(true);
localStorage.setItem("isRegistrationHappened", "true");
localStorage.setItem("userNameLoggedIn", data.userName!);
localStorage.setItem("jwt", data.jwt!);
setTimeout(function () {
window.location.reload();
}, 1200);
} else {
setAlertType("error");
setAlertMessage(t(`${data.error}`));
setAlertOpen(true);
}
})
.catch((error) => console.error(error));
}
};
/*const trackEmailLoginFinished = () => {
if (useClientSide) {
if (
window.location.hostname !== "localhost" &&
props.trackUserInteractions &&
!userInteractions.includes(`IA ${props.eventName} EmailLoginFinished`)
) {
ReactPixel.track(`IA ${props.eventName} EmailLoginFinished`, {
content_ids: [props.eventId],
});
userInteractions.push(`IA ${props.eventName} EmailLoginFinished`);
localStorage.setItem(
"userInteractions",
JSON.stringify([...userInteractions])
);
}
}
};*/
const [userInteractions, setUserInteractions] = useState();
useEffect(()=> {
setUserInteractions(JSON.parse(
localStorage.getItem("userInteractions") ?? "[]"
))
},[])
return (
<>
<div className={styles.loginContainer}>
<label className={styles.loginInputLabel}>{`${t(
"Please enter your e-mail address"
)}`}</label>
<input
id="loginMail"
name="loginMail"
className="loginInput toLowerCase"
autoFocus
type="email"
onChange={(event) => setEmail(event.target.value.toLowerCase())}
/>
</div>
<label className="loginInputLabel">{`${t(
"Please enter your password"
)}`}</label>
<input
id="loginPassword"
className="loginInput"
name="loginPassword"
type="password"
onChange={(event) => setPassword(event.target.value)}
/>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
}}
>
<button
className="loginAndRegButton"
onClick={() => {
loginButtonPressed();
/*trackEmailLoginFinished();*/
}}
>
{t("Login")}
</button>
<p style={{ margin: 0 }} className="loginOrRegSwitch">
{t("You don't have an account yet")}?{" "}
<a href="#" onClick={() => props.setLogin(false)}>
{" "}
{t("Sign up")}
</a>
</p>
</div>
<Snackbar open={alertOpen} autoHideDuration={3000} onClose={alertClose}>
<Alert onClose={alertClose} severity={alertType}>
{alertMessage}
</Alert>
</Snackbar>
</>
);
}
export default withTranslation("translate")<any>(LoginWithEmail);
I think it has to be:
function LoginWithEmail({ t, ...props }) { /* ... */ }
I've spun my gears an entire work day trying to figure out how to do this. I have a component that renders a PowerBi embedded report. I have a button on the page that needs to pop open a Bootstrap Modal wrapped component. I can do this normally with state, but due to having a embedded PowerBi report, I cannot change the state (as this will re-render the PowerBI report which takes time, and also resets the report). I have tried using useRef(), to store this variable but obviously it doesn't notify the Modal component of the change.
Thoughts? Any advice?
import React, {useEffect, useRef, useState,useMemo} from 'react';
import ReportManager from '../managers/reportManager';
import SubscribeModel from '../components/subscription/SubscribeModal';
// #ts-ignore
import Report from 'powerbi-report-component';
import {FaChartLine, FaChartBar, FaDesktop, FaPrint, FaMailBulk} from 'react-icons/fa';
import PreloadManager from '../managers/preloadManager';
// #ts-ignore
import LoadingOverlay from 'react-loading-overlay';
import Preloader from '../components/Preloader';
interface ReportConfig {
id : string;
name : string;
webUrl : string;
embedUrl : string; //Embed URL
datasetId : string; //Report ID
embedToken : string; //Embed Token
}
class ReportConfigReal implements ReportConfig {
'id' : string;
'name' : string;
'webUrl' : string;
'embedUrl' : string;
'datasetId' : string;
'embedToken' : string;
'expiration' : string;
}
const Reports = (props : any) => {
const [config,
setConfig] = useState({
id: "",
name: "",
webUrl: "",
embedUrl: "",
embedToken: "",
expiration: ""
});
const [currentUser,
setCurrentUser] = useState(props.currentuser);
const [reportList,
setReportList] = useState(new Array());
const [reportId,
setReportId] = useState(props.match.params.report_id);
const [loading,
setLoading] = useState(false);
const [reportsLoading,
setReportsLoading] = useState(false);
const [report,
setReport] = useState(null);
const [subModal,
setSubModal] = useState(false);
let reportManager : ReportManager = new ReportManager();
let preloadManager : PreloadManager = new PreloadManager();
const currentPage = useRef(null);
const showSubscribe = useRef(null);
const createExpiration = (minutes : number) => {
const date = new Date();
return new Date(date.getTime() + minutes * 60000);
};
const onLoadAndSetTokenListener = (reportFromCallback : any) => {
setTokenExpirationListener(config.expiration, 1);
setReport(reportFromCallback);
};
const setTokenExpirationListener = (tokenExpiration : string, minutesToRefresh = 2) => {
// time until token refresh in milliseconds
const currentTime = Date.now();
const expiration = Date.parse(tokenExpiration);
const safetyInterval = minutesToRefresh * 60 * 1000;
let timeout = expiration - currentTime - safetyInterval;
// if token already expired, generate new token and set the access token
if (timeout <= 0) {
console.log('Updating Report Embed Token');
updateToken() // set timeout so minutesToRefresh minutes before token expires, token will be
// updated;
} else {
console.log('Report Embed Token will be updated in ' + timeout + ' milliseconds.');
setTimeout(() => {
console.log('Set time out');
updateToken();
}, timeout);
}
};
const updateToken = () => {
console.log('Update token called');
// Generate new EmbedToken (Axios call to get config/ token)
reportManager
.generateEmbedToken(currentUser)
.then((res : any) => {
// Set AccessToken (Use the report object)
if (report !== null) {
report
.setAccessToken(res.embedToken)
.then(() => {
console.log('new token set');
setTokenExpirationListener(createExpiration(2).toString(), 1);
})
.catch((err : any) => console.error('Error setting token', err));
}
});
};
const handleFullScreen = () => {
var elem = document.documentElement;
elem.requestFullscreen();
};
const handlePrint = () => {
window.print();
};
const handleSubscribe = () => {
console.log("page", currentPage.current);
console.log("showsub", showSubscribe);
};
const handleReportChange = (e : any) => {
window.location.href = '/reports/' + e;
};
const handleDataSelected = (data : any) => {
console.log("data selected", data);
};
const handlePageChange = (data : any) => {
console.log("page changed", data);
currentPage.current = data.newPage;
};
useEffect(() => {
let promiseList : any = [];
setLoading(true);
setReportsLoading(true);
if (currentUser && currentUser.allowedReports.length !== 0) {
currentUser
.allowedReports
.forEach((report : string) => {
promiseList.push(reportManager.getReportInfo(currentUser, report).then((info : any) => {
return info;
}),);
});
}
Promise
.all(promiseList)
.then(values => {
setReportList(values);
});
if (currentUser && currentUser.allowedReports.length !== 0 && currentUser.authenticated) {
if (reportId === undefined) {
reportManager
.getReport(currentUser)
.then(data => {
setConfig(data);
setLoading(false);
setReportsLoading(false);
})
.catch(error => {
console.log(error);
});
} else {
reportManager
.getReportInfo(currentUser, reportId)
.then((info : any) => {
setConfig(info);
setLoading(false);
setReportsLoading(false);
});
}
}
}, []);
return (
<LoadingOverlay active={loading} spinner={< Preloader />}>
<div>
<div
className={reportsLoading !== true
? 'slide-wrapper'
: 'col-sm-12 loading-delete'}>
<div id="slide-report">
<div className="menu_icon">
<div>
<FaChartLine color="#003267" size="30"/>
</div>
<span>Reports</span>
</div>
<div className="menu_content">
<ul>
{reportList.map((report, index) => {
return (
<li key={index} onClick={() => handleReportChange(report.id)}>
<FaChartBar className="icon-slide" color="#fff" size="30"/>
<span>{report
.name
.slice(0, 25)}</span>
</li>
);
})}
</ul>
</div>
</div>
<div id="slide-full-screen">
<div className="menu_icon" onClick={handleFullScreen}>
<div>
<FaDesktop color="#003267" size="30"/>
</div>
<span>Full Screen</span>
</div>
</div>
<div id="slide-print">
<div className="menu_icon" onClick={handlePrint}>
<div>
<FaPrint color="#003267" size="30"/>
</div>
<span>Print</span>
</div>
</div>
<div id="slide-subscribe">
<div className="menu_icon" onClick={handleSubscribe}>
<div>
<FaMailBulk color="#003267" size="30"/>
</div>
<span>Subscribe</span>
</div>
</div>
</div>
<div
key={reportId}
className={loading !== true
? 'col-sm-12'
: 'col-sm-12 loading-delete'}>
<Report
className={reportId}
embedType="report"
tokenType="Embed"
pageName={reportId}
accessToken={config.embedToken}
embedUrl={config.embedUrl}
embedId={config.id}
permissions="All"
reportMode="view"
onLoad={onLoadAndSetTokenListener}
onPageChange={handlePageChange}
onSelectData={handleDataSelected}
style={{
height: '90vh',
width: '100%',
display: 'block',
top: '0',
left: '0',
position: 'absolute',
border: '0',
padding: '20px',
background: '#fff',
zIndex: '1'
}}/>
</div>
</div>
<SubscribeModel show={false} />
</LoadingOverlay>
);
};
export default Reports;
This looks like the wrong way to go about doing it but this will open a modal without having to update state. Have you considered looking into componentShouldUpdate? The powerBiReport should also not be re-rendered unless any props that are passed into it have changed or state within the report itself has changed so consider looking there.
/* -- snip -- */
onButtonClick={() => createModal(<YourModal onClose={removeModal}/>)}
/* -- snip -- */
const createModal(component) {
const container = document.appendChild("div");
container.id = "modal-container";
ReactDOM.render(container, component);
}
const removeModal() {
const container = document.getElementById("modal-container");
ReactDOM.unmountComponentAtNode(container);
}
I'm using hooks and Context when after login my URL refreshing sometimes and get this Error Maximum update depth exceeded and my page not loading when refresh page everything is Ok!
this code my Login Page :
function LoginView(props) {
const classes = useStyles()
const [Username, setUsername] = useState('');
const [Password, setPassword] = useState('');
const { getUserLogin, isLogin } = useContext(UserContext)
const handelSubmit = (e) => {
console.log(Username, Password)
if (Username.length < 1) {
alert("لطفا نام کاربری را وارد نمایید")
if (Password.length < 1) {
alert("لطفا رمز عبور را واردنمایید")
}
}
let uuid = uuidv1()
console.log(uuid)
localStorage.setItem('myUUID', uuid)
let xml = 'exampel xlm (srver is SOAP)';
console.log(xml)
getUserLogin(xml)
}
useEffect(() => {
if (isLogin) {
props.history.push("/MainPage")
}
})
return (
<div style={{ direction: 'rtl', }}>
<MyLogo />
<div className={classes.root} >
<div className='textfiled'>
<TextField
className={classes.txt}
name='username'
inputProps={{ style: { textAlign: 'center' } }}
onChange={(e) => setUsername(e.target.value)}
placeholder='نام کاربری' ></TextField>
</div>
<div >
<TextField
className={classes.txt}
inputProps={{ style: { textAlign: 'center' } }}
name='password'
type='password'
onChange={(e) => setPassword(e.target.value)}
placeholder='رمز عبور' ></TextField>
</div>
<div>
<Button color={'inherit'} className={classes.btn} onClick={() => handelSubmit()} > ورود</Button>
</div>
</div>
</div>
)
}
export default withRouter(LoginView);
after submitting my cod get some error in console google I read this post
Maximum update depth exceeded
and change my onclick function but steel error Maximum update depth exceeded
and this is my Context :
export const UserContext = createContext()
export const UserContextDispacher = createContext();
const UserProvider = (props) => {
const [user, setUser] = useState({ username: '', password: '', })
const [isLogin, setisLogin] = useState(false)
const getUserLogin = (value) => {
axios.post('https://exampel.com/myexampel.asmx', value, { headers: { 'Content-Type': 'text/xml;charset=UTF-8' } }).then(function (response) {
// console.log(response)
var options = {
attributeNamePrefix: "#_",
attrNodeName: "attr", //default is 'false'
textNodeName: "#text",
ignoreAttributes: true,
ignoreNameSpace: false,
allowBooleanAttributes: false,
parseNodeValue: true,
parseAttributeValue: false,
trimValues: true,
cdataTagName: "__cdata", //default is 'false'
cdataPositionChar: "\\c",
localeRange: "", //To support non english character in tag/attribute values.
parseTrueNumberOnly: false,
attrValueProcessor: a => he.decode(a, { isAttributeValue: true }),//default is a=>a
tagValueProcessor: a => he.decode(a) //default is a=>a
};
// Intermediate obj
var tObj = parser.getTraversalObj(response.data, options);
var jsonObj = parser.convertToJson(tObj, options);
//set Token
var token = jsonObj["soap:Envelope"]["soap:Body"].AuthenticateUserResponse.Token
var authResult = jsonObj["soap:Envelope"]["soap:Body"].AuthenticateUserResponse.AuthenticateUserResult
if (authResult != false) {
localStorage.setItem('mytoken', token)
localStorage.setItem('myisLogin', authResult)
setisLogin(true)
} else {
localStorage.setItem('myisLogin', authResult)
setisLogin(false)
}
return authResult
}).catch(function (error) {
// console.log("erorr in send to login : " + error)
})
}
return (
<UserContext.Provider value={{ user, getUserLogin, isLogin }}>
<UserContextDispacher.Provider>
{props.children}
</UserContextDispacher.Provider>
</UserContext.Provider>
)
}
export default withRouter(UserProvider);
how to fix it this error?
thank for helping me
UPDATE
if (authResult != false) {
localStorage.setItem('mytoken', token)
localStorage.setItem('myisLogin', authResult)
setisLogin(true)
props.history.push("/MainPage");
}
and delete useEffect from loginview.js
useEffect runs every time a change occurs so useEffect is getting triggered infinitely many times so the error.
Solution : Use isLogin as dependency for useEffect.
useEffect(() => {
if (isLogin) {
props.history.push("/MainPage")
}
},[isLogin])