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/account/licenses/managed-licenses.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Alert, Checkbox, Spin } from "antd";6import { load_target } from "@cocalc/frontend/history";7import {8CSS,9React,10useActions,11useEffect,12useIsMountedRef,13useMemo,14useState,15useTypedRedux,16} from "@cocalc/frontend/app-framework";17import { ErrorDisplay, Title } from "@cocalc/frontend/components";18import { SiteLicensePublicInfoTable } from "@cocalc/frontend/site-licenses/site-license-public-info";19import type { SiteLicenses } from "@cocalc/frontend/site-licenses/types";20import { plural } from "@cocalc/util/misc";2122export const LICENSES_STYLE: CSS = {23margin: "30px 0",24padding: "0",25} as const;2627export const ManagedLicenses: React.FC = () => {28const [error, setError] = useState<string | undefined>();29const [loading, setLoading] = useState<boolean>(true);30const [show_all, set_show_all] = useState<boolean>(false);31const actions = useActions("billing");32const is_mounted_ref = useIsMountedRef();3334const active_licenses = useTypedRedux("billing", "managed_license_ids"); // currently or recently valid35const all_licenses = useTypedRedux("billing", "all_managed_license_ids");36const licenses = useMemo(37() => (show_all ? all_licenses : active_licenses),38[active_licenses, all_licenses, show_all],39);4041async function reload() {42setLoading(true);43try {44await actions.update_managed_licenses();45} catch (err) {46if (!is_mounted_ref.current) return;47setError(err.toString());48} finally {49if (!is_mounted_ref.current) return;50setLoading(false);51}52}5354// When we first mount the component or when error gets cleared,55// we try to load the managed licenses:56useEffect(() => {57if (error) return; // do nothing when error is set.58reload();59}, [error]);6061function render_error() {62if (!error) return;63return (64<ErrorDisplay banner error={error} onClose={() => setError(undefined)} />65);66}6768function render_managed() {69if (error) return;70if (licenses == null) {71return <Spin />;72}73if (licenses.size == 0) {74return <div>You are not the manager of any licenses yet.</div>;75}7677const site_licenses: SiteLicenses = licenses.toJS().reduce((acc, v) => {78acc[v] = null; // we have no info about them yet79return acc;80}, {});8182return (83<div style={LICENSES_STYLE}>84<SiteLicensePublicInfoTable site_licenses={site_licenses} />85</div>86);87}8889function render_count() {90if (licenses != null && licenses.size > 0) {91return <>({licenses.size})</>;92}93}9495function render_show_all() {96if (97licenses == null ||98all_licenses == null ||99active_licenses == null ||100all_licenses.size == active_licenses.size101) {102// don't show if not loaded or not useful103return;104}105const n = all_licenses.size - licenses.size;106return (107<Checkbox108style={{ marginRight: "15px", fontWeight: 450 }}109checked={show_all}110onChange={() => set_show_all(!show_all)}111>112{n == 0113? "Showing all"114: `Show all (${n} older expired ${plural(n, "license")} omitted)`}115</Checkbox>116);117}118119return (120<>121<Title level={3}>122Licenses You Manage {render_count()}123<div style={{ float: "right" }}>{render_show_all()}</div>124{loading && <Spin />}125</Title>126<CancelSubscriptionBanner />127{render_error()}128{render_managed()}129</>130);131};132133// TODO: obviously this should only be shown if the user *has* a subscription!134function CancelSubscriptionBanner() {135return (136<Alert137banner138type="info"139message={140<>141To cancel a subscription,{" "}142<a143onClick={() => {144load_target("settings/subscriptions");145}}146>147visit the Subscription tab above148</a>149. To edit a license <i>that you purchased</i> expand the license150below, then click on the "Edit License..." button. To apply a license151to a project, select the project under Projects below.152</>153}154/>155);156}157158159