Start forgot password

This commit is contained in:
Paulo Gustavo Veiga 2020-12-07 23:34:01 -08:00
parent 7c53c6b9c7
commit a6fe41b5c9
14 changed files with 194 additions and 69 deletions

View File

@ -8,7 +8,6 @@
"lint": "eslint src",
"extract": "formatjs extract",
"compile": "formatjs compile"
},
"repository": "http://www.wisemapping.com",
"author": "Paulo Veiga <pveiga@gmail.com>, Ezequiel Bergamaschi <ezequielbergamaschi@gmail.com>",
@ -44,6 +43,7 @@
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"@types/react-google-recaptcha": "^2.1.0",
"axios": "^0.21.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",

View File

@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="WiseMappping" />
<!-- <link rel="apple-touch-icon" href="%PUBLIC_URL%/favicon.png" /> -->

View File

@ -2,9 +2,9 @@ import React, { useEffect, useState } from 'react';
import { Service, RestService } from './services/Service';
import { IntlProvider } from 'react-intl'
import LoginPage from './components/LoginPage';
import { RegistationPage } from './components/RegistrationPage';
import { RegistrationSuccessPage } from './components/RegistrationSuccessPage';
import { RegistrationSuccessPage } from './components/registration-success-page';
import { RegistationPage } from './components/registration-page';
import LoginPage from './components/login-page';
import {
Route,
@ -12,6 +12,7 @@ import {
Redirect,
BrowserRouter as Router,
} from 'react-router-dom';
import { ForgotPasswordPage } from './components/forgot-password-page';
function loadLocaleData(language: string) {
switch (language) {
@ -56,6 +57,7 @@ const App = () => {
<RegistationPage service={service} />
</Route>
<Route path="/c/user/registrationSuccess" component={RegistrationSuccessPage} />
<Route path="/c/user/resetPassword" component={ForgotPasswordPage} />
</Switch>
</Router>
</IntlProvider>

View File

@ -1,27 +1,29 @@
import React from 'react'
import { FormattedMessage } from 'react-intl'
const logo = require('../images/logo-text.svg')
const logo = require('../../images/logo-text.svg')
const Footer = () => {
return (
<footer className="footer" >
{/* Todo: Replace this with a SVG Image */}
<div style={{padding: 0, margin: 0}}>
<div style={{ padding: 0, margin: 0 }}>
<a href="http://www.wisemapping.org/">
<div style={{textAlign: "left"}}>Powered By</div><img src={logo} alt="logo" />
<div style={{ textAlign: "left" }}>Powered By</div><img src={logo} alt="logo" />
</a>
</div>
<div >
<div><a href="https://www.wisemapping.com/termsofuse.html"> <FormattedMessage id="footer.termsandconditions" defaultMessage="Term And Conditions" /> </a></div>
<h4><FormattedMessage id="footer.faqandhelp" defaultMessage="Help &amp; FAQ" /></h4>
<div><a href="https://www.wisemapping.com/faq.html"> <FormattedMessage id="footer.faq" defaultMessage="F.A.Q." /> </a></div >
<div><a href="https://www.wisemapping.com/aboutus.html"> <FormattedMessage id="footer.aboutus" defaultMessage="About Us" /></a></div >
<div><a href="https://www.wisemapping.com/termsofuse.html"> <FormattedMessage id="footer.termsandconditions" defaultMessage="Term And Conditions" /> </a></div>
<div><a href="mailto:team@wisemapping.com"> <FormattedMessage id="footer.contactus" defaultMessage="Contact Us" /> </a></div>
</div>
<div >
<div><a href="http://www.wisemapping.org/"> <FormattedMessage id="footer.opensource" defaultMessage="Open Source" /> </a></div>
<div><a href="mailto:team@wisemapping.com"> <FormattedMessage id="footer.contactus" defaultMessage="Contact Us" /> </a></div>
<h4><FormattedMessage id="footer.others" defaultMessage="Others" /></h4>
<div><a href="https://www.wisemapping.com/aboutus.html"> <FormattedMessage id="footer.aboutus" defaultMessage="About Us" /></a></div >
<div><a href="mailto:feedback@wisemapping.com" > <FormattedMessage id="footer.feedback" defaultMessage="Feedback" /> </a></div>
<div><a href="http://www.wisemapping.org/"> <FormattedMessage id="footer.opensource" defaultMessage="Open Source" /> </a></div>
</div>
<div>
<div><span className="button-style2" >< a href="https://www.paypal.com/webapps/shoppingcart?flowlogging_id=c7ac923b53025&mfid=1606520600355_c7ac923b53025#/checkout/openButton">< FormattedMessage id="footer.donations" defaultMessage="PayPal Donations" /> </a></span ></div>

View File

@ -0,0 +1,86 @@
import React, { useState, useEffect } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { useHistory } from "react-router-dom"
import { Service } from '../../services/Service'
import Header from '../header'
import Footer from '../footer'
import SubmitButton from '../submit-button'
const css = require('../../css/registration.css');
interface ErrorMessageDialogProps {
message: string
}
const ErrorMessageDialog = (props: ErrorMessageDialogProps) => {
const message = props.message;
return message ? <p className='form-error-dialog'>{message}</p> : <span></span>;
}
type ForgotPasswordProps = {
email: string;
}
const RegistrationForm = (props: ServiceProps) => {
const [email, setEmail] = useState("");
const [errorMsg, setErrorMsg] = useState("");
const [disableButton, setDisableButton] = useState(false);
const history = useHistory();
const intl = useIntl();
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
setDisableButton(true);
// Call Service ...
props.service.resetPassword(
email,
() => history.push("/c/user/forgotPasswordSuccess"),
(msg) => { setErrorMsg(msg); setDisableButton(false); }
);
}
return (
<div className="wrapper">
<div className="content">
<h1><FormattedMessage id="forgot.title" defaultMessage="Reset your password" /></h1>
<p><FormattedMessage id="forgot.desc" defaultMessage="We will send you an email to reset your password" /></p>
<form action="/" method="POST" onSubmit={e => handleSubmit(e)}>
<input type="email" name="email" onChange={e => setEmail(e.target.value)} placeholder={intl.formatMessage({ id: "forgot.email", defaultMessage: "Email" })} required={true} autoComplete="email" />
<ErrorMessageDialog message={errorMsg} />
<SubmitButton disabled={disableButton} value={intl.formatMessage({ id: "forgot.register", defaultMessage: "Send recovery link" })} />
</form>
</div>
</div>
);
}
type ServiceProps = {
service: Service
}
const ForgotPasswordPage = (props: ServiceProps) => {
useEffect(() => {
document.title = 'Forgot Password | WiseMapping';
});
return (
<div>
<Header type='only-signin' />
<RegistrationForm service={props.service} />
<Footer />
</div>
);
}
export { ForgotPasswordPage }

View File

@ -2,7 +2,7 @@ import React from 'react'
import { FormattedMessage } from 'react-intl'
import { Link } from 'react-router-dom'
const logo = require('../images/header-logo.png')
const logo = require('../../images/header-logo.png')
interface HeaderProps {
type: 'only-signup' | 'only-signin' | 'none';

View File

@ -2,11 +2,11 @@ import React, { useEffect } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { Link } from 'react-router-dom'
import Header from './Header'
import Footer from './Footer'
import SubmitButton from './SubmitButton'
import Header from '../header'
import Footer from '../footer'
import SubmitButton from '../submit-button'
const css = require('../css/login.css')
const css = require('../../css/login.css')
const ConfigStatusMessage = (props: any) => {
@ -53,8 +53,8 @@ const LoginForm = () => {
return (
<div className="wrapper">
<div className="content">
<h1><FormattedMessage id="login.welcome" defaultMessage="Welcome" /></h1>
<p><FormattedMessage id="login.loginto" defaultMessage="Log Into Your Account" /></p>
<h1><FormattedMessage id="login.title" defaultMessage="Welcome" /></h1>
<p><FormattedMessage id="login.desc" defaultMessage="Log Into Your Account" /></p>
<LoginError />

View File

@ -1,15 +1,15 @@
import React, { useState, useEffect} from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import ReCAPTCHA from "react-google-recaptcha"
import ReCAPTCHA from 'react-google-recaptcha'
import { useHistory } from "react-router-dom"
import { Service, NewUser } from '../services/Service'
import { Service, NewUser } from '../../services/Service'
import Header from './Header'
import Footer from './Footer'
import SubmitButton from './SubmitButton'
import Header from '../header'
import Footer from '../footer'
import SubmitButton from '../submit-button'
const css = require('../css/registration.css');
const css = require('../../css/registration.css');
interface ErrorMessageDialogProps {
message: string
@ -29,15 +29,16 @@ const ErrorMessageDialog = (props: ErrorMessageDialogProps) => {
type RegistrationBody = {
email: string;
firstName: string;
lastName: string;
firstname: string;
lastlname: string;
password: string;
recaptcha: string | null;
}
const RegistrationForm = (props: ServiceProps) => {
const [email, setEmail] = useState("");
const [lastName, setLastname] = useState("")
const [firstName, setFirstname] = useState("");
const [lastname, setLastname] = useState("")
const [firstname, setFirstname] = useState("");
const [password, setPassword] = useState("");
const [recaptchaToken, setRecaptchaToken] = useState<string | null>("");
const [errorMsg, setErrorMsg] = useState("");
@ -54,8 +55,8 @@ const RegistrationForm = (props: ServiceProps) => {
const user: NewUser =
{
email: email,
firstname: firstName,
lastname: lastName,
firstname: firstname,
lastname: lastname,
password: password,
recaptcha: String(recaptchaToken)
};
@ -71,10 +72,10 @@ const RegistrationForm = (props: ServiceProps) => {
return (
<div className="wrapper">
<div className="content">
<h1><FormattedMessage id="registration.become" defaultMessage="Become a member of our comunity" /></h1>
<p><FormattedMessage id="registration.signup" defaultMessage="Signing up is free and just take a moment " /></p>
<h1><FormattedMessage id="registration.title" defaultMessage="Become a member of our comunity" /></h1>
<p><FormattedMessage id="registration.desc" defaultMessage="Signing up is free and just take a moment " /></p>
<form method="POST" onSubmit={e => handleSubmit(e)}>
<form action="/" method="POST" onSubmit={e => handleSubmit(e)}>
<input type="email" name="email" onChange={e => setEmail(e.target.value)} placeholder={intl.formatMessage({ id: "registration.email", defaultMessage: "Email" })} required={true} autoComplete="email" />
<input type="text" name="firstname" onChange={e => setFirstname(e.target.value)} placeholder={intl.formatMessage({ id: "registration.firstname", defaultMessage: "First Name" })} required={true} autoComplete="given-name" />
<input type="text" name="lastname" onChange={e => setLastname(e.target.value)} placeholder={intl.formatMessage({ id: "registration.lastname", defaultMessage: "Last Name" })} required={true} autoComplete="family-name" />

View File

@ -1,10 +1,10 @@
import React, { useEffect } from 'react'
import { FormattedMessage } from 'react-intl'
import Header, { SignInButton } from './Header'
import Footer from './Footer'
import Header, { SignInButton } from '../header'
import Footer from '../footer'
const css = require('../css/success.css');
const css = require('../../css/success.css');
const RegistrationSuccessPage = () => {
@ -21,7 +21,7 @@ const RegistrationSuccessPage = () => {
<FormattedMessage id="registration.success.title" defaultMessage="Your account has been created successfully" />
</h1>
<p>
<FormattedMessage id="registration.success.desc" defaultMessage="Click to 'Sign In' button below and start creating mind maps." />
<FormattedMessage id="registration.success.desc" defaultMessage="Click 'Sign In' button below and start creating mind maps." />
</p>
<SignInButton style='style1'/>

View File

@ -136,19 +136,25 @@ nav a {
/* Footer */
.footer {
height: 170px;
margin-top: 50px;
padding: 30px 40px 10px 50px;
height: 250px;
margin-top: 80px;
padding: 60px 40px 10px 50px;
background-color: #f9a826;
display: grid;
}
.footer a {
font-size: 14px;
margin: 0px 10px;
color: white;
word-wrap: nowrap;
text-align: center;
}
.footer h4 {
font-size: 14px;
color: white;
word-wrap: nowrap;
font-weight: 500px;
margin: 0px;
}
.footer>svg {
@ -196,11 +202,8 @@ nav a {
.footer {
grid-template-columns: 0px 1fr 1fr 5px;
}
.footer>svg,
.footer div:nth-child(4) {
display: none;
visibility: hidden;
}
.footer div:nth-child(1),
.footer div:nth-child(4),
.header-area-content-span {
display: none;
visibility: hidden;
@ -291,6 +294,7 @@ input:placeholder {
}
.button-style1 a {
color: #f9a826;
background-color: white;
border: solid 1px #f9a826;
}

View File

@ -0,0 +1,39 @@
@import "core.css";
.wrapper {
max-width: 1024px;
display: grid;
grid-template-areas: "content" "footer";
}
.content {
grid-area: content;
text-align: center;
}
.content input:placeholder {
color: grey;
}
.content label {
font-size: 14px;
}
.content a {
color: #f9a826;
font-size: 15px;
}
.db-warn-msg {
margin-top: 30px;
width: 100%;
}
.db-warn-msg p {
margin: 0 auto;
width: 500px;
background-color: #e97450;
font-size: 15px;
color: white;
padding: 15px 30px;
border-radius: 10px;
}

View File

@ -20,20 +20,3 @@
color: #f9a826;
font-size: 30px;
}
/* .button-style1 {
font-size: 20px;
font-weight: 500;
font-stretch: normal;
font-style: normal;
letter-spacing: normal;
white-space: nowrap;
padding-top: 10px;
}
.button-style1 a {
padding: 10px 30px 10px 30px;
transition: background-color 0.3s ease;
border-radius: 9px;
} */

View File

@ -1,14 +1,17 @@
import axios from 'axios'
type NewUser = {
email: string;
firstname: string;
lastname: string;
password: string;
recaptcha: string;
}
recaptcha: string | null;
}
interface Service {
registerNewUser(user: NewUser, onSuccess: () => void, onError: (msg: string) => void): void;
resetPassword(email:string, onSuccess: () => void, onError: (msg: string) => void): void;
}
class RestService implements Service {
@ -56,5 +59,10 @@ class RestService implements Service {
onError(msg);
});
}
resetPassword(email:string, onSuccess: () => void, onError: (msg: string) => void): void {
}
}
export { Service, RestService, NewUser }