Change auth state from custom component while using #aws-amplify with react - reactjs

I am trying to integrate Amplify Auth with a React application.
I am using AmplifyAuthenticator from #aws-amplify/ui-react package to customize the auth flow.
Though I can use AmplifySignIn component and customize it, I want to create a totally custom instead of AmplifySignIn.
Following is what my custom component looks like:
import React from 'react';
import { Auth } from 'aws-amplify';
import { useForm } from "react-hook-form";
export default function CustomSignIn(props){
const { register, reset, errors, handleSubmit } = useForm();
const onSubmit = async data => {
await Auth.signIn(data.username, data.password);
};
return(
<form className="mt-5" onSubmit={handleSubmit(onSubmit)} slot={props.slot}>
<h4>Login</h4>
<p>Need an account? <span>Create an account</span></p>
<div className="form-group">
<label>Email address</label>
<input type="username" name="username" className="form-control" ref={register({required: true})}/>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" name="password" className="form-control" ref={register({required: true})}/>
</div>
<button type="submit" class="btn btn-primary btn-block">Continue</button>
</form>
);
}
Following is how I am trying to manage auth state:
import React, {useEffect} from 'react';
import { AmplifyAuthenticator } from '#aws-amplify/ui-react';
import '../styles/App.scss';
import { AuthState, onAuthUIStateChange } from '#aws-amplify/ui-components';
import ProtectedRoutes from './ProtectedRoutes';
import logo from '../assets/logo.svg';
import CustomSignIn from '../modules/auth/CustomSignIn';
function App() {
const [authState, setAuthState] = React.useState();
const [user, setUser] = React.useState();
useEffect(() => {
return onAuthUIStateChange((nextAuthState, authData) => {
setAuthState(nextAuthState);
setUser(authData)
});
}, []);
return ( authState === AuthState.SignedIn && user )
?
(
<ProtectedRoutes />
)
:
(
<div className="container-fluid container-fluid--auth">
<div className="row">
<div className="col-md-8">
<div className="row">
<div className="col-12 py-3">
<img className="logo" src={logo} alt="logo" />
</div>
</div>
<div className="row">
<div className="col-md-4 offset-md-4">
<AmplifyAuthenticator>
<CustomSignIn slot="sign-in" />
</AmplifyAuthenticator>
</div>
</div>
</div>
<div className="col-md-4 col--auth-sidebar">
</div>
</div>
</div>
);
}
export default App;
The thing is, how do I take the user to the Sign Up page when the user clicks on the "Create an account" button on the Sign In page?

Related

Clicking on react button asks me to leave site

I am learning react and I have a component which as a 2 input fields and a button, at the moment, clicking on the button will display a message in console log, but when the button is clicked it displays a popup Leave site?, Changes that you made may not be saved.
this is my code in this component
import React, { useRef, useState, Component } from 'react'
import { useAuthState } from 'react-firebase-hooks/auth';
import { useCollectionData } from 'react-firebase-hooks/firestore';
import { signOut } from 'firebase/auth';
class InfoLgnTest extends Component {
render() {
this.state = {
user: null
}
return (
<div>
<div className="App">
<SignInWithEmailPassword />
</div>
</div>
)
}
}
function SignInWithEmailPassword() {
const emailRef = useRef()
const passwordRef = useRef()
const signIn = () => {
console.log("InfoLgnTest singin clicked")
}
return (
<>
<div className="form">
<form>
<div className="input-container">
<label>Username </label>
<input
name="email"
type="text"
ref={emailRef}
required
placeholder ="something#gmail.com"
/>
</div>
<div className="input-container">
<label>Password </label>
<input
type="text"
name="pass"
ref={passwordRef}
required
placeholder ="..."
/>
</div>
<div className="button-container">
<input type="submit" onClick={signIn}/>
</div>
</form>
</div>
</>
)
}
export default InfoLgnTest
This code has a form, by default form send data as a request on the same page, for resolve this:
Add onSubmit to form,
call preventDefault method from event
call the function signIn
Change <input type="submit" ... /> to <button type="submit">Send</button>
function SignInWithEmailPassword() {
const emailRef = useRef()
const passwordRef = useRef()
const signIn = () => {
console.log("InfoLgnTest singin clicked")
}
// new function to handle submit
const submitForm = (event) => {
event.preventDefault();
signIn();
}
return (
<>
<div className="form">
{/* Add onSubmit */}
<form onSubmit={submitForm}>
<div className="input-container">
<label>Username </label>
<input
name="email"
type="text"
ref={emailRef}
required
placeholder ="something#gmail.com"
/>
</div>
<div className="input-container">
<label>Password </label>
<input
type="text"
name="pass"
ref={passwordRef}
required
placeholder ="..."
/>
</div>
<div className="button-container">
{/* Change input to button */}
<button type="submit">Send</button>
</div>
</form>
</div>
</>
)
}

Using useEffect in react js to sent google rechaptha token

