Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/next/components/store/add-box.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Add a cash voucher to your shopping cart.7*/8import { CostInputPeriod } from "@cocalc/util/licenses/purchase/types";9import { round2up, round4 } from "@cocalc/util/misc";10import { money } from "@cocalc/util/licenses/purchase/utils";11import { Alert, Button, Tooltip } from "antd";12import { addToCart } from "./add-to-cart";13import { DisplayCost } from "./site-license-cost";14import { periodicCost } from "@cocalc/util/licenses/purchase/compute-cost";1516interface Props {17cost?: CostInputPeriod;18router;19form;20cartError: string | undefined;21setCartError: (error) => void;22dedicatedItem?: boolean;23disabled?: boolean;24noAccount: boolean;25}2627export function AddBox(props: Props) {28const {29cost,30router,31form,32cartError,33setCartError,34dedicatedItem = false,35noAccount,36} = props;37// console.log({ cost });38if (cost?.input.type == "cash-voucher") {39return null;40}41let disabled = props.disabled ?? false;42// if any of the fields in cost that start with the string "cost" are NaN, disable submission:43if (44!cost ||45Object.keys(cost).some((k) => k.startsWith("cost") && isNaN(cost[k]))46) {47disabled = true;48}4950function costPerProject() {51if (cost?.input.type != "quota") {52return;53}54if (dedicatedItem || cost.input.quantity == null) {55return;56}57const costPer = periodicCost(cost) / cost.input.quantity;58return (59<Tooltip title={`$${round4(costPer)} per project`}>60<div>{money(round2up(costPer))} per project</div>61</Tooltip>62);63}6465function renderButton(): JSX.Element | null {66if (noAccount) return null;6768return (69<div style={{ textAlign: "center" }}>70{router.query.id != null && (71<Button72size="large"73style={{ marginRight: "5px" }}74onClick={() => router.push("/store/cart")}75disabled={disabled}76>77Cancel78</Button>79)}80<AddToCartButton81cartError={cartError}82cost={cost}83disabled={disabled}84form={form}85router={router}86setCartError={setCartError}87/>88{cartError && <Alert type="error" message={cartError} />}89</div>90);91}9293return (94<div style={{ textAlign: "center" }}>95<div96style={{97display: "inline-block",98maxWidth: "550px",99background: "white",100border: "1px solid #ccc",101padding: "10px 20px",102borderRadius: "5px",103margin: "15px 0",104fontSize: "12pt",105}}106>107{cost && <DisplayCost cost={cost} />}108{cost && costPerProject()}109{renderButton()}110</div>111</div>112);113}114115interface CartButtonProps {116cost: CostInputPeriod | undefined;117router;118form;119setCartError: (error) => void;120disabled?: boolean;121cartError: string | undefined;122variant?: "primary" | "small";123}124125export function AddToCartButton(props: CartButtonProps) {126const {127cost,128form,129router,130setCartError,131cartError,132variant = "primary",133} = props;134135const style = variant === "primary" ? { marginTop: "5px" } : {};136const disabled =137(props.disabled ?? false) || !!cartError || cost == null || cost.cost === 0;138139return (140<Button141size={variant === "small" ? "small" : "large"}142type="primary"143htmlType="submit"144style={style}145onClick={() => addToCart({ form, setCartError, router })}146disabled={disabled}147>148{disabled149? "Finish configuring the license..."150: router.query.id != null151? "Save Changes"152: "Add to Cart"}153</Button>154);155}156157158