forked from M-Labs/web2019
Cache total price calculation
Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
parent
4527189994
commit
15d9124025
61763
static/js/shop.bundle.js
61763
static/js/shop.bundle.js
File diff suppressed because one or more lines are too long
|
@ -3,11 +3,10 @@ import {Cart} from "./Cart";
|
|||
import {CrateMode} from "./CrateMode";
|
||||
import {CrateWarnings} from "./CrateWarnings";
|
||||
import {useShopStore} from "./shop_store";
|
||||
import {CrateOptions} from "./CrateOptions";
|
||||
|
||||
// #!render_count
|
||||
import {useRenderCount} from "@uidotdev/usehooks";
|
||||
import {CrateFanTray} from "./CrateFanTray";
|
||||
import {CrateOptions} from "./CrateOptions";
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
import {useShopStore} from "./shop_store";
|
||||
import {Tip} from "./options/components/Tip";
|
||||
import {formatMoney} from "./utils";
|
||||
|
||||
export function CrateFanTray({crate_index}) {
|
||||
const currency = useShopStore((state) => state.currency);
|
||||
const fanTray = useShopStore((state) => state.fanTray);
|
||||
const crate_id = useShopStore((state) => state.crates[crate_index].id);
|
||||
const fanTrayAvailable = useShopStore((state) => state.fanTrayAvailableByIndex(crate_index));
|
||||
const fanTrayEnabled = useShopStore((state) => state.crates[crate_index].fan_tray);
|
||||
const updateFanTray = useShopStore((state) => state.updateFanTrayOption);
|
||||
|
||||
const base_id = crate_id + "fan_tray";
|
||||
return fanTrayAvailable ? (
|
||||
<div className="crate-bar">
|
||||
<div className="shop-switch">
|
||||
<div className="form-check form-switch">
|
||||
<input
|
||||
className="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id={base_id}
|
||||
checked={fanTrayEnabled}
|
||||
onClick={() => updateFanTray(crate_id, !fanTrayEnabled)}
|
||||
onChange={() => updateFanTray(crate_id, !fanTrayEnabled)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor={base_id} style={{"display": "inline", marginRight: "0.125rem"}}>
|
||||
{fanTray.optionTitle} (+{`${currency} ${formatMoney(fanTray.price)}`})
|
||||
</label>
|
||||
{fanTray.tip && <Tip id={base_id + "tooltip"} tip={fanTray.tip}/>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
|
@ -9,8 +9,6 @@ export function CrateOptions({crate_index}) {
|
|||
const updateOptions = useShopStore((state) => state.updateCrateOptions);
|
||||
const options_data = useShopStore((state) => state.crates[crate_index].options_data || {});
|
||||
|
||||
console.log(options_data)
|
||||
|
||||
const options = ProcessOptions({
|
||||
options: optionsLogic,
|
||||
data: options_data,
|
||||
|
@ -33,8 +31,6 @@ export function CrateOptions({crate_index}) {
|
|||
}
|
||||
});
|
||||
|
||||
console.log(options)
|
||||
|
||||
return (
|
||||
<div className="crate-bar">
|
||||
{options}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
import {formatMoney} from "./utils";
|
||||
import React from "react";
|
||||
import {useShopStore} from "./shop_store";
|
||||
|
||||
// #!render_count
|
||||
import {useRenderCount} from "@uidotdev/usehooks";
|
||||
|
||||
|
||||
export function SummaryCrateFanTray({crate_index}) {
|
||||
// #!render_count
|
||||
const renderCount = useRenderCount();
|
||||
|
||||
const currency = useShopStore((state) => state.currency);
|
||||
const fanTray = useShopStore((state) => state.fanTray);
|
||||
const crate_id = useShopStore((state) => state.crates[crate_index].id);
|
||||
const fanTrayAvailable = useShopStore((state) => state.fanTrayAvailableByIndex(crate_index));
|
||||
const fanTrayEnabled = useShopStore((state) => state.crates[crate_index].fan_tray);
|
||||
const updateFanTray = useShopStore((state) => state.updateFanTrayOption);
|
||||
|
||||
|
||||
// #!render_count
|
||||
console.log("SummaryCrateCard renders: ", renderCount)
|
||||
|
||||
return (fanTrayAvailable && fanTrayEnabled) ? (<tr
|
||||
key={"summary_crate_" + crate_id + "_fan_tray"}>
|
||||
<td className="item-card-name">
|
||||
<span style={{
|
||||
'display': 'inline-block', 'width': '16px',
|
||||
}}> </span>
|
||||
<div>{fanTray.optionTitle}</div>
|
||||
</td>
|
||||
|
||||
<td className="price">
|
||||
<div className="d-inline-flex align-content-center">
|
||||
{`${currency} ${formatMoney(fanTray.price)}`}
|
||||
|
||||
<button onClick={() => updateFanTray(crate_id, false)}>
|
||||
<img src="/images/shop/icon-remove.svg" className="d-block"/>
|
||||
</button>
|
||||
|
||||
<div style={{'width': '45px', 'height': '20px'}} className="d-inline"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>) : null;
|
||||
}
|
|
@ -18,8 +18,6 @@ export function SummaryCratePricedOptions({crate_index}) {
|
|||
|
||||
const options = ProcessOptionsToData({options: optionsPrices, data: options_data});
|
||||
|
||||
console.log(options, options_data, optionsPrices)
|
||||
|
||||
// #!render_count
|
||||
console.log("SummaryCratePricedOptions renders: ", renderCount)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import React from "react";
|
|||
|
||||
export function SummaryTotalPrice() {
|
||||
const currency = useShopStore((state) => state.currency);
|
||||
const total_price = useShopStore((state) => state.totalOrderPrice());
|
||||
const total_price = useShopStore((state) => state.total_order_price);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
|
@ -36,12 +36,11 @@ export function JSONToCrates(description) {
|
|||
const parsed = JSON.parse(description);
|
||||
const crates_raw = parsed.crates;
|
||||
const pn_to_card = useShopStore.getState().getCardDescriptionByPn;
|
||||
const fanTrayAvailable = useShopStore.getState().fanTrayAvailableForMode;
|
||||
|
||||
const crates = Array.from(crates_raw.map((crate, c_i) => ({
|
||||
id: crate.type === "no_crate" ? "spare" : "crate" + c_i,
|
||||
name: crate.type === "no_crate" ? "Spare cards" : undefined,
|
||||
fan_tray: fanTrayAvailable(crate.type) && crate.fan_tray === true,
|
||||
options_data: crate.options,
|
||||
crate_mode: crate.type,
|
||||
items: Array.from(crate.items.map((card, _i) => ({
|
||||
...pn_to_card(card.pn),
|
||||
|
@ -59,7 +58,7 @@ export function JSONToCrates(description) {
|
|||
}
|
||||
|
||||
export function CratesToJSON(crates) {
|
||||
const fanTrayAvailable = useShopStore.getState().fanTrayAvailableForMode;
|
||||
const crateOptions = useShopStore.getState().crate_options;
|
||||
return JSON.stringify({
|
||||
// additional fields can go here
|
||||
crates: Array.from(crates.map((crate, _i) => ({
|
||||
|
@ -68,7 +67,7 @@ export function CratesToJSON(crates) {
|
|||
options: (card.options_data && card.options) ? FilterOptions(card.options, card.options_data) : null
|
||||
}))),
|
||||
type: crate.crate_mode,
|
||||
fan_tray: (!fanTrayAvailable(crate.crate_mode) ? undefined : true) && crate.fan_tray
|
||||
options: FilterOptions(crateOptions, crate.options_data)
|
||||
})))
|
||||
}, null, 2)
|
||||
}
|
|
@ -9,6 +9,8 @@ import {FillExtCardData} from "./options/utils";
|
|||
import {TriggerCrateWarnings, TriggerWarnings} from "./warnings";
|
||||
import {Validation, validateEmail, validateNote, validateJSONInput} from "./validate";
|
||||
import {CratesToJSON, JSONToCrates} from "./json_porter";
|
||||
import {ProcessOptionsToData} from "./options/Options";
|
||||
import {forEach} from "react-bootstrap/ElementChildren";
|
||||
|
||||
|
||||
const cards_to_pn_map = (cards) => {
|
||||
|
@ -58,13 +60,6 @@ const useCrateOptions = ((set, get) => ({
|
|||
crates: state.crates.map((crate, _i) => {
|
||||
if (crate_id === crate.id) {
|
||||
const previous_options = crate.options_data || {};
|
||||
console.log(crate_id, new_options, {
|
||||
...crate,
|
||||
options_data: {
|
||||
...previous_options,
|
||||
...new_options
|
||||
}
|
||||
})
|
||||
return {
|
||||
...crate,
|
||||
options_data: {
|
||||
|
@ -80,6 +75,7 @@ const useCrateOptions = ((set, get) => ({
|
|||
updateCrateOptions: (crate_id, new_options) => {
|
||||
get().fillExtCrateData(crate_id);
|
||||
get()._updateCrateOption(crate_id, new_options);
|
||||
get()._updateTotalOrderPrice();
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -101,6 +97,7 @@ const useOrderOptions = ((set, get) => ({
|
|||
updateOrderOptions: (new_options) => {
|
||||
get().fillOrderExtData();
|
||||
get()._updateOrderOptions(new_options);
|
||||
get()._updateTotalOrderPrice();
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -158,9 +155,11 @@ const useImportJSON = ((set, get) => ({
|
|||
loadDescription: () => {
|
||||
get()._loadDescription()
|
||||
get().crates.forEach((crate, _i) => {
|
||||
get().fillExtData(crate.id)
|
||||
get().fillWarnings(crate.id)
|
||||
})
|
||||
get().fillExtData(crate.id);
|
||||
get().fillWarnings(crate.id);
|
||||
get().fillExtCrateData(crate.id);
|
||||
});
|
||||
get()._updateTotalOrderPrice();
|
||||
},
|
||||
updateImportDescription: (new_description) => set(state => ({
|
||||
importValue: {
|
||||
|
@ -309,6 +308,7 @@ const useCart = ((set, get) => ({
|
|||
crates: shared_data.columns.crates,
|
||||
active_crate: "crate0",
|
||||
_defaultCrates: Array.from(shared_data.columns.crates),
|
||||
total_order_price: 0,
|
||||
|
||||
_newCrate: (crate_id) => set((state) => ({
|
||||
crates: state.crates.toSpliced(-1, 0, {
|
||||
|
@ -461,17 +461,18 @@ const useCart = ((set, get) => ({
|
|||
})
|
||||
})),
|
||||
|
||||
totalOrderPrice: () => {
|
||||
_updateTotalOrderPrice: () => set(state => {
|
||||
let sum = 0;
|
||||
get().crates.forEach( (crate, i) => {
|
||||
sum += get().crate_modes[crate.crate_mode].price;
|
||||
sum += (crate.fan_tray && get().fanTrayAvailableByIndex(i)) ? get().fanTray.price : 0;
|
||||
const crate_options = ProcessOptionsToData({options: get().crate_prices, data: crate.options_data || {}});
|
||||
sum += crate_options ? crate_options.reduce((accumulator, currentValue) => accumulator+currentValue.price, 0) : 0;
|
||||
crate.items.forEach((item, _) => {
|
||||
sum += item.price;
|
||||
});
|
||||
});
|
||||
return sum;
|
||||
},
|
||||
return {total_order_price: sum};
|
||||
}),
|
||||
|
||||
// Composite actions that require warnings recalculation:
|
||||
|
||||
|
@ -481,6 +482,7 @@ const useCart = ((set, get) => ({
|
|||
get().fillExtData(crate_id);
|
||||
get().fillExtCrateData(crate_id);
|
||||
get().fillWarnings(crate_id);
|
||||
get()._updateTotalOrderPrice();
|
||||
},
|
||||
|
||||
setCrateMode: (id, mode) => {
|
||||
|
@ -489,6 +491,7 @@ const useCart = ((set, get) => ({
|
|||
get().fillExtCrateData(id);
|
||||
get().fillWarnings(id);
|
||||
get().setActiveCrate(id);
|
||||
get()._updateTotalOrderPrice();
|
||||
},
|
||||
|
||||
addCardFromBacklog: (crate_to, index_from, index_to, just_mounted) => {
|
||||
|
@ -502,6 +505,7 @@ const useCart = ((set, get) => ({
|
|||
get().fillExtData(dest);
|
||||
get().fillWarnings(dest);
|
||||
get().setActiveCrate(dest);
|
||||
get()._updateTotalOrderPrice();
|
||||
if (!just_mounted) {
|
||||
get().cardAdded()
|
||||
}
|
||||
|
@ -512,6 +516,7 @@ const useCart = ((set, get) => ({
|
|||
get().fillExtData(crate_to);
|
||||
get().fillWarnings(crate_to);
|
||||
get().setActiveCrate(crate_to);
|
||||
get()._updateTotalOrderPrice();
|
||||
if (crate_from !== crate_to) {
|
||||
get().fillExtData(crate_from);
|
||||
get().fillWarnings(crate_from);
|
||||
|
@ -521,6 +526,7 @@ const useCart = ((set, get) => ({
|
|||
get()._deleteCard(crate_id, index);
|
||||
get().fillExtData(crate_id);
|
||||
get().fillWarnings(crate_id);
|
||||
get()._updateTotalOrderPrice();
|
||||
if (crate_id === get().highlighted.crate && index === get().highlighted.card) get().highlightReset()
|
||||
},
|
||||
clearCrate: (id) => {
|
||||
|
@ -534,28 +540,13 @@ const useCart = ((set, get) => ({
|
|||
get().fillWarnings(crate_id);
|
||||
},
|
||||
|
||||
updateFanTrayOption: (crate_id, add_fan_tray) => set(state => ({
|
||||
crates: state.crates.map((crate, _i) => {
|
||||
if (crate_id === crate.id) {
|
||||
return {
|
||||
...crate,
|
||||
fan_tray: add_fan_tray
|
||||
}
|
||||
}
|
||||
else return crate;
|
||||
})
|
||||
})),
|
||||
|
||||
fanTrayAvailableByIndex: (crate_index) => {
|
||||
return get().fanTrayAvailableForMode(get().crates[crate_index].crate_mode);
|
||||
},
|
||||
|
||||
initExtData: () => {
|
||||
get().fillOrderExtData();
|
||||
get().crates.forEach((crate, _i) => {
|
||||
get().fillExtData(crate.id);
|
||||
get().fillExtCrateData(crate.id);
|
||||
})
|
||||
get()._updateTotalOrderPrice();
|
||||
}
|
||||
}))
|
||||
|
||||
|
|
Loading…
Reference in New Issue