Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/components/admin/Billing/LoadError.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ import { Grid } from '@mui/material';
import { FormattedMessage } from 'react-intl';

import AlertBox from 'src/components/shared/AlertBox';
import { useBillingStore } from 'src/stores/Billing';
import { useBillingInvoices } from 'src/hooks/billing/useBillingInvoices';

function BillingLoadError() {
const hydrationErrorsExist = useBillingStore(
(state) => state.hydrationErrorsExist
);
const { errorExists } = useBillingInvoices();

if (!hydrationErrorsExist) {
if (!errorExists) {
return null;
}

Expand Down
3 changes: 1 addition & 2 deletions src/components/admin/Billing/PricingTierDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ function PricingTierDetails() {
const [externalPaymentMethod, marketPlaceProvider] =
useTenantUsesExternalPayment(selectedTenant);

const billingStoreHydrated = useBillingStore((state) => state.hydrated);
const paymentMethodExists = useBillingStore(
(state) => state.paymentMethodExists
);
Expand All @@ -38,7 +37,7 @@ function PricingTierDetails() {
return 'admin.billing.message.freeTier';
}, [externalPaymentMethod, marketPlaceProvider, paymentMethodExists]);

if (!billingStoreHydrated || typeof paymentMethodExists !== 'boolean') {
if (typeof paymentMethodExists !== 'boolean') {
return (
<Skeleton>
<Typography>
Expand Down
95 changes: 4 additions & 91 deletions src/components/admin/Billing/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
import type { AdminBillingProps } from 'src/components/admin/Billing/types';

import { useEffect, useMemo } from 'react';
import useConstant from 'use-constant';

import { Divider, Grid, Typography } from '@mui/material';

import { useShallow } from 'zustand/react/shallow';

import { endOfMonth, startOfMonth, subMonths } from 'date-fns';
import { ErrorBoundary } from 'react-error-boundary';
import { useIntl } from 'react-intl';
import { useUnmount } from 'react-use';

import { getInvoicesBetween } from 'src/api/billing';
import { authenticatedRoutes } from 'src/app/routes';
import DateRange from 'src/components/admin/Billing/DateRange';
import BillingLoadError from 'src/components/admin/Billing/LoadError';
import PaymentMethods from 'src/components/admin/Billing/PaymentMethods';
import PricingTierDetails from 'src/components/admin/Billing/PricingTierDetails';
import { INVOICE_ROW_HEIGHT } from 'src/components/admin/Billing/shared';
import { useTenantChangeReset } from 'src/components/admin/Billing/useTenantChangeReset';
import AdminTabs from 'src/components/admin/Tabs';
import GraphLoadingState from 'src/components/graphs/states/Loading';
import GraphStateWrapper from 'src/components/graphs/states/Wrapper';
Expand All @@ -28,14 +19,10 @@ import AlertBox from 'src/components/shared/AlertBox';
import CardWrapper from 'src/components/shared/CardWrapper';
import BillingHistoryTable from 'src/components/tables/Billing';
import BillingLineItemsTable from 'src/components/tables/BillLineItems';
import { useBillingInvoices } from 'src/hooks/billing/useBillingInvoices';
import usePageTitle from 'src/hooks/usePageTitle';
import { logRocketEvent } from 'src/services/shared';
import { CustomEvents } from 'src/services/types';
import {
useBilling_selectedInvoice,
useBillingStore,
} from 'src/stores/Billing';
import { useTenantStore } from 'src/stores/Tenant';
import { invoiceId, TOTAL_CARD_HEIGHT } from 'src/utils/billing-utils';

const routeTitle = authenticatedRoutes.admin.billing.title;
Expand All @@ -50,83 +37,9 @@ function AdminBilling({ showAddPayment }: AdminBillingProps) {
headerLink: 'https://www.estuary.dev/pricing/',
});

useTenantChangeReset();

const intl = useIntl();

const selectedTenant = useTenantStore((state) => state.selectedTenant);

// Billing Store
// TODO (billing store)
// The `active` stuff could probably be removed now that other stuff is
// cleaned up - but leaving to make it easier
const [active, setActive] = useBillingStore(
useShallow((state) => [state.active, state.setActive])
);
const [hydrated, setHydrated] = useBillingStore(
useShallow((state) => [state.hydrated, state.setHydrated])
);
const setHydrationErrorsExist = useBillingStore(
(state) => state.setHydrationErrorsExist
);
const setInvoices = useBillingStore((state) => state.setInvoices);
const setNetworkFailed = useBillingStore((state) => state.setNetworkFailed);

const selectedInvoice = useBilling_selectedInvoice();

const resetBillingState = useBillingStore((state) => state.resetState);

const currentMonth = useConstant(() => {
const today = new Date();

return endOfMonth(today);
});

const dateRange = useMemo(() => {
const startMonth = startOfMonth(subMonths(currentMonth, 5));

return { start: startMonth, end: currentMonth };
}, [currentMonth]);

useEffect(() => {
if (selectedTenant) {
void (async () => {
setNetworkFailed(null);
setActive(true);
try {
const response = await getInvoicesBetween(
selectedTenant,
dateRange.start,
dateRange.end
);
if (response.error) {
throw new Error(response.error.message);
}
setNetworkFailed(null);
setHydrationErrorsExist(false);
setInvoices(response.data);
} catch (errorMessage: unknown) {
setNetworkFailed(`${errorMessage}`);
setHydrationErrorsExist(true);
setInvoices([]);
} finally {
setHydrated(true);
setActive(false);
}
})();
}
}, [
dateRange.end,
dateRange.start,
selectedTenant,
setActive,
setHydrated,
setHydrationErrorsExist,
setInvoices,
setNetworkFailed,
]);

useUnmount(() => resetBillingState());
const { isLoading, selectedInvoice } = useBillingInvoices();

return (
<>
Expand Down Expand Up @@ -173,7 +86,7 @@ function AdminBilling({ showAddPayment }: AdminBillingProps) {
<CardWrapper
height={invoiceCardHeight}
message={
active || !hydrated ? (
isLoading ? (
intl.formatMessage({
id: 'admin.billing.label.lineItems.loading',
})
Expand All @@ -194,7 +107,7 @@ function AdminBilling({ showAddPayment }: AdminBillingProps) {
)
}
>
{!active && hydrated ? (
{!isLoading ? (
<BillingLineItemsTable
// The key here makes sure that any stateful fetching logic doesn't get confused.
key={
Expand Down
22 changes: 0 additions & 22 deletions src/components/admin/Billing/useTenantChangeReset.ts

This file was deleted.

9 changes: 4 additions & 5 deletions src/components/graphs/TaskHoursByMonthGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
} from 'src/components/graphs/tooltips';
import useTooltipConfig from 'src/components/graphs/useTooltipConfig';
import { defaultOutlineColor } from 'src/context/Theme';
import { useBillingStore } from 'src/stores/Billing';
import { useBillingInvoices } from 'src/hooks/billing/useBillingInvoices';
import { CARD_AREA_HEIGHT, stripTimeFromDate } from 'src/utils/billing-utils';

const chartContainerId = 'task-hours-by-month';
Expand All @@ -39,8 +39,7 @@ function TaskHoursByMonthGraph() {
const intl = useIntl();
const tooltipConfig = useTooltipConfig();

const billingStoreHydrated = useBillingStore((state) => state.hydrated);
const invoices = useBillingStore((state) => state.invoices);
const { invoices, isLoading } = useBillingInvoices();

const resizeListener = useRef<EventListener | null>(null);
const [myChart, setMyChart] = useState<echarts.ECharts | null>(null);
Expand Down Expand Up @@ -85,7 +84,7 @@ function TaskHoursByMonthGraph() {
}, [invoices, intl, today]);

useEffect(() => {
if (billingStoreHydrated && invoices.length > 0) {
if (!isLoading && invoices.length > 0) {
if (!myChart) {
echarts.use([
GridComponent,
Expand Down Expand Up @@ -190,7 +189,7 @@ function TaskHoursByMonthGraph() {
}
}, [
invoices,
billingStoreHydrated,
isLoading,
intl,
months,
myChart,
Expand Down
9 changes: 4 additions & 5 deletions src/components/graphs/UsageByMonthGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { useIntl } from 'react-intl';
import useLegendConfig from 'src/components/graphs/useLegendConfig';
import useTooltipConfig from 'src/components/graphs/useTooltipConfig';
import { eChartsColors } from 'src/context/Theme';
import { useBillingStore } from 'src/stores/Billing';
import { useBillingInvoices } from 'src/hooks/billing/useBillingInvoices';
import { CARD_AREA_HEIGHT, stripTimeFromDate } from 'src/utils/billing-utils';

const chartContainerId = 'data-by-month';
Expand All @@ -40,8 +40,7 @@ function UsageByMonthGraph() {
const tooltipConfig = useTooltipConfig();
const legendConfig = useLegendConfig([{ name: 'Data' }, { name: 'Hours' }]);

const billingStoreHydrated = useBillingStore((state) => state.hydrated);
const invoices = useBillingStore((state) => state.invoices);
const { invoices, isLoading } = useBillingInvoices();

const [myChart, setMyChart] = useState<echarts.ECharts | null>(null);

Expand Down Expand Up @@ -96,7 +95,7 @@ function UsageByMonthGraph() {
}, [invoices, intl, today]);

useEffect(() => {
if (billingStoreHydrated && invoices.length > 0) {
if (!isLoading && invoices.length > 0) {
if (!myChart) {
echarts.use([
GridComponent,
Expand Down Expand Up @@ -126,7 +125,7 @@ function UsageByMonthGraph() {
return undefined;
}, [
invoices,
billingStoreHydrated,
isLoading,
intl,
legendConfig,
months,
Expand Down
13 changes: 7 additions & 6 deletions src/components/graphs/states/Wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import { FormattedMessage } from 'react-intl';
import EmptyGraphState from 'src/components/graphs/states/Empty';
import GraphLoadingState from 'src/components/graphs/states/Loading';
import { eChartsTooltipSX } from 'src/components/graphs/tooltips';
import { useBillingStore } from 'src/stores/Billing';
import { useBillingInvoices } from 'src/hooks/billing/useBillingInvoices';
import { hasLength } from 'src/utils/misc-utils';

function GraphStateWrapper({ children }: BaseComponentProps) {
const billingStoreActive = useBillingStore((state) => state.active);
const billingStoreHydrated = useBillingStore((state) => state.hydrated);
const networkFailed = useBillingStore((state) => state.networkFailed);
const billingHistory = useBillingStore((state) => state.invoices);
const {
invoices: billingHistory,
isLoading,
networkFailed,
} = useBillingInvoices();

if (networkFailed) {
return (
Expand All @@ -29,7 +30,7 @@ function GraphStateWrapper({ children }: BaseComponentProps) {
);
}

if (!billingStoreActive && billingStoreHydrated) {
if (!isLoading) {
return hasLength(billingHistory) ? (
<Box sx={eChartsTooltipSX}>{children}</Box>
) : (
Expand Down
14 changes: 4 additions & 10 deletions src/components/tables/BillLineItems/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ import TotalLines from 'src/components/tables/BillLineItems/TotalLines';
import EntityTableBody from 'src/components/tables/EntityTable/TableBody';
import EntityTableHeader from 'src/components/tables/EntityTable/TableHeader';
import { getTableHeaderWithoutHeaderColor } from 'src/context/Theme';
import {
useBilling_selectedInvoice,
useBillingStore,
} from 'src/stores/Billing';
import { useBillingInvoices } from 'src/hooks/billing/useBillingInvoices';
import { useTenantStore } from 'src/stores/Tenant';
import { TableStatuses } from 'src/types';

Expand Down Expand Up @@ -57,10 +54,7 @@ function BillingLineItemsTable() {

const selectedTenant = useTenantStore((state) => state.selectedTenant);

const selectedInvoice = useBilling_selectedInvoice();

const hydrated = useBillingStore((state) => state.hydrated);
const invoices = useBillingStore((state) => state.invoices);
const { invoices, selectedInvoice, isLoading } = useBillingInvoices();

const dataRows = useMemo(
() => <Rows lineItems={selectedInvoice?.line_items ?? []} />,
Expand Down Expand Up @@ -120,7 +114,7 @@ function BillingLineItemsTable() {
? { status: TableStatuses.DATA_FETCHED }
: { status: TableStatuses.NO_EXISTING_DATA }
}
loading={!hydrated}
loading={isLoading}
rows={dataRows}
/>
</Table>
Expand All @@ -135,7 +129,7 @@ function BillingLineItemsTable() {
}}
>
{selectedInvoice?.invoice_type !== 'preview' ? (
hydrated ? (
!isLoading ? (
<Box>
<Button
href={stripeInvoice?.invoice_pdf}
Expand Down
19 changes: 8 additions & 11 deletions src/components/tables/Billing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ import Rows from 'src/components/tables/Billing/Rows';
import EntityTableBody from 'src/components/tables/EntityTable/TableBody';
import EntityTableHeader from 'src/components/tables/EntityTable/TableHeader';
import { getTableHeaderWithoutHeaderColor } from 'src/context/Theme';
import {
useBilling_selectedInvoice,
useBillingStore,
} from 'src/stores/Billing';
import { useBillingInvoices } from 'src/hooks/billing/useBillingInvoices';
import { TableStatuses } from 'src/types';
import { invoiceId } from 'src/utils/billing-utils';

Expand Down Expand Up @@ -46,12 +43,12 @@ export const columns: TableColumns[] = [
function BillingHistoryTable() {
const intl = useIntl();

const selectedInvoice = useBilling_selectedInvoice();

const active = useBillingStore((state) => state.active);
const hydrated = useBillingStore((state) => state.hydrated);
const networkFailed = useBillingStore((state) => state.networkFailed);
const billingHistory = useBillingStore((state) => state.invoices);
const {
invoices: billingHistory,
selectedInvoice,
isLoading,
networkFailed,
} = useBillingInvoices();

const dataRows = useMemo(
() =>
Expand Down Expand Up @@ -95,7 +92,7 @@ function BillingHistoryTable() {
? { status: TableStatuses.NETWORK_FAILED }
: { status: TableStatuses.NO_EXISTING_DATA }
}
loading={Boolean(active || !hydrated)}
loading={isLoading}
rows={dataRows}
/>
</Table>
Expand Down
Loading