CurrentPaymentMethod.tsx 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { PermissionAction, SupportCategories } from '@supabase/shared-types/out/constants'
  2. import { useParams } from 'common'
  3. import { CreditCardIcon } from 'lucide-react'
  4. import Link from 'next/link'
  5. import { Button } from 'ui'
  6. import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
  7. import CreditCard from './CreditCard'
  8. import { SupportLink } from '@/components/interfaces/Support/SupportLink'
  9. import { useOrganizationPaymentMethodsQuery } from '@/data/organizations/organization-payment-methods-query'
  10. import { useOrgSubscriptionQuery } from '@/data/subscriptions/org-subscription-query'
  11. import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
  12. const CurrentPaymentMethod = () => {
  13. const { slug } = useParams()
  14. const {
  15. data: subscription,
  16. isPending: isLoadingSubscription,
  17. isError: isErrorSubscription,
  18. } = useOrgSubscriptionQuery({
  19. orgSlug: slug,
  20. })
  21. const {
  22. data: paymentMethods,
  23. isPending: isLoadingOrganizationPaymentMethods,
  24. isError: isErrorOrganizationPaymentMethods,
  25. } = useOrganizationPaymentMethodsQuery({ slug })
  26. const isLoading = isLoadingSubscription || isLoadingOrganizationPaymentMethods
  27. const isError = isErrorSubscription || isErrorOrganizationPaymentMethods
  28. const defaultPaymentMethod = paymentMethods?.data.find((pm) => pm.is_default)
  29. const { can: canReadPaymentMethods } = useAsyncCheckPermissions(
  30. PermissionAction.BILLING_READ,
  31. 'stripe.payment_methods'
  32. )
  33. // since this component is an enhancement,
  34. // if it can't read payment methods, we will just not show it
  35. if (!canReadPaymentMethods || isError) return null
  36. return (
  37. <div className="flex justify-between items-center gap-4 w-full text-sm rounded-lg p-4 text-foreground bg-alternative border">
  38. {isLoading ? (
  39. <ShimmeringLoader className="flex-1" />
  40. ) : subscription?.payment_method_type === 'invoice' ? (
  41. <p className="flex-1 text-sm">
  42. You get a monthly invoice and payment link via email. To change your payment method,
  43. please contact us via our support form.
  44. </p>
  45. ) : !defaultPaymentMethod ? (
  46. <div className="flex-1 flex items-center gap-2 opacity-50">
  47. <CreditCardIcon size={16} strokeWidth={1.5} />
  48. <p className="text-sm">No payment methods</p>
  49. </div>
  50. ) : (
  51. <CreditCard
  52. paymentMethod={defaultPaymentMethod}
  53. paymentMethodType={subscription?.payment_method_type}
  54. canUpdatePaymentMethods={false}
  55. paymentMethodCount={paymentMethods?.data.length ?? 0}
  56. subscriptionPlan={subscription?.plan.id}
  57. />
  58. )}
  59. <Button type="outline" asChild>
  60. {subscription?.payment_method_type === 'invoice' ? (
  61. <SupportLink
  62. queryParams={{
  63. category: SupportCategories.BILLING,
  64. message: 'I would like to change my payment method',
  65. }}
  66. >
  67. Contact support
  68. </SupportLink>
  69. ) : (
  70. <Link href={`/org/${slug}/billing#payment-methods`}>Manage payment methods</Link>
  71. )}
  72. </Button>
  73. </div>
  74. )
  75. }
  76. export default CurrentPaymentMethod