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/index.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/4import { Alert, Layout } from "antd";5import { useRouter } from "next/router";6import { useEffect, useState } from "react";78import * as purchasesApi from "@cocalc/frontend/purchases/api";9import { COLORS } from "@cocalc/util/theme";10import Anonymous from "components/misc/anonymous";11import Loading from "components/share/loading";12import SiteName from "components/share/site-name";13import { StoreBalanceContext } from "lib/balance";14import { MAX_WIDTH } from "lib/config";15import useProfile from "lib/hooks/profile";16import useCustomize from "lib/use-customize";17import Boost from "./boost";18import Cart from "./cart";19import Checkout from "./checkout";20import Congrats from "./congrats";21import DedicatedResource from "./dedicated";22import Menu from "./menu";23import Overview from "./overview";24import SiteLicense from "./site-license";25import { StoreInplaceSignInOrUp } from "./store-inplace-signup";26import Vouchers from "./vouchers";2728const { Content } = Layout;2930interface Props {31page: (32| "site-license"33| "boost"34| "dedicated"35| "cart"36| "checkout"37| "congrats"38| "vouchers"39| undefined40)[];41}4243export default function StoreLayout({ page }: Props) {44const { isCommercial } = useCustomize();45const router = useRouter();46const profile = useProfile({ noCache: true });4748const [balance, setBalance] = useState<number>();4950const refreshBalance = async () => {51if (!profile || !profile.account_id) {52setBalance(undefined);53return;54}5556// Set balance if user is logged in57//58setBalance(await purchasesApi.getBalance());59};6061useEffect(() => {62router.prefetch("/store/site-license");63}, []);6465useEffect(() => {66refreshBalance();67}, [profile]);6869function renderNotCommercial(): JSX.Element {70return (71<Alert72showIcon73style={{74margin: "30px auto",75maxWidth: "400px",76fontSize: "12pt",77padding: "15px 30px",78}}79type="warning"80message={81<>82The <SiteName /> store is not enabled.83</>84}85/>86);87}8889if (!isCommercial) {90return renderNotCommercial();91}9293if (!profile) {94return <Loading large center />;95}96const { account_id, is_anonymous } = profile;97const noAccount = account_id == null;9899// wrapper: only the pages showing the prices will be shown to the general public or anonymous users100function requireAccount(StorePage): JSX.Element {101if (noAccount) {102return (103<Alert104style={{ margin: "15px auto" }}105type="warning"106message={<StoreInplaceSignInOrUp />}107/>108);109}110111return <StorePage />;112}113114const [main] = page;115116function body() {117if (main == null) return <Overview />;118119if (is_anonymous) {120return <Anonymous />;121}122123switch (main) {124case "site-license":125return <SiteLicense noAccount={noAccount} />;126case "boost":127return <Boost />;128case "dedicated":129return <DedicatedResource noAccount={noAccount} />;130case "cart":131return requireAccount(Cart);132case "checkout":133return requireAccount(Checkout);134case "vouchers":135return requireAccount(Vouchers);136case "congrats":137return requireAccount(Congrats);138default:139return <Alert type="error" message={`Invalid page ${main}`} />;140}141}142143// this layout is the same as ../licenses/layout.tsx and ../billing/layout.tsx144function renderMain(): JSX.Element {145return (146<Layout147style={{148padding: "0 24px 24px",149backgroundColor: "white",150color: COLORS.GRAY_D,151}}152>153<Content154style={{155margin: "0 30px",156minHeight: "60vh",157}}158>159<div style={{ maxWidth: MAX_WIDTH, margin: "auto" }}>160<StoreBalanceContext.Provider value={{ balance, refreshBalance }}>161<Menu main={main} />162{body()}163</StoreBalanceContext.Provider>164</div>165</Content>166</Layout>167);168}169170return renderMain();171}172173174