Commit f1c7c74c authored by Trần Ngọc Nam Anh's avatar Trần Ngọc Nam Anh

Finish Signup, Change Password

parent 70e03924
...@@ -22,6 +22,9 @@ import Signin from "./services/Signin"; ...@@ -22,6 +22,9 @@ import Signin from "./services/Signin";
import Signup from "services/Signup"; import Signup from "services/Signup";
import { authServices } from "./services/AuthServices"; import { authServices } from "./services/AuthServices";
import { Routes } from "reoutes"; import { Routes } from "reoutes";
import VerifyCode from "services/VerifyCode";
import ForgotPassword from "services/ForgotPassword";
import ResetPassword from "services/ResetPassword";
// import { Routes } from "./reoutes"; // import { Routes } from "./reoutes";
const RouteWithLoader = ({ component: Component, ...rest }) => { const RouteWithLoader = ({ component: Component, ...rest }) => {
...@@ -33,7 +36,10 @@ const RouteWithLoader = ({ component: Component, ...rest }) => { ...@@ -33,7 +36,10 @@ const RouteWithLoader = ({ component: Component, ...rest }) => {
export default () => ( export default () => (
<Switch> <Switch>
<Route exact path="/login-page" component={Signin} /> <Route exact path="/login-page" component={Signin} />
<Route exact path="/signup" component={Signup} />
<Route exact path="/verify-code" component={VerifyCode} />
<Route exact path="/forgot-password" component={ForgotPassword} />
<Route exact path="/reset-password" component={ResetPassword} />
<RouteWithLoader exact path="/" component={SearchProfile} /> <RouteWithLoader exact path="/" component={SearchProfile} />
<RouteWithLoader exact path="/profile" component={SearchProfile} /> <RouteWithLoader exact path="/profile" component={SearchProfile} />
<RouteWithLoader exact path="/profile/add" component={AddProfile} /> <RouteWithLoader exact path="/profile/add" component={AddProfile} />
......
export const Routes = { export const Routes = {
SearchDetail: { path: "./profile" }, SearchDetail: { path: "./profile" },
TraceCode: { path: "./trace-code" }, TraceCode: { path: "./trace-code" },
Signin: { path: "./signin" }, Signin: { path: "./login-page" },
Signup: { path: "./signup" }, Signup: { path: "./signup" },
ForgotPassword: { path: "./forgot-password" },
ResetPassword: {path: "./reset-password"},
Home: { path: "" } Home: { path: "" }
} }
\ No newline at end of file
import React, { useState } from "react"; import React, { useState } from "react";
import { import {
Col, Alert,
Row,
Form,
Card,
Button, Button,
Container, Card,
CardBody,
FormGroup,
Form,
FormFeedback,
Input,
InputGroupAddon,
InputGroupText,
InputGroup, InputGroup,
Alert, Container,
Spinner Row,
} from "@themesberg/react-bootstrap"; Col,
Spinner,
CardHeader
} from "reactstrap";
import { Link, useHistory } from "react-router-dom"; import { Link, useHistory } from "react-router-dom";
import { Routes } from "../routes"; // core components
import BgImage from "../assets/img/illustrations/signin.svg"; import DemoNavbar from "components/Navbars/DemoNavbar.js";
import { authServices, validateEmail } from "./AuthServices"; import SimpleFooter from "components/Footers/SimpleFooter.js";
import { Routes } from "../reoutes";
import { authServices } from "./AuthServices";
import { validateEmail } from "constans";
export default () => { export default () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
...@@ -31,17 +42,17 @@ export default () => { ...@@ -31,17 +42,17 @@ export default () => {
setShowMessage(false); setShowMessage(false);
setValidEmail(false); setValidEmail(false);
authServices authServices
.forgotPassword(email) .forgotPassword(email)
.then((rs) => { .then((rs) => {
history.push(Routes.ResetPassword.path); history.push(Routes.ResetPassword.path);
setShowMessage(false); setShowMessage(false);
setLoading(false); setLoading(false);
}) })
.catch((err) => { .catch((err) => {
setShowMessage(true); setShowMessage(true);
setLoading(false); setLoading(false);
setErrorMessage(err.message); setErrorMessage(err.message);
}); });
} else { } else {
setShowMessage(false); setShowMessage(false);
setValidEmail(true); setValidEmail(true);
...@@ -49,60 +60,91 @@ export default () => { ...@@ -49,60 +60,91 @@ export default () => {
} }
return ( return (
<main> <>
<section className="vh-lg-100 mt-4 mt-lg-0 bg-soft d-flex align-items-center"> <DemoNavbar />
<Container> <main>
{loading ? ( <section className="section section-shaped section-lg">
<div className="text-center mb-2"> <div className="shape shape-style-1 bg-gradient-default">
<Spinner animation="border" variant="secondary" role="status" /> <span />
</div> <span />
) : ( <span />
false <span />
)} <span />
<div className="text-center"><Alert show={showMessage} variant="danger">{errorMessage}</Alert></div> <span />
<Row className="justify-content-center form-bg-image" style={{ backgroundImage: `url(${BgImage})` }}> <span />
<Col <span />
xs={12} </div>
className="d-flex align-items-center justify-content-center" <Container className="pt-lg-7">
> {showMessage ? (
<div className="signin-inner my-3 my-lg-0 bg-white shadow-soft border rounded border-light p-4 p-lg-5 w-100 fmxw-500"> <div className="text-center"><Alert className="px-lg-5" color="danger">{errorMessage}</Alert></div>
<h3>Forgot your password?</h3> ) : (
<Form onSubmit={onHandleForgotPassword}> false
<div className="mb-4"> )}
<Form.Label htmlFor="email">Your Email</Form.Label> {loading ? (
<InputGroup id="email"> <div className="text-center mb-3">
<Form.Control <Spinner color="primary" />
required
autoFocus
type="email"
placeholder="example@company.com"
value={email} onChange={(e) => setEmail(e.target.value)}
/>
</InputGroup>
<Form.Control.Feedback
type="invalid"
className="invalid-feedback"
>
{validEmail ? "Please input validate email" : false}
</Form.Control.Feedback>
</div>
<Button variant="primary" type="submit" className="w-100">
Recover password
</Button>
</Form>
<div className="d-flex justify-content-center align-items-center mt-4">
<span className="fw-normal">
No forgot password?
<Card.Link as={Link} to={Routes.Signin.path} className="fw-bold">
{` Back to sign in `}
</Card.Link>
</span>
</div>
</div> </div>
</Col> ) : (
</Row> false
</Container> )}
</section> <Row className="justify-content-center">
</main> <Col lg={5}>
<Card className="bg-secondary shadow border-0">
<CardHeader>
<h5 className="text-center text-primary">Password recovery</h5>
</CardHeader>
<CardBody className="px-lg-5 py-lg-5">
<Form role="form" onSubmit={onHandleForgotPassword}>
<FormGroup id="code">
<InputGroup className="input-group-alternative mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="ni ni-email-83" />
</InputGroupText>
</InputGroupAddon>
<Input
required
autoFocus
type="text"
placeholder="Your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
invalid={validEmail} />
<FormFeedback className="bg-transparent shadow-0">{validEmail ? "Please input valid email" : false}</FormFeedback>
</InputGroup>
</FormGroup>
<div className="text-center">
<Button
className="mt-4"
color="primary"
type="submit"
>
Recover password
</Button>
</div>
</Form>
</CardBody>
</Card>
<Row className="mt-3">
<Col className="d-flex justify-content-start align-items-center">
<small className="text-light mr-2">
No forgot password?
</small>
<Link
to={Routes.Signin.path}>
<small className="text-primary">
Login
</small>
</Link>
</Col>
</Row>
</Col>
</Row>
</Container>
</section>
</main>
<SimpleFooter />
</>
); );
}; };
This diff is collapsed.
...@@ -10,6 +10,7 @@ import { ...@@ -10,6 +10,7 @@ import {
Button, Button,
Card, Card,
CardBody, CardBody,
CardHeader,
FormGroup, FormGroup,
Form, Form,
FormFeedback, FormFeedback,
...@@ -24,9 +25,9 @@ import { ...@@ -24,9 +25,9 @@ import {
} from "reactstrap"; } from "reactstrap";
// core components // core components
import DemoNavbar from "components/Navbars/DemoNavbar.js"; // import DemoNavbar from "components/Navbars/DemoNavbar.js";
import SimpleFooter from "components/Footers/SimpleFooter.js"; // import SimpleFooter from "components/Footers/SimpleFooter.js";
import MainBanner from "components/Generals/MainBanner"; // import MainBanner from "components/Generals/MainBanner";
export default () => { export default () => {
...@@ -88,7 +89,7 @@ export default () => { ...@@ -88,7 +89,7 @@ export default () => {
<main> <main>
{/* <MainBanner /> */} {/* <MainBanner /> */}
<section className="section section-shaped section-lg"> <section className="section section-shaped section-xl">
<div className="shape shape-style-1 bg-gradient-default"> <div className="shape shape-style-1 bg-gradient-default">
<span /> <span />
<span /> <span />
...@@ -115,6 +116,9 @@ export default () => { ...@@ -115,6 +116,9 @@ export default () => {
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col lg="5"> <Col lg="5">
<Card className="bg-secondary shadow border-0"> <Card className="bg-secondary shadow border-0">
<CardHeader>
<h5 className="text-center text-primary">Sign in</h5>
</CardHeader>
<CardBody className="px-lg-5 py-lg-5"> <CardBody className="px-lg-5 py-lg-5">
<Form role="form" onSubmit={onHandleLogin}> <Form role="form" onSubmit={onHandleLogin}>
<FormGroup id="email" className="mb-3"> <FormGroup id="email" className="mb-3">
...@@ -161,7 +165,7 @@ export default () => { ...@@ -161,7 +165,7 @@ export default () => {
<Row className="mt-3"> <Row className="mt-3">
<Col xs="6"> <Col xs="6">
<Link <Link
to={Routes.Signup.path} to={Routes.ForgotPassword.path}
className="text-light"> className="text-light">
<small>Forgot password?</small> <small>Forgot password?</small>
</Link> </Link>
......
...@@ -7,9 +7,11 @@ import { authServices } from "./AuthServices"; ...@@ -7,9 +7,11 @@ import { authServices } from "./AuthServices";
import { validateEmail } from "../constans/index"; import { validateEmail } from "../constans/index";
import { import {
Alert,
Button, Button,
Card, Card,
CardBody, CardBody,
CardHeader,
FormGroup, FormGroup,
Form, Form,
FormFeedback, FormFeedback,
...@@ -19,7 +21,8 @@ import { ...@@ -19,7 +21,8 @@ import {
InputGroup, InputGroup,
Container, Container,
Row, Row,
Col Col,
Spinner
} from "reactstrap"; } from "reactstrap";
// core components // core components
...@@ -59,7 +62,7 @@ export default () => { ...@@ -59,7 +62,7 @@ export default () => {
authServices authServices
.signUp(email, password) .signUp(email, password)
.then((rs) => { .then((rs) => {
history.push(Routes.VerifyCode.path); history.push("/verify-code");
setShowMessage(false); setShowMessage(false);
setLoading(false); setLoading(false);
}) })
...@@ -87,9 +90,24 @@ export default () => { ...@@ -87,9 +90,24 @@ export default () => {
<span /> <span />
</div> </div>
<Container className="pt-lg-7"> <Container className="pt-lg-7">
{showMessage ? (
<div className="text-center"><Alert className="px-lg-5" color="danger">{errorMessage}</Alert></div>
) : (
false
)}
{loading ? (
<div className="text-center mb-3">
<Spinner color="primary" />
</div>
) : (
false
)}
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col lg="5"> <Col lg={5}>
<Card className="bg-secondary shadow border-0"> <Card className="bg-secondary shadow border-0">
<CardHeader>
<h5 className="text-center text-primary">Sign up</h5>
</CardHeader>
<CardBody className="px-lg-5 py-lg-5"> <CardBody className="px-lg-5 py-lg-5">
<Form role="form" onSubmit={onHandleSignUp}> <Form role="form" onSubmit={onHandleSignUp}>
...@@ -100,8 +118,13 @@ export default () => { ...@@ -100,8 +118,13 @@ export default () => {
<i className="ni ni-email-83" /> <i className="ni ni-email-83" />
</InputGroupText> </InputGroupText>
</InputGroupAddon> </InputGroupAddon>
<Input placeholder="Email" type="text" {...validEmail ? "invalid" : ""} /> <Input
<FormFeedback>Invalid email</FormFeedback> placeholder="Email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
invalid={validEmail} />
<FormFeedback className="bg-transparent shadow-0">{validEmail ? "Please input validate email" : false}</FormFeedback>
</InputGroup> </InputGroup>
</FormGroup> </FormGroup>
...@@ -112,7 +135,12 @@ export default () => { ...@@ -112,7 +135,12 @@ export default () => {
<i className="ni ni-lock-circle-open" /> <i className="ni ni-lock-circle-open" />
</InputGroupText> </InputGroupText>
</InputGroupAddon> </InputGroupAddon>
<Input placeholder="Password" type="password" autoComplete="off" /> <Input
placeholder="Password"
type="password"
autoComplete="off"
value={password}
onChange={(e) => setPassword(e.target.value)} />
</InputGroup> </InputGroup>
</FormGroup> </FormGroup>
...@@ -127,7 +155,10 @@ export default () => { ...@@ -127,7 +155,10 @@ export default () => {
placeholder="Confirm Password" placeholder="Confirm Password"
type="password" type="password"
autoComplete="off" autoComplete="off"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
/> />
<FormFeedback>{checkPassword ? "Please input match password" : false}</FormFeedback>
</InputGroup> </InputGroup>
</FormGroup> </FormGroup>
<div className="text-center"> <div className="text-center">
......
import React, { useState } from "react"; import React, { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faFilter, faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import { Col, Row, Form, Button, Container, InputGroup, Card, Alert, Spinner } from '@themesberg/react-bootstrap';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import { Routes } from "../routes"; import { Routes } from "../reoutes";
import BgImage from "../assets/img/illustrations/signin.svg";
import { authServices } from "./AuthServices"; import { authServices } from "./AuthServices";
import {
Alert,
Button,
Card,
CardBody,
FormGroup,
Form,
Input,
InputGroupAddon,
InputGroupText,
InputGroup,
Container,
Row,
Col,
Spinner
} from "reactstrap";
// core components
import DemoNavbar from "components/Navbars/DemoNavbar.js";
import SimpleFooter from "components/Footers/SimpleFooter.js";
export default () => { export default () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [code, setCode] = useState(""); const [code, setCode] = useState("");
...@@ -36,47 +53,84 @@ export default () => { ...@@ -36,47 +53,84 @@ export default () => {
}; };
return ( return (
<main> <>
<section className="d-flex align-items-center my-5 mt-lg-6 mb-lg-5"> <DemoNavbar />
<Container> <main>
{loading ? ( <section className="section section-shaped section-lg">
<div className="text-center mb-2"> <div className="shape shape-style-1 bg-gradient-default">
<Spinner animation="border" variant="secondary" role="status" /> <span />
</div> <span />
) : ( <span />
false <span />
)} <span />
<div className="text-center"><Alert show={showMessage} variant="danger">{errorMessage}</Alert></div> <span />
<Row className="justify-content-center form-bg-image" style={{ backgroundImage: `url(${BgImage})` }}> <span />
<p className="text-center"> <span />
<Card.Link as={Link} to={Routes.Signup.path} className="text-gray-700"> </div>
<FontAwesomeIcon icon={faAngleLeft} className="me-2" /> Back to sign up <Container className="pt-lg-7">
</Card.Link> {showMessage ? (
</p> <div className="text-center"><Alert className="px-lg-5" color="danger">{errorMessage}</Alert></div>
<Col xs={12} className="d-flex align-items-center justify-content-center"> ) : (
<div className="bg-white shadow-soft border rounded border-light p-4 p-lg-5 w-100 fmxw-500"> false
<div className="text-center text-md-center mb-4 mt-md-0"> )}
<h3 className="mb-0">Verify Code</h3> {loading ? (
</div> <div className="text-center mb-3">
<Form className="mt-4" onSubmit={onHandleVerifyCode}> <Spinner color="primary" />
<Form.Group id="code" className="mb-4">
<Form.Label>Verify Code</Form.Label>
<InputGroup>
<InputGroup.Text>
<FontAwesomeIcon icon={faFilter} />
</InputGroup.Text>
<Form.Control autoFocus required type="number" placeholder="Verify Code" min={0} value={code} onChange={(e) => setCode(e.target.value)} />
</InputGroup>
</Form.Group>
<Button variant="primary" type="submit" className="w-100">
Verify
</Button>
</Form>
</div> </div>
</Col> ) : (
</Row> false
</Container> )}
</section> <Row className="justify-content-center">
</main> <Col lg={5}>
<Card className="bg-secondary shadow border-0">
<CardBody className="px-lg-5 py-lg-5">
<Form role="form" onSubmit={onHandleVerifyCode}>
<FormGroup id="code">
<InputGroup className="input-group-alternative mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="ni ni-lock-circle-open" />
</InputGroupText>
</InputGroupAddon>
<Input
autoFocus
required
type="number"
placeholder="Verify Code"
min={0}
value={code}
onChange={(e) => setCode(e.target.value)} />
</InputGroup>
</FormGroup>
<div className="text-center">
<Button
className="mt-4"
color="primary"
type="submit"
>
Verify
</Button>
</div>
</Form>
</CardBody>
</Card>
<Row className="mt-3">
<Col className="d-flex justify-content-start align-items-center">
<Link
to={Routes.Signup.path}>
<small className="text-primary">
Back to sign up
</small>
</Link>
</Col>
</Row>
</Col>
</Row>
</Container>
</section>
</main>
<SimpleFooter />
</>
); );
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment