mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
added new create account screen
This commit is contained in:
parent
f10e10d525
commit
78fe7f3cb2
@ -1,5 +1,4 @@
|
||||
import styled from 'styled-components';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export const AppWrapper = styled.div`
|
||||
position: absolute;
|
||||
|
@ -4,6 +4,7 @@ import { AppContext } from 'context/AppContext';
|
||||
import { ViewportContext } from 'context/ViewportContext';
|
||||
import { AccessWrapper } from './Access.styled';
|
||||
import { Login } from './login/Login';
|
||||
import { CreateAccount } from './createAccount/CreateAccount';
|
||||
|
||||
import login from 'images/login.png'
|
||||
|
||||
@ -19,12 +20,15 @@ export function Access({ mode }) {
|
||||
navigate('/session');
|
||||
}
|
||||
}
|
||||
}, [app]);
|
||||
}, [app, navigate]);
|
||||
|
||||
const Prompt = () => {
|
||||
if (mode === 'login') {
|
||||
return <Login />
|
||||
}
|
||||
if (mode === 'create') {
|
||||
return <CreateAccount />
|
||||
}
|
||||
return <></>
|
||||
}
|
||||
|
||||
|
77
net/web/src/access/createAccount/CreateAccount.jsx
Normal file
77
net/web/src/access/createAccount/CreateAccount.jsx
Normal file
@ -0,0 +1,77 @@
|
||||
import { Button, Modal, Form, Input } from 'antd';
|
||||
import { SettingOutlined, LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import { CreateAccountWrapper } from './CreateAccount.styled';
|
||||
import { useCreateAccount } from './useCreateAccount.hook';
|
||||
|
||||
export function CreateAccount() {
|
||||
|
||||
const { state, actions } = useCreateAccount();
|
||||
|
||||
const create = async () => {
|
||||
try {
|
||||
await actions.onCreateAccount();
|
||||
}
|
||||
catch(err) {
|
||||
Modal.error({
|
||||
title: 'Create Account Error',
|
||||
content: 'Please check with you administrator.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const keyDown = (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
create()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<CreateAccountWrapper>
|
||||
<div class="app-title">
|
||||
<span>Databag</span>
|
||||
<div class="settings" onClick={() => actions.onSettings()}>
|
||||
<SettingOutlined />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-title">Create Account</div>
|
||||
<div class="form-form">
|
||||
<Form name="basic" wrapperCol={{ span: 24, }}>
|
||||
|
||||
<Form.Item name="username" validateStatus={state.validateStatus} help={state.help}>
|
||||
<Input placeholder="Username" spellCheck="false" onChange={(e) => actions.setUsername(e.target.value)}
|
||||
autocomplete="username" autocapitalize="none" onKeyDown={(e) => keyDown(e)} prefix={<UserOutlined />} />
|
||||
</Form.Item>
|
||||
|
||||
<div class="form-space"></div>
|
||||
|
||||
<Form.Item name="password">
|
||||
<Input.Password placeholder="Password" spellCheck="false" onChange={(e) => actions.setPassword(e.target.value)}
|
||||
autocomplete="new-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="confirm">
|
||||
<Input.Password placeholder="Confirm Password" spellCheck="false" onChange={(e) => actions.setConfirm(e.target.value)}
|
||||
autocomplete="new-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} />
|
||||
</Form.Item>
|
||||
|
||||
<div class="form-button">
|
||||
<div class="form-create">
|
||||
<Button type="primary" block onClick={create} disabled={ actions.isDisabled()}
|
||||
loading={state.busy}>
|
||||
Create Account
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-button">
|
||||
<Button type="link" block onClick={(e) => actions.onLogin()}>
|
||||
Account Login
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</Form>
|
||||
</div>
|
||||
</CreateAccountWrapper>
|
||||
);
|
||||
};
|
||||
|
62
net/web/src/access/createAccount/CreateAccount.styled.js
Normal file
62
net/web/src/access/createAccount/CreateAccount.styled.js
Normal file
@ -0,0 +1,62 @@
|
||||
import styled from 'styled-components';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export const CreateAccountWrapper = styled.div`
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.app-title {
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
color: ${Colors.grey};
|
||||
|
||||
.settings {
|
||||
color: ${Colors.grey};
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-form {
|
||||
flex: 2;
|
||||
|
||||
.form-space {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.form-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.form-login {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-submit {
|
||||
background-color: #444444;
|
||||
}
|
||||
`;
|
||||
|
||||
|
111
net/web/src/access/createAccount/useCreateAccount.hook.js
Normal file
111
net/web/src/access/createAccount/useCreateAccount.hook.js
Normal file
@ -0,0 +1,111 @@
|
||||
import { useContext, useState, useEffect, useRef } from 'react';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
|
||||
export function useCreateAccount() {
|
||||
|
||||
const [checked, setChecked] = useState(true);
|
||||
const [state, setState] = useState({
|
||||
username: '',
|
||||
password: '',
|
||||
confirm: '',
|
||||
busy: false,
|
||||
validatetatus: 'success',
|
||||
help: '',
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { search } = useLocation();
|
||||
const app = useContext(AppContext);
|
||||
const debounce = useRef(null);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
const usernameSet = (name) => {
|
||||
setChecked(false)
|
||||
clearTimeout(debounce.current)
|
||||
debounce.current = setTimeout(async () => {
|
||||
if (app.actions?.username && name !== '') {
|
||||
try {
|
||||
let valid = await app.actions.username(name, state.token)
|
||||
if (!valid) {
|
||||
updateState({ validateStatus: 'error', help: 'Username is not available' })
|
||||
}
|
||||
else {
|
||||
updateState({ validateStatus: 'success', help: '' })
|
||||
}
|
||||
setChecked(true)
|
||||
}
|
||||
catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
updateState({ validateStatus: 'success', help: '' });
|
||||
setChecked(true);
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const actions = {
|
||||
setUsername: (username) => {
|
||||
updateState({ username });
|
||||
usernameSet(username);
|
||||
},
|
||||
setPassword: (password) => {
|
||||
updateState({ password });
|
||||
},
|
||||
setConfirm: (confirm) => {
|
||||
updateState({ confirm });
|
||||
},
|
||||
isDisabled: () => {
|
||||
if (state.username === '' || state.password === '' || state.password !== state.confirm || !checked ||
|
||||
state.validateStatus === 'error') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
onSettings: () => {
|
||||
navigate('/admin');
|
||||
},
|
||||
onCreateAccount: async () => {
|
||||
if (!state.busy && state.username !== '' && state.password !== '' && state.password === state.confirm) {
|
||||
updateState({ busy: true })
|
||||
try {
|
||||
await app.actions.create(state.username, state.password)
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false })
|
||||
throw new Error('create failed: check with your admin');
|
||||
}
|
||||
updateState({ busy: false })
|
||||
}
|
||||
},
|
||||
onLogin: () => {
|
||||
navigate('/login');
|
||||
},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (app) {
|
||||
if (app.state) {
|
||||
if (app.state.access) {
|
||||
navigate('/session')
|
||||
}
|
||||
}
|
||||
else {
|
||||
let params = new URLSearchParams(search);
|
||||
let token = params.get("add");
|
||||
if (token) {
|
||||
updateState({ token });
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [app, navigate, search])
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button, Modal, Form, Input } from 'antd';
|
||||
import { SettingOutlined, LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import { LoginWrapper, SubmitButton } from './Login.styled';
|
||||
import { LoginWrapper } from './Login.styled';
|
||||
import { useLogin } from './useLogin.hook';
|
||||
|
||||
export function Login() {
|
||||
@ -40,12 +39,12 @@ export function Login() {
|
||||
|
||||
<Form.Item name="username">
|
||||
<Input placeholder="Username" spellCheck="false" onChange={(e) => actions.setUsername(e.target.value)}
|
||||
autocapitalize="none" onKeyDown={(e) => keyDown(e)} prefix={<UserOutlined />} />
|
||||
autocomplete="username" autocapitalize="none" onKeyDown={(e) => keyDown(e)} prefix={<UserOutlined />} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="password">
|
||||
<Input.Password placeholder="Password" spellCheck="false" onChange={(e) => actions.setPassword(e.target.value)}
|
||||
onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} />
|
||||
autocomplete="current-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} />
|
||||
</Form.Item>
|
||||
|
||||
<div class="form-button">
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useContext, useState, useEffect } from 'react';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
import { useNavigate, useLocation, useParams } from "react-router-dom";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
|
||||
export function useLogin() {
|
||||
|
||||
@ -37,7 +37,7 @@ export function useLogin() {
|
||||
navigate('/admin');
|
||||
},
|
||||
onLogin: async () => {
|
||||
if (!state.busy && state.username != '' && state.password != '') {
|
||||
if (!state.busy && state.username !== '' && state.password !== '') {
|
||||
updateState({ busy: true })
|
||||
try {
|
||||
await app.actions.login(state.username, state.password)
|
||||
@ -45,7 +45,7 @@ export function useLogin() {
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false })
|
||||
throw 'login failed: check your username and password';
|
||||
throw new Error('login failed: check your username and password');
|
||||
}
|
||||
updateState({ busy: false })
|
||||
}
|
||||
@ -92,7 +92,7 @@ export function useLogin() {
|
||||
count();
|
||||
}
|
||||
}
|
||||
}, [app])
|
||||
}, [app, navigate, search])
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
|
||||
export function Admin() {
|
||||
return <></>
|
||||
|
@ -16,7 +16,7 @@ export function Root() {
|
||||
navigate('/login');
|
||||
}
|
||||
}
|
||||
}, [app]);
|
||||
}, [app, navigate]);
|
||||
|
||||
return <></>
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
|
||||
export function Session() {
|
||||
return <></>
|
||||
|
Loading…
Reference in New Issue
Block a user