Home / Function/ InvoicesSettings() — supabase Function Reference

InvoicesSettings() — supabase Function Reference

Architecture documentation for the InvoicesSettings() function in InvoicesSettings.tsx from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  e27f6414_0bbc_c8c9_ab6e_281257f845ed["InvoicesSettings()"]
  82054de4_d586_58e7_d6a8_d5b94a9a724a["getPartnerManagedResourceCta()"]
  e27f6414_0bbc_c8c9_ab6e_281257f845ed -->|calls| 82054de4_d586_58e7_d6a8_d5b94a9a724a
  style e27f6414_0bbc_c8c9_ab6e_281257f845ed fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Organization/InvoicesSettings/InvoicesSettings.tsx lines 50–259

export const InvoicesSettings = () => {
  const [page, setPage] = useState(1)

  const { data: selectedOrganization } = useSelectedOrganizationQuery()
  const slug = selectedOrganization?.slug
  const offset = (page - 1) * PAGE_LIMIT

  const { data: count, isError: isErrorCount } = useInvoicesCountQuery(
    {
      slug,
    },
    { enabled: selectedOrganization?.managed_by === 'supabase' }
  )
  const {
    data,
    error,
    isPending: isLoading,
    isError,
  } = useInvoicesQuery(
    {
      slug,
      offset,
      limit: PAGE_LIMIT,
    },
    { enabled: selectedOrganization?.managed_by === 'supabase' }
  )
  const invoices = data || []

  useEffect(() => {
    setPage(1)
  }, [slug])

  const fetchInvoice = async (id: string) => {
    try {
      const invoice = await getInvoice({ invoiceId: id, slug })
      if (invoice?.invoice_pdf) window.open(invoice.invoice_pdf, '_blank')
    } catch (error: any) {
      toast.error(`Failed to fetch the selected invoice: ${error.message}`)
    }
  }

  const fetchReceipt = async (invoiceId: string) => {
    if (!slug) return

    try {
      const receipt = await getInvoiceReceipt({ invoiceId, slug })
      if (receipt?.receipt_pdf) window.open(receipt.receipt_pdf, '_blank')
    } catch (error: any) {
      toast.error(`Failed to fetch receipt: ${error.message}`)
    }
  }

  if (
    selectedOrganization?.managed_by !== undefined &&
    selectedOrganization?.managed_by !== 'supabase'
  ) {
    return (
      <PartnerManagedResource
        managedBy={selectedOrganization?.managed_by}
        resource="Invoices"
        cta={getPartnerManagedResourceCta(selectedOrganization)}
      />
    )
  }

  // Handle loading state faded text for table headers
  const tableHeadClassName =
    isLoading || invoices.length === 0 ? 'text-foreground-muted' : undefined

  return (
    <Card>
      <Table>
        <TableHeader>
          <TableRow>
            {invoices.length > 0 && (
              <TableHead className="w-2">
                <span className="sr-only">Icon</span>
              </TableHead>
            )}
            <TableHead className={cn(tableHeadClassName)}>Date</TableHead>
            <TableHead className={cn(tableHeadClassName)}>Amount</TableHead>
            <TableHead className={cn(tableHeadClassName)}>Invoice number</TableHead>
            <TableHead className={cn(tableHeadClassName)}>Status</TableHead>
            <TableHead>
              <span className="sr-only">Actions</span>
            </TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {isLoading ? (
            new Array(6).fill(0).map((_, idx) => (
              <TableRow key={`loading-${idx}`}>
                <TableCell colSpan={invoices.length > 0 ? 6 : 5}>
                  <ShimmeringLoader />
                </TableCell>
              </TableRow>
            ))
          ) : isError ? (
            <TableRow className="rounded-b">
              <TableCell
                colSpan={invoices.length > 0 ? 6 : 5}
                className="!p-0 !rounded-b overflow-hidden"
              >
                <AlertError
                  className="border-0 rounded-none"
                  error={error}
                  subject="Failed to retrieve invoices"
                />
              </TableCell>
            </TableRow>
          ) : invoices.length === 0 ? (
            <TableRow className="[&>td]:hover:bg-inherit">
              <TableCell colSpan={5} className="py-6">
                <p className="text-foreground-lighter">No invoices for this organization yet</p>
              </TableCell>
            </TableRow>
          ) : (
            <>
              {invoices.map((x) => {
                return (
                  <TableRow key={x.id}>
                    <TableCell className="w-2">
                      <FileText aria-hidden="true" size={16} className="text-foreground-muted" />
                    </TableCell>
                    <TableCell>
                      <p>{dayjs(x.period_end * 1000).format('MMM DD, YYYY')}</p>
                    </TableCell>
                    <TableCell translate="no">
                      <p>{formatCurrency(x.amount_due / 100)}</p>
                    </TableCell>
                    <TableCell>
                      <p className="font-mono text-foreground-light">{x.number}</p>
                    </TableCell>
                    <TableCell>
                      <InvoiceStatusBadge
                        status={x.status as InvoiceStatus}
                        paymentAttempted={x.payment_attempted}
                        paymentProcessing={x.payment_is_processing}
                      />
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="flex items-center justify-end space-x-2">
                        {x.amount_due > 0 &&
                          !x.payment_is_processing &&
                          [
                            InvoiceStatus.UNCOLLECTIBLE,
                            InvoiceStatus.OPEN,
                            InvoiceStatus.ISSUED,
                          ].includes(x.status as InvoiceStatus) && (
                            <InvoicePayButton slug={slug} invoiceId={x.id} />
                          )}

                        <ButtonTooltip
                          type="outline"
                          className="w-7"
                          icon={<ScrollText size={16} strokeWidth={1.5} />}
                          onClick={() => fetchInvoice(x.id)}
                          tooltip={{ content: { side: 'bottom', text: 'Download invoice' } }}
                        />

                        {x.status === InvoiceStatus.PAID && x.amount_due > 0 && (
                          <ButtonTooltip
                            type="outline"
                            className="w-7"
                            icon={<Receipt size={16} strokeWidth={1.5} />}
                            onClick={() => fetchReceipt(x.id)}
                            tooltip={{ content: { side: 'bottom', text: 'Download receipt' } }}
                          />
                        )}
                      </div>
                    </TableCell>
                  </TableRow>
                )
              })}
            </>
          )}
        </TableBody>
      </Table>
      {invoices.length > 0 && (
        <CardFooter className="border-t p-4 flex items-center justify-between">
          <p className="text-foreground-muted text-sm">
            {isErrorCount
              ? 'Failed to retrieve total number of invoices'
              : typeof count === 'number'
                ? `Showing ${offset + 1} to ${offset + invoices.length} out of ${count} invoices`
                : `Showing ${offset + 1} to ${offset + invoices.length} invoices`}
          </p>
          <div className="flex items-center gap-x-2" aria-label="Pagination">
            <Button
              icon={<ChevronLeft />}
              aria-label="Previous page"
              type="default"
              size="tiny"
              disabled={page === 1}
              onClick={async () => setPage(page - 1)}
            />
            <Button
              icon={<ChevronRight />}
              aria-label="Next page"
              type="default"
              size="tiny"
              disabled={page * PAGE_LIMIT >= (count ?? 0)}
              onClick={async () => setPage(page + 1)}
            />
          </div>
        </CardFooter>
      )}
    </Card>
  )
}

Subdomains

Frequently Asked Questions

What does InvoicesSettings() do?
InvoicesSettings() is a function in the supabase codebase.
What does InvoicesSettings() call?
InvoicesSettings() calls 1 function(s): getPartnerManagedResourceCta.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free