mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-22 06:37:56 +01:00
Compelte migration of summit form
This commit is contained in:
parent
503bc125c7
commit
911f131a2a
@ -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>
|
||||||
|
@ -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(() => {
|
||||||
|
@ -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(() => {
|
||||||
|
@ -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;
|
|
||||||
|
|
@ -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;
|
|
||||||
`
|
|
20
packages/webapp/src/components/form/global-error/index.tsx
Normal file
20
packages/webapp/src/components/form/global-error/index.tsx
Normal 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;
|
13
packages/webapp/src/components/form/global-error/styled.ts
Normal file
13
packages/webapp/src/components/form/global-error/styled.ts
Normal 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;
|
37
packages/webapp/src/components/form/input/index.tsx
Normal file
37
packages/webapp/src/components/form/input/index.tsx
Normal 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;
|
27
packages/webapp/src/components/form/input/styles.ts
Normal file
27
packages/webapp/src/components/form/input/styles.ts
Normal 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);
|
@ -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 (
|
@ -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';
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}`
|
||||||
`
|
|
@ -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";
|
||||||
|
|
||||||
|
|
@ -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,
|
@ -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>
|
||||||
|
|
@ -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;
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 }
|
@ -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 };
|
Loading…
Reference in New Issue
Block a user