import React, {useEffect} from "react";
import {MemoryRouter, Route, Switch} from "react-router-dom";
import {useAsyncState} from "hooks";
import {withTemplate} from "components/hocs";
import {Fragments} from "components";
import {FETCH_LOYALTY} from "utils/api";
import {config, constants, Routes} from "utils";
import css from "./loyalty.module.css";
import INITIAL_DATA from "./initializer";
import CreditBased from "./CreditBased";
import WalletBased from "./WalletBased";
import RedeemForm from "./WalletBased/Rewards/RedeemForm";
const {
LOYALTY_SYSTEMS: {CREDIT, WALLET},
} = constants;
const {
Loader,
Routes: {RouteWithProps},
} = Fragments;
const loyaltySections = config?.theme?.loyalty?.length
? config.theme.loyalty
: null;
/**
* Fetch loyalty data from '/loyalty' endpoint & returns Loyalty component
*
* @author Htin Linn Aung
* @memberof Templates.Templates/Loyalty
* @param {object} props
* @param {object} prop.style - Theme - Theme value from template provider
* @param props.style
* @param {object} props.walletProps - props just for wallet configuration
* @param {object} props.sections - Config - Loyalty Section to render
* @returns {React.Element} - Fetch loyalty data from '/loyalty' endpoint & returns Loyalty component
*/
const Loyalty = ({style, walletProps}) => {
const [loyalty, setLoyalty] = useAsyncState({
fetching: false,
state: INITIAL_DATA,
});
let loyaltySectionId = 0;
/**
* Fetch loyalty data from '/loyalty' endpoint and set component states
*
* @author Htin Linn Aung
* @memberof Templates.Templates/Loyalty
* @async
* @function fetchLoyalty
*/
const fetchLoyalty = async () => {
setLoyalty.setIsFetching();
try {
const res = await FETCH_LOYALTY();
if (res.status === 200) {
setLoyalty.setState(res.data);
}
} catch (e) {
console.error(e);
} finally {
setLoyalty.setNotFetching();
}
};
useEffect(() => {
fetchLoyalty();
}, []);
/**
* Loyalty section selector
*
* @author Htin Linn Aung
* @memberof Templates.Templates/Loyalty
* @function selectSection
* @param {object} section
* @param {object} location - Memory Router location
* @param {object} history - Memory Router history
*/
const selectSection = (section, location, history) => {
let Component;
let componentSpecificProps = {};
switch (section.system) {
case CREDIT:
Component = CreditBased;
break;
case WALLET:
Component = WalletBased;
componentSpecificProps = {
...walletProps,
onClickRedeem: () => history.push(Routes.REDEEM_REWARDS),
};
break;
default:
Component = CreditBased;
}
loyaltySectionId += 1;
return (
<Component
key={loyaltySectionId}
loyaltyData={loyalty.state}
loyaltyLayout={section.layout}
location={location}
history={history}
{...componentSpecificProps}
/>
);
};
/**
* Render all available loyalty sections
*
* @author Htin Linn Aung
* @memberof Templates.Templates/Loyalty
* @function renderLoyalty
* @param {object} location - Memory Router location
* @param {object} history - Memory Router history
*/
const renderLoyalty = (location, history) => {
if (loyalty.fetching) {
return (
<div className={css.loader}>
<Loader />
</div>
);
}
return loyaltySections?.map((section) =>
selectSection(section, location, history),
);
};
const handleSuccess = (history) => {
fetchLoyalty();
history.goBack();
};
return (
<MemoryRouter initialEntries={["/"]} initialIndex={0}>
<Route
render={({location, history}) => (
<div>
<Switch>
<RouteWithProps
exact
path={Routes.ROOT}
render={() => (
<div className={css.container}>
{renderLoyalty(location, history)}
</div>
)}
/>
<RouteWithProps
path={Routes.REDEEM_REWARDS}
component={RedeemForm}
style={style}
history={history}
location={location}
onSuccess={() => handleSuccess(history)}
/>
</Switch>
</div>
)}
/>
</MemoryRouter>
);
};
Loyalty.defaultProps = {
walletProps: {},
};
export default withTemplate(Loyalty, "loyalty");