Skip to content

Instantly share code, notes, and snippets.

@longtc
Created June 6, 2020 03:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save longtc/d02ec557ddebbb2e4b5372094434b7fa to your computer and use it in GitHub Desktop.
Save longtc/d02ec557ddebbb2e4b5372094434b7fa to your computer and use it in GitHub Desktop.
code sample
import React, { useReducer, useEffect, useMemo, useState } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import { reducer, initialState } from "../app-reducer";
import {
getProvinces, refreshAccessToken, getHolidays,
} from "../app-effects";
import { AppContext } from "../context/AppContext";
import { TimeLimitContext, AppliedRoleContext } from "../context/TimeLimitContext";
import { saveItems, saveLogin, saveUser, saveDayRange, saveDueTime } from "../util/consistentStorage";
import {
setAllowedDayRange,
setAllowedOrderDueTime,
setCurrentRole,
ALLOWED_ORDER_DAY_RANGE,
ALLOWED_ORDER_DUE_TIME,
DIRECTOR,
EMPLOYEE,
} from "../util/constant";
import { isArray } from "../util/object";
import { PrivateRoute } from "./component/PrivateRoute.jsx";
import { DialogSelectProvince } from "./component/DialogSelectProvince.jsx";
import { BottomMenuBar } from "./component/mobile/BottomMenuBar.jsx";
import { Footer } from "./component/Footer/Footer.jsx";
import { Header } from "./component/Header/Header.jsx";
import { Breadcrumbs } from "./component/BreadCrumps.jsx";
import { NotFound } from "./page/NotFound.jsx";
import { routeConfig } from "./routeConfig";
const TIME_REFRESH_TOKEN = 1500000;
export function App() {
const [state, dispatch] = useReducer(reducer, initialState);
const {
provinces,
user,
login,
cart,
} = state;
const [timeLimit, setTimeLimit] = useState({
dayRange: ALLOWED_ORDER_DAY_RANGE,
dueTime: ALLOWED_ORDER_DUE_TIME,
});
const appliedRole = useMemo(() => {
const result = (isArray(login.role) && login.role.includes(DIRECTOR)) ? DIRECTOR : EMPLOYEE;
setCurrentRole(result);
return result;
}, [login.role]);
const itemQuantity = useMemo(() => {
return Array.from(cart.items.values())
.reduce((acc, cur) => acc + cur.qtty, 0);
}, [cart.items]);
const selectedProvince = useMemo(() => {
return provinces.filter(p => p.provinceCode === state.global.provinceCode)[0];
}, [state.global.provinceCode, provinces]);
useEffect(() => {
getProvinces(dispatch);
getHolidays(dispatch);
}, []);
useEffect(() => {
setImmediate(() => {
saveItems(Array.from(
cart.items.entries()
));
});
}, [cart.items]);
useEffect(() => {
setImmediate(() => {
if (login.accessToken && login.refreshToken)
refreshAccessToken({
dispatch,
refreshToken: login.refreshToken,
});
});
const id = setInterval(() => {
if (login.accessToken && login.refreshToken)
refreshAccessToken({
dispatch,
refreshToken: login.refreshToken,
});
}, TIME_REFRESH_TOKEN);
return () => clearInterval(id);
}, [login.refreshToken]);
useEffect(() => {
setImmediate(() => {
saveLogin(login);
});
}, [login]);
useEffect(() => {
setImmediate(() => {
saveUser(user);
});
}, [user]);
useEffect(() => {
if (selectedProvince) {
const { endDate, endTime } = selectedProvince;
// for now, we need to save these two values in 2 places and synchronize them,
// once at the 'outside' so `isInOrderableRange` get easily get it,
// and another as the context so it'll change when provinceCode changed,
// TODO?
setAllowedDayRange(endDate);
setAllowedOrderDueTime(endTime);
setTimeLimit({
dayRange: endDate,
dueTime: endTime,
});
setImmediate(() => {
saveDayRange(endDate);
saveDueTime(endTime);
});
}
}, [state.global.provinceCode, provinces]);
return (
<AppContext.Provider value={{ state, dispatch }} >
<TimeLimitContext.Provider value={timeLimit}>
<AppliedRoleContext.Provider value={appliedRole}>
<div className="full m-auto black main flex flex-column">
<DialogSelectProvince
dispatch={dispatch}
provinceCode={state.global.provinceCode}
provinces={provinces}
/>
<BrowserRouter>
<Header
dispatch={dispatch}
user={user}
accessToken={login.accessToken}
itemQuantity={itemQuantity}
selectedProvince={selectedProvince}
/>
<BottomMenuBar itemQuantity={itemQuantity} />
<Breadcrumbs />
<Switch>
{routeConfig.map(({ path, component: Component, isProtected }) => (
<CustomRouter
key={path}
path={path}
isProtected={isProtected}
accessToken={login.accessToken}
exact
component={Component}
/>
))}
<Route
path="*"
exact
component={NotFound}
/>
</Switch>
<Footer />
</BrowserRouter>
</div>
</AppliedRoleContext.Provider>
</TimeLimitContext.Provider>
</AppContext.Provider>
);
}
// ***************************************
// private
function CustomRouter({ path, component: Component, accessToken, isProtected }) {
if (isProtected) {
return (
<PrivateRoute
key={path}
accessToken={accessToken}
path={path}
exact
component={Component}
/>
);
}
return (
<Route
key={path}
path={path}
exact
render={routeProps =>
<Component {...routeProps} />
}
/>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment