diff --git a/studio/components/layouts/LogsLayout/LogsMenu.utils.ts b/studio/components/layouts/LogsLayout/LogsMenu.utils.ts index 3674bb566f6..5db493663a6 100644 --- a/studio/components/layouts/LogsLayout/LogsMenu.utils.ts +++ b/studio/components/layouts/LogsLayout/LogsMenu.utils.ts @@ -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', diff --git a/studio/components/layouts/SettingsLayout/SettingsMenu.utils.ts b/studio/components/layouts/SettingsLayout/SettingsMenu.utils.ts index 165b6c54270..7af1c2abe3d 100644 --- a/studio/components/layouts/SettingsLayout/SettingsMenu.utils.ts +++ b/studio/components/layouts/SettingsLayout/SettingsMenu.utils.ts @@ -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: [], }, ], diff --git a/studio/pages/project/[ref]/settings/billing/invoices.tsx b/studio/pages/project/[ref]/settings/billing/invoices.tsx new file mode 100644 index 00000000000..29c76ba8d21 --- /dev/null +++ b/studio/pages/project/[ref]/settings/billing/invoices.tsx @@ -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 ( +
+
+ +
+
+ ) +} + +ProjectBilling.getLayout = (page) => ( + {page} +) + +export default observer(ProjectBilling) + +interface SettingsProps { + project?: Project +} + +const Settings: FC = ({ 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 + } + + return ( +
+ {projectTier !== undefined && } + +
+

Invoices

+ +
+
+ ) +} diff --git a/studio/pages/project/[ref]/settings/billing/subscription.tsx b/studio/pages/project/[ref]/settings/billing/subscription.tsx new file mode 100644 index 00000000000..e576ae8e385 --- /dev/null +++ b/studio/pages/project/[ref]/settings/billing/subscription.tsx @@ -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 ( +
+
+ +
+
+ ) +} + +ProjectBilling.getLayout = (page) => ( + {page} +) + +export default observer(ProjectBilling) + +interface SettingsProps { + project?: Project +} + +const Settings: FC = ({ 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 + } + + return ( +
+ {projectTier !== undefined && } + + {loading ? ( + +
+
+

Loading usage breakdown

+
+
+
+ ) : ( + <> + )} +
+ ) +} diff --git a/studio/pages/project/[ref]/settings/billing/index.tsx b/studio/pages/project/[ref]/settings/billing/usage.tsx similarity index 75% rename from studio/pages/project/[ref]/settings/billing/index.tsx rename to studio/pages/project/[ref]/settings/billing/usage.tsx index f1db9798a2a..17d51e7475e 100644 --- a/studio/pages/project/[ref]/settings/billing/index.tsx +++ b/studio/pages/project/[ref]/settings/billing/usage.tsx @@ -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) => ( {page} ) -export default observer(ProjectBilling) +export default observer(ProjectBillingUsage) interface SettingsProps { project?: Project @@ -39,7 +38,6 @@ interface SettingsProps { const Settings: FC = ({ project }) => { const { ui } = useStore() - const projectTier = ui.selectedProject?.subscription_tier const [dateRange, setDateRange] = useState() @@ -69,15 +67,6 @@ const Settings: FC = ({ project }) => { return (
- {projectTier !== undefined && } - {loading ? (
@@ -115,10 +104,6 @@ const Settings: FC = ({ project }) => { ) : ( )} -
-

Invoices

- -
) }