Skip to content
Snippets Groups Projects
App.js 4.18 KiB
Newer Older
  • Learn to ignore specific revisions
  • meskio's avatar
    meskio committed
    import React from "react";
    import { BrowserRouter, Switch, Route } from "react-router-dom";
    import MemberList from "./MemberList";
    import ProductList from "./ProductList";
    import Dashboard from "./Dashboard";
    import Purchase from "./purchase/Purchase";
    import Topup from "./Topup";
    import ShowTransaction from "./ShowTransaction";
    import ShowOrder from "./order/ShowOrder";
    import CreateOrder from "./order/CreateOrder";
    import AuthContext from "./AuthContext";
    import SignIn from "./SignIn";
    import Head from "./Head";
    
    meskio's avatar
    meskio committed
    function Panel(props) {
    
    meskio's avatar
    meskio committed
      return (
        <div>
          <BrowserRouter>
            <Head onLogout={props.onLogout} />
            <Switch>
              <Route path="/members">
                <MemberList />
              </Route>
              <Route path="/products">
                <ProductList />
              </Route>
              <Route path="/transaction/:id">
                <ShowTransaction />
              </Route>
              <Route path="/purchase">
                <Purchase />
              </Route>
              <Route path="/topup">
                <Topup />
              </Route>
              <Route path="/order/create">
                <CreateOrder />
              </Route>
              <Route path="/order/:id" component={ShowOrder} />
              <Route path="/">
                <Dashboard />
              </Route>
            </Switch>
          </BrowserRouter>
        </div>
      );
    
    meskio's avatar
    meskio committed
    function getClaims(token) {
    
    meskio's avatar
    meskio committed
      const base64Url = token.split(".")[1];
      const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
      const jsonPayload = decodeURIComponent(
        atob(base64)
          .split("")
          .map(function (c) {
            return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
          })
          .join("")
      );
    
    meskio's avatar
    meskio committed
    
    
    meskio's avatar
    meskio committed
      return JSON.parse(jsonPayload);
    
    meskio's avatar
    meskio committed
    }
    
    
    meskio's avatar
    meskio committed
    class App extends React.Component {
    
    meskio's avatar
    meskio committed
      constructor(props) {
        super(props);
        this.state = {
          num: null,
          role: null,
          token: null,
        };
    
    meskio's avatar
    meskio committed
    
    
    meskio's avatar
    meskio committed
        this.logout = this.logout.bind(this);
        this.login = this.login.bind(this);
      }
    
    meskio's avatar
    meskio committed
    
    
    meskio's avatar
    meskio committed
      componentDidMount() {
        const token = localStorage.getItem("token");
        if (token) {
          const num = localStorage.getItem("num");
          const role = localStorage.getItem("role");
          this.setState({ num, role, token });
          if (getClaims(token)["exp"] !== undefined) {
            this.timerID = setInterval(
              () => this.renewToken(),
              60000 // every minute
            );
          }
    
    meskio's avatar
    meskio committed
        }
    
    meskio's avatar
    meskio committed
      }
    
    meskio's avatar
    meskio committed
    
    
    meskio's avatar
    meskio committed
      componentWillUnmount() {
        if (this.timeID) {
          clearInterval(this.timerID);
    
    meskio's avatar
    meskio committed
      }
    
    meskio's avatar
    meskio committed
      storeState(token, num, role) {
        localStorage.setItem("token", token);
        localStorage.setItem("num", num);
        localStorage.setItem("role", role);
      }
    
    meskio's avatar
    meskio committed
      login(token, member) {
        this.setState({
          num: member.num,
          role: member.role,
          token: token,
        });
        this.storeState(token, member.num, member.role);
        if (getClaims(token)["exp"] !== undefined) {
          this.timerID = setInterval(
            () => this.renewToken(),
            60000 // every minute
          );
    
    meskio's avatar
    meskio committed
        }
    
    meskio's avatar
    meskio committed
      }
    
    meskio's avatar
    meskio committed
    
    
    meskio's avatar
    meskio committed
      logout() {
        if (this.timeID) {
          clearInterval(this.timerID);
    
    meskio's avatar
    meskio committed
        }
    
    meskio's avatar
    meskio committed
        this.setState({
          num: null,
          role: null,
          token: null,
        });
        this.storeState("", "", "");
      }
    
    meskio's avatar
    meskio committed
    
    
    meskio's avatar
    meskio committed
      isLoged() {
        if (!this.state.token) {
          return false;
    
    meskio's avatar
    meskio committed
        }
    
    meskio's avatar
    meskio committed
        const claims = getClaims(this.state.token);
        if (claims["exp"] === undefined) {
          return true;
        }
        return claims["exp"] > Date.now() / 1000;
      }
    
    meskio's avatar
    meskio committed
    
    
    meskio's avatar
    meskio committed
      renewToken() {
        fetch("/api/token", { headers: { "x-authentication": this.state.token } })
          .then((response) => {
            if (!response.ok) {
              throw new Error(
                response.status.toString() + " " + response.statusText
              );
    
    meskio's avatar
    meskio committed
            }
    
    meskio's avatar
    meskio committed
            return response.json();
          })
          .then((data) => {
            const token = data.token;
            this.setState({ token });
            localStorage.setItem("token", token);
          })
          .catch((error) => {
            console.log("Error renewing token: " + error.message);
          });
      }
    
    meskio's avatar
    meskio committed
      render() {
    
        let component;
    
    meskio's avatar
    meskio committed
        if (!this.isLoged()) {
          component = <SignIn onLogin={this.login} />;
    
        } else {
          component = <Panel onLogout={this.logout} />;
    
    meskio's avatar
    meskio committed
        }
    
    meskio's avatar
    meskio committed
    
        return (
          <AuthContext.Provider value={this.state}>
            {component}
          </AuthContext.Provider>
        );
      }
    
    }
    
    export default App;