Skip to content

Commit

Permalink
usage tab fe
Browse files Browse the repository at this point in the history
  • Loading branch information
jusrhee committed May 1, 2024
1 parent 3e5320e commit 648c21d
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 99 deletions.
12 changes: 7 additions & 5 deletions dashboard/src/components/TabRegion.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { Component } from "react";
import styled from "styled-components";

import TabSelector from "./TabSelector";
import Loading from "./Loading";
import TabSelector from "./TabSelector";

export interface TabOption {
export type TabOption = {
label: string;
value: string;
}
};

type PropsType = {
options: TabOption[];
Expand All @@ -31,7 +31,7 @@ export default class TabRegion extends Component<PropsType, StateType> {
: "";

componentDidUpdate(prevProps: PropsType) {
let { options, currentTab } = this.props;
const { options, currentTab } = this.props;
if (prevProps.options !== options) {
if (options.filter((x) => x.value === currentTab).length === 0) {
this.props.setCurrentTab(this.defaultTab());
Expand All @@ -50,7 +50,9 @@ export default class TabRegion extends Component<PropsType, StateType> {
options={this.props.options}
color={this.props.color}
currentTab={this.props.currentTab}
setCurrentTab={(x: string) => this.props.setCurrentTab(x)}
setCurrentTab={(x: string) => {
this.props.setCurrentTab(x);
}}
addendum={this.props.addendum}
/>
<Gap />
Expand Down
95 changes: 2 additions & 93 deletions dashboard/src/main/home/project-settings/BillingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import Text from "components/porter/Text";
import {
checkIfProjectHasPayment,
useCustomerPlan,
useCustomerUsage,
usePaymentMethods,
usePorterCredits,
useReferralDetails,
Expand All @@ -31,7 +30,6 @@ import gift from "assets/gift.svg";
import trashIcon from "assets/trash.png";

import BillingModal from "../modals/BillingModal";
import Bars from "./Bars";

dayjs.extend(relativeTime);

Expand All @@ -55,45 +53,10 @@ function BillingPage(): JSX.Element {

const { refetchPaymentEnabled } = checkIfProjectHasPayment();

const { usage } = useCustomerUsage("day", true);

const processedData = useMemo(() => {
const before = usage;
const resultMap = new Map();

before?.forEach(
(metric: {
metric_name: string;
usage_metrics: Array<{ starting_on: string; value: number }>;
}) => {
const metricName = metric.metric_name.toLowerCase().replace(" ", "_");
metric.usage_metrics.forEach(({ starting_on, value }) => {
if (resultMap.has(starting_on)) {
resultMap.get(starting_on)[metricName] = value;
} else {
resultMap.set(starting_on, {
starting_on: new Date(starting_on).toLocaleDateString("en-US", {
month: "short",
day: "numeric",
}),
[metricName]: value,
});
}
});
}
);

// Convert the map to an array of values
const x = Array.from(resultMap.values());
return x;
}, [usage]);

const formatCredits = (credits: number): string => {
return (credits / 100).toFixed(2);
};

const readableDate = (s: string): string => new Date(s).toLocaleDateString();

const onCreate = async (): Promise<void> => {
await refetchPaymentMethods({ throwOnError: false, cancelRefetch: false });
setShouldCreate(false);
Expand Down Expand Up @@ -248,50 +211,6 @@ function BillingPage(): JSX.Element {
</Button>
<Spacer y={2} />

{currentProject?.metronome_enabled && plan && plan.plan_name !== "" ? (
<>
<Text size={16}>Current usage</Text>
<Spacer y={1} />
<Text color="helper">
View the current usage of this billing period.
</Text>
<Spacer y={1} />
{usage?.length &&
usage.length > 0 &&
usage[0].usage_metrics.length > 0 ? (
<Flex>
<BarWrapper>
<Bars
title="GiB Hours"
fill="#8784D2"
yKey="gib_hours"
xKey="starting_on"
data={processedData}
/>
</BarWrapper>
<Spacer x={1} inline />
<BarWrapper>
<Bars
title="CPU Hours"
fill="#5886E0"
yKey="cpu_hours"
xKey="starting_on"
data={processedData}
/>
</BarWrapper>
</Flex>
) : (
<Fieldset>
<Text color="helper">
No usage data available for this billing period.
</Text>
</Fieldset>
)}
<Spacer y={2} />
</>
) : (
<Text>This project does not have an active billing plan.</Text>
)}
{showReferralModal && (
<Modal
closeModal={() => {
Expand Down Expand Up @@ -330,7 +249,8 @@ function BillingPage(): JSX.Element {
<Spacer y={1} />
<Text color="helper">
You have referred{" "}
{referralDetails ? referralDetails.referral_count : "?"}/{referralDetails?.max_allowed_referrals} users.
{referralDetails ? referralDetails.referral_count : "?"}/
{referralDetails?.max_allowed_referrals} users.
</Text>
</Modal>
)}
Expand Down Expand Up @@ -359,17 +279,6 @@ const ReferralCode = styled.div`
width: fit-content;
`;

const Flex = styled.div`
display: flex;
flex-wrap: wrap;
`;

const BarWrapper = styled.div`
flex: 1;
height: 300px;
min-width: 450px;
`;

const I = styled.i`
font-size: 16px;
margin-right: 8px;
Expand Down
15 changes: 14 additions & 1 deletion dashboard/src/main/home/project-settings/ProjectSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import BillingPage from "./BillingPage";
import InvitePage from "./InviteList";
import Metadata from "./Metadata";
import ProjectDeleteConsent from "./ProjectDeleteConsent";
import UsagePage from "./UsagePage";

type PropsType = RouteComponentProps & WithAuthProps & {};
type ValidationError = {
Expand Down Expand Up @@ -95,6 +96,16 @@ function ProjectSettings(props: any) {
});
}

if (
currentProject?.billing_enabled &&
currentProject?.metronome_enabled
) {
tabOpts.push({
value: "usage",
label: "Usage",
});
}

tabOpts.push({
value: "additional-settings",
label: "Additional settings",
Expand Down Expand Up @@ -171,7 +182,9 @@ function ProjectSettings(props: any) {
} else if (currentTab === "api-tokens") {
return <APITokensSection />;
} else if (currentTab === "billing") {
return <BillingPage></BillingPage>;
return <BillingPage />;
} else if (currentTab === "usage") {
return <UsagePage />;
} else {
return (
<>
Expand Down
138 changes: 138 additions & 0 deletions dashboard/src/main/home/project-settings/UsagePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import React, { useContext, useMemo, useState } from "react";
import styled from "styled-components";

import Fieldset from "components/porter/Fieldset";
import Select from "components/porter/Select";
import Spacer from "components/porter/Spacer";
import Text from "components/porter/Text";
import { useCustomerUsage } from "lib/hooks/useStripe";

import Bars from "./Bars";

function UsagePage(): JSX.Element {
const [currentPeriod, setCurrentPeriod] = useState("4-17-24");

const { usage } = useCustomerUsage("day", true);

const processedData = useMemo(() => {
const before = usage;
const resultMap = new Map();

before?.forEach(
(metric: {
metric_name: string;
usage_metrics: Array<{ starting_on: string; value: number }>;
}) => {
const metricName = metric.metric_name.toLowerCase().replace(" ", "_");
metric.usage_metrics.forEach(({ starting_on, value }) => {
if (resultMap.has(starting_on)) {
resultMap.get(starting_on)[metricName] = value;
} else {
resultMap.set(starting_on, {
starting_on: new Date(starting_on).toLocaleDateString("en-US", {
month: "short",
day: "numeric",
}),
[metricName]: value,
});
}
});
}
);

// Convert the map to an array of values
const x = Array.from(resultMap.values());
return x;
}, [usage]);

return (
<>
<Select
options={[
{ value: "4-17-24", label: "4/17/24 - 5/17/24" },
{ value: "3-17-24", label: "3/17/24 - 4/17/24" },
{ value: "2-17-24", label: "2/17/24 - 3/17/24" },
{ value: "1-17-24", label: "1/17/24 - 2/17/24" },
{ value: "12-17-23", label: "12/17/23 - 1/17/24" },
]}
value={currentPeriod}
setValue={(value) => {
setCurrentPeriod(value);
}}
width="fit-content"
prefix={<>Billing period</>}
/>
<Spacer y={1} />
{/* usage?.length &&
usage.length > 0 &&
usage[0].usage_metrics.length > 0 ? ( */}
{true ? (
<>
<BarWrapper>
<Total>Total cost: $457.58</Total>
<Bars
fill="#8784D2"
yKey="cost"
xKey="starting_on"
data={processedData}
/>
</BarWrapper>
<Spacer y={0.5} />
<Flex>
<BarWrapper>
<Bars
title="GiB Hours"
fill="#8784D2"
yKey="gib_hours"
xKey="starting_on"
data={processedData}
/>
</BarWrapper>
<Spacer x={1} inline />
<BarWrapper>
<Bars
title="CPU Hours"
fill="#5886E0"
yKey="cpu_hours"
xKey="starting_on"
data={processedData}
/>
</BarWrapper>
</Flex>
</>
) : (
<Fieldset>
<Text color="helper">
No usage data available for this billing period.
</Text>
</Fieldset>
)}
</>
);
}

export default UsagePage;

const Total = styled.div`
position: absolute;
top: 20px;
left: 15px;
font-size: 13px;
background: #42444933;
backdrop-filter: saturate(150%) blur(8px);
padding: 7px 10px;
border-radius: 5px;
border: 1px solid #494b4f;
`;

const Flex = styled.div`
display: flex;
flex-wrap: wrap;
`;

const BarWrapper = styled.div`
flex: 1;
height: 300px;
min-width: 450px;
position: relative;
`;

0 comments on commit 648c21d

Please sign in to comment.