feat(website): add `/register` page
This commit is contained in:
parent
60917c962e
commit
2764564c4c
|
@ -1,4 +0,0 @@
|
||||||
import list from "./list"
|
|
||||||
import login from "./login"
|
|
||||||
|
|
||||||
export default { list, login }
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import list from "./list"
|
||||||
|
import login from "./login"
|
||||||
|
import register from "./register"
|
||||||
|
|
||||||
|
const api = { list, login, register }
|
||||||
|
|
||||||
|
export default api
|
|
@ -0,0 +1,32 @@
|
||||||
|
import axios from './axios'
|
||||||
|
|
||||||
|
export default async function register(username: string, password: string): Promise<string> {
|
||||||
|
const request = axios.post("/auth/register", {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
})
|
||||||
|
|
||||||
|
const response = request
|
||||||
|
.then(response => {
|
||||||
|
const { data } = response
|
||||||
|
|
||||||
|
return data.LoggedIn.access_token
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.response?.data?.error_message) {
|
||||||
|
const error = err.response.data.error_message
|
||||||
|
|
||||||
|
if (error.toString() == "[object Object]") {
|
||||||
|
Object.keys(error).forEach(key => {
|
||||||
|
throw new Error(key)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Button } from "@mui/material"
|
||||||
|
import styled from "styled-components"
|
||||||
|
|
||||||
|
const SubmitButton = styled(Button)`
|
||||||
|
margin-top: 1rem;
|
||||||
|
align-content: "center";
|
||||||
|
`
|
||||||
|
|
||||||
|
export default SubmitButton
|
|
@ -0,0 +1,7 @@
|
||||||
|
import styled from "styled-components"
|
||||||
|
|
||||||
|
const ErrorComponent = styled.div`
|
||||||
|
color: ${({ theme }) => theme.colors.error};
|
||||||
|
`
|
||||||
|
|
||||||
|
export default ErrorComponent
|
|
@ -0,0 +1,35 @@
|
||||||
|
import styled from "styled-components"
|
||||||
|
|
||||||
|
const Title = styled.h1`
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.15;
|
||||||
|
font-size: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: ${({ theme }) => theme.pages.index.title.a};
|
||||||
|
text-decoration: none;
|
||||||
|
animation: animate 1.5s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animate {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover,
|
||||||
|
a:focus,
|
||||||
|
a:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default Title
|
|
@ -45,7 +45,7 @@ export default function NotFound() {
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<Title>
|
<Title>
|
||||||
404 | Server-side error occurred
|
404 | This page could not be found
|
||||||
</Title>
|
</Title>
|
||||||
|
|
||||||
<StyledButton href="/">
|
<StyledButton href="/">
|
||||||
|
|
|
@ -41,11 +41,11 @@ export default function NotFound() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>404 - HomeDisk</title>
|
<title>500 - HomeDisk</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<Title>
|
<Title>
|
||||||
404 | This page could not be found
|
500 | Server-side error occurred
|
||||||
</Title>
|
</Title>
|
||||||
|
|
||||||
<StyledButton href="/">
|
<StyledButton href="/">
|
||||||
|
|
|
@ -1,52 +1,13 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Button, TextField } from '@mui/material'
|
import { TextField } from '@mui/material'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import Router from 'next/router'
|
import Router from 'next/router'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useCookies } from 'react-cookie'
|
import { useCookies } from 'react-cookie'
|
||||||
import styled from 'styled-components'
|
import api from '../api_utils'
|
||||||
import api from '../api'
|
import Title from '../components/auth/title'
|
||||||
|
import ErrorComponent from '../components/auth/error'
|
||||||
const Title = styled.h1`
|
import SubmitButton from '../components/auth/button'
|
||||||
margin: 0;
|
|
||||||
line-height: 1.15;
|
|
||||||
font-size: 2rem;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: ${({ theme }) => theme.pages.index.title.a};
|
|
||||||
text-decoration: none;
|
|
||||||
animation: animate 1.5s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes animate {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover,
|
|
||||||
a:focus,
|
|
||||||
a:active {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const LoginButton = styled(Button)`
|
|
||||||
margin-top: 1rem;
|
|
||||||
align-content: "center";
|
|
||||||
`
|
|
||||||
|
|
||||||
const ErrorComponent = styled.div`
|
|
||||||
color: ${({ theme }) => theme.colors.error};
|
|
||||||
`
|
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const [cookie, setCookie] = useCookies(["token"])
|
const [cookie, setCookie] = useCookies(["token"])
|
||||||
|
@ -122,7 +83,7 @@ export default function Login() {
|
||||||
onKeyPress={handleKeyPress}
|
onKeyPress={handleKeyPress}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<LoginButton
|
<SubmitButton
|
||||||
variant="contained"
|
variant="contained"
|
||||||
size="large"
|
size="large"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
|
@ -130,7 +91,7 @@ export default function Login() {
|
||||||
disabled={username == "" || password == ""}
|
disabled={username == "" || password == ""}
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</LoginButton>
|
</SubmitButton>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { TextField } from '@mui/material'
|
||||||
|
import Head from 'next/head'
|
||||||
|
import Router from 'next/router'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useCookies } from 'react-cookie'
|
||||||
|
import api from '../api_utils'
|
||||||
|
import ErrorComponent from '../components/auth/error'
|
||||||
|
import Title from '../components/auth/title'
|
||||||
|
import SubmitButton from '../components/auth/button'
|
||||||
|
|
||||||
|
export default function Login() {
|
||||||
|
const [cookie, setCookie] = useCookies(["token"])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (cookie.token) {
|
||||||
|
Router.push('/user/files')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const [error, setError] = useState("")
|
||||||
|
const [username, setUsername] = useState("")
|
||||||
|
const [password, setPassword] = useState("")
|
||||||
|
|
||||||
|
const handleUsernameChange: React.ChangeEventHandler<HTMLInputElement> = event => {
|
||||||
|
const value = event.target.value
|
||||||
|
setUsername(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePasswordChange: React.ChangeEventHandler<HTMLInputElement> = event => {
|
||||||
|
const value = event.target.value
|
||||||
|
setPassword(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle click "Enter (Return)"
|
||||||
|
const handleKeyPress = (event: React.KeyboardEvent) => {
|
||||||
|
if (event.keyCode === 13 || event.which === 13 || event.charCode === 13) {
|
||||||
|
handleLogin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
const request = api.register(username, password)
|
||||||
|
|
||||||
|
request
|
||||||
|
.then(token => {
|
||||||
|
setCookie("token", token)
|
||||||
|
setError("")
|
||||||
|
})
|
||||||
|
.catch(err => setError(err.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>Register - HomeDisk</title>
|
||||||
|
</Head>
|
||||||
|
|
||||||
|
<Title>
|
||||||
|
Register
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
{error != "" && (
|
||||||
|
<ErrorComponent>{error}</ErrorComponent>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
label="Username"
|
||||||
|
placeholder="Username"
|
||||||
|
margin="normal"
|
||||||
|
value={username}
|
||||||
|
onChange={handleUsernameChange}
|
||||||
|
onKeyPress={handleKeyPress}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
label="Password"
|
||||||
|
placeholder="Password"
|
||||||
|
type="password"
|
||||||
|
margin="normal"
|
||||||
|
value={password}
|
||||||
|
onChange={handlePasswordChange}
|
||||||
|
onKeyPress={handleKeyPress}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SubmitButton
|
||||||
|
variant="contained"
|
||||||
|
size="large"
|
||||||
|
color="secondary"
|
||||||
|
onClick={handleLogin}
|
||||||
|
disabled={username == "" || password == ""}
|
||||||
|
>
|
||||||
|
Register
|
||||||
|
</SubmitButton>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import Link from 'next/link'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useCookies } from 'react-cookie'
|
import { useCookies } from 'react-cookie'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import api from '../../api'
|
import api from '../../api_utils'
|
||||||
|
|
||||||
const Table = styled.table`
|
const Table = styled.table`
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
|
@ -99,7 +99,7 @@ function FolderComponent({ name, path, size, modified, refresh }: Props) {
|
||||||
<Link href={`?dir=${path}`}>
|
<Link href={`?dir=${path}`}>
|
||||||
<MuiLink onClick={() => refresh(path)}>
|
<MuiLink onClick={() => refresh(path)}>
|
||||||
<Icon icon={faFolder} />
|
<Icon icon={faFolder} />
|
||||||
{name}
|
{name.replace("/", "")}
|
||||||
</MuiLink>
|
</MuiLink>
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
|
@ -116,7 +116,7 @@ function FileComponent({ name, path, size, modified, refresh }: Props) {
|
||||||
<Link href={`?dir=${path}`}>
|
<Link href={`?dir=${path}`}>
|
||||||
<MuiLink onClick={() => refresh(path)}>
|
<MuiLink onClick={() => refresh(path)}>
|
||||||
<Icon icon={faFile} />
|
<Icon icon={faFile} />
|
||||||
{name}
|
{name.replace("/", "")}
|
||||||
</MuiLink>
|
</MuiLink>
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
|
|
Loading…
Reference in New Issue