diff --git a/apps/studio/components/interfaces/Billing/Invoices.tsx b/apps/studio/components/interfaces/Billing/Invoices.tsx
deleted file mode 100644
index d346c37c0b1..00000000000
--- a/apps/studio/components/interfaces/Billing/Invoices.tsx
+++ /dev/null
@@ -1,159 +0,0 @@
-import { useParams } from 'common'
-import Link from 'next/link'
-import { useEffect, useState } from 'react'
-import { Button, IconChevronLeft, IconChevronRight, IconDownload, IconFileText } from 'ui'
-
-import Table from 'components/to-be-cleaned/Table'
-import AlertError from 'components/ui/AlertError'
-import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
-import { getInvoice } from 'data/invoices/invoice-query'
-import { useProjectInvoicesCountQuery } from 'data/invoices/project-invoices-count-query'
-import { useProjectInvoicesQuery } from 'data/invoices/project-invoices-query'
-import { useStore } from 'hooks'
-import { InvoiceStatus } from './Invoices.types'
-import InvoiceStatusBadge from './InvoiceStatusBadge'
-
-const PAGE_LIMIT = 10
-
-const Invoices = () => {
- const { ui } = useStore()
- const { ref: projectRef } = useParams()
- const [page, setPage] = useState(1)
-
- const offset = (page - 1) * PAGE_LIMIT
- const { data: count, isError: isErrorCount } = useProjectInvoicesCountQuery({ projectRef })
- const { data, error, isLoading, isError, isSuccess } = useProjectInvoicesQuery({
- projectRef,
- limit: PAGE_LIMIT,
- offset,
- })
- const invoices = data || []
-
- useEffect(() => {
- setPage(1)
- }, [projectRef])
-
- const fetchInvoice = async (id: string) => {
- try {
- const invoice = await getInvoice({ id })
- if (invoice?.invoice_pdf) window.open(invoice.invoice_pdf, '_blank')
- } catch (error: any) {
- ui.setNotification({
- category: 'info',
- message: `Failed to fetch the selected invoice: ${error.message}`,
- })
- }
- }
-
- return (
-
- {isLoading &&
}
-
- {isError &&
}
-
- {isSuccess && (
-
,
- Date ,
- Amount due ,
- Invoice number ,
-
- Status
- ,
- ,
- ]}
- body={
- invoices.length === 0 ? (
-
-
- No invoices for this project yet
-
-
- ) : (
- <>
- {invoices.map((x) => {
- return (
-
-
-
-
-
- {new Date(x.period_end * 1000).toLocaleString()}
-
-
-
- {x.subtotal >= 0
- ? `$${x.subtotal / 100}`
- : `-$${Math.abs(x.subtotal / 100)}`}
-
-
-
- {x.number}
-
-
-
-
-
-
- {[InvoiceStatus.UNCOLLECTIBLE, InvoiceStatus.OPEN].includes(x.status) && (
-
-
- Pay Now
-
-
- )}
-
- }
- onClick={() => fetchInvoice(x.id)}
- />
-
-
-
- )
- })}
-
-
-
-
- {isErrorCount
- ? 'Failed to retrieve total number of invoices'
- : `Showing ${offset + 1} to ${
- offset + invoices.length
- } out of ${count} invoices`}
-
-
- }
- type="default"
- size="tiny"
- disabled={page === 1}
- onClick={async () => setPage(page - 1)}
- />
- }
- type="default"
- size="tiny"
- disabled={page * PAGE_LIMIT >= (count ?? 0)}
- onClick={async () => setPage(page + 1)}
- />
-
-
-
-
- >
- )
- }
- />
- )}
-
- )
-}
-
-export default Invoices
diff --git a/apps/studio/data/analytics/keys.ts b/apps/studio/data/analytics/keys.ts
index 84986a68455..4d7f028cc8c 100644
--- a/apps/studio/data/analytics/keys.ts
+++ b/apps/studio/data/analytics/keys.ts
@@ -57,31 +57,6 @@ export const analyticsKeys = {
},
] as const,
- dailyStats: (
- projectRef: string | undefined,
- {
- attribute,
- startDate,
- endDate,
- interval,
- }: {
- attribute?: string
- startDate?: string
- endDate?: string
- interval?: string
- }
- ) =>
- [
- 'projects',
- projectRef,
- 'daily-stats',
- {
- attribute,
- startDate: isoDateStringToDate(startDate),
- endDate: isoDateStringToDate(endDate),
- interval,
- },
- ] as const,
orgDailyStats: (
orgSlug: string | undefined,
{
diff --git a/apps/studio/data/invoices/project-invoices-count-query.ts b/apps/studio/data/invoices/project-invoices-count-query.ts
deleted file mode 100644
index 7453d934013..00000000000
--- a/apps/studio/data/invoices/project-invoices-count-query.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { useQuery, UseQueryOptions } from '@tanstack/react-query'
-import { head } from 'data/fetchers'
-import { ResponseError } from 'types'
-import { invoicesKeys } from './keys'
-
-export type ProjectInvoicesCountVariables = {
- projectRef?: string
-}
-
-export async function getProjectInvoicesCount(
- { projectRef }: ProjectInvoicesCountVariables,
- signal?: AbortSignal
-) {
- if (!projectRef) throw new Error('Project ref is required')
-
- const res = await head(`/platform/projects/{ref}/invoices`, {
- params: { path: { ref: projectRef } },
- signal,
- parseAs: 'text',
- })
-
- if (res.error) throw (res as any).error
- return Number(res.response.headers.get('X-Total-Count'))
-}
-
-export type ProjectInvoicesCountData = Awaited>
-export type ProjectInvoicesCountError = ResponseError
-
-export const useProjectInvoicesCountQuery = (
- { projectRef }: ProjectInvoicesCountVariables,
- {
- enabled = true,
- ...options
- }: UseQueryOptions = {}
-) =>
- useQuery(
- invoicesKeys.projectInvoicesCount(projectRef),
- ({ signal }) => getProjectInvoicesCount({ projectRef }, signal),
- {
- enabled: enabled && typeof projectRef !== 'undefined',
- ...options,
- }
- )
diff --git a/apps/studio/data/invoices/project-invoices-query.ts b/apps/studio/data/invoices/project-invoices-query.ts
deleted file mode 100644
index 01475bf4aa5..00000000000
--- a/apps/studio/data/invoices/project-invoices-query.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { useQuery, UseQueryOptions } from '@tanstack/react-query'
-import { get } from 'data/fetchers'
-import { ResponseError } from 'types'
-import { invoicesKeys } from './keys'
-
-export type ProjectInvoicesVariables = {
- projectRef?: string
- offset?: number
- limit?: number
-}
-
-export async function getProjectInvoices(
- { projectRef, offset = 0, limit = 10 }: ProjectInvoicesVariables,
- signal?: AbortSignal
-) {
- if (!projectRef) throw new Error('Project ref is required')
-
- const { data, error } = await get(`/platform/projects/{ref}/invoices`, {
- params: {
- path: { ref: projectRef },
- query: { offset: offset.toString(), limit: limit.toString() },
- },
- signal,
- })
-
- if (error) throw error
- return data
-}
-
-export type ProjectInvoicesData = Awaited>
-export type ProjectInvoicesError = ResponseError
-
-export const useProjectInvoicesQuery = (
- { projectRef, offset, limit }: ProjectInvoicesVariables,
- {
- enabled = true,
- ...options
- }: UseQueryOptions = {}
-) =>
- // [Joshen] Switch to useInfiniteQuery
- useQuery(
- invoicesKeys.projectInvoices(projectRef, offset),
- ({ signal }) => getProjectInvoices({ projectRef, offset, limit }, signal),
- {
- enabled: enabled && typeof projectRef !== 'undefined',
- ...options,
- }
- )
diff --git a/apps/studio/data/organizations/keys.ts b/apps/studio/data/organizations/keys.ts
index 682a0956d66..ff03165c3b2 100644
--- a/apps/studio/data/organizations/keys.ts
+++ b/apps/studio/data/organizations/keys.ts
@@ -11,9 +11,6 @@ export const organizationKeys = {
slug: string | undefined,
{ date_start, date_end }: { date_start: string | undefined; date_end: string | undefined }
) => ['organizations', slug, 'audit-logs', { date_start, date_end }] as const,
- migrateBilling: (slug: string | undefined) => ['organizations', slug, 'migrate-billing'] as const,
- migrateBillingPreview: (slug: string | undefined) =>
- ['organizations', slug, 'migrate-billing', 'preview'] as const,
subscriptionPreview: (slug: string | undefined, tier: string | undefined) =>
['organizations', slug, 'subscription', 'preview', tier] as const,
taxIds: (slug: string | undefined) => ['organizations', slug, 'tax-ids'] as const,
diff --git a/apps/studio/data/organizations/organization-migrate-billing-mutation.ts b/apps/studio/data/organizations/organization-migrate-billing-mutation.ts
deleted file mode 100644
index 12e57816bb1..00000000000
--- a/apps/studio/data/organizations/organization-migrate-billing-mutation.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
-import { toast } from 'react-hot-toast'
-
-import { post } from 'lib/common/fetch'
-import { API_URL } from 'lib/constants'
-import { ResponseError } from 'types'
-import { organizationKeys } from './keys'
-
-export type OrganizationBillingMigrationVariables = {
- organizationSlug?: string
- tier?: string
- paymentMethodId?: string
-}
-
-export async function migrateBilling({
- organizationSlug,
- tier,
- paymentMethodId,
-}: OrganizationBillingMigrationVariables) {
- if (!organizationSlug) throw new Error('organizationSlug is required')
- if (!tier) throw new Error('tier is required')
-
- const payload: { tier: string; payment_method_id?: string } = {
- tier,
- payment_method_id: paymentMethodId,
- }
-
- const response = await post(
- `${API_URL}/organizations/${organizationSlug}/org-billing-migration`,
- payload
- )
- if (response.error) throw response.error
-
- return response
-}
-
-type OrganizationBillingMigrationData = Awaited>
-
-export const useOrganizationBillingMigrationMutation = ({
- onSuccess,
- onError,
- ...options
-}: Omit<
- UseMutationOptions<
- OrganizationBillingMigrationData,
- ResponseError,
- OrganizationBillingMigrationVariables
- >,
- 'mutationFn'
-> = {}) => {
- const queryClient = useQueryClient()
-
- return useMutation<
- OrganizationBillingMigrationData,
- ResponseError,
- OrganizationBillingMigrationVariables
- >((vars) => migrateBilling(vars), {
- async onSuccess(data, variables, context) {
- const { organizationSlug } = variables
- await Promise.all([
- queryClient.invalidateQueries(organizationKeys.members(organizationSlug)),
- queryClient.invalidateQueries(organizationKeys.list()),
- queryClient.invalidateQueries(organizationKeys.freeProjectLimitCheck(organizationSlug)),
- ])
- await onSuccess?.(data, variables, context)
- },
- async onError(data, variables, context) {
- if (onError === undefined) {
- toast.error(`Failed to migrate billing: ${data.message}`)
- } else {
- onError(data, variables, context)
- }
- },
- ...options,
- })
-}
diff --git a/apps/studio/data/organizations/organization-migrate-billing-preview-query.ts b/apps/studio/data/organizations/organization-migrate-billing-preview-query.ts
deleted file mode 100644
index 4b6628acecd..00000000000
--- a/apps/studio/data/organizations/organization-migrate-billing-preview-query.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import { useQuery, UseQueryOptions } from '@tanstack/react-query'
-import { post } from 'lib/common/fetch'
-import { API_URL } from 'lib/constants'
-import { organizationKeys } from './keys'
-import { SubscriptionTier } from 'data/subscriptions/types'
-
-export type OrganizationBillingMigrationPreviewVariables = {
- organizationSlug?: string
- tier?: string
-}
-
-export type OrganizationBillingMigrationPreviewResponse = {
- added_credits: number
- addons_to_be_removed: {
- projectRef: string
- projectName: string
- addons: { variant: string; name: string; type: string }[]
- }[]
- monthly_invoice_breakdown: {
- description: string
- unit_price: number
- quantity: number
- total_price: number
- }[]
- old_tiers: SubscriptionTier[]
-}
-
-export async function previewOrganizationBillingMigration(
- { organizationSlug, tier }: OrganizationBillingMigrationPreviewVariables,
- signal?: AbortSignal
-) {
- if (!organizationSlug) throw new Error('organizationSlug is required')
- if (!tier) throw new Error('tier is required')
-
- const payload: { tier: string } = {
- tier,
- }
-
- const response = await post(
- `${API_URL}/organizations/${organizationSlug}/org-billing-migration/preview`,
- payload,
- { signal }
- )
-
- if (response.error) throw response.error
-
- return response as OrganizationBillingMigrationPreviewResponse
-}
-
-export type OrganizationBillingMigrationPreviewData = Awaited<
- ReturnType
->
-export type OrganizationBillingMigrationPreviewError = {
- message: string
-}
-
-export const useOrganizationBillingMigrationPreview = <
- TData = OrganizationBillingMigrationPreviewData
->(
- { organizationSlug, tier }: OrganizationBillingMigrationPreviewVariables,
- {
- enabled = true,
- ...options
- }: UseQueryOptions<
- OrganizationBillingMigrationPreviewData,
- OrganizationBillingMigrationPreviewError,
- TData
- > = {}
-) =>
- useQuery<
- OrganizationBillingMigrationPreviewData,
- OrganizationBillingMigrationPreviewError,
- TData
- >(
- organizationKeys.migrateBillingPreview(organizationSlug),
- ({ signal }) => previewOrganizationBillingMigration({ organizationSlug, tier }, signal),
- {
- enabled: enabled && typeof organizationSlug !== 'undefined' && typeof tier !== 'undefined',
- ...options,
-
- retry: (failureCount, error) => {
- // Don't retry on 400s
- if (
- typeof error === 'object' &&
- error !== null &&
- 'code' in error &&
- (error as any).code === 400
- ) {
- return false
- }
-
- if (failureCount < 3) {
- return true
- }
-
- return false
- },
- }
- )