mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 03:45:06 +03:00
## Problem Knip reports many duplicate exports (both named and default). Besides, we're moving away from default exports and even have an eslint rule to enforce it on new code. ## Solution - Cleanup those exports - Update imports when necessary No functional changes. If it builds, it's fine
103 lines
4.0 KiB
TypeScript
103 lines
4.0 KiB
TypeScript
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
|
import { useParams } from 'common'
|
|
import { useInView } from 'react-intersection-observer'
|
|
|
|
import { CreditCodeRedemption } from './CreditCodeRedemption'
|
|
import { CreditTopUp } from './CreditTopUp'
|
|
import {
|
|
ScaffoldSection,
|
|
ScaffoldSectionContent,
|
|
ScaffoldSectionDetail,
|
|
} from '@/components/layouts/Scaffold'
|
|
import { AlertError } from '@/components/ui/AlertError'
|
|
import { FormPanel } from '@/components/ui/Forms/FormPanel'
|
|
import { FormSection, FormSectionContent } from '@/components/ui/Forms/FormSection'
|
|
import { NoPermission } from '@/components/ui/NoPermission'
|
|
import { useOrgBalanceQuery } from '@/data/subscriptions/org-balance-query'
|
|
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
|
|
|
const CreditBalance = () => {
|
|
const { slug } = useParams()
|
|
|
|
const { isSuccess: isPermissionsLoaded, can: canReadSubscriptions } = useAsyncCheckPermissions(
|
|
PermissionAction.BILLING_READ,
|
|
'stripe.subscriptions'
|
|
)
|
|
const { ref, inView } = useInView({ triggerOnce: true })
|
|
|
|
// Endpoint is expensive, so we only load it if it's in view
|
|
const {
|
|
data: balanceData,
|
|
error: balanceError,
|
|
isPending: isBalanceLoading,
|
|
isError: isBalanceError,
|
|
isSuccess: isBalanceSuccess,
|
|
} = useOrgBalanceQuery({ orgSlug: slug }, { enabled: canReadSubscriptions && inView })
|
|
|
|
const combinedCreditBalanceCents = balanceData?.total_balance_cents ?? 0
|
|
const combinedCreditBalance = combinedCreditBalanceCents / 100
|
|
const hasCredits = combinedCreditBalanceCents > 0
|
|
const hasDebt = combinedCreditBalanceCents < 0
|
|
const balance = Math.abs(combinedCreditBalance).toFixed(2)
|
|
|
|
return (
|
|
<ScaffoldSection ref={ref}>
|
|
<ScaffoldSectionDetail>
|
|
<div className="sticky space-y-2 top-12 pr-3">
|
|
<div className="flex items-center space-x-2">
|
|
<p className="text-foreground text-base m-0">Credit Balance</p>
|
|
</div>
|
|
<p className="text-sm text-foreground-light m-0">
|
|
Credits will be applied to future invoices, before charging your payment method. This
|
|
balance includes purchased credits and any prorated credits from plan changes.
|
|
</p>
|
|
<p className="text-sm text-foreground-light m-0">
|
|
If your credits run out, your default payment method will be charged.
|
|
</p>
|
|
</div>
|
|
</ScaffoldSectionDetail>
|
|
<ScaffoldSectionContent>
|
|
{isPermissionsLoaded && !canReadSubscriptions ? (
|
|
<NoPermission resourceText="view this organization's credits" />
|
|
) : (
|
|
<FormPanel
|
|
footer={
|
|
balanceData?.billing_via_partner ? undefined : (
|
|
<div className="flex justify-end items-center py-4 px-8 gap-x-2">
|
|
<CreditCodeRedemption slug={slug} />
|
|
<CreditTopUp slug={slug} />
|
|
</div>
|
|
)
|
|
}
|
|
>
|
|
<FormSection>
|
|
<FormSectionContent fullWidth loading={isBalanceLoading}>
|
|
{isBalanceError && (
|
|
<AlertError
|
|
subject="Failed to retrieve organization customer profile"
|
|
error={balanceError}
|
|
/>
|
|
)}
|
|
|
|
{isBalanceSuccess && (
|
|
<div className="flex w-full justify-between items-center">
|
|
<span>Balance</span>
|
|
<div className="flex items-center space-x-1">
|
|
{hasDebt && <h4 className="opacity-50">-</h4>}
|
|
<h4 className="opacity-50">$</h4>
|
|
<h1 className="relative">{balance}</h1>
|
|
{hasCredits && <h4 className="opacity-50">/credits</h4>}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</FormSectionContent>
|
|
</FormSection>
|
|
</FormPanel>
|
|
)}
|
|
</ScaffoldSectionContent>
|
|
</ScaffoldSection>
|
|
)
|
|
}
|
|
|
|
export default CreditBalance
|