Skip to content
Snippets Groups Projects
App.js 5.38 KiB
Newer Older
meskio's avatar
meskio committed
import React from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
meskio's avatar
meskio committed
import { Container, Row } from "react-bootstrap";
meskio's avatar
meskio committed
import MemberAdder from "./MemberAdder";
meskio's avatar
meskio committed
import MemberList from "./MemberList";
import ProductList from "./ProductList";
import Dashboard from "./Dashboard";
meskio's avatar
meskio committed
import OwnPassword from "./OwnPassword";
meskio's avatar
meskio committed
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";
meskio's avatar
meskio committed
import ResetRequest from "./ResetRequest";
import ResetPassword from "./ResetPassword";
meskio's avatar
meskio committed
import Head from "./Head";
meskio's avatar
meskio committed
import logo from "./logo.svg";
meskio's avatar
meskio committed
function Panel(props) {
meskio's avatar
meskio committed
  return (
    <div>
      <BrowserRouter>
        <Head onLogout={props.onLogout} />
        <Container fluid="lg">
          <Switch>
            <Route path="/members/add">
              <MemberAdder />
            </Route>
            <Route path="/members/purchase">
              <Purchase member />
            </Route>
            <Route path="/members">
              <MemberList />
            </Route>
            <Route path="/products">
              <ProductList />
            </Route>
            <Route path="/transaction/:id">
              <ShowTransaction />
            </Route>
            <Route path="/password">
              <OwnPassword />
            </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>
        </Container>
meskio's avatar
meskio committed
      </BrowserRouter>
    </div>
  );
meskio's avatar
meskio committed
function UnlogedPanel(props) {
  return (
    <Container>
      <Row className="justify-content-center">
        <img src={logo} alt="Garbanzo Negro" />
      </Row>
      <BrowserRouter>
        <Switch>
          <Route path="/reset/:token" component={ResetPassword} />
meskio's avatar
meskio committed
          <Route path="/nreset/:token">
            <ResetPassword login />
          </Route>
meskio's avatar
meskio committed
          <Route path="/reset/" component={ResetRequest} />
          <Route path="/">
            <SignIn onLogin={props.onLogin} />
          </Route>
        </Switch>
      </BrowserRouter>
    </Container>
  );
}

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

Quique's avatar
Quique committed
  isLoggedIn() {
meskio's avatar
meskio committed
    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;
Quique's avatar
Quique committed
    if (!this.isLoggedIn()) {
meskio's avatar
meskio committed
      component = <UnlogedPanel 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;