override fix & auto parse token

This commit is contained in:
srgooglo 2020-04-02 01:40:53 +02:00
parent f9e3014c13
commit bf8f878bce
11 changed files with 763 additions and 196 deletions

View File

@ -11,6 +11,9 @@ module.exports = {
resource_bundle: 'light_ng', resource_bundle: 'light_ng',
sync_server: 'http://eu653-node.ragestudio.net:5500', sync_server: 'http://eu653-node.ragestudio.net:5500',
g_recaptcha_key: '6Lc55uUUAAAAAEIACMVf3BUzAJSNCmI3RrjEirZ6',
g_recaptcha_secret: '6Lc55uUUAAAAAOP4OgUa5DpqJC-70t53AmW0lyYf',
/* Layout configuration, specify which layout to use for route. */ /* Layout configuration, specify which layout to use for route. */
layouts: [ layouts: [
{ {

View File

@ -3,8 +3,8 @@
"UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4", "UUID": "C8mVSr-4nmPp2-pr5Vrz-CU4kg4",
"title": "Comty™", "title": "Comty™",
"DevBuild": true, "DevBuild": true,
"version": "0.2.32", "version": "0.3.01",
"stage": "A1", "stage": "dev-pre",
"description": "", "description": "",
"main": "app/main.js", "main": "app/main.js",
"author": "RageStudio", "author": "RageStudio",
@ -48,8 +48,10 @@
"radium": "^0.26.0", "radium": "^0.26.0",
"react-animations": "^1.0.0", "react-animations": "^1.0.0",
"react-dazzle": "^1.4.0", "react-dazzle": "^1.4.0",
"react-google-recaptcha": "^2.0.1",
"react-helmet": "^5.2.1", "react-helmet": "^5.2.1",
"react-perfect-scrollbar": "^1.5.8", "react-perfect-scrollbar": "^1.5.8",
"react-reveal": "^1.2.2",
"react-scripts": "^3.4.1", "react-scripts": "^3.4.1",
"react-select-country-list": "^2.1.2", "react-select-country-list": "^2.1.2",
"react-sound": "^1.2.0", "react-sound": "^1.2.0",

View File

@ -152,6 +152,7 @@ export const app_session = {
const UserID = JSON.parse(res)['user_id'] const UserID = JSON.parse(res)['user_id']
const UserToken = JSON.parse(res)['access_token'] const UserToken = JSON.parse(res)['access_token']
const preframepayload = { user_token: UserToken, user_id: UserID}
ycore.__rscloud.sdcp_cloud.get( ycore.__rscloud.sdcp_cloud.get(
(err, res) => { (err, res) => {
if (err) { if (err) {
@ -170,7 +171,7 @@ export const app_session = {
callback(null, '200') callback(null, '200')
}, framepayload) }, framepayload)
}, },
{ user_token: UserToken, user_id: UserID } preframepayload
) )
} }
if (identState == 400) { if (identState == 400) {

View File

@ -10,28 +10,44 @@ export function API_Call(callback, endpoint, payload, options, __token) {
let payloadContainer = payload ? payload : new FormData() let payloadContainer = payload ? payload : new FormData()
payloadContainer.append('server_key', ycore.__server.getKey()) payloadContainer.append('server_key', ycore.__server.getKey())
let fendpoint = `${endpoint}${ycore.token_data.__token()}` const autoIncludeToken = endpoint.includes('?access_token=')
let method if (autoIncludeToken) {
let timeout console.log(`Uri Endpoint parsed '?access_token= ' | Auto including token!`)
let processData }
let includeUserID
let override__token const defaultOptions = {
let disabledToken method: 'POST',
timeout: 0,
processData: false,
includeUserID: false,
override__token: false,
disabledToken: autoIncludeToken ? false : true,
}
let fendpoint
let method = defaultOptions.method
let timeout = defaultOptions.timeout
let processData = defaultOptions.processData
let includeUserID = defaultOptions.includeUserID
let override__token = defaultOptions.override__token
let disabledToken = defaultOptions.disabledToken
if (options) { if (options) {
method = options.method ? options.method : 'POST' options.method ? (method = options.method) : null
timeout = options.timeout ? options.timeout : 0 options.timeout ? (timeout = options.timeout) : null
processData = options.processData ? options.processData : false options.processData ? (processData = true) : null
includeUserID = options.includeUserID ? options.includeUserID : false options.includeUserID ? (includeUserID = true) : null
override__token = options.override__token ? options.override__token : false options.override__token ? (override__token = true) : null
disabledToken = options.disabledToken ? options.disabledToken : false options.disabledToken ? (disabledToken = true) : null
} else { }
method = 'POST'
timeout = 0 if (disabledToken) {
processData = false ycore.yconsole.log(`${prefix} Dimmissing the token generation`)
includeUserID = false fendpoint = `${endpoint}`
override__token = false }
disabledToken = false
if (!disabledToken && !override__token) {
fendpoint = `${endpoint}${ycore.token_data.__token()}`
} }
if (override__token || __token) { if (override__token || __token) {
@ -43,14 +59,10 @@ export function API_Call(callback, endpoint, payload, options, __token) {
fendpoint = `${endpoint}${__token}` fendpoint = `${endpoint}${__token}`
} }
if (disabledToken) {
ycore.yconsole.log('${prefix} Dimmissing the token generation')
fendpoint = `${endpoint}`
}
if (includeUserID) { if (includeUserID) {
payloadContainer.append('user_id', ycore.token_data.__id()) payloadContainer.append('user_id', ycore.token_data.__id())
} }
const requestOptions = { const requestOptions = {
url: fendpoint, url: fendpoint,
method: method, method: method,
@ -70,7 +82,9 @@ export function API_Call(callback, endpoint, payload, options, __token) {
ycore.Alive_API.tokenError(response) ycore.Alive_API.tokenError(response)
} }
} catch (error) { } catch (error) {
ycore.yconsole.log('[VIOLATION] The status of the request has not been identified!') ycore.yconsole.log(
'[VIOLATION] The status of the request has not been identified!'
)
ycore.Alive_API.violation() ycore.Alive_API.violation()
} }
ycore.yconsole.log(response) ycore.yconsole.log(response)

View File

@ -36,3 +36,24 @@ export const IsThisUser = {
return false return false
}, },
} }
export const get_early = {
user: (callback, payload)=>{
if (!payload) {
return false
}
const { username } = payload
let formdata = new FormData()
formdata.append('username', username)
const callOptions = { timeout: 10000 }
ycore.API_Call(
(err, res) => {
return callback(err, res)
},
ycore.comty_rsa.endpoint('early_user', {join_token: false}),
formdata,
callOptions
)
}
}

View File

@ -106,6 +106,7 @@ class YulioID extends Component {
width="100%" width="100%"
mask={false} mask={false}
getContainer={false} getContainer={false}
closable={false} closable={false}
visible={visible} visible={visible}
className={styles.loginWrapper} className={styles.loginWrapper}
@ -114,7 +115,6 @@ class YulioID extends Component {
<h6> <h6>
<img src={'https://api.ragestudio.net/id.svg'} /> YulioID&trade; <img src={'https://api.ragestudio.net/id.svg'} /> YulioID&trade;
</h6> </h6>
<h1>Login</h1>
</div> </div>
<main className={styles.mainlp}> <main className={styles.mainlp}>
<form className={styles.formlogin}> <form className={styles.formlogin}>

View File

@ -1,83 +1,131 @@
import React, { Component } from 'react' import React from 'react'
import { AppInfo } from 'ycore' import { AppInfo } from 'ycore'
import { YulioID } from 'components'
import styles from './index.less' import styles from './index.less'
import classnames from 'classnames' import classnames from 'classnames'
import * as antd from 'antd'
import * as Icons from '@ant-design/icons'
import { RegistrationForm } from './register.js'
import { NormalLoginForm } from './login.js'
import { siteName } from 'config'
export function transitionToogle() { export function transitionToogle() {
window.LoginComponent.setState({ window.LoginComponent.setState({
transition: !window.LoginComponent.state.transition transition: !window.LoginComponent.state.transition,
}) })
window.LoginComponent.toogleYulioID() window.LoginComponent.toogleYulioID()
} }
class Login extends Component { class Login extends React.PureComponent {
constructor(props) { constructor(props) {
super(props) super(props)
window.LoginComponent = this window.LoginComponent = this
this.state = { this.state = {
showYulioID: true, transition: false,
transition: false using: 1,
} }
} }
toogleYulioID() { switchType = {
this.setState({ showYulioID: !this.state.showYulioID }) f: a => {
this.setState({ using: a })
},
login: () => {
this.switchType.f(1)
},
register: () => {
this.switchType.f(2)
},
forgot: () => {
this.switchType.f(3)
},
}
renderType(t) {
const a = this.state.using
if (t) {
switch (a) {
case 1:
return `Sign in ${siteName}`
case 2:
return 'Register'
case 3:
return 'Forgot'
default:
return 'Auth'
}
} else {
switch (a) {
case 1:
return <NormalLoginForm />
case 2:
return <RegistrationForm />
case 3:
return null
default:
return <NormalLoginForm />
}
}
}
renderHelperButtons = () => {
if (this.state.using == 1) {
return (
<div className={styles.login_helper_footer}>
<antd.Button type="link" onClick={() => this.switchType.forgot()}>
Forgotten password
</antd.Button>
<antd.Button type="link" onClick={() => this.switchType.register()}>
Create an account
</antd.Button>
</div>
)
}
if (this.state.using == 2 || 3) {
return (
<div className={styles.login_helper_footer}>
<antd.Button type="link" onClick={() => this.switchType.login()}>
Login
</antd.Button>
</div>
)
}
} }
render() { render() {
return ( return (
<div className={classnames(styles.login_wrapper, {[styles.goOut]: this.state.transition})} > <div
<svg className={classnames(styles.login_wrapper, {
className={styles.backgroud} [styles.goOut]: this.state.transition,
xmlns="http://www.w3.org/2000/svg" })}
fillRule="evenodd" >
preserveAspectRatio="xMidYMax slice" <div
strokeLinejoin="round" style={{
strokeMiterlimit="1.41421" fontSize: '8px',
clipRule="evenodd" position: 'absolute',
viewBox="0 0 1920 1200" top: '12px',
> left: '12px',
<path }}
className="vibrate-slow-1" >
fill="url(#_Linear1)" Using v{AppInfo.version} {AppInfo.stage}
d="M1933-19s-273.175 481.215-543.607 443.874c-270.431-37.341-491.08-251.918-677.168-175.592-161.697 66.321-325.778 320.713-29.035 557.338 376.292 300.059 1119.66 396.359 1119.66 396.359l-1642.31 14.014V-1.247L1933-18.998z" </div>
/>
<path
fill="url(#_Linear2)"
d="M1690 0s-42.182 372.782-341 336c-298.818-36.782-466.852-265.409-693-161-226.148 104.409-350.389 405.447-147 722s193 303 193 303H0V0h1690z"
/>
<defs>
<linearGradient
id="_Linear1"
x2="1"
gradientTransform="matrix(1772.46 0 0 1235.99 160.542 598.996)"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stopColor="#513db6" />
<stop offset="1" stopColor="#562590" />
</linearGradient>
<linearGradient
id="_Linear2"
x2="1"
gradientTransform="matrix(1690 0 0 1200.08 0 600.042)"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stopColor="#8137dd" />
<stop offset="1" stopColor="#6143ef" />
</linearGradient>
</defs>
</svg>
<div className={styles.loginLandingWrapper}> <div className={styles.login_wrapper}>
<div className={styles.brand}> <div className={styles.auth_box}>
<img src={AppInfo.logo} /> <div className={styles.left_body}>
<h6>
<img className={styles.yid_logo} src={'https://api.ragestudio.net/id.svg'} /> YulioID&trade;
</h6>
<h2> {this.renderType(true)} </h2>
</div>
<div className={styles.right_body}>
{this.renderType()}
{this.renderHelperButtons()}
</div> </div>
</div> </div>
<div className={styles.version}>
<h2>{`v${AppInfo.version} ${AppInfo.stage}`}</h2>
</div>
<YulioID visible={this.state.showYulioID} />
</div> </div>
</div>
) )
} }
} }

View File

@ -2,55 +2,130 @@
.login_wrapper{ .login_wrapper{
overflow: hidden; width: 100%;
height: 100%;
font-family: "Poppins", sans-serif!important;
h1,h2,h3,h4,h5,h6{color: #333;}
position: absolute; position: absolute;
left: 0;
top: 0; top: 0;
bottom: 0; left: 0;
width: 100vw; display: flex;
height: 100vh; display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
margin: auto;
overflow-y: scroll;
overflow-x: hidden;
&.goOut{ &.goOut{
clip:rect(); .auth_box{
animation: go-out 1.5s linear; -webkit-animation-name: fadeOutLeft;
animation-name: fadeOutLeft;
}
}
transition: all 300ms ease-in-out;
}
.auth_box{
display: flex;
transition: all 300ms ease-in-out;
.yid_logo {
vertical-align: middle;
height: 17px;
}
:global{
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
border: 0;
-webkit-text-fill-color: #333;
-webkit-box-shadow: 0 0 0px 1000px #ffffff98 inset;
box-shadow: #fff 0px 0px 0px 1000px inset;
transition: background-color 5000s ease-in-out 0s;
}
.ant-input-affix-wrapper {
width: 100%;
height: 40px;
padding: 4px 11px;
color: #333;
font-size: 14px;
line-height: 1.5715;
background-color: #fff; //rgba(255, 255, 255, 0.596);
border: 1.5px #2F66DF solid;
border-radius: 7px;
}
} }
} }
/* Animation */ .centering_wrapper{
width: 100%;
.parallax>use { text-align: center;
animation: move-forever 25s cubic-bezier(.55, .5, .45, .5) infinite;
} }
.parallax>use:nth-child(1) { .left_body{
animation-delay: -2s; z-index: 50;
animation-duration: 7s; transform: translate(12px,0);
float: left;
width: 30%;
color: #333;
background-color: #fff;
padding: 20px;
border-radius: 12px 0 0 12px;
box-shadow: 0px 10px 20px 0px rgba(51,51,51,0.52);
transition: all 300ms ease-in-out;
}
.right_body{
z-index: 51;
float: right;
width: 70%;
max-height: -webkit-fill-available;
height: 150px;
padding: 20px 50px 20px 50px;
color: #333;
background-color: #fff;
border-radius: 12px;
box-shadow: 0px 10px 20px 0px rgba(51,51,51,0.52);
transition: all 300ms ease-in-out;
} }
.parallax>use:nth-child(2) {
animation-delay: -3s;
animation-duration: 10s; .helper_login_btn{
transform: translate(-20px, -14px);
} }
.parallax>use:nth-child(3) {
animation-delay: -4s;
animation-duration: 13s;
}
.parallax>use:nth-child(4) { .login_helper_footer{
animation-delay: -5s; width: 100%;
animation-duration: 20s; position: absolute;
} bottom: 0;
left: 0;
@keyframes move-forever { right: 0;
0% { display: flex;
transform: translate3d(-90px, 0, 0); margin: auto;
:global{
.ant-btn{
margin: auto;
padding: 0 5px 0 5px;
}
} }
100% { transform: translate(0, -10px);
transform: translate3d(85px, 0, 0);
}
} }
@keyframes go-out { @keyframes go-out {
0% { 0% {
filter: blur(0px) filter: blur(0px)
@ -61,82 +136,100 @@
} }
} }
.backgroud { // // Full format
background-color: #2d2d2d; // @media (min-width: 486px){
position: absolute; // .login_wrapper {
height: 100%; // min-height: 580px;
width: 100%; // }
z-index: 0; // .auth_box {
top: 0; // width: 784px;
left: 0; // }
} // }
.version { // Medium format max-width: 830px
display: flex; @media (min-width: 486px){
z-index: 2; .auth_box {
font-family: "Poppins", sans-serif; padding: 0 16px 40px;
font-size: 11px; width: 500px;
bottom: 0; min-height: 500px;
position: absolute;
padding: 0 0 5px 3%;
color: #F9F9F9;
h2 {
margin: 0 14px 0 0;
color: #F9F9F9;
}
:global {
.ant-tag {
border-radius: 4px;
}
}
}
.loginLandingWrapper {
background-color: #F9F9F9;
width: 100%;
height: 100%;
font-family: "Nunito", sans-serif;
padding: 15px 30px 15px 35px;
}
.brand {
width: 100%;
top: 0;
float: left;
vertical-align: middle;
position: relative;
img {
max-width: 250px;
width: 11vw;
}
}
.prest {
z-index: 2;
position: relative;
font-family: "Source Sans Pro", sans-serif;
padding: 25px;
margin: auto;
vertical-align: bottom;
img {
width: 100%;
max-height: 60vh;
}
.loginbtn {
margin: auto;
position: relative;
display: flex; display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.left_body{
width: 100%; width: 100%;
float: none;
:global { border-radius: 12px 12px 0 0;
.ant-btn { padding: 20px 20px 20px 20px;
margin: auto; transform: translate(0, 22px);
} }
} .right_body{
width: 100%;
float: none;
padding: 20px 60px 20px 60px;
}
}
// Mobile format
@media (max-width: 485px){
.auth_box {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 70px 16px 40px;
width: 100%;
height: 100%;
min-height: 500px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 0;
}
.left_body{
box-shadow: none;
width: 100%;
float: none;
position: absolute;
top: 0;
margin-top: 30px;
transform: translate(0, 0);
}
.right_body{
box-shadow: none;
width: 100%;
float: none;
padding: 20px 20px 20px 20px;
}
}
.register_form{
}
@-webkit-keyframes fadeOutLeft {
from {
opacity: 1;
}
to {
opacity: 0;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
@keyframes fadeOutLeft {
from {
opacity: 1;
}
to {
opacity: 0;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
} }
} }

221
src/pages/login/login.js Normal file
View File

@ -0,0 +1,221 @@
import React from 'react'
import styles from './index.less'
import Fade from 'react-reveal/Fade'
import HeadShake from 'react-reveal/HeadShake';
import * as antd from 'antd'
import * as ycore from 'ycore'
import { Form, Input, Button, Checkbox } from 'antd'
import {
UserOutlined,
LockOutlined,
BulbOutlined,
SwapLeftOutlined
} from '@ant-design/icons'
export class NormalLoginForm extends React.PureComponent {
state = {
step: 1,
validating: false,
error_count: 0,
step_error: false,
step_show: true,
swpass: false,
}
next = values => {
let a = this.state.step
const b = btoa(Object.values(values).toString())
switch (a) {
case 1:
const payload = { username: Object.values(values).toString() }
ycore.get_early.user((err, res) => {
if (err || !res) return false
try {
const res_data = JSON.parse(res)
if (res_data.api_status == 200) {
a++
this.anim_transition(300)
this.setState({
step_error: false,
early_data: res_data.data,
form_rawd_1: b,
step: a,
})
}
if (res_data.api_status == 400) {
this.anim_error()
}
} catch (error) {
return false
}
}, payload)
return true
case 2:
this.setState({ form_rawd_2: b, step: a })
this.auth()
return true
default:
return false
}
}
back() {
let a = this.state.step
if (a > 1) {
a--
this.anim_transition(150)
}
this.setState({ step: a })
}
anim_transition(duration) {
this.setState({ step_show: false })
setTimeout(() => {
this.setState({ step_show: true })
}, duration || 1000)
}
anim_error() {
this.setState({ step_error: true, error_count: (this.state.error_count + 1) })
}
auth() {
const { form_rawd_1, form_rawd_2 } = this.state
if (!form_rawd_1 || !form_rawd_2) return false
const frame = { EncUsername: form_rawd_1, EncPassword: form_rawd_2 }
this.setState({ step_error: false, validating: true })
ycore.app_session.login((err, res) => {
switch (res) {
case '200': {
this.anim_transition(300)
ycore.LoginPage.transitionToogle()
return
}
case '400': {
console.log('Credentials error')
this.setState({ validating: false })
this.anim_error()
return
}
case '500': {
console.log('Server error')
this.setState({ validating: false })
this.back()
return
}
default:
this.back()
this.setState({ validating: false })
return false
}
}, frame)
}
renderState = () => {
switch (this.state.step) {
case 1:
return (
<Form
name="signin_username"
className="login-form"
onFinish={this.next}
>
<h5>
<BulbOutlined /> You can use your YulioID account to login
</h5>
<HeadShake spy={this.state.error_count}>
<Form.Item
name="username"
hasFeedback
help={this.state.step_error? "It seems that this user does not exist" : null}
validateStatus={this.state.step_error? 'error' : this.state.validating? 'validating' : null}
rules={[
{
required: true,
message: 'Please use your Username or Email!',
},
]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder="Username or Email"
/>
</Form.Item>
</HeadShake>
<Button
type="primary"
htmlType="submit"
className="login-form-button"
>
Next
</Button>
</Form>
)
case 2:
return (
<Form
name="signin_password"
className="login-form"
onFinish={this.next}
>
<h4><antd.Avatar shape='square' src={this.state.early_data.avatar} /> Welcome Back @{this.state.early_data.username}</h4>
<HeadShake spy={this.state.error_count}>
<Form.Item
name="password"
hasFeedback
help={this.state.step_error? "Incorrect password" : null}
validateStatus={this.state.step_error? 'error' : this.state.validating? 'validating' : null}
rules={[
{ required: true, message: 'Please input your Password!' },
]}
>
<Input.Password
prefix={<LockOutlined className="site-form-item-icon" />}
type={this.state.swpass ? 'text' : 'password'}
placeholder="Password"
/>
</Form.Item>
</HeadShake>
<div className={styles.helper_login_btn}>
<antd.Button
icon={<SwapLeftOutlined />}
type="link"
onClick={() => this.back()}
>
Back
</antd.Button>
<Button
type="primary"
htmlType="submit"
className="login-form-button"
>
Login
</Button>
</div>
</Form>
)
case 3: {
return <h3>Wait a sec...</h3>
}
default:
return null
}
}
render() {
return (
<div className={styles.login_form}>
<Fade left opposite when={this.state.step_show}>
{this.renderState()}
</Fade>
</div>
)
}
}

162
src/pages/login/register.js Normal file
View File

@ -0,0 +1,162 @@
import React, { useState } from 'react'
import {
MailOutlined,
TagOutlined,
LockOutlined,
} from '@ant-design/icons'
import styles from './index.less'
import {
Form,
Input,
Tooltip,
Cascader,
Select,
Row,
Col,
Checkbox,
Button,
AutoComplete,
} from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import ReCAPTCHA from 'react-google-recaptcha'
import { g_recaptcha_key } from 'config'
function capchaOnChange(value) {
console.log('Captcha value:', value)
}
export const RegistrationForm = () => {
const onFinish = values => {
console.log('Received values of form: ', values)
}
return (
<div className={styles.centering_wrapper}>
<Form
name="register"
className={styles.register_form}
onFinish={onFinish}
scrollToFirstError
>
<Form.Item
name="username"
rules={[
{
required: true,
message: 'Please input your username!',
whitespace: true,
},
]}
>
<Input prefix={<TagOutlined />}
placeholder="ramdomuser"/>
</Form.Item>
<Form.Item
name="email"
rules={[
{
type: 'email',
message: 'The input is not valid E-mail!',
},
{
required: true,
message: 'Please input your E-mail!',
},
]}
>
<Input
prefix={<MailOutlined />}
placeholder="example@no-real.com"
/>
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
hasFeedback
>
<Input.Password prefix={<LockOutlined />}
placeholder="example@no-real.com"/>
</Form.Item>
<Form.Item
name="confirm"
dependencies={['password']}
hasFeedback
rules={[
{
required: true,
message: 'Please confirm your password!',
},
({ getFieldValue }) => ({
validator(rule, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve()
}
return Promise.reject(
'The two passwords that you entered do not match!'
)
},
}),
]}
>
<Input.Password prefix={<LockOutlined />}
placeholder="example@no-real.com"/>
</Form.Item>
<Form.Item extra="We must make sure that your are a human.">
<Row gutter={8}>
<Col span={12}>
<Form.Item
name="captcha"
noStyle
rules={[
{
required: true,
message: 'Please complete the captcha!',
},
]}
>
<ReCAPTCHA sitekey={g_recaptcha_key} onChange={capchaOnChange} />
</Form.Item>
</Col>
<Col span={12}></Col>
</Row>
</Form.Item>
<Form.Item
name="agreement"
valuePropName="checked"
rules={[
{
validator: (_, value) =>
value
? Promise.resolve()
: Promise.reject('Should accept agreement'),
},
]}
>
<Checkbox>
I have read the <a href="">agreement</a>
</Checkbox>
</Form.Item>
<Form.Item >
<Button type="primary" htmlType="submit">
Register
</Button>
</Form.Item>
</Form>
</div>
)
}

View File

@ -42,14 +42,16 @@
body { body {
scroll-behavior: smooth; scroll-behavior: smooth;
height: 100%; height: 100%;
overflow-y: hidden; // min-width: 430px;
min-width: 430px;
background-color: transparent; background-color: transparent;
// overflow-y: hidden;
// overflow-x: hidden;
// overflow: hidden;
font-size: @base-font-size; font-size: @base-font-size;
line-height: @base-line-height; line-height: @base-line-height;
} }
@media (min-width: @bp-medium) { @media (min-width: @bp-medium) {