diff --git a/components/dashboard/src/components/UsageLimitReachedModal.tsx b/components/dashboard/src/components/UsageLimitReachedModal.tsx new file mode 100644 index 00000000000000..a5944197f992c0 --- /dev/null +++ b/components/dashboard/src/components/UsageLimitReachedModal.tsx @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2022 Gitpod GmbH. All rights reserved. + * Licensed under the GNU Affero General Public License (AGPL). + * See License-AGPL.txt in the project root for license information. + */ + +import { Team } from "@gitpod/gitpod-protocol"; +import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution"; +import { useContext, useEffect, useState } from "react"; +import { gitpodHostUrl } from "../service/service"; +import { TeamsContext } from "../teams/teams-context"; +import Alert from "./Alert"; +import Modal from "./Modal"; + +export function UsageLimitReachedModal(p: { hints: any }) { + const { teams } = useContext(TeamsContext); + // const [attributionId, setAttributionId] = useState(); + const [attributedTeam, setAttributedTeam] = useState(); + + useEffect(() => { + const attributionId: AttributionId | undefined = p.hints && p.hints.attributionId; + if (attributionId) { + // setAttributionId(attributionId); + if (attributionId.kind === "team") { + const team = teams?.find((t) => t.id === attributionId.teamId); + setAttributedTeam(team); + } + } + }, []); + + const attributedTeamName = attributedTeam?.name; + return ( + {}}> +

+ Usage Limit Reached +

+
+ + You have reached the usage limit of your billing account. + +

+ {"Contact a team owner "} + {attributedTeamName && ( + <> + of {attributedTeamName} + + )} + to increase the usage limit, or change your billing settings. +

+
+
+ + + +
+
+ ); +} diff --git a/components/dashboard/src/start/CreateWorkspace.tsx b/components/dashboard/src/start/CreateWorkspace.tsx index d38c76128f2b6b..6a374b8621aef5 100644 --- a/components/dashboard/src/start/CreateWorkspace.tsx +++ b/components/dashboard/src/start/CreateWorkspace.tsx @@ -10,7 +10,6 @@ import { RunningWorkspacePrebuildStarting, ContextURL, DisposableCollection, - Team, GitpodServer, } from "@gitpod/gitpod-protocol"; import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error"; @@ -26,10 +25,8 @@ import PrebuildLogs from "../components/PrebuildLogs"; import FeedbackComponent from "../feedback-form/FeedbackComponent"; import { isGitpodIo } from "../utils"; import { BillingAccountSelector } from "../components/BillingAccountSelector"; -import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution"; -import { TeamsContext } from "../teams/teams-context"; -import Alert from "../components/Alert"; import { FeatureFlagContext } from "../contexts/FeatureFlagContext"; +import { UsageLimitReachedModal } from "../components/UsageLimitReachedModal"; export interface CreateWorkspaceProps { contextUrl: string; @@ -380,50 +377,6 @@ function LimitReachedOutOfHours() { ); } -function UsageLimitReachedModal(p: { hints: any }) { - const { teams } = useContext(TeamsContext); - // const [attributionId, setAttributionId] = useState(); - const [attributedTeam, setAttributedTeam] = useState(); - - useEffect(() => { - const attributionId: AttributionId | undefined = p.hints && p.hints.attributionId; - if (attributionId) { - // setAttributionId(attributionId); - if (attributionId.kind === "team") { - const team = teams?.find((t) => t.id === attributionId.teamId); - setAttributedTeam(team); - } - } - }, []); - - const attributedTeamName = attributedTeam?.name; - return ( - {}}> -

- Usage Limit Reached -

-
- - You have reached the usage limit of your billing account. - -

- {"Contact a team owner "} - {attributedTeamName && ( - <> - of {attributedTeamName} - - )} - to increase the usage limit, or change your billing settings. -

-
- -
- ); -} function RepositoryNotFoundView(p: { error: StartWorkspaceError }) { const [statusMessage, setStatusMessage] = useState(); diff --git a/components/dashboard/src/start/StartPage.tsx b/components/dashboard/src/start/StartPage.tsx index 5e17b14141b435..6b3fbe9db62fbe 100644 --- a/components/dashboard/src/start/StartPage.tsx +++ b/components/dashboard/src/start/StartPage.tsx @@ -7,6 +7,7 @@ import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error"; import { useEffect } from "react"; import Alert from "../components/Alert"; +import { UsageLimitReachedModal } from "../components/UsageLimitReachedModal"; import gitpodIconUA from "../icons/gitpod.svg"; import { gitpodHostUrl } from "../service/service"; import { VerifyModal } from "./VerifyModal"; @@ -109,6 +110,9 @@ export function StartPage(props: StartPageProps) { )} {error && error.code === ErrorCodes.NEEDS_VERIFICATION && } + {error && error.code === ErrorCodes.PAYMENT_SPENDING_LIMIT_REACHED && ( + + )} {error && } {props.children} {props.showLatestIdeWarning && ( diff --git a/components/gitpod-protocol/src/util/gitpod-host-url.ts b/components/gitpod-protocol/src/util/gitpod-host-url.ts index 71dbecbe46665c..431ede3e5593dc 100644 --- a/components/gitpod-protocol/src/util/gitpod-host-url.ts +++ b/components/gitpod-protocol/src/util/gitpod-host-url.ts @@ -93,6 +93,10 @@ export class GitpodHostUrl { return this.with((url) => ({ pathname: "/" })); } + asBilling(): GitpodHostUrl { + return this.with((url) => ({ pathname: "/billing" })); + } + asLogin(): GitpodHostUrl { return this.with((url) => ({ pathname: "/login" })); }