Compelte migration of summit form

This commit is contained in:
Paulo Gustavo Veiga 2020-12-27 09:58:21 -08:00
parent 503bc125c7
commit 911f131a2a
25 changed files with 270 additions and 202 deletions

View File

@ -12,6 +12,7 @@ import store from "./store";
import { ForgotPasswordPage } from './components/forgot-password-page'; import { ForgotPasswordPage } from './components/forgot-password-page';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { QueryClient, QueryClientProvider } from 'react-query';
function loadLocaleData(language: string) { function loadLocaleData(language: string) {
switch (language) { switch (language) {
@ -22,19 +23,14 @@ function loadLocaleData(language: string) {
} }
} }
type AppProps = { const queryClient = new QueryClient();
baseRestUrl: string;
}
const App = () => { const App = () => {
const [messages, setMessages] = useState(undefined); const [messages, setMessages] = useState(undefined);
// Boostrap i18n ... // Boostrap i18n ...
const locale = (navigator.languages && navigator.languages[0]) const locale = (navigator.languages && navigator.languages[0])
|| navigator.language || navigator.language
|| 'en-US'; || 'en-US';
useEffect(() => { useEffect(() => {
const language = locale.split('-')[0]; const language = locale.split('-')[0];
const fetchData = async () => { const fetchData = async () => {
@ -47,28 +43,30 @@ const App = () => {
return messages ? ( return messages ? (
<Provider store={store}> <Provider store={store}>
<IntlProvider locale={locale} defaultLocale='en' messages={messages}> <QueryClientProvider client={queryClient}>
<GlobalStyle /> <IntlProvider locale={locale} defaultLocale='en' messages={messages}>
<Router> <GlobalStyle />
<Switch> <Router>
<Route exact path="/"> <Switch>
<Redirect to="/c/login" /> <Route exact path="/">
</Route> <Redirect to="/c/login" />
<Route path="/c/login" component={LoginPage} /> </Route>
<Route path="/c/registration"> <Route path="/c/login" component={LoginPage} />
<RegistationPage /> <Route path="/c/registration">
</Route> <RegistationPage />
<Route path="/c/registration-success" component={RegistrationSuccessPage} /> </Route>
<Route path="/c/forgot-password"> <Route path="/c/registration-success" component={RegistrationSuccessPage} />
<ForgotPasswordPage /> <Route path="/c/forgot-password">
</Route> <ForgotPasswordPage />
<Route path="/c/forgot-password-success" component={ForgotPasswordSuccessPage} /> </Route>
<Route path="/c/maps/"> <Route path="/c/forgot-password-success" component={ForgotPasswordSuccessPage} />
<MapsPage /> <Route path="/c/maps/">
</Route> <MapsPage />
</Switch> </Route>
</Router> </Switch>
</IntlProvider> </Router>
</IntlProvider>
</QueryClientProvider>
</Provider> </Provider>
) : <div>Loading ... </div> ) : <div>Loading ... </div>

View File

@ -3,37 +3,35 @@ import { FormattedMessage, useIntl } from 'react-intl'
import { useHistory } from "react-router-dom" import { useHistory } from "react-router-dom"
import { Service, ErrorInfo } from '../../services/Service' import { Service, ErrorInfo } from '../../services/Service'
import Header from '../header' import Header from '../layout/header'
import Footer from '../footer' import Footer from '../layout/footer'
import { PageContent } from '../../theme/global-style' import { PageContent } from '../../theme/global-style'
import FormErrorDialog from '../form-error-dialog' import { useSelector } from 'react-redux'
import SubmitButton from '../submit-button' import { useMutation } from 'react-query'
import { activeInstance } from '../../reducers/serviceSlice'
type ForgotPasswordProps = { import Input from '../form/input'
email: string; import GlobalError from '../form/global-error'
}
const ForgotPassword = () => { const ForgotPassword = () => {
const [email, setEmail] = useState(''); const [email, setEmail] = useState<string>('');
const [errorMsg, setErrorMsg] = useState(''); const [error, setError] = useState<ErrorInfo>();
const [disableButton, setDisableButton] = useState(false);
const history = useHistory(); const history = useHistory();
const intl = useIntl(); const intl = useIntl();
const service: Service = useSelector(activeInstance);
const mutation = useMutation<void, ErrorInfo, string>(
(email: string) => service.resetPassword(email),
{
onSuccess: () => history.push("/c/forgot-password-success"),
onError: (error) => {
setError(error);
}
}
);
const handleOnSubmit = (event: React.FormEvent<any>) => { const handleOnSubmit = (event: React.FormEvent<any>) => {
event.preventDefault(); event.preventDefault();
setDisableButton(true); mutation.mutate(email);
// Call Service ...
// const service = props.service;
// service.resetPassword(email)
// .then(() => {
// history.push("/c/forgot-password-success");
// }).catch((error: ErrorInfo) => {
// setErrorMsg(error.msg ? error.msg : '');
// setDisableButton(false);
// });
} }
return ( return (
@ -41,20 +39,18 @@ const ForgotPassword = () => {
<h1><FormattedMessage id="forgot.title" defaultMessage="Reset your password" /></h1> <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> <p><FormattedMessage id="forgot.desc" defaultMessage="We will send you an email to reset your password" /></p>
<GlobalError error={error} />
<form onSubmit={handleOnSubmit}> <form onSubmit={handleOnSubmit}>
<input type="email" name="email" onChange={e => setEmail(e.target.value)} placeholder={intl.formatMessage({ id: "forgot.email", defaultMessage: "Email" })} required={true} autoComplete="email" /> <Input type="email" name="email" label={{ id: "forgot.email", defaultMessage: "Email" }}
autoComplete="email" onChange={e => setEmail(e.target.value)} />
<FormErrorDialog message={errorMsg} /> <input type="submit" value={intl.formatMessage({ id: "forgot.register", defaultMessage: "Send recovery link" })} />
<SubmitButton disabled={disableButton} value={intl.formatMessage({ id: "forgot.register", defaultMessage: "Send recovery link" })} />
</form> </form>
</PageContent> </PageContent>
); );
} }
type ServiceProps = {
service: Service
}
const ForgotPasswordPage = () => { const ForgotPasswordPage = () => {
useEffect(() => { useEffect(() => {

View File

@ -3,8 +3,8 @@ import { FormattedMessage } from 'react-intl'
import { PageContent } from '../../theme/global-style'; import { PageContent } from '../../theme/global-style';
import Header, { SignInButton } from '../header' import Header, { SignInButton } from '../layout/header'
import Footer from '../footer' import Footer from '../layout/footer'
const ForgotPasswordSuccessPage = () => { const ForgotPasswordSuccessPage = () => {
useEffect(() => { useEffect(() => {

View File

@ -1,12 +0,0 @@
import React from 'react'
import { StyleDiv } from './styled'
type FormErrorDialogProps = {
message?: string;
}
const FormErrorDialog = (props: FormErrorDialogProps) => {
return props.message ? <StyleDiv>{props.message}</StyleDiv > : null;
}
export default FormErrorDialog;

View File

@ -1,12 +0,0 @@
import styled from 'styled-components';
export const StyleDiv = styled.div`
margin: 10px auto;
width: 260px;
font-size: 15px;
border: 2px solid #e97450;
padding: 10px 10px;
border-radius: 9px;
color: white;
background-color: #e78b72;
`

View File

@ -0,0 +1,20 @@
import React from "react";
import { ErrorInfo } from "../../../services/Service"
import StyledAlert from "./styled";
type GlobalErrorProps = {
error?: ErrorInfo;
}
const GlobalError = (props: GlobalErrorProps) => {
const error = props.error;
const hasError = Boolean(error?.msg);
const errorMsg = error?.msg;
return (hasError ? <StyledAlert severity="error" variant="filled" hidden={!hasError}> {errorMsg}</StyledAlert> : null);
};
export default GlobalError;

View File

@ -0,0 +1,13 @@
import { withStyles } from "@material-ui/core";
import { Alert } from "@material-ui/lab";
export const StyledAlert = withStyles({
root:
{
width: '300px',
margin:'0 auto'
}
})(Alert);
export default StyledAlert;

View File

@ -0,0 +1,37 @@
import { FormControl, TextField } from "@material-ui/core";
import React, { ChangeEvent } from "react";
import { MessageDescriptor, useIntl } from "react-intl";
import { ErrorInfo } from "../../../services/Service";
import { StyledTextField } from "./styles";
type InputProps = {
name: string;
error?: ErrorInfo;
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
label: MessageDescriptor;
required?: boolean;
type: string;
value?: string
autoComplete?: string;
}
const Input = (props: InputProps) => {
const intl = useIntl();
const error: ErrorInfo | undefined = props?.error;
const name = props.name;
const value = props.value;
const onChange = props.onChange ? props.onChange : () => { };
const fieldError = error?.fields?.get(name);
const required = props.required ? props.required : true;
return (
<FormControl margin="normal" required={required} fullWidth>
<StyledTextField name={name} type={props.type} label={intl.formatMessage(props.label)}
value={value} onChange={onChange}
error={Boolean(fieldError)} helperText={fieldError}
variant="outlined" required={required} />
</FormControl>
);
}
export default Input;

View File

@ -0,0 +1,27 @@
import { TextField, withStyles } from "@material-ui/core";
export const StyledTextField = withStyles({
root:
{
margin: '0 auto',
'& label.Mui-focused': {
color: '#f9a826',
},
'& .MuiOutlinedInput-root': {
width: '300px',
height: '53px',
borderRadius: '9px',
fontSize: '16px',
'& fieldset': {
border: 'solid 1px #ffcb66',
},
'&:hover fieldset': {
borderColor: '#f9a826',
},
'&.Mui-focused fieldset': {
borderColor: '#f9a826'
},
},
},
})(TextField);

View File

@ -2,7 +2,7 @@ import React from 'react'
import { FormattedMessage } from 'react-intl' import { FormattedMessage } from 'react-intl'
import { StyledFooter } from './styled' import { StyledFooter } from './styled'
const logo = require('../../images/logo-text.svg') const logo = require('../../../images/logo-text.svg')
const Footer = () => { const Footer = () => {
return ( return (

View File

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

View File

@ -3,12 +3,11 @@ import { FormattedMessage, useIntl } from 'react-intl'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { PageContent } from '../../theme/global-style'; import { PageContent } from '../../theme/global-style';
import FormErrorDialog from '../form-error-dialog' import Header from '../layout/header'
import Footer from '../layout/footer'
import SubmitButton from '../form/submit-button'
import Header from '../header' import Input from '../form/input';
import Footer from '../footer' import GlobalError from '../form/global-error';
import SubmitButton from '../submit-button'
const ConfigStatusMessage = (props: any) => { const ConfigStatusMessage = (props: any) => {
@ -38,10 +37,11 @@ const LoginError = () => {
msg = intl.formatMessage({ id: "login.error", defaultMessage: "The email address or password you entered is not valid." }); msg = intl.formatMessage({ id: "login.error", defaultMessage: "The email address or password you entered is not valid." });
} }
} }
return <FormErrorDialog message={msg} /> <GlobalError error={{msg: msg}} />
return null;
} }
const LoginPage = () => { const LoginPage = () => {
const intl = useIntl(); const intl = useIntl();
@ -60,17 +60,18 @@ const LoginPage = () => {
<LoginError /> <LoginError />
<form action="/c/perform-login" method="POST"> <form action="/c/perform-login" method="POST">
<input type="email" name="username" placeholder={intl.formatMessage({ id: "login.email", defaultMessage: "Email" })} required={true} autoComplete="email" /> <Input name="email" type="email" label={{ id: "login.email", defaultMessage: "Email" }} required={true} autoComplete="email" />
<input type="password" name="password" placeholder={intl.formatMessage({ id: "login.password", defaultMessage: "Password" })} required={true} autoComplete="current-password" /> <Input name="password" type="password" label={{ id: "login.password", defaultMessage: "Password" }} required={true} autoComplete="current-password" />
<div> <div>
<input name="_spring_security_login.remberme" id="staySignIn" type="checkbox" /> <input name="_spring_security_login.remberme" id="staySignIn" type="checkbox" />
<label htmlFor="staySignIn"><FormattedMessage id="login.remberme" defaultMessage="Remember me" /></label> <label htmlFor="staySignIn"><FormattedMessage id="login.remberme" defaultMessage="Remember me" /></label>
</div> </div>
<SubmitButton value={intl.formatMessage({ id: "login.signin", defaultMessage: "Sign In" })} /> <SubmitButton value={intl.formatMessage({ id: "login.signin", defaultMessage: "Sign In" })} />
</form> </form>
<Link to="/c/forgot-password"><FormattedMessage id="login.forgotpwd" defaultMessage="Forgot Password ?" /></Link>
<Link to="/c/forgot-password"><FormattedMessage id="login.forgotpwd" defaultMessage="Forgot Password ?" /></Link>
<ConfigStatusMessage enabled='false' /> <ConfigStatusMessage enabled='false' />
</PageContent> </PageContent>

View File

@ -1,3 +1,4 @@
import { TextField, withStyles } from '@material-ui/core';
import styled from 'styled-components'; import styled from 'styled-components';
@ -15,5 +16,5 @@ export const StyledNav = styled.div`
color: white; color: white;
padding: 15px 30px; padding: 15px 30px;
border-radius: 10px; border-radius: 10px;
} }`
`

View File

@ -4,8 +4,8 @@ import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { useMutation, useQueryClient } from "react-query"; import { useMutation, useQueryClient } from "react-query";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { Service } from "../../services/Service"; import { Service } from "../../../services/Service";
import { activeInstance } from '../../reducers/serviceSlice'; import { activeInstance } from '../../../reducers/serviceSlice';
import { DialogProps, fetchMapById, handleOnMutationSuccess } from "./DialogCommon"; import { DialogProps, fetchMapById, handleOnMutationSuccess } from "./DialogCommon";

View File

@ -1,7 +1,7 @@
import { QueryClient, useQuery } from "react-query"; import { QueryClient, useQuery } from "react-query";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { ErrorInfo, MapInfo, Service } from "../../services/Service"; import { ErrorInfo, MapInfo, Service } from "../../../services/Service";
import { activeInstance, } from '../../reducers/serviceSlice'; import { activeInstance, } from '../../../reducers/serviceSlice';
type MapLoadResult = { type MapLoadResult = {
isLoading: boolean, isLoading: boolean,

View File

@ -4,8 +4,8 @@ import React, { useEffect } from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { useMutation, useQueryClient } from "react-query"; import { useMutation, useQueryClient } from "react-query";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { BasicMapInfo, ErrorInfo, Service } from "../../services/Service"; import { BasicMapInfo, ErrorInfo, Service } from "../../../services/Service";
import { activeInstance } from '../../reducers/serviceSlice'; import { activeInstance } from '../../../reducers/serviceSlice';
import { DialogProps, fetchMapById, handleOnMutationSuccess } from "./DialogCommon"; import { DialogProps, fetchMapById, handleOnMutationSuccess } from "./DialogCommon";
export type RenameModel = { export type RenameModel = {
@ -13,8 +13,8 @@ export type RenameModel = {
name: string; name: string;
description?: string; description?: string;
} }
const defaultModel: RenameModel = { name: '', description: '', id: -1 };
const defaultModel: RenameModel = { name: '', description: '', id: -1 };
const RenameDialog = (props: DialogProps) => { const RenameDialog = (props: DialogProps) => {
const service: Service = useSelector(activeInstance); const service: Service = useSelector(activeInstance);
const [model, setModel] = React.useState<RenameModel>(defaultModel); const [model, setModel] = React.useState<RenameModel>(defaultModel);
@ -70,7 +70,7 @@ const RenameDialog = (props: DialogProps) => {
return ( return (
<div> <div>
<Dialog <Dialog
open={props.open} open={open}
onClose={() => handleOnClose()} > onClose={() => handleOnClose()} >
<form autoComplete="off" onSubmit={handleOnSubmit}> <form autoComplete="off" onSubmit={handleOnSubmit}>
<DialogTitle> <DialogTitle>
@ -83,6 +83,7 @@ const RenameDialog = (props: DialogProps) => {
</DialogContentText> </DialogContentText>
{Boolean(error?.msg) ? <Alert severity="error" variant="filled" hidden={!Boolean(error?.msg)}>{error?.msg}</Alert> : null} {Boolean(error?.msg) ? <Alert severity="error" variant="filled" hidden={!Boolean(error?.msg)}>{error?.msg}</Alert> : null}
<FormControl margin="normal" required fullWidth> <FormControl margin="normal" required fullWidth>
<TextField name="name" label={intl.formatMessage({ id: "action.rename-name-placeholder", defaultMessage: "Name" })} <TextField name="name" label={intl.formatMessage({ id: "action.rename-name-placeholder", defaultMessage: "Name" })}
value={model.name} onChange={handleOnChange} value={model.name} onChange={handleOnChange}
@ -90,7 +91,8 @@ const RenameDialog = (props: DialogProps) => {
variant="filled" required={true} /> variant="filled" required={true} />
</FormControl> </FormControl>
<FormControl margin="normal" required fullWidth> <FormControl margin="normal" required fullWidth>
<TextField name="description" label={intl.formatMessage({ id: "action.rename-description-placeholder", defaultMessage: "Description" })} value={model.description} onChange={handleOnChange} variant="filled" /> <TextField name="description" label={intl.formatMessage({ id: "action.rename-description-placeholder", defaultMessage: "Description" })}
value={model.description} onChange={handleOnChange} variant="filled" />
</FormControl> </FormControl>
</DialogContent> </DialogContent>

View File

@ -22,10 +22,10 @@ import StarRateRoundedIcon from '@material-ui/icons/StarRateRounded';
import MoreHorizIcon from '@material-ui/icons/MoreHoriz'; import MoreHorizIcon from '@material-ui/icons/MoreHoriz';
import { CSSProperties } from 'react'; import { CSSProperties } from 'react';
import MapActionMenu, { ActionType } from './MapActionMenu'; import MapActionMenu, { ActionType } from './MapActionMenu';
import ActionDialog, { DialogType } from './ActionDialog'; import ActionDialog, { DialogType } from './dialogs/ActionDialog';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { activeInstance } from '../../reducers/serviceSlice'; import { activeInstance } from '../../reducers/serviceSlice';
import { QueryClient, QueryClientProvider, useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { ErrorInfo, MapInfo, Service } from '../../services/Service'; import { ErrorInfo, MapInfo, Service } from '../../services/Service';
@ -225,7 +225,7 @@ const EnhancedTable = () => {
const service: Service = useSelector(activeInstance); const service: Service = useSelector(activeInstance);
const { isLoading, error, data } = useQuery<unknown, ErrorInfo, MapInfo[]>('maps', async () => { const { isLoading, error, data } = useQuery<unknown, ErrorInfo, MapInfo[]>('maps', async () => {
const result = await service.fetchAllMaps(); const result = await service.fetchAllMaps();
return result; return result;
}); });
@ -409,7 +409,6 @@ const EnhancedTable = () => {
const queryClient = new QueryClient();
const MapsPage = () => { const MapsPage = () => {
useEffect(() => { useEffect(() => {
@ -417,19 +416,17 @@ const MapsPage = () => {
}, []); }, []);
return ( return (
<QueryClientProvider client={queryClient}> <PageContainer>
<PageContainer> <HeaderArea>
<HeaderArea> <h2>Header</h2>
<h2>Header</h2> </HeaderArea>
</HeaderArea> <NavArea>
<NavArea> <h1> Nav </h1>
<h1> Nav </h1> </NavArea>
</NavArea> <MapsListArea>
<MapsListArea> <EnhancedTable />
<EnhancedTable /> </MapsListArea>
</MapsListArea> </PageContainer>
</PageContainer>
</QueryClientProvider>
); );
} }
export default MapsPage; export default MapsPage;

View File

@ -1,82 +1,96 @@
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react';
import { FormattedMessage, useIntl } from 'react-intl' 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 { useHistory } from 'react-router-dom';
import { Service, NewUser, ErrorInfo } from '../../services/Service' import { ErrorInfo, Service } from '../../services/Service';
import FormErrorDialog from '../form-error-dialog'
import Header from '../header' import Header from '../layout/header';
import Footer from '../footer' import Footer from '../layout/footer';
import SubmitButton from '../submit-button'
import { StyledReCAPTCHA } from './styled'; import { StyledReCAPTCHA } from './styled';
import { PageContent } from '../../theme/global-style'; import { PageContent } from '../../theme/global-style';
import { FormControl } from '@material-ui/core';
import { useSelector } from 'react-redux';
import { useMutation } from 'react-query';
import { activeInstance } from '../../reducers/serviceSlice';
import Input from '../form/input';
import GlobalError from '../form/global-error';
export type Model = {
email: string;
lastname: string;
firstname: string;
password: string;
recaptcha: string;
}
const defaultModel: Model = { email: '', lastname: '', firstname: '', password: '', recaptcha: '' };
const RegistrationForm = () => { const RegistrationForm = () => {
const [email, setEmail] = useState(''); const [model, setModel] = useState<Model>(defaultModel);
const [lastname, setLastname] = useState('') const [error, setError] = useState<ErrorInfo>();
const [firstname, setFirstname] = useState('');
const [password, setPassword] = useState('');
const [recaptchaToken, setRecaptchaToken] = useState<string | null>('');
const [errorMsg, setErrorMsg] = useState<string | undefined>();
const [disableButton, setDisableButton] = useState(false);
const history = useHistory(); const history = useHistory();
const intl = useIntl(); const intl = useIntl();
const service: Service = useSelector(activeInstance);
const handleOnSubmit = (event: React.FormEvent<any>): void => { const mutation = useMutation<void, ErrorInfo, Model>(
event.preventDefault(); (model: Model) => service.registerNewUser({ ...model }),
setDisableButton(true);
const user: NewUser =
{ {
email: email, onSuccess: () => history.push("/c/registration-success"),
firstname: firstname, onError: (error) => {
lastname: lastname, setError(error);
password: password, }
recaptcha: String(recaptchaToken) }
}; );
// Call Service ... const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
// const service = props.service; event.preventDefault();
// service.registerNewUser(user) mutation.mutate(model);
// .then(() => { };
// history.push("/c/registration-success")
// }).catch((error: ErrorInfo) => { const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
// const errorMsg = error.msg ? error.msg : undefined; event.preventDefault();
// setErrorMsg(errorMsg);
// setDisableButton(false); const name = event.target.name;
// }); const value = event.target.value;
setModel({ ...model, [name as keyof Model]: value });
} }
return ( return (
<PageContent> <PageContent>
<h1><FormattedMessage id="registration.title" defaultMessage="Become a member of our comunity" /></h1> <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> <p><FormattedMessage id="registration.desc" defaultMessage="Signing up is free and just take a moment " /></p>
<form onSubmit={handleOnSubmit}> <form onSubmit={handleOnSubmit}>
<input type="email" name="email" onChange={e => setEmail(e.target.value)} placeholder={intl.formatMessage({ id: "registration.email", defaultMessage: "Email" })} required={true} autoComplete="email" /> <GlobalError error={error} />
<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" /> <Input name="email" type="email" onChange={handleOnChange} label={{ id: "registration.email", defaultMessage: "Email" }}
<input type="password" name="password" onChange={e => setPassword(e.target.value)} placeholder={intl.formatMessage({ id: "registration.password", defaultMessage: "Password" })} required={true} autoComplete="new-password" /> autoComplete="email" />
<StyledReCAPTCHA> <Input name="firstname" type="text" onChange={handleOnChange} label={{ id: "registration.firstname", defaultMessage: "First Name" }}
<ReCAPTCHA autoComplete="given-name" />
sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
onChange={setRecaptchaToken} />
</StyledReCAPTCHA>
<FormErrorDialog message={errorMsg} /> <Input name="lastname" type="text" onChange={handleOnChange} label={{ id: "registration.lastname", defaultMessage: "Last Name" }}
autoComplete="family-name" />
<div style={{ width: "300px", textAlign: "center", fontSize: "13px", margin: "auto" }}> <Input name="password" type="password" onChange={handleOnChange} label={{ id: "registration.password", defaultMessage: "Password" }}
autoComplete="new-password" />
<FormControl>
<StyledReCAPTCHA>
<ReCAPTCHA
sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
onChange={(value: string) => { model.recaptcha = value; setModel(model) }} />
</StyledReCAPTCHA>
</FormControl>
<div style={{ width: "300px", textAlign: "center", fontSize: "12px", margin: "auto" }}>
<FormattedMessage id="registration.termandconditions" defaultMessage="Terms of Service: Please check the WiseMapping Account information you've entered above, and review the Terms of Service here. By clicking on 'Register' below you are agreeing to the Terms of Service above and the Privacy Policy" /> <FormattedMessage id="registration.termandconditions" defaultMessage="Terms of Service: Please check the WiseMapping Account information you've entered above, and review the Terms of Service here. By clicking on 'Register' below you are agreeing to the Terms of Service above and the Privacy Policy" />
</div> </div>
<SubmitButton disabled={disableButton} value={intl.formatMessage({ id: "registration.register", defaultMessage: "Register" })} /> <input type="submit" value={intl.formatMessage({ id: "registration.register", defaultMessage: "Register" })} />
</form> </form>
</PageContent > </PageContent >
); );
@ -91,7 +105,7 @@ const RegistationPage = () => {
return ( return (
<div> <div>
<Header type='only-signin' /> <Header type='only-signin' />
<RegistrationForm/> <RegistrationForm />
<Footer /> <Footer />
</div> </div>
); );

View File

@ -3,8 +3,8 @@ import { FormattedMessage } from 'react-intl'
import {PageContent} from '../../theme/global-style'; import {PageContent} from '../../theme/global-style';
import Header, { SignInButton } from '../header' import Header, { SignInButton } from '../layout/header'
import Footer from '../footer' import Footer from '../layout/footer'

View File

@ -43,7 +43,7 @@ interface Service {
loadMapInfo(id: number): Promise<BasicMapInfo>; loadMapInfo(id: number): Promise<BasicMapInfo>;
} }
class RestService implements Service { class MockService implements Service {
private baseUrl: string; private baseUrl: string;
private authFailed: () => void private authFailed: () => void
private maps: MapInfo[] = []; private maps: MapInfo[] = [];
@ -129,7 +129,7 @@ class RestService implements Service {
resetPassword(email: string): Promise<void> { resetPassword(email: string): Promise<void> {
const handler = (success: () => void, reject: (error: ErrorInfo) => void) => { const handler = (success: () => void, reject: (error: ErrorInfo) => void) => {
axios.post(this.baseUrl + '/service/users/resetPassword?email=' + email, axios.post(`${this.baseUrl}/service/users/resetPassword?email=${email}`,
null, null,
{ headers: { 'Content-Type': 'application/json' } } { headers: { 'Content-Type': 'application/json' } }
).then(response => { ).then(response => {
@ -142,7 +142,6 @@ class RestService implements Service {
}); });
} }
return new Promise(handler); return new Promise(handler);
} }
private parseResponseOnError = (response: any): ErrorInfo => { private parseResponseOnError = (response: any): ErrorInfo => {
@ -159,7 +158,7 @@ class RestService implements Service {
break; break;
default: default:
if (data) { if (data) {
// Set global errorrs ... // Set global errors ...
if (data.globalErrors) { if (data.globalErrors) {
let msg; let msg;
let errors = data.globalErrors; let errors = data.globalErrors;
@ -191,4 +190,4 @@ class RestService implements Service {
} }
} }
export { Service, RestService } export { Service, MockService as RestService }

View File

@ -1,3 +1,5 @@
import { TextField, withStyles } from '@material-ui/core';
import { Alert } from '@material-ui/lab';
import styled, { createGlobalStyle } from 'styled-components'; import styled, { createGlobalStyle } from 'styled-components';
@ -87,20 +89,6 @@ padding: 20px 10px 20px 10px;
/* Form Styles Section */ /* Form Styles Section */
& input[type=email],
& input[type=password],
& input[type=text] {
width: 258px;
height: 53px;
padding: 0px 20px;
margin: 10px 20px;
border-radius: 9px;
font-size: 16px;
border: solid 1px #f9a826;
display: block;
margin: 10px auto;
}
& input[type=checkbox] { & input[type=checkbox] {
border: solid 1px #f9a826; border: solid 1px #f9a826;
background-color: #f9a826; background-color: #f9a826;
@ -108,7 +96,7 @@ padding: 20px 10px 20px 10px;
& input[type=submit], & input[type=submit],
& input[type=button] { & input[type=button] {
width: 258px; width: 300px;
height: 53px; height: 53px;
padding: 0px 20px; padding: 0px 20px;
margin: 10px 20px; margin: 10px 20px;
@ -157,5 +145,4 @@ padding: 20px 10px 20px 10px;
`; `;
export { GlobalStyle, PageContent }; export { GlobalStyle, PageContent };