Hi i want implementation google rechapta using react, this is my react code
import { useForm } from 'react-hook-form';
import { useHistory } from 'react-router-dom';
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import swal from 'sweetalert';
import ReCAPTCHA from "react-google-recaptcha";
const ContactForm = (props) => {
const {submitBtnClass } = props;
const { register, handleSubmit } = useForm();
const [token, setToken] = useState();
const history=useHistory();
const recaptchaRef = React.useRef();
function onChange(value) {
console.log("Captcha value:", value);
setToken(value);
}
useEffect(()=>{
document.getElementById("contact_tokenVal").value = token;
//const value = props.value
//setToken(value)
},[token]);
const onSubmit = data_api => {
axios
.post('http://localhost/erlanggastudio-rest-api/contact.php',data_api)
.then(res=>{
console.log(data_api);
history.push('/onepage-3');
swal(res.data.title, res.data.text, res.data.icon);
})
.catch(err => {
console.log(err);
});
};
return (
<form id="contact-form" onSubmit={handleSubmit(onSubmit)}>
<div className="row">
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="contact_name" name="contact_name" placeholder="Nama" {...register('contact_name')} required />
</div>
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="contact_email" name="contact_email" placeholder="E-Mail" {...register('contact_email')} required />
</div>
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="contact_mobilephone" name="contact_mobilephone" placeholder="No Telepon" {...register('contact_mobilephone')} required/>
</div>
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="contact_website" name="contact_website" placeholder="Website Anda" {...register('contact_website')} />
</div>
<div className="col-12 mb-30">
<textarea className="from-control" id="contact_message" name="contact_message" placeholder="Isi Pesan" {...register('contact_message')} required ></textarea>
</div>
<div className="col-12 mb-30">
<input className="from-control" type="hidden" id="contact_serverKey" name="contact_serverKey" value="6Lea50IhAAAAAAtfj-sElz7biY8WlDgrNwy7M7Tx" {...register('contact_serverKey')} />
<input className="from-control" type="hidden" id="contact_siteKey" name="contact_siteKey" value="6Lea50IhAAAAAEgdIvB6xUJ8KJCUyO-xKpPnA0fO" {...register('contact_siteKey')} />
<textarea className="from-control" id="contact_tokenVal" name="contact_tokenVal" defaultValue={token} {...register('contact_tokenVal')} />
</div>
<div className="col-md-6 mb-30">
<ReCAPTCHA
ref={recaptchaRef}
sitekey="6Lea50IhAAAAAEgdIvB6xUJ8KJCUyO-xKpPnA0fO"
onChange={onChange}
/>
</div>
</div>
<div className="btn-part">
<button className={submitBtnClass ? submitBtnClass : 'readon learn-more submit'} type="submit">Kirim</button>
</div>
</form>
);
}
export default ContactForm;
when the code running the view is like this :
i want to sent rechapta token using
<textarea className="from-control" id="contact_tokenVal" name="contact_tokenVal" defaultValue={token} {...register('contact_tokenVal')} />
after user klik rechapta, end will sent to server using axios, but i have some problem when sent the data to API Server using axion the rechapta token is blank like this screenshot :
my question is how to sent the rechapta token?, i'm using document.getElementById in useEffect, but still the value after sent is blank

React Hook Form with file just submitting fakepath

I'm trying to add an <Input type="file" to my react-hook-form, but it submit a C:\fakepath when I submit the form.
import React from "react";
import { Controller, useForm } from "react-hook-form";
import { Button, Form, Label, Input } from "reactstrap";
const App = () => {
const {
handleSubmit,
control,
setValue,
formState: { errors }
} = useForm();
const submitData = (data) => {
console.log(data);
};
return (
<div className="row">
<div className="col-sm-12 col-md-12 col-xl-12">
<Form onSubmit={handleSubmit(submitData)}>
<div className="row">
<div className="col-sm-6">
<Label for="file">File</Label>
<Controller
name="file"
control={control}
render={({ field }) => (
<Input {...field} type="file" id="file" />
)}
/>
</div>
</div>
<Button type="submit" color="primary">
Submit
</Button>
</Form>
</div>
</div>
);
};
export default App;
Here is the sandbox: https://codesandbox.io/s/morning-water-hyi9o
How can I use files with react-hook-form?
Thanks
You can find a solution here: https://github.com/react-hook-form/react-hook-form/discussions/5394#discussioncomment-848215
Here is another way to achieve that with register:
import React from "react";
import { useForm } from "react-hook-form";
import { Button, Form, Label, Input } from "reactstrap";
const App = () => {
const { register, handleSubmit } = useForm();
const submitData = (data) => {
console.log(data);
};
const { ref, ...field } = register("file");
return (
<div className="row">
<div className="col-sm-12 col-md-12 col-xl-12">
<Form onSubmit={handleSubmit(submitData)}>
<div className="row">
<div className="col-sm-6">
<Label for="file">File</Label>
<Input {...field} innerRef={ref} type="file" id="file" />
</div>
</div>
<Button type="submit" color="primary">
Submit
</Button>
</Form>
</div>
</div>
);
};
export default App;
I had the same problem and I solved it by changing the object data.file = e.target.file.files in the onSubmit as follows:
import React from "react";
import { Controller, useForm } from "react-hook-form";
import { Button, Form, Label, Input } from "reactstrap";
const App = () => {
const {
handleSubmit,
control,
setValue,
formState: { errors }
} = useForm();
const submitData = (data, e) => {
data.file = e.target.file.files
console.log(data);
};
return (
<div className="row">
<div className="col-sm-12 col-md-12 col-xl-12">
<Form onSubmit={handleSubmit(submitData)}>
<div className="row">
<div className="col-sm-6">
<Label for="file">File</Label>
<Controller
name="file"
control={control}
render={({ field }) => (
<Input {...field} type="file" id="file" />
)}
/>
</div>
</div>
<Button type="submit" color="primary">
Submit
</Button>
</Form>
</div>
</div>
);
};
export default App;

