diff --git a/src/components/admin/Billing/LoadError.tsx b/src/components/admin/Billing/LoadError.tsx index 630fb98d4c..34a430006d 100644 --- a/src/components/admin/Billing/LoadError.tsx +++ b/src/components/admin/Billing/LoadError.tsx @@ -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; } diff --git a/src/components/admin/Billing/PricingTierDetails.tsx b/src/components/admin/Billing/PricingTierDetails.tsx index 20db091910..8102906886 100644 --- a/src/components/admin/Billing/PricingTierDetails.tsx +++ b/src/components/admin/Billing/PricingTierDetails.tsx @@ -13,7 +13,6 @@ function PricingTierDetails() { const [externalPaymentMethod, marketPlaceProvider] = useTenantUsesExternalPayment(selectedTenant); - const billingStoreHydrated = useBillingStore((state) => state.hydrated); const paymentMethodExists = useBillingStore( (state) => state.paymentMethodExists ); @@ -38,7 +37,7 @@ function PricingTierDetails() { return 'admin.billing.message.freeTier'; }, [externalPaymentMethod, marketPlaceProvider, paymentMethodExists]); - if (!billingStoreHydrated || typeof paymentMethodExists !== 'boolean') { + if (typeof paymentMethodExists !== 'boolean') { return ( diff --git a/src/components/admin/Billing/index.tsx b/src/components/admin/Billing/index.tsx index e769541e49..129e9d6c97 100644 --- a/src/components/admin/Billing/index.tsx +++ b/src/components/admin/Billing/index.tsx @@ -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'; @@ -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; @@ -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 ( <> @@ -173,7 +86,7 @@ function AdminBilling({ showAddPayment }: AdminBillingProps) { - {!active && hydrated ? ( + {!isLoading ? ( state.selectedTenant); - - const resetBillingState = useBillingStore((state) => state.resetState); - - const resetStores = useCallback(() => { - resetBillingState(); - }, [resetBillingState]); - - const previousTenant = useRef(selectedTenant); - useEffect(() => { - if (previousTenant.current !== selectedTenant) { - previousTenant.current = selectedTenant; - resetStores(); - } - }, [selectedTenant, resetStores]); -} diff --git a/src/components/graphs/TaskHoursByMonthGraph.tsx b/src/components/graphs/TaskHoursByMonthGraph.tsx index 581c0539c2..d53e769a95 100644 --- a/src/components/graphs/TaskHoursByMonthGraph.tsx +++ b/src/components/graphs/TaskHoursByMonthGraph.tsx @@ -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'; @@ -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(null); const [myChart, setMyChart] = useState(null); @@ -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, @@ -190,7 +189,7 @@ function TaskHoursByMonthGraph() { } }, [ invoices, - billingStoreHydrated, + isLoading, intl, months, myChart, diff --git a/src/components/graphs/UsageByMonthGraph.tsx b/src/components/graphs/UsageByMonthGraph.tsx index 0de4754ab3..20d6624c4a 100644 --- a/src/components/graphs/UsageByMonthGraph.tsx +++ b/src/components/graphs/UsageByMonthGraph.tsx @@ -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'; @@ -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(null); @@ -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, @@ -126,7 +125,7 @@ function UsageByMonthGraph() { return undefined; }, [ invoices, - billingStoreHydrated, + isLoading, intl, legendConfig, months, diff --git a/src/components/graphs/states/Wrapper.tsx b/src/components/graphs/states/Wrapper.tsx index 00693b82a2..f81e410f4e 100644 --- a/src/components/graphs/states/Wrapper.tsx +++ b/src/components/graphs/states/Wrapper.tsx @@ -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 ( @@ -29,7 +30,7 @@ function GraphStateWrapper({ children }: BaseComponentProps) { ); } - if (!billingStoreActive && billingStoreHydrated) { + if (!isLoading) { return hasLength(billingHistory) ? ( {children} ) : ( diff --git a/src/components/tables/BillLineItems/index.tsx b/src/components/tables/BillLineItems/index.tsx index 5c1dcbce40..69ed0244ac 100644 --- a/src/components/tables/BillLineItems/index.tsx +++ b/src/components/tables/BillLineItems/index.tsx @@ -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'; @@ -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( () => , @@ -120,7 +114,7 @@ function BillingLineItemsTable() { ? { status: TableStatuses.DATA_FETCHED } : { status: TableStatuses.NO_EXISTING_DATA } } - loading={!hydrated} + loading={isLoading} rows={dataRows} /> @@ -135,7 +129,7 @@ function BillingLineItemsTable() { }} > {selectedInvoice?.invoice_type !== 'preview' ? ( - hydrated ? ( + !isLoading ? (