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

View File

@ -3,37 +3,35 @@ import { FormattedMessage, useIntl } from 'react-intl'
import { useHistory } from "react-router-dom"
import { Service, ErrorInfo } from '../../services/Service'
import Header from '../header'
import Footer from '../footer'
import Header from '../layout/header'
import Footer from '../layout/footer'
import { PageContent } from '../../theme/global-style'
import FormErrorDialog from '../form-error-dialog'
import SubmitButton from '../submit-button'
type ForgotPasswordProps = {
email: string;
}
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'
const ForgotPassword = () => {
const [email, setEmail] = useState('');
const [errorMsg, setErrorMsg] = useState('');
const [disableButton, setDisableButton] = useState(false);
const [email, setEmail] = useState<string>('');
const [error, setError] = useState<ErrorInfo>();
const history = useHistory();
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>) => {
event.preventDefault();
setDisableButton(true);
// 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);
// });
mutation.mutate(email);
}
return (
@ -41,20 +39,18 @@ const ForgotPassword = () => {
<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>
<GlobalError error={error} />
<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} />
<SubmitButton disabled={disableButton} value={intl.formatMessage({ id: "forgot.register", defaultMessage: "Send recovery link" })} />
<input type="submit" value={intl.formatMessage({ id: "forgot.register", defaultMessage: "Send recovery link" })} />
</form>
</PageContent>
);
}
type ServiceProps = {
service: Service
}
const ForgotPasswordPage = () => {
useEffect(() => {

View File

@ -3,8 +3,8 @@ import { FormattedMessage } from 'react-intl'
import { PageContent } from '../../theme/global-style';
import Header, { SignInButton } from '../header'
import Footer from '../footer'
import Header, { SignInButton } from '../layout/header'
import Footer from '../layout/footer'
const ForgotPasswordSuccessPage = () => {
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 { StyledFooter } from './styled'
const logo = require('../../images/logo-text.svg')
const logo = require('../../../images/logo-text.svg')
const Footer = () => {
return (

View File

@ -4,7 +4,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

@ -3,12 +3,11 @@ import { FormattedMessage, useIntl } from 'react-intl'
import { Link } from 'react-router-dom'
import { PageContent } from '../../theme/global-style';
import FormErrorDialog from '../form-error-dialog'
import Header from '../header'
import Footer from '../footer'
import SubmitButton from '../submit-button'
import Header from '../layout/header'
import Footer from '../layout/footer'
import SubmitButton from '../form/submit-button'
import Input from '../form/input';
import GlobalError from '../form/global-error';
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." });
}
}
return <FormErrorDialog message={msg} />
<GlobalError error={{msg: msg}} />
return null;
}
const LoginPage = () => {
const intl = useIntl();
@ -60,17 +60,18 @@ const LoginPage = () => {
<LoginError />
<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 type="password" name="password" placeholder={intl.formatMessage({ id: "login.password", defaultMessage: "Password" })} required={true} autoComplete="current-password" />
<Input name="email" type="email" label={{ id: "login.email", defaultMessage: "Email" }} required={true} autoComplete="email" />
<Input name="password" type="password" label={{ id: "login.password", defaultMessage: "Password" }} required={true} autoComplete="current-password" />
<div>
<input name="_spring_security_login.remberme" id="staySignIn" type="checkbox" />
<label htmlFor="staySignIn"><FormattedMessage id="login.remberme" defaultMessage="Remember me" /></label>
</div>
<SubmitButton value={intl.formatMessage({ id: "login.signin", defaultMessage: "Sign In" })} />
</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' />
</PageContent>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,82 +1,96 @@
import React, { useState, useEffect } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import ReCAPTCHA from 'react-google-recaptcha'
import { useHistory } from "react-router-dom"
import { Service, NewUser, ErrorInfo } from '../../services/Service'
import FormErrorDialog from '../form-error-dialog'
import React, { useState, useEffect } from 'react';
import { FormattedMessage, useIntl } from 'react-intl';
import ReCAPTCHA from 'react-google-recaptcha';
import { useHistory } from 'react-router-dom';
import { ErrorInfo, Service } from '../../services/Service';
import Header from '../header'
import Footer from '../footer'
import SubmitButton from '../submit-button'
import Header from '../layout/header';
import Footer from '../layout/footer';
import { StyledReCAPTCHA } from './styled';
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 [email, setEmail] = useState('');
const [lastname, setLastname] = useState('')
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 [model, setModel] = useState<Model>(defaultModel);
const [error, setError] = useState<ErrorInfo>();
const history = useHistory();
const intl = useIntl();
const handleOnSubmit = (event: React.FormEvent<any>): void => {
event.preventDefault();
setDisableButton(true);
const user: NewUser =
const service: Service = useSelector(activeInstance);
const mutation = useMutation<void, ErrorInfo, Model>(
(model: Model) => service.registerNewUser({ ...model }),
{
email: email,
firstname: firstname,
lastname: lastname,
password: password,
recaptcha: String(recaptchaToken)
};
onSuccess: () => history.push("/c/registration-success"),
onError: (error) => {
setError(error);
}
}
);
// Call Service ...
// const service = props.service;
// service.registerNewUser(user)
// .then(() => {
// history.push("/c/registration-success")
// }).catch((error: ErrorInfo) => {
// const errorMsg = error.msg ? error.msg : undefined;
// setErrorMsg(errorMsg);
// setDisableButton(false);
// });
const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
event.preventDefault();
mutation.mutate(model);
};
const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
event.preventDefault();
const name = event.target.name;
const value = event.target.value;
setModel({ ...model, [name as keyof Model]: value });
}
return (
<PageContent>
<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 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" />
<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 type="password" name="password" onChange={e => setPassword(e.target.value)} placeholder={intl.formatMessage({ id: "registration.password", defaultMessage: "Password" })} required={true} autoComplete="new-password" />
<GlobalError error={error} />
<StyledReCAPTCHA>
<ReCAPTCHA
sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
onChange={setRecaptchaToken} />
</StyledReCAPTCHA>
<Input name="email" type="email" onChange={handleOnChange} label={{ id: "registration.email", defaultMessage: "Email" }}
autoComplete="email" />
<FormErrorDialog message={errorMsg} />
<Input name="firstname" type="text" onChange={handleOnChange} label={{ id: "registration.firstname", defaultMessage: "First Name" }}
autoComplete="given-name" />
<div style={{ width: "300px", textAlign: "center", fontSize: "13px", margin: "auto" }}>
<Input name="lastname" type="text" onChange={handleOnChange} label={{ id: "registration.lastname", defaultMessage: "Last Name" }}
autoComplete="family-name" />
<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" />
</div>
<SubmitButton disabled={disableButton} value={intl.formatMessage({ id: "registration.register", defaultMessage: "Register" })} />
<input type="submit" value={intl.formatMessage({ id: "registration.register", defaultMessage: "Register" })} />
</form>
</PageContent >
);
@ -91,7 +105,7 @@ const RegistationPage = () => {
return (
<div>
<Header type='only-signin' />
<RegistrationForm/>
<RegistrationForm />
<Footer />
</div>
);

View File

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

View File

@ -43,7 +43,7 @@ interface Service {
loadMapInfo(id: number): Promise<BasicMapInfo>;
}
class RestService implements Service {
class MockService implements Service {
private baseUrl: string;
private authFailed: () => void
private maps: MapInfo[] = [];
@ -129,7 +129,7 @@ class RestService implements Service {
resetPassword(email: string): Promise<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,
{ headers: { 'Content-Type': 'application/json' } }
).then(response => {
@ -142,7 +142,6 @@ class RestService implements Service {
});
}
return new Promise(handler);
}
private parseResponseOnError = (response: any): ErrorInfo => {
@ -159,7 +158,7 @@ class RestService implements Service {
break;
default:
if (data) {
// Set global errorrs ...
// Set global errors ...
if (data.globalErrors) {
let msg;
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';
@ -87,20 +89,6 @@ padding: 20px 10px 20px 10px;
/* 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] {
border: solid 1px #f9a826;
background-color: #f9a826;
@ -108,7 +96,7 @@ padding: 20px 10px 20px 10px;
& input[type=submit],
& input[type=button] {
width: 258px;
width: 300px;
height: 53px;
padding: 0px 20px;
margin: 10px 20px;
@ -157,5 +145,4 @@ padding: 20px 10px 20px 10px;
`;
export { GlobalStyle, PageContent };