e.preventDefault() not working in my react app which is causing unnessary redirect

Hi I am trying to create a react-redux form and my e.preventDefault() is not working which i causing a redirect everytime I press an enter key.
Could someone look in my code and tell me where am I going wrong:
I am having an input field and when I am giving an e.preventDefault(), but for some reason its redirecting.
import React, { useState } from "react";
import { useDispatch } from "react-redux";
function InputField() {
let [task, setTask] = useState("");
const dispatch = useDispatch();
let onTaskAdd = (e) => {
setTask(e.target.value);
};
let addTaskinTaskManager = () => {
dispatch({ type: "ADD_TASK", payload: task });
setTask("");
};
return (
<div className="container-fluid mt-5">
<div className="row justify-content-center">
<div className="col-md-6">
<form>
<div className="form-group row">
<label className="col-md-2 col-form-label">Task:</label>
<div className="col-md-10">
<input
type="text"
id="task"
name="task"
className="form-control"
placeholder="eg, singing"
value={task}
onChange={(e) => {
e.preventDefault();
e.stopPropagation();
onTaskAdd(e);
}}
/>
</div>
</div>
</form>
</div>
<div className="col-md-2">
<button
type="button"
onClick={addTaskinTaskManager}
className="btn btn-primary"
>
Add Task
</button>
</div>
</div>
</div>
);
}
export default InputField;

"useHistory is not defined" in react js create-react-app

I am trying to build an easy password protected page with an hardcoded password and a random token generated, However I am getting multiple errors, the most prominent one being "userHistory" is not defined, there area host of other bugs but I intend to solve them as I am new to react, anybody here care to help? Please find below my code
import React, {useState} from 'react';
function Singmein () {
const [passwordInput, setPasswordInput] = useState('');
const history = useHistory();
function handlePasswordChange(e){
setPasswordInput(e.target.value);
}
const handleLoginSubmit = (e) => {
e.preventDefault();
let hardcodedCred = {
password: 'password123'
}
if ((passwordInput == hardcodedCred.password)) {
//combination is good. Log them in.
//this token can be anything. You can use random.org to generate a random string;
const token = '123456abcdef';
sessionStorage.setItem('auth-token', token);
//go to www.website.com/todo
history.push('/signin');
} else {
//bad combination
alert('wrong email or password combination');
}
}
}
class signin extends React.Component{
render () {
return (
<div className="d-flex flex-column flex-root">
<div className="login login-4 login-signin-on d-flex flex-row-fluid" id="kt_login">
<div className="d-flex flex-center flex-row-fluid bgi-size-cover bgi-position-top bgi-no-repeat" style={{backgroundColor: 'white'}}>
<div className="login-form p-7 position-relative overflow-hidden">
<div className="d-flex flex-center">
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
</div>
<div className="card card-board" style={{backgroundColor: '#F0F1F4', width: '100%'}}>
<div className="card-body">
<div className="mb-10">
<h3 className="font-weight-bold">This website is password protected</h3>
</div>
<form className="form" autoComplete="off" id="kt_login_signin_form" onSubmit={handleLoginSubmit}>
<div className="form-group mb-5">
<label htmlFor="username">Enter Unique Password</label>
<input className="form-control h-auto form-control-solid py-4 px-8"
style={{backgroundColor: 'white'}}
type="password"
placeholder="Password"
name="password"
value={passwordInput}
onChange={handlePasswordChange} />
</div>
Enter
</form>
</div>
</div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
</div>
</div>
</div>
</div>
);
}
};
export default signin;
You need to import { useHistory } from 'react-router-dom';
You have to import react-router-dom like this:
import {useHistory} from "react-router-dom";
So, your full code will look like this:
import React, {useState} from 'react';
import {useHistory} from "react-router-dom";
function Singmein () {
const [passwordInput, setPasswordInput] = useState('');
const history = useHistory();
...
}

Resources