mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-10 17:33:24 +01:00
Migration to TypeScript
This commit is contained in:
parent
c7f0c3e02e
commit
cd72287481
@ -44,5 +44,8 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"homepage": "http://localhost:8080/react",
|
"homepage": "http://localhost:8080/react",
|
||||||
"license": "https://wisemapping.atlassian.net/wiki/spaces/WS/pages/524357/WiseMapping+Public+License+Version+1.0+WPL"
|
"license": "https://wisemapping.atlassian.net/wiki/spaces/WS/pages/524357/WiseMapping+Public+License+Version+1.0+WPL",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react-google-recaptcha": "^2.1.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,58 +1,48 @@
|
|||||||
{
|
{
|
||||||
"name": "@wisemapping/login",
|
"name": "@wisemapping/login",
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"main": "src/app.jsx",
|
"main": "app.jsx",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "webpack serve",
|
||||||
"build": "react-scripts build",
|
"build": "webpack --mode production",
|
||||||
"test": "react-scripts test",
|
"lint": "eslint src"
|
||||||
"eject": "react-scripts eject",
|
},
|
||||||
"extract": "formatjs extract",
|
"repository": "http://www.wisemapping.com",
|
||||||
"compile": "formatjs compile"
|
"author": "Paulo Veiga <pveiga@gmail.com>, Ezequiel Bergamaschi <ezequielbergamaschi@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"private": false,
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/preset-env": "^7.12.7",
|
||||||
|
"@babel/preset-react": "^7.12.7",
|
||||||
|
"@types/react": "^17.0.0",
|
||||||
|
"@types/react-dom": "^17.0.0",
|
||||||
|
"@types/react-router-dom": "^5.1.6",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
||||||
|
"@typescript-eslint/parser": "^4.8.1",
|
||||||
|
"babel-loader": "^8.2.2",
|
||||||
|
"clean-webpack-plugin": "^3.0.0",
|
||||||
|
"css-loader": "^5.0.1",
|
||||||
|
"eslint": "^7.14.0",
|
||||||
|
"eslint-plugin-react": "^7.21.5",
|
||||||
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
|
"html-webpack-plugin": "^4.5.0",
|
||||||
|
"sass-loader": "^10.1.0",
|
||||||
|
"style-loader": "^2.0.0",
|
||||||
|
"svg-url-loader": "^7.1.1",
|
||||||
|
"ts-loader": "^8.0.11",
|
||||||
|
"ts-node": "^9.0.0",
|
||||||
|
"typescript": "^4.1.2",
|
||||||
|
"url-loader": "^4.1.1",
|
||||||
|
"webpack": "^5.6.0",
|
||||||
|
"webpack-cli": "^4.2.0",
|
||||||
|
"webpack-dev-server": "^3.11.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
"cors": "^2.8.5",
|
|
||||||
"joi": "^17.3.0",
|
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-google-recaptcha": "^2.1.0",
|
"react-intl": "^5.10.6",
|
||||||
"react-intl": "^5.10.5",
|
"react-recaptcha-v3": "^2.0.1",
|
||||||
"web-vitals": "^0.2.4",
|
"react-router-dom": "^5.2.0"
|
||||||
"chokidar": "^3.4.3"
|
}
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@formatjs/cli": "^2.13.14",
|
|
||||||
"@testing-library/jest-dom": "^5.11.6",
|
|
||||||
"@testing-library/react": "^11.2.2",
|
|
||||||
"@testing-library/user-event": "^12.2.2",
|
|
||||||
"react-scripts": "4.0.1"
|
|
||||||
},
|
|
||||||
"author": {
|
|
||||||
"name": "Paulo Veiga",
|
|
||||||
"login.email": "pveiga@wisemapping.com"
|
|
||||||
},
|
|
||||||
"contributors": [
|
|
||||||
"Ezequiel Bergamaschi"
|
|
||||||
],
|
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"react-app",
|
|
||||||
"react-app/jest"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"browserslist": {
|
|
||||||
"production": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not op_mini all"
|
|
||||||
],
|
|
||||||
"development": [
|
|
||||||
"last 1 chrome version",
|
|
||||||
"last 1 firefox version",
|
|
||||||
"last 1 safari version"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"homepage": "http://localhost:8080/react",
|
|
||||||
"license": "https://wisemapping.atlassian.net/wiki/spaces/WS/pages/524357/WiseMapping+Public+License+Version+1.0+WPL"
|
|
||||||
}
|
}
|
@ -1,28 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { FormattedMessage } from 'react-intl'
|
|
||||||
import { ReactComponent as SvgLogo } from './images/logo-text.svg'
|
|
||||||
|
|
||||||
class Footer extends React.Component {
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<footer className="footer" >
|
|
||||||
{/* FIXME: we have to unify the way we load SVGs <Logo />*/}
|
|
||||||
<div >
|
|
||||||
<div><a href="termsofuse.html"> <FormattedMessage id="footer.termsandconditions" defaultMessage="Term And Conditions" /> </a></div>
|
|
||||||
<div><a href="faq.html"> <FormattedMessage id="footer.faq" defaultMessage="F.A.Q."/> </a></div >
|
|
||||||
<div><a href="aboutus.html"> <FormattedMessage id="footer.aboutus" defaultMessage="About Us" /></a></div >
|
|
||||||
</div>
|
|
||||||
<div >
|
|
||||||
<div><a href="http://www.wisemapping.org/"> <FormattedMessage id="footer.opensource" defaultMessage="Open Source" /> </a></div>
|
|
||||||
<div><a href="mailto:team@wisemapping.com"> <FormattedMessage id="footer.contactus" defaultMessage="Contact Us" /> </a></div>
|
|
||||||
<div>< a href="mailto:feedback@wisemapping.com" > <FormattedMessage id="footer.feedback" defaultMessage="Feedback" /> </a></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div><span className="button-style2" >< a href="https://www.paypal.com/webapps/shoppingcart?flowlogging_id=c7ac923b53025&mfid=1606520600355_c7ac923b53025#/checkout/openButton">< FormattedMessage id="footer.donations" defaultMessage="PayPal Donations" /> </a></span ></div>
|
|
||||||
</div >
|
|
||||||
</footer>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Footer;
|
|
26
packages/login/src/Footer.tsx
Normal file
26
packages/login/src/Footer.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FormattedMessage } from 'react-intl'
|
||||||
|
// import { ReactComponent as SvgLogo } from './images/logo-text.svg'
|
||||||
|
|
||||||
|
const Footer = () => {
|
||||||
|
return (
|
||||||
|
<footer className="footer" >
|
||||||
|
{/* FIXME: we have to unify the way we load SVGs <Logo />*/}
|
||||||
|
<div >
|
||||||
|
<div><a href="termsofuse.html"> <FormattedMessage id="footer.termsandconditions" defaultMessage="Term And Conditions" /> </a></div>
|
||||||
|
<div><a href="faq.html"> <FormattedMessage id="footer.faq" defaultMessage="F.A.Q." /> </a></div >
|
||||||
|
<div><a href="aboutus.html"> <FormattedMessage id="footer.aboutus" defaultMessage="About Us" /></a></div >
|
||||||
|
</div>
|
||||||
|
<div >
|
||||||
|
<div><a href="http://www.wisemapping.org/"> <FormattedMessage id="footer.opensource" defaultMessage="Open Source" /> </a></div>
|
||||||
|
<div><a href="mailto:team@wisemapping.com"> <FormattedMessage id="footer.contactus" defaultMessage="Contact Us" /> </a></div>
|
||||||
|
<div>< a href="mailto:feedback@wisemapping.com" > <FormattedMessage id="footer.feedback" defaultMessage="Feedback" /> </a></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div><span className="button-style2" >< a href="https://www.paypal.com/webapps/shoppingcart?flowlogging_id=c7ac923b53025&mfid=1606520600355_c7ac923b53025#/checkout/openButton">< FormattedMessage id="footer.donations" defaultMessage="PayPal Donations" /> </a></span ></div>
|
||||||
|
</div >
|
||||||
|
</footer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Footer;
|
@ -1,13 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl'
|
import { FormattedMessage } from 'react-intl'
|
||||||
import logo from './images/header-logo.png'
|
|
||||||
|
|
||||||
class Header extends React.Component {
|
//const logo = require('./images/header-logo.png')
|
||||||
constructor(props) {
|
|
||||||
|
interface HeaderProps {
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Header extends React.Component<HeaderProps, HeaderProps> {
|
||||||
|
constructor(props: HeaderProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = props;
|
||||||
type: props.type
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -23,14 +26,14 @@ class Header extends React.Component {
|
|||||||
text = <span className="header-area-content-span"><span><FormattedMessage id="header.haveaccount" defaultMessage="Already have an account?" /></span></span>;
|
text = <span className="header-area-content-span"><span><FormattedMessage id="header.haveaccount" defaultMessage="Already have an account?" /></span></span>;
|
||||||
signUpButton = <SignInButton className="header-area-right2" />;
|
signUpButton = <SignInButton className="header-area-right2" />;
|
||||||
} else {
|
} else {
|
||||||
signUpButton = <SignUpButton />
|
signUpButton = <SignUpButton className="header-area-right2" />
|
||||||
signInButton = <SignInButton />;
|
signInButton = <SignInButton className="header-area-right2" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav>
|
<nav>
|
||||||
<div className="header">
|
<div className="header">
|
||||||
<span className="header-logo"><a href="/"><img src={logo} alt="logo" /></a></span>
|
<span className="header-logo"><a href="/"><img src="" alt="logo" /></a></span>
|
||||||
{text}
|
{text}
|
||||||
{signUpButton}
|
{signUpButton}
|
||||||
{signInButton}
|
{signInButton}
|
||||||
@ -40,18 +43,22 @@ class Header extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const SignInButton = (props) => {
|
interface ButtonProps {
|
||||||
|
className: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SignInButton = (props: ButtonProps) => {
|
||||||
return (
|
return (
|
||||||
<span className={`button-style1 ${props.className}`}>
|
<span className={`button-style1 ${props.className}`}>
|
||||||
<a href="/c/login"><FormattedMessage id="login.signin" defaultMessage="Sign In" /></a>
|
<a href="/c/login"><FormattedMessage id="login.signin" defaultMessage="Sign In" /></a>
|
||||||
</span>);
|
</span>);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SignUpButton = (props) => {
|
const SignUpButton = (props: ButtonProps) => {
|
||||||
return (
|
return (
|
||||||
<span className={`button-style1 ${props.className}`}>
|
<span className={`button-style1 ${props.className}`}>
|
||||||
<a href="/c/user/registration"><FormattedMessage id="login.signup" defaultMessage="Sign Up" /></a>
|
<a href="/c/user/registration"><FormattedMessage id="login.signup" defaultMessage="Sign Up" /></a>
|
||||||
</span>);
|
</span>);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Header;
|
export default Header;
|
@ -1,90 +0,0 @@
|
|||||||
import './css/login.css';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { FormattedMessage, injectIntl } from 'react-intl'
|
|
||||||
|
|
||||||
import Header from './Header';
|
|
||||||
import Footer from './Footer';
|
|
||||||
|
|
||||||
const ConfigStatusMessage = (props) => {
|
|
||||||
const enabled = props.enabled
|
|
||||||
let result;
|
|
||||||
|
|
||||||
if (enabled === true) {
|
|
||||||
result = (<div className="db-warn-msg">
|
|
||||||
<p>
|
|
||||||
<FormattedMessage id="login.hsqldbcofig" defaultMessage="Although HSQLDB is bundled with WiseMapping by default during the installation, we do not recommend this database for production use. Please consider using MySQL 5.7 instead. You can find more information how to configure MySQL" description="Missing production database configured" /><a href="https://wisemapping.atlassian.net/wiki/display/WS/Database+Configuration"> here</a>
|
|
||||||
</p>
|
|
||||||
</div>);
|
|
||||||
} else {
|
|
||||||
result = <span></span>;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const LoginError = (props) => {
|
|
||||||
// @Todo: This must be reviewed to be based on navigation state.
|
|
||||||
// Login error example: http://localhost:8080/c/login?login.error=2
|
|
||||||
const errorCode = new URLSearchParams(window.location.search).get('login_error');
|
|
||||||
|
|
||||||
let result;
|
|
||||||
if (errorCode) {
|
|
||||||
if (errorCode === 3) {
|
|
||||||
result = (
|
|
||||||
<div className='form-error-dialog'>
|
|
||||||
<FormattedMessage id="login.userinactive" defaultMessage="Sorry, your account has not been activated yet. You'll receive a notification login.email when it becomes active. Stay tuned!." />
|
|
||||||
</div>)
|
|
||||||
} else {
|
|
||||||
result = (
|
|
||||||
<div className='form-error-dialog'>
|
|
||||||
<FormattedMessage id="login.error" defaultMessage="The login.email address or login.password you entered is not valid." />
|
|
||||||
</div>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (<span>{result}</span>);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoginForm extends React.Component {
|
|
||||||
render() {
|
|
||||||
const intl = this.props.intl;
|
|
||||||
return (
|
|
||||||
<div className="wrapper">
|
|
||||||
<div className="content">
|
|
||||||
<h1><FormattedMessage id="login.welcome" defaultMessage="Welcome" /></h1>
|
|
||||||
<p><FormattedMessage id="login.loginto" defaultMessage="Log Into Your Account" /></p>
|
|
||||||
|
|
||||||
<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" />
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<input name="_spring_security_login.remberme" id="staySignIn" type="checkbox" />
|
|
||||||
<label htmlFor="staySignIn"><FormattedMessage id="login.remberme" defaultMessage="Remember me" /></label>
|
|
||||||
</div>
|
|
||||||
<input type="submit" value={intl.formatMessage({ id: "login.signin", defaultMessage: "Sign In" })} />
|
|
||||||
</form>
|
|
||||||
<a href="/c/user/resetPassword"><FormattedMessage id="login.forgotpwd" defaultMessage="Forgot Password ?" /></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const LoginPage = (props) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Header type='only-signup' />
|
|
||||||
<LoginForm />
|
|
||||||
<ConfigStatusMessage enabled='false' />
|
|
||||||
<Footer />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginForm = injectIntl(LoginForm)
|
|
||||||
|
|
||||||
export default LoginPage;
|
|
||||||
|
|
89
packages/login/src/LoginPage.tsx
Normal file
89
packages/login/src/LoginPage.tsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { FormattedMessage, useIntl } from 'react-intl'
|
||||||
|
|
||||||
|
import Header from './Header'
|
||||||
|
import Footer from './Footer'
|
||||||
|
|
||||||
|
const css = require('./css/login.css')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ConfigStatusMessage = (props: any) => {
|
||||||
|
const enabled = props.enabled
|
||||||
|
let result;
|
||||||
|
|
||||||
|
if (enabled === true) {
|
||||||
|
result = (<div className="db-warn-msg">
|
||||||
|
<p>
|
||||||
|
<FormattedMessage id="login.hsqldbcofig" defaultMessage="Although HSQLDB is bundled with WiseMapping by default during the installation, we do not recommend this database for production use. Please consider using MySQL 5.7 instead. You can find more information how to configure MySQL" description="Missing production database configured" /><a href="https://wisemapping.atlassian.net/wiki/display/WS/Database+Configuration"> here</a>
|
||||||
|
</p>
|
||||||
|
</div>);
|
||||||
|
} else {
|
||||||
|
result = <span></span>;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LoginError = (props: any) => {
|
||||||
|
// @Todo: This must be reviewed to be based on navigation state.
|
||||||
|
// Login error example: http://localhost:8080/c/login?login.error=2
|
||||||
|
const errorCode: string = new URLSearchParams(window.location.search).get('login_error');
|
||||||
|
|
||||||
|
let result;
|
||||||
|
if (errorCode) {
|
||||||
|
if (errorCode === "3") {
|
||||||
|
result = (
|
||||||
|
<div className='form-error-dialog'>
|
||||||
|
<FormattedMessage id="login.userinactive" defaultMessage="Sorry, your account has not been activated yet. You'll receive a notification login.email when it becomes active. Stay tuned!." />
|
||||||
|
</div>)
|
||||||
|
} else {
|
||||||
|
result = (
|
||||||
|
<div className='form-error-dialog'>
|
||||||
|
<FormattedMessage id="login.error" defaultMessage="The login.email address or login.password you entered is not valid." />
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (<span>{result}</span>);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const LoginForm = () => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="wrapper">
|
||||||
|
<div className="content">
|
||||||
|
<h1><FormattedMessage id="login.welcome" defaultMessage="Welcome" /></h1>
|
||||||
|
<p><FormattedMessage id="login.loginto" defaultMessage="Log Into Your Account" /></p>
|
||||||
|
|
||||||
|
<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" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input name="_spring_security_login.remberme" id="staySignIn" type="checkbox" />
|
||||||
|
<label htmlFor="staySignIn"><FormattedMessage id="login.remberme" defaultMessage="Remember me" /></label>
|
||||||
|
</div>
|
||||||
|
<input type="submit" value={intl.formatMessage({ id: "login.signin", defaultMessage: "Sign In" })} />
|
||||||
|
</form>
|
||||||
|
<a href="/c/user/resetPassword"><FormattedMessage id="login.forgotpwd" defaultMessage="Forgot Password ?" /></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LoginPage = (props: any) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Header type='only-signup' />
|
||||||
|
<LoginForm />
|
||||||
|
<ConfigStatusMessage enabled='false' />
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LoginPage;
|
||||||
|
|
@ -1,17 +1,21 @@
|
|||||||
import './css/registration.css';
|
import React from 'react'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { FormattedMessage, useIntl } from 'react-intl'
|
||||||
|
import useHistory from 'react-router-dom'
|
||||||
|
import { ReCaptcha } from 'react-recaptcha-v3'
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import axios from 'axios';
|
|
||||||
import { FormattedMessage, injectIntl } from 'react-intl'
|
|
||||||
import { useHistory } from "react-router-dom";
|
|
||||||
|
|
||||||
import ReCAPTCHA from "react-google-recaptcha";
|
|
||||||
|
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
import Footer from './Footer';
|
import Footer from './Footer';
|
||||||
|
|
||||||
|
const css = require('./css/registration.css');
|
||||||
|
|
||||||
const ErrorMessageDialog = (props) => {
|
|
||||||
|
interface ErrorMessageDialogProps {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const ErrorMessageDialog = (props: ErrorMessageDialogProps) => {
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
const message = props.message;
|
const message = props.message;
|
||||||
@ -23,28 +27,37 @@ const ErrorMessageDialog = (props) => {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegistrationForm extends React.Component {
|
interface RegistrationFormState {
|
||||||
|
email: string;
|
||||||
|
firstname: string;
|
||||||
|
lastname: string;
|
||||||
|
password: string;
|
||||||
|
recaptcha: string;
|
||||||
|
|
||||||
constructor(props) {
|
errorMsg: string;
|
||||||
|
intl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegistrationForm extends React.Component<{}, RegistrationFormState> {
|
||||||
|
|
||||||
|
constructor(props: {}) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
|
||||||
errorMsg: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
this.handleChange = this.handleChange.bind(this);
|
this.handleChange = this.handleChange.bind(this);
|
||||||
this.handleRecaptchaChange = this.handleRecaptchaChange.bind(this);
|
this.handleRecaptchaChange = this.handleRecaptchaChange.bind(this);
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange(event) {
|
handleChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
this.setState({ [event.target.name]: event.target.value });
|
const { name, value }: any = event.target;
|
||||||
|
this.setState({ [name]: value } as Pick<RegistrationFormState, keyof RegistrationFormState>);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRecaptchaChange(value) {
|
handleRecaptchaChange(value: string) {
|
||||||
this.setState({ "recaptcha": value });
|
this.setState({ recaptcha: value });
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleSubmit(event) {
|
async handleSubmit(event: React.FormEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const { errorMsg, ...rest } = this.state;
|
const { errorMsg, ...rest } = this.state;
|
||||||
@ -53,20 +66,20 @@ class RegistrationForm extends React.Component {
|
|||||||
rest,
|
rest,
|
||||||
{ headers: { 'Content-Type': 'application/json' } }
|
{ headers: { 'Content-Type': 'application/json' } }
|
||||||
).then(response => {
|
).then(response => {
|
||||||
const history = useHistory();
|
// const history = useHistory();
|
||||||
history.push("/c/user/registrationSuccess");
|
// history.push("/c/user/registrationSuccess");
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
// Handle error ...
|
// Handle error ...
|
||||||
const data = error.response.data;
|
const data = error.response.data;
|
||||||
// const status = error.response.status;
|
// const status = error.response.status;
|
||||||
|
|
||||||
const errorMsg = Object.values(data.fieldErrors)[0];
|
const errorMsg = Object.values(data.fieldErrors)[0] as string;
|
||||||
this.setState({ "errorMsg": errorMsg });
|
this.setState({ errorMsg: errorMsg });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const intl = this.props.intl;
|
const intl = useIntl();
|
||||||
const errrMsg = this.state.errorMsg;
|
const errrMsg = this.state.errorMsg;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -84,9 +97,9 @@ class RegistrationForm extends React.Component {
|
|||||||
<input type="password" name="password" onChange={this.handleChange} placeholder={intl.formatMessage({ id: "registration.password", defaultMessage: "Password" })} required={true} autoComplete="new-password" />
|
<input type="password" name="password" onChange={this.handleChange} placeholder={intl.formatMessage({ id: "registration.password", defaultMessage: "Password" })} required={true} autoComplete="new-password" />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ReCAPTCHA
|
<ReCaptcha
|
||||||
sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
|
sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
|
||||||
onChange={this.handleRecaptchaChange}
|
verifyCallback={this.handleRecaptchaChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
@ -100,19 +113,19 @@ class RegistrationForm extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RegistrationForm = injectIntl(RegistrationForm);
|
|
||||||
|
|
||||||
const RegistationFormPage = props => {
|
|
||||||
|
const RegistationFormPage = (props: any) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Header type='only-signin' />
|
<Header type='only-signin' />
|
||||||
<RegistrationForm />
|
<RegistrationForm/>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const RegistrationSuccessPage = (props) => {
|
const RegistrationSuccessPage = (props: any) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Header type='only-signup' />
|
<Header type='only-signup' />
|
@ -1,21 +1,20 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import LoginPage from './LoginPage.jsx';
|
import LoginPage from './LoginPage';
|
||||||
import { RegistrationSuccessPage, RegistationFormPage } from './RegistrationPage.jsx';
|
import { RegistrationSuccessPage, RegistationFormPage } from './RegistrationPage';
|
||||||
import { IntlProvider } from 'react-intl'
|
import { IntlProvider } from 'react-intl'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Route,
|
Route,
|
||||||
Switch,
|
Switch,
|
||||||
Redirect,
|
Redirect
|
||||||
useRouteMatch,
|
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
|
|
||||||
function loadLocaleData(language) {
|
function loadLocaleData(language: string) {
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case 'es':
|
case 'es':
|
||||||
return import('./compiled-lang/es.json')
|
return require('./compiled-lang/es.json')
|
||||||
default:
|
default:
|
||||||
return import('./compiled-lang/en.json')
|
return require('./compiled-lang/en.json')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +24,6 @@ const App = () => {
|
|||||||
// Boostrap i18n ...
|
// Boostrap i18n ...
|
||||||
const locale = (navigator.languages && navigator.languages[0])
|
const locale = (navigator.languages && navigator.languages[0])
|
||||||
|| navigator.language
|
|| navigator.language
|
||||||
|| navigator.userLanguage
|
|
||||||
|| 'en-US';
|
|| 'en-US';
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +32,6 @@ const App = () => {
|
|||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const messages = await loadLocaleData(language);
|
const messages = await loadLocaleData(language);
|
||||||
setMessages(messages);
|
setMessages(messages);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData();
|
fetchData();
|
9
packages/login/src/css/login.css.d.ts
vendored
Normal file
9
packages/login/src/css/login.css.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// This file is automatically generated.
|
||||||
|
// Please do not change this file!
|
||||||
|
interface CssExports {
|
||||||
|
'content': string;
|
||||||
|
'db-warn-msg': string;
|
||||||
|
'wrapper': string;
|
||||||
|
}
|
||||||
|
export const cssExports: CssExports;
|
||||||
|
export default cssExports;
|
9
packages/login/src/css/registration.css.d.ts
vendored
Normal file
9
packages/login/src/css/registration.css.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// This file is automatically generated.
|
||||||
|
// Please do not change this file!
|
||||||
|
interface CssExports {
|
||||||
|
'content': string;
|
||||||
|
'db-warn-msg': string;
|
||||||
|
'wrapper': string;
|
||||||
|
}
|
||||||
|
export const cssExports: CssExports;
|
||||||
|
export default cssExports;
|
@ -4,8 +4,11 @@ import App from './app';
|
|||||||
import { BrowserRouter as Router } from 'react-router-dom';
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
|
||||||
function bootstrapApplication() {
|
function bootstrapApplication() {
|
||||||
ReactDOM.render(<Router><App /></Router>,
|
ReactDOM.render(
|
||||||
document.getElementById('root')
|
<Router>
|
||||||
|
<App />
|
||||||
|
</Router>,
|
||||||
|
document.getElementById('root') as HTMLElement
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
1
packages/login/src/react-recaptcha-v3.d.ts
vendored
Normal file
1
packages/login/src/react-recaptcha-v3.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
declare module 'react-recaptcha-v3';
|
12
packages/login/src/tsconfig.json
Normal file
12
packages/login/src/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"sourceMap": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"jsx": "react",
|
||||||
|
"allowJs": true,
|
||||||
|
"esModuleInterop": true
|
||||||
|
}
|
||||||
|
}
|
12
packages/login/tsconfig.json
Normal file
12
packages/login/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"sourceMap": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"jsx": "react",
|
||||||
|
"allowJs": true,
|
||||||
|
"esModuleInterop": true
|
||||||
|
}
|
||||||
|
}
|
50
packages/login/webpack.config.js
Normal file
50
packages/login/webpack.config.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: 'development',
|
||||||
|
devtool: 'eval-source-map',
|
||||||
|
entry: {
|
||||||
|
app: path.join(__dirname, 'src', 'index.tsx')
|
||||||
|
},
|
||||||
|
target: 'web',
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.tsx', '.js', '.jsx']
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: 'ts-loader',
|
||||||
|
exclude: '/node_modules/'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ["style-loader", "css-loader"]
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: 'bundle.js',
|
||||||
|
path: path.resolve(__dirname, 'dist')
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new CleanWebpackPlugin(),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: path.join(__dirname, 'public/index.html')
|
||||||
|
}),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': JSON.stringify('development')
|
||||||
|
})
|
||||||
|
],
|
||||||
|
devServer: {
|
||||||
|
contentBase: path.join(__dirname, 'dist'),
|
||||||
|
compress: true,
|
||||||
|
port: 3000,
|
||||||
|
hot: true,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user