diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx index 179d9b8..b989cb7 100644 --- a/src/pages/admin/index.tsx +++ b/src/pages/admin/index.tsx @@ -1,13 +1,21 @@ import React from "react"; -import { Helmet } from "react-helmet"; +import { NextPage } from "next"; +import Head from "next/head"; +import PageWrapper from "@views/common/AdminPageWrapper"; -const AdminFrontView: React.FC = () => ( - - +const AdminFrontPage: NextPage = () => { + return ( + <> + - - SIK Admin - -); + + + + SIK Admin + + + > + ) +}; -export default AdminFrontView; +export default AdminFrontPage; diff --git a/src/pages/admin/login.tsx b/src/pages/admin/login.tsx index f287153..269aea9 100644 --- a/src/pages/admin/login.tsx +++ b/src/pages/admin/login.tsx @@ -1,9 +1,9 @@ -import React from "react"; +import React, { useState, useEffect } from "react"; import styled from "styled-components"; import { Helmet } from "react-helmet"; -import { withRouter } from "next/router"; -import { WithRouterProps } from "next/dist/client/with-router"; +import { useRouter } from "next/router"; import { generateToken, setTokenCookie, isAuthenticated } from "@utils/auth"; +import PageWrapper from "@views/common/AdminPageWrapper"; const Main = styled.div` input { @@ -11,118 +11,74 @@ const Main = styled.div` } `; -type AdminLoginPageProps = WithRouterProps; -interface AdminLoginPageState { - username: string; - password: string; - isAuthenticated: boolean; - error: string; -} - const DEFAULT_REDIRECT = "/admin"; -class AdminLoginPage extends React.Component { - constructor(props) { - super(props); - this.state = { - username: "", - password: "", - isAuthenticated: false, - error: "", - }; +const AdminLoginPage: React.FC = () => { + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const router = useRouter(); + const next = router.query.next as string || DEFAULT_REDIRECT; - this.handleUserAuthenticated(); - } + useEffect(() => { + isAuthenticated().then(res => { + if (res) { + router.push(next); + } + }) + }, []); - handleUserAuthenticated = async () => { - const authenticated = await isAuthenticated(); - if (authenticated) { - this.setState({ - isAuthenticated: true, - }); - } - } - - handleSubmit = async (e) => { + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - const { username, password } = this.state; - const { router } = this.props; - try { const token = await generateToken(username, password); - console.log("JWT token:", token); setTokenCookie(token); - - const next = this.getRedirectURL(); router.push(next); } catch (err) { - this.setState({ - error: "Failed to log in!", - }); - console.error("Failed to log in!"); + setError("Failed to log in!"); } } - handleUserNameChange = (e) => { - this.setState({ - username: e.target.value, - }); - } - - handlePasswordChange = (e) => { - this.setState({ - password: e.target.value, - }); - } - - renderError = () => { - const { error } = this.state; - if (!error) return null; - - return ( - - { error } - - ); - } - - getRedirectURL = () => { - const { router: { query } } = this.props; - const { next } = query; - // TODO: Any change of next being string[]? We get type error on without the cast. - return next as string || DEFAULT_REDIRECT; - } - - render() { - const { router } = this.props; - const { username, password, isAuthenticated } = this.state; - const next = this.getRedirectURL(); - - if (isAuthenticated) { - router.push(next); - } - - return ( + return ( + Log in to SIK Admin - { next && next !== DEFAULT_REDIRECT && ( + {next && next !== DEFAULT_REDIRECT && ( You have to log in first. - ) } - + )} + Username - + { + setUsername(e.target.value); + }} /> Password - + { + setPassword(e.target.value); + }} /> - { this.renderError() } + {error && ( + + {error} + + )} - ); - } + + ); } -export default withRouter(AdminLoginPage); +export default AdminLoginPage; diff --git a/src/views/common/AdminPageWrapper.tsx b/src/views/common/AdminPageWrapper.tsx index 5d05e1c..c82a4af 100644 --- a/src/views/common/AdminPageWrapper.tsx +++ b/src/views/common/AdminPageWrapper.tsx @@ -1,11 +1,11 @@ -import React, { useEffect, useState, ReactNode, ComponentType } from "react"; +import React, { useEffect, useState } from "react"; import styled from "styled-components"; -import { RouteComponentProps, Redirect } from "react-router-dom"; import colors from "@theme/colors"; import breakpoints from "@theme/breakpoints"; import AdminHeader from "@components/AdminHeader"; import AdminSidebar from "@components/AdminSidebar"; import { isAuthenticated } from "@utils/auth"; +import { useRouter } from "next/router"; const Main = styled.main` display: flex; @@ -57,19 +57,19 @@ const useShouldRedirect = (enabled = true) => { } -type PageProps = RouteComponentProps & { - page: ComponentType; +type PageProps = { requiresAuthentication: boolean; } -const PageWrapper: React.FC = ({ page, requiresAuthentication, ...props }) => { - const { path } = props.match; - const Page = page; +const PageWrapper: React.FC = ({ requiresAuthentication, children }) => { + const router = useRouter(); const { completed, redirecting } = useShouldRedirect(requiresAuthentication); + const { pathname } = router; + if (redirecting) { - const loginURL = `/admin/login?next=${path}`; - return ; + const loginURL = `/admin/login?next=${pathname}`; + router.push(loginURL); } // TODO: Loading screen @@ -81,16 +81,11 @@ const PageWrapper: React.FC = ({ page, requiresAuthentication, ...pro <> - - + + {children} > ) } -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -const renderPage = (Page: ReactNode, requiresAuthentication = true) => (props: any): JSX.Element => ( - -); - -export default renderPage; \ No newline at end of file +export default PageWrapper; \ No newline at end of file