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/account-page.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6The account page. This is what you see when you7click "Account" in the upper right. It has tabs8for different account related information9and configuration.10*/1112import { useEffect } from "react";13import { Space } from "antd";14import { useIntl } from "react-intl";15import { SignOut } from "@cocalc/frontend/account/sign-out";16import { AntdTabItem, Col, Row, Tabs } from "@cocalc/frontend/antd-bootstrap";17import {18React,19redux,20useIsMountedRef,21useTypedRedux,22useWindowDimensions,23} from "@cocalc/frontend/app-framework";24import { Icon, Loading } from "@cocalc/frontend/components";25import { cloudFilesystemsEnabled } from "@cocalc/frontend/compute";26import CloudFilesystems from "@cocalc/frontend/compute/cloud-filesystem/cloud-filesystems";27import { labels } from "@cocalc/frontend/i18n";28import PurchasesPage from "@cocalc/frontend/purchases/purchases-page";29import StatementsPage from "@cocalc/frontend/purchases/statements-page";30import SubscriptionsPage from "@cocalc/frontend/purchases/subscriptions-page";31import { SupportTickets } from "@cocalc/frontend/support";32import {33KUCALC_COCALC_COM,34KUCALC_ON_PREMISES,35} from "@cocalc/util/db-schema/site-defaults";36import { AccountPreferences } from "./account-preferences";37import { I18NSelector } from "./i18n-selector";38import { LicensesPage } from "./licenses/licenses-page";39import { PublicPaths } from "./public-paths/public-paths";40import { SSHKeysPage } from "./ssh-keys/global-ssh-keys";41import { UpgradesPage } from "./upgrades/upgrades-page";42import { appBasePath } from "@cocalc/frontend/customize/app-base-path";4344export const AccountPage: React.FC = () => {45const intl = useIntl();4647const { width: windowWidth } = useWindowDimensions();48const isWide = windowWidth > 800;4950const active_page = useTypedRedux("account", "active_page");51const is_logged_in = useTypedRedux("account", "is_logged_in");52const account_id = useTypedRedux("account", "account_id");53const is_anonymous = useTypedRedux("account", "is_anonymous");54const kucalc = useTypedRedux("customize", "kucalc");55const ssh_gateway = useTypedRedux("customize", "ssh_gateway");56const is_commercial = useTypedRedux("customize", "is_commercial");57const get_api_key = useTypedRedux("page", "get_api_key");5859function handle_select(key: string): void {60switch (key) {61case "billing":62redux.getActions("billing").update_customer();63break;64case "support":65break;66case "signout":67return;68}69redux.getActions("account").set_active_tab(key);70redux.getActions("account").push_state(`/${key}`);71}7273function render_account_tab(): AntdTabItem {74return {75key: "account",76label: (77<span>78<Icon name="wrench" /> {intl.formatMessage(labels.preferences)}79</span>80),81children: (active_page == null || active_page === "account") && (82<AccountPreferences />83),84};85}8687function render_special_tabs(): AntdTabItem[] {88// adds a few conditional tabs89if (is_anonymous) {90// None of these make any sense for a temporary anonymous account.91return [];92}93const items: AntdTabItem[] = [];94if (is_commercial) {95items.push({96key: "purchases",97label: (98<span>99<Icon name="money" /> {intl.formatMessage(labels.purchases)}100</span>101),102children: active_page === "purchases" && <PurchasesPage />,103});104items.push({105key: "subscriptions",106label: (107<span>108<Icon name="calendar" /> {intl.formatMessage(labels.subscriptions)}109</span>110),111children: active_page === "subscriptions" && <SubscriptionsPage />,112});113items.push({114key: "statements",115label: (116<span>117<Icon name="money" /> {intl.formatMessage(labels.statements)}118</span>119),120children: active_page === "statements" && <StatementsPage />,121});122}123124if (125kucalc === KUCALC_COCALC_COM ||126kucalc === KUCALC_ON_PREMISES ||127is_commercial128) {129items.push({130key: "licenses",131label: (132<span>133<Icon name="key" /> {intl.formatMessage(labels.licenses)}134</span>135),136children: active_page === "licenses" && <LicensesPage />,137});138}139140if (ssh_gateway || kucalc === KUCALC_COCALC_COM) {141items.push({142key: "ssh-keys",143label: (144<span>145<Icon name="key" /> {intl.formatMessage(labels.ssh_keys)}146</span>147),148children: active_page === "ssh-keys" && <SSHKeysPage />,149});150}151if (is_commercial) {152items.push({153key: "support",154label: (155<span>156<Icon name="medkit" /> {intl.formatMessage(labels.support)}157</span>158),159children: active_page === "support" && <SupportTickets />,160});161}162items.push({163key: "public-files",164label: (165<span>166<Icon name="share-square" />{" "}167{intl.formatMessage(labels.published_files)}168</span>169),170children: active_page === "public-files" && <PublicPaths />,171});172if (is_commercial && kucalc === KUCALC_COCALC_COM) {173items.push({174key: "upgrades",175label: (176<span>177<Icon name="arrow-circle-up" />{" "}178{intl.formatMessage(labels.upgrades)}179</span>180),181children: active_page === "upgrades" && <UpgradesPage />,182});183}184if (cloudFilesystemsEnabled()) {185items.push({186key: "cloud-filesystems",187label: (188<>189<Icon name="disk-round" />{" "}190{intl.formatMessage(labels.cloud_file_system)}191</>192),193children: <CloudFilesystems />,194});195}196197return items;198}199200function renderExtraContent() {201return (202<Space>203<I18NSelector isWide={isWide} />204<SignOut everywhere={false} highlight={true} narrow={!isWide} />205</Space>206);207}208209function render_logged_in_view(): JSX.Element {210if (!account_id) {211return (212<div style={{ textAlign: "center", paddingTop: "15px" }}>213<Loading theme={"medium"} />214</div>215);216}217if (is_anonymous) {218return (219<div style={{ margin: "15px 10%" }}>220<AccountPreferences />221</div>222);223}224225const tabs: AntdTabItem[] = [226render_account_tab(),227...render_special_tabs(),228];229230return (231<Row>232<Col md={12}>233<Tabs234activeKey={active_page ?? "account"}235onSelect={handle_select}236animation={false}237tabBarExtraContent={renderExtraContent()}238items={tabs}239/>240</Col>241</Row>242);243}244245return (246<div247className="smc-vfill"248style={{ overflow: "auto", paddingLeft: "5%", paddingRight: "5%" }}249>250{is_logged_in && !get_api_key ? (251render_logged_in_view()252) : (253<RedirectToNextApp />254)}255</div>256);257};258259function RedirectToNextApp({}) {260const isMountedRef = useIsMountedRef();261262useEffect(() => {263const f = () => {264if (isMountedRef.current) {265// didn't get signed in so go to landing page266window.location.href = appBasePath;267}268};269setTimeout(f, 5000);270}, []);271272return <Loading theme="medium" />;273}274275276