Add css classes to the radio component, add shipping summary and other content fixes

Signed-off-by: Egor Savkin <es@m-labs.hk>
pull/117/head
Egor Savkin 2024-02-02 17:24:01 +08:00
parent 0b5797b1ba
commit 759f7cffcc
13 changed files with 592 additions and 469 deletions

912
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,24 +13,23 @@
"url": "https://git.m-labs.hk/M-Labs/web2019.git"
},
"devDependencies": {
"@babel/cli": "^7.23.0",
"@babel/core": "^7.23.2",
"@babel/preset-env": "^7.23.2",
"@babel/preset-react": "^7.22.15",
"@babel/cli": "^7.23.9",
"@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"@babel/preset-react": "^7.23.3",
"babel-loader": "^9.1.3",
"babel-preset-minify": "^0.5.2",
"bootstrap": "^5.3.0",
"jquery": "^3.7.0",
"prop-types": "^15.8.1",
"bootstrap": "^5.3.2",
"jquery": "^3.7.1",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-bootstrap": "^2.10.0",
"@hello-pangea/dnd": "^16.5.0",
"react-dom": "^18.2.0",
"uuid": "^9.0.1",
"webpack": "^5.89.0",
"webpack": "^5.90.1",
"webpack-cli": "^5.1.4",
"json-logic-js": "^2.0.2",
"zustand": "^4.4.7",
"zustand": "^4.5.0",
"@uidotdev/usehooks":"^2.4.1",
"webpack-preprocessor-loader": "^1.3.0"
},

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,7 @@ import {SummaryCrate} from "./SummaryCrate";
// #!render_count
import {useRenderCount} from "@uidotdev/usehooks";
import {SummaryOrderPricedOptions} from "./SummaryOrderPricedOptions";
import {SummaryOrderShipping} from "./SummaryOrderShipping";
export function SummaryCrates() {
// #!render_count
@ -22,6 +23,7 @@ export function SummaryCrates() {
return <SummaryCrate crate_index={index} key={"summary_crate_body_" + index} />
})}
<SummaryOrderPricedOptions/>
<SummaryOrderShipping/>
</>
)
}

View File

@ -0,0 +1,35 @@
import {formatMoney} from "./utils";
import React from "react";
import {useShopStore} from "./shop_store";
import {ProcessOptions, ProcessOptionsToData} from "./options/Options";
// #!render_count
import {useRenderCount} from "@uidotdev/usehooks";
export function SummaryOrderShipping() {
// #!render_count
const renderCount = useRenderCount();
const shipping_summary = useShopStore((state) => state.shipping_summary);
const options_data = useShopStore((state) => state.order_options_data);
// #!render_count
console.log("SummaryOrderShipping renders: ", renderCount)
const options = ProcessOptions({
options: shipping_summary,
data: options_data,
id: "shipping_options",
target: null,
});
return <tbody key="summary_shipping_order_body">
{options.map((option, i) => (
<tr key={"summary_shipping_order_option_" + i} id={"summary_shipping_order_option_" + i}>
<td className="item-card-name" key={"summary_shipping_order_key_option_" + i} id={"summary_shipping_order_key_option_" + i}>
{option}
</td>
</tr>
))}
</tbody>;
}

View File

@ -0,0 +1,17 @@
import React from "react";
import {apply as json_logic_apply, add_operation as json_add_operation} from "json-logic-js";
json_add_operation("lower", (some_str) => some_str.toLowerCase(some_str));
json_add_operation("upper", (some_str) => some_str.toUpperCase(some_str));
json_add_operation("capitalize", (some_str) => some_str.capitalizeFirstLetter(some_str));
export function Label(target, id, data, {content}) {
const resulting_string = json_logic_apply(content, data).flat().join("");
return (
<div id={id+"label"} key={id+"label"} className="options-label">
{resulting_string}
</div>
)
}

View File

