mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-25 15:47:55 +01:00
Start forgot password
This commit is contained in:
parent
7c53c6b9c7
commit
a6fe41b5c9
@ -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",
|
||||
|
@ -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" /> -->
|
||||
|
@ -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>
|
||||
|
@ -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 & 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>
|
@ -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 }
|
||||
|
||||
|
@ -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';
|
@ -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 />
|
||||
|
@ -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" />
|
@ -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'/>
|
@ -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;
|
||||
}
|
||||
|
39
packages/webapp/src/css/reset-password.css
Normal file
39
packages/webapp/src/css/reset-password.css
Normal 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;
|
||||
}
|
@ -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;
|
||||
} */
|
@ -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 }
|
Loading…
Reference in New Issue
Block a user