Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
Add a private "Dashboard" route. Add links for easier access.
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonraimondi committed Aug 6, 2019
1 parent b853647 commit 609842c
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 6 deletions.
9 changes: 9 additions & 0 deletions web/components/links.tsx
@@ -0,0 +1,9 @@
import React from "react";

export function Links() {
return <ul>
<li><a href={"/"}>Home</a></li>
<li><a href={"/login"}>Login</a></li>
<li><a href={"/dashboard"}>Dashboard (protected)</a></li>
</ul>
}
50 changes: 50 additions & 0 deletions web/components/private_route.tsx
@@ -0,0 +1,50 @@
import ServerCookie from "next-cookies";
import Router from "next/router";
import React, { Component } from "react";
import { COOKIES } from "../services/login_service";
import { AuthToken } from "../services/auth_token";

export type AuthProps = {
auth: AuthToken
}

type AuthState = {
auth: AuthToken
}

export function privateRoute(WrappedComponent: any) {
return class extends Component<AuthProps, AuthState> {
state = {
auth: new AuthToken(this.props.auth.token),
};

static async getInitialProps(ctx: any) {
const token = ServerCookie(ctx)[COOKIES.authToken];
const auth = new AuthToken(token);
const initialProps = { auth };
if (WrappedComponent.getInitialProps) return WrappedComponent.getInitialProps(initialProps);
return initialProps;
}

componentDidMount(): void {
if (this.props.auth.decodedToken.exp === 0 || this.state.auth.isExpired) {
Router.push("/login");
}
}

componentDidUpdate(): void {
if (this.props.auth.decodedToken.exp === 0 || this.state.auth.isExpired) {
Router.push("/login");
}
}

render() {
// the server pass to the client serializes the token
// so we have to reinitialize the authToken class
//
// @see https://github.com/zeit/next.js/issues/3536
// const auth =;
return <WrappedComponent auth={this.state.auth} {...this.props} />;
}
};
}
21 changes: 21 additions & 0 deletions web/pages/dashboard.tsx
@@ -0,0 +1,21 @@
import React from "react"
import { AuthProps, privateRoute } from "../components/private_route";
import Cookie from "js-cookie";
import Router from "next/router";
import { COOKIES } from "../services/login_service";

function Page(props: AuthProps) {
const logout = async () => {
Cookie.remove(COOKIES.authToken);
alert("logout");
await Router.push("/login");
};

return <>
<p>Hello Dashboard</p>
<p>{JSON.stringify(props.auth)}</p>
<button onClick={logout}>Logout</button>
</>
}

export default privateRoute(Page);
10 changes: 4 additions & 6 deletions web/pages/index.tsx
@@ -1,12 +1,10 @@
import React from "react";
import { Links } from "../components/links";

function Page() {
return <>
<ul>
<li><a href={"/"}>Home</a></li>
<li><a href={"/login"}>Login</a></li>
</ul>
</>;
return <>
<Links/>
</>;
}

export default Page;
4 changes: 4 additions & 0 deletions web/pages/login.tsx
@@ -1,5 +1,6 @@
import React, { useState } from "react";
import { login } from "../services/login_service";
import { Links } from "../components/links";

export type LoginInputs = {
email: string
Expand Down Expand Up @@ -28,7 +29,10 @@ function Page() {
};

return <>
<Links/>

{error ? <p>Error: {error}</p> : null}

<form className="container mx-auto max-w-sm" onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
Expand Down

0 comments on commit 609842c

Please sign in to comment.