Move billing components to own files

This commit is contained in:
Terry Sutton committed 2022-10-13 11:41:27 -02:30
1 parent 414f6c7854
commit 71de50995f
5 files changed
+175 -109

No files matched your search

@@ -24,12 +24,6 @@ export const generateLogsMenu = (project?: Project): ProductMenuGroup[] => {
url: `/project/${ref}/logs/postgres-logs`,
items: [],
},
{
name: 'Query logs(?)',
key: 'api-logs',
url: `/project/${ref}/database/insights?`,
items: [],
},
{
name: 'PostgREST logs',
key: 'postgrest-logs',
@@ -39,95 +39,25 @@ export const generateSettingsMenu = (ref: string, project?: ProjectBase): Produc
},
],
},
{
title: 'Project settings',
items: [
{
name: 'Authentication',
key: 'auth',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/auth/settings`,
items: [],
},
{
name: 'Storage',
key: 'storage',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/storage/settings`,
items: [],
// disabled: canReadStorage,
},
{
name: 'Billing & Usage',
key: 'billing',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/billing`,
items: [],
// disabled: canReadInvoices && canReadSubscriptions,
},
],
},
{
title: 'API',
items: [
{
name: 'API Keys',
key: 'generaleeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/api`,
items: [],
},
{
name: 'API Settings',
key: 'databaseeeeeeeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/databaseeeeee`,
items: [],
},
],
},
{
title: 'Project keys',
items: [
{
name: 'Roll keys',
key: 'generaleeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/api`,
items: [],
},
{
name: 'JWT',
key: 'databaseeeeeeeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/databaseeeeee`,
items: [],
},
],
},
{
title: 'Backups?',
items: [
{
name: 'Backups?',
key: 'generaleeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/api`,
items: [],
},
],
},
{
title: 'Billing',
items: [
{
name: 'Subscription',
key: 'generaleeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/api`,
key: 'billing',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/billing/subscription`,
items: [],
},
{
name: 'Usage',
key: 'databaseeeeeeeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/databaseeeeee`,
key: 'usage',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/billing/usage`,
items: [],
},
{
name: 'Invoices',
key: 'databaseeeeeeeeeee',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/databaseeeeee`,
key: 'billing/invoices',
url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/billing/invoices`,
items: [],
},
],
@@ -0,0 +1,68 @@
import { observer } from 'mobx-react-lite'
import { FC, useEffect } from 'react'
import { SettingsLayout } from 'components/layouts'
import LoadingUI from 'components/ui/Loading'
import OveragesBanner from 'components/ui/OveragesBanner/OveragesBanner'
import { useProjectSubscription, useStore } from 'hooks'
import { NextPageWithLayout, Project } from 'types'
import { Invoices } from 'components/interfaces/Billing'
const ProjectBilling: NextPageWithLayout = () => {
const { ui } = useStore()
const project = ui.selectedProject
return (
<div className="content h-full w-full overflow-y-auto">
<div className="mx-auto w-full">
<Settings project={project} />
</div>
</div>
)
}
ProjectBilling.getLayout = (page) => (
<SettingsLayout title="Billing and Usage">{page}</SettingsLayout>
)
export default observer(ProjectBilling)
interface SettingsProps {
project?: Project
}
const Settings: FC<SettingsProps> = ({ project }) => {
const { ui } = useStore()
const projectTier = ui.selectedProject?.subscription_tier
const {
subscription,
isLoading: loading,
error,
} = useProjectSubscription(ui.selectedProject?.ref)
useEffect(() => {
if (error) {
ui.setNotification({
category: 'error',
message: `Failed to get project subscription: ${error?.message ?? 'unknown'}`,
})
}
}, [error])
if (!subscription) {
return <LoadingUI />
}
return (
<div className="container max-w-4xl space-y-8 p-4">
{projectTier !== undefined && <OveragesBanner tier={projectTier} />}
<div className="space-y-2">
<h4 className="text-lg">Invoices</h4>
<Invoices projectRef={ui.selectedProject?.ref ?? ''} />
</div>
</div>
)
}
@@ -0,0 +1,89 @@
import { observer } from 'mobx-react-lite'
import { FC, useEffect, useState } from 'react'
import { Loading } from 'ui'
import { SettingsLayout } from 'components/layouts'
import LoadingUI from 'components/ui/Loading'
import OveragesBanner from 'components/ui/OveragesBanner/OveragesBanner'
import { useProjectPaygStatistics, useProjectSubscription, useStore } from 'hooks'
import { NextPageWithLayout, Project } from 'types'
import { Subscription } from 'components/interfaces/Billing'
import { PaygStats } from 'components/interfaces/Billing/PAYGUsage/PAYGUsage.types'
const ProjectBilling: NextPageWithLayout = () => {
const { ui } = useStore()
const project = ui.selectedProject
return (
<div className="content h-full w-full overflow-y-auto">
<div className="mx-auto w-full">
<Settings project={project} />
</div>
</div>
)
}
ProjectBilling.getLayout = (page) => (
<SettingsLayout title="Billing and Usage">{page}</SettingsLayout>
)
export default observer(ProjectBilling)
interface SettingsProps {
project?: Project
}
const Settings: FC<SettingsProps> = ({ project }) => {
const { ui } = useStore()
const projectTier = ui.selectedProject?.subscription_tier
const {
subscription,
isLoading: loading,
error,
} = useProjectSubscription(ui.selectedProject?.ref)
const { paygStats }: { paygStats: PaygStats | undefined } = useProjectPaygStatistics(
ui.selectedProject?.ref,
subscription?.tier?.supabase_prod_id
)
useEffect(() => {
if (error) {
ui.setNotification({
category: 'error',
message: `Failed to get project subscription: ${error?.message ?? 'unknown'}`,
})
}
}, [error])
if (!subscription) {
return <LoadingUI />
}
return (
<div className="container max-w-4xl space-y-8 p-4">
{projectTier !== undefined && <OveragesBanner tier={projectTier} />}
<Subscription
loading={loading}
project={project}
subscription={subscription}
paygStats={paygStats}
currentPeriodStart={subscription?.billing.current_period_start}
currentPeriodEnd={subscription?.billing.current_period_end}
/>
{loading ? (
<Loading active={loading}>
<div className="mb-8 w-full overflow-hidden rounded border border-panel-border-light dark:border-panel-border-dark">
<div className="flex items-center justify-center bg-panel-body-light px-6 py-6 dark:bg-panel-body-dark">
<p>Loading usage breakdown</p>
</div>
</div>
</Loading>
) : (
<></>
)}
</div>
)
}
@@ -1,20 +1,19 @@
import dayjs from 'dayjs'
import { FC, useEffect, useState } from 'react'
import { observer } from 'mobx-react-lite'
import { Loading, IconArrowRight } from 'ui'
import { FC, useEffect, useState } from 'react'
import { IconArrowRight, Loading } from 'ui'
import { Project, NextPageWithLayout } from 'types'
import { useProjectPaygStatistics, useProjectSubscription, useStore } from 'hooks'
import { STRIPE_PRODUCT_IDS, TIME_PERIODS_REPORTS, TIME_PERIODS_BILLING } from 'lib/constants'
import { SettingsLayout } from 'components/layouts'
import LoadingUI from 'components/ui/Loading'
import OveragesBanner from 'components/ui/OveragesBanner/OveragesBanner'
import DateRangePicker from 'components/to-be-cleaned/DateRangePicker'
import { PAYGUsage, Subscription, Invoices } from 'components/interfaces/Billing'
import { PAYGUsage } from 'components/interfaces/Billing'
import { PaygStats } from 'components/interfaces/Billing/PAYGUsage/PAYGUsage.types'
import ProjectUsage from 'components/interfaces/Settings/ProjectUsageBars/ProjectUsageBars'
import { SettingsLayout } from 'components/layouts'
import DateRangePicker from 'components/to-be-cleaned/DateRangePicker'
import LoadingUI from 'components/ui/Loading'
import { useProjectPaygStatistics, useProjectSubscription, useStore } from 'hooks'
import { STRIPE_PRODUCT_IDS, TIME_PERIODS_BILLING, TIME_PERIODS_REPORTS } from 'lib/constants'
import { NextPageWithLayout, Project } from 'types'
const ProjectBilling: NextPageWithLayout = () => {
const ProjectBillingUsage: NextPageWithLayout = () => {
const { ui } = useStore()
const project = ui.selectedProject
@@ -27,11 +26,11 @@ const ProjectBilling: NextPageWithLayout = () => {
)
}
ProjectBilling.getLayout = (page) => (
ProjectBillingUsage.getLayout = (page) => (
<SettingsLayout title="Billing and Usage">{page}</SettingsLayout>
)
export default observer(ProjectBilling)
export default observer(ProjectBillingUsage)
interface SettingsProps {
project?: Project
@@ -39,7 +38,6 @@ interface SettingsProps {
const Settings: FC<SettingsProps> = ({ project }) => {
const { ui } = useStore()
const projectTier = ui.selectedProject?.subscription_tier
const [dateRange, setDateRange] = useState<any>()
@@ -69,15 +67,6 @@ const Settings: FC<SettingsProps> = ({ project }) => {
return (
<div className="container max-w-4xl space-y-8 p-4">
{projectTier !== undefined && <OveragesBanner tier={projectTier} />}
<Subscription
loading={loading}
project={project}
subscription={subscription}
paygStats={paygStats}
currentPeriodStart={subscription?.billing.current_period_start}
currentPeriodEnd={subscription?.billing.current_period_end}
/>
{loading ? (
<Loading active={loading}>
<div className="mb-8 w-full overflow-hidden rounded border border-panel-border-light dark:border-panel-border-dark">
@@ -115,10 +104,6 @@ const Settings: FC<SettingsProps> = ({ project }) => {
) : (
<ProjectUsage projectRef={project?.ref} />
)}
<div className="space-y-2">
<h4 className="text-lg">Invoices</h4>
<Invoices projectRef={ui.selectedProject?.ref ?? ''} />
</div>
</div>
)
}