@ -46,7 +46,7 @@ class Line extends Component {
}
}
export function LineWrapper(target, id, data, {title, fallback, outvar, icon, tip}) {
export function LineWrapper(target, id, data, {title, fallback, outvar, icon, tip, classes}) {
return <Line target={target} title={title} fallback={fallback} outvar={outvar} icon={icon} tip={tip} key={id}
id={id} data={data}/>;
id={id} data={data} classes={classes}/>;
}

View File

@ -42,7 +42,7 @@ class Radio extends Component {
</div>
{this.props.tip && <Tip id={this.props.id + "tooltip"} tip={this.props.tip}/>}
{this.props.variants.map((variant, _) => (
<div className="form-check shop-radio-variant" key={key + variant}>
<div className={`form-check shop-radio-variant ${this.props.classes}`} key={key + variant}>
<input
className="form-check-input"
type="radio"
@ -62,8 +62,8 @@ class Radio extends Component {
}
}
export function RadioWrapper(target, id, data, {title, variants, outvar, fallback, icon, tip}) {
export function RadioWrapper(target, id, data, {title, variants, outvar, fallback, icon, tip, classes}) {
return <Radio target={target} title={title} variants={variants} outvar={outvar} icon={icon} tip={tip} key={id}
fallback={fallback}
fallback={fallback} classes={classes}
id={id} data={data}/>;
}

View File

@ -57,7 +57,7 @@ class Switch extends Component {
}
}
export function SwitchWrapper(target, id, data, {title, fallback, outvar, icon, tip}) {
export function SwitchWrapper(target, id, data, {title, fallback, outvar, icon, tip, classes}) {
return <Switch target={target} title={title} fallback={fallback} outvar={outvar} icon={icon} tip={tip} key={id}
id={id} data={data}/>;
id={id} data={data} classes={classes}/>;
}

View File

@ -71,7 +71,7 @@ class SwitchLine extends Component {
}
}
export function SwitchLineWrapper(target, id, data, {title, fallback, outvar, icon, tip}) {
export function SwitchLineWrapper(target, id, data, {title, fallback, outvar, icon, tip, classes}) {
return <SwitchLine target={target} title={title} fallback={fallback} outvar={outvar} icon={icon} tip={tip} key={id}
id={id} data={data}/>;
id={id} data={data} classes={classes}/>;
}

View File

@ -5,6 +5,7 @@ import {RadioWrapper} from "./Radio";
import {SwitchWrapper} from "./Switch";
import {SwitchLineWrapper} from "./SwitchLine";
import {UnimplementedComponent} from "./UnimplementedComponent";
import {Label} from "./Label";
// Class components are used because we cannot use hooks for updating the state
@ -13,5 +14,6 @@ export const componentsList = {
"Switch": SwitchWrapper,
"Line": LineWrapper,
"SwitchLine": SwitchLineWrapper,
"Label": Label,
"Default": UnimplementedComponent,
};

View File

@ -82,6 +82,7 @@ const useCrateOptions = ((set, get) => ({
const useOrderOptions = ((set, get) => ({
order_options: shared_data.orderOptions.options,
order_prices: shared_data.orderOptions.prices,
shipping_summary: shared_data.orderOptions.shippingSummary,
order_options_data: {},
fillOrderExtData: () => set(state => ({

View File

@ -50,7 +50,7 @@ const shop_data = {
options: [
{"type": "Group", items:[
{type: "Switch", args: {
title: "Include optional pre-installed Intel® NUC mini-computer",
title: "Include optional Intel® NUC mini-computer with pre-installed ARTIQ software",
outvar: "nuc",
tip: "OS: latest stable NixOS with Gnome or KDE with pre-installed ARTIQ software. " +
"Hardware (other choices available): Intel® NUC 13 Pro Kit NUC13ANKi7, i7-1360P CPU, " +
@ -68,20 +68,30 @@ const shop_data = {
outvar: "nuc_desktop",
variants: ["Gnome", "KDE"],
tip: "Gnome has clean and minimalist design. KDE has more feature-rich and classic interface.",
fallback: 0
fallback: 0,
classes: "form-check-inline ms-4"
}
},
{type: "Line", args: {title: "Additional software to be pre-installed", outvar: "software", fallback: "",
tip: "Pre-install additional software, if needed."}},
],
{"if": [
{"if": [
{"var": "ext_data.has_crate"},
{type: "Switch", args: {
title: "Opt-out from promotional USB stick",
outvar: "usb_stick_opt_out",
tip: "Choose if you don't need a USB stick and wish to receive configuration files via other electronic means (e.g. email or cloud).",
title: "Include promotional USB stick",
outvar: "include_usb_stick_nuc",
tip: "Choose if you need a USB stick and wish to receive configuration files via other electronic means (e.g. email or cloud).",
fallback: false,
}}
}}
]},
],
{"if": [
{"var": "ext_data.has_crate"},
{type: "Switch", args: {
title: "Include promotional USB stick",
outvar: "include_usb_stick",
tip: "Choose if you need a USB stick and wish to receive configuration files via other electronic means (e.g. email or cloud).",
fallback: true,
}}
]},
]
},
@ -127,7 +137,32 @@ const shop_data = {
prices: [{
"if": [{"var": "nuc"}, {title: "Include optional pre-installed Intel® NUC mini-computer", price: 1300, disable_patch: {"nuc": false}, id: "nuc"}],
}]
}],
shippingSummary: [
{type: "Label", args: {
content: ["Shipping method: ", {"var": "shipping"}]
}},
{"if": [
{"var": "shipping_instructions"},
{type: "Label", args: {
content: [
{"if": [
{"==": [{"var": "shipping"}, "Incoterms 2020 FCA"]},
"carrier account information and/or other shipping instructions: ",
"delivery address: "
]},
{"var": "shipping_instructions"}
]
}}]},
{type: "Label", args: {
content: [
{"if": [
{"==": [{"var": "shipping"}, "Prepay and add shipping (only available to credit customers)"]},
["In case of additional customs fees: ", {"lower": {"var": "prepay_fees_handling"}}],
]}
]
}},
]
},
items: {