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/frontend/billing/subscription-grid.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Row, Col } from "@cocalc/frontend/antd-bootstrap";6import { Component, Rendered, redux } from "../app-framework";7import { keys, intersection } from "lodash";8import { PeriodName } from "./types";9import { PlanInfo } from "./plan-info";10import { PROJECT_UPGRADES } from "@cocalc/util/schema";1112interface Props {13periods: PeriodName[];14selected_plan?: string;15is_static?: boolean; // used for display mode16}1718export class SubscriptionGrid extends Component<Props> {19private is_selected(plan: string): boolean {20if (this.props.selected_plan === plan) return true;21const period = this.props.periods[0];22if (period == null) return false; // doesn't happen23if (period.slice(0, 4) === "year") {24return this.props.selected_plan === `${plan}-year`;25} else if (period.slice(0, 4) === "week") {26return this.props.selected_plan === `${plan}-week`;27} else {28return false;29}30}3132private click_on_plan(plan: string): void {33if (this.props.is_static) return;34const actions = redux.getActions("billing");35if (actions == null) return;36const period = this.props.periods[0];37if (period == null) return; // doesn't happen38actions.set_selected_plan(plan, period);39}4041private render_plan_info(plan: string): Rendered {42return (43<PlanInfo44plan={plan}45periods={this.props.periods}46selected={this.is_selected(plan)}47on_click={48this.props.is_static ? undefined : () => this.click_on_plan(plan)49}50/>51);52}5354private render_cols(row: string[], ncols: number): Rendered[] {55const width = 12 / ncols;56return row.map((plan) => (57<Col sm={width} key={plan}>58{this.render_plan_info(plan)}59</Col>60));61}6263private render_rows(live_subscriptions: string[][], ncols): Rendered[] {64const v: Rendered[] = [];65for (const i in live_subscriptions) {66const row: string[] = live_subscriptions[i];67v.push(<Row key={i}>{this.render_cols(row, ncols)}</Row>);68}69return v;70}7172public render(): Rendered {73const live_subscriptions: string[][] = [];74let ncols: number = 0; // max number of columns in any row75for (const row of PROJECT_UPGRADES.live_subscriptions) {76const v: string[] = [];77for (const x of row) {78const price_keys = keys(PROJECT_UPGRADES.subscription[x].price);79if (intersection(this.props.periods, price_keys).length > 0) {80ncols = Math.max(ncols, row.length); // this row matters.81v.push(x);82}83}84if (v.length > 0) {85live_subscriptions.push(v);86}87}88// Round up to nearest divisor of 1289if (ncols === 5) {90ncols = 6;91} else if (ncols >= 7) {92ncols = 12;93}94return <div>{this.render_rows(live_subscriptions, ncols)}</div>;95}96}979899