diff --git a/frontend/src/hooks/api/organization/types.ts b/frontend/src/hooks/api/organization/types.ts index 5fbbd18634..629c4a330d 100644 --- a/frontend/src/hooks/api/organization/types.ts +++ b/frontend/src/hooks/api/organization/types.ts @@ -52,7 +52,7 @@ export type Invoice = { }; export type PmtMethod = { - id: string; + _id: string; brand: string; exp_month: number; exp_year: number; diff --git a/frontend/src/views/Settings/BillingSettingsPage/components/BillingDetailsTab/PmtMethodsTable.tsx b/frontend/src/views/Settings/BillingSettingsPage/components/BillingDetailsTab/PmtMethodsTable.tsx index 5ccfef1d38..8dfe7e6056 100644 --- a/frontend/src/views/Settings/BillingSettingsPage/components/BillingDetailsTab/PmtMethodsTable.tsx +++ b/frontend/src/views/Settings/BillingSettingsPage/components/BillingDetailsTab/PmtMethodsTable.tsx @@ -1,8 +1,10 @@ import { faCreditCard, faXmark } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; import { + DeleteActionModal, EmptyState, IconButton, Table, @@ -15,76 +17,101 @@ import { Tr } from "@app/components/v2"; import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context"; +import { usePopUp } from "@app/hooks"; import { useDeleteOrgPmtMethod, useGetOrgPmtMethods } from "@app/hooks/api"; export const PmtMethodsTable = () => { const { currentOrg } = useOrganization(); const { data, isLoading } = useGetOrgPmtMethods(currentOrg?.id ?? ""); const deleteOrgPmtMethod = useDeleteOrgPmtMethod(); + const { handlePopUpOpen, handlePopUpClose, handlePopUpToggle, popUp } = usePopUp([ + "removeCard" + ] as const); - const handleDeletePmtMethodBtnClick = async (pmtMethodId: string) => { - if (!currentOrg?.id) return; - await deleteOrgPmtMethod.mutateAsync({ - organizationId: currentOrg.id, - pmtMethodId - }); + const pmtMethodToRemove = popUp.removeCard.data as { id: string; last4: string } | undefined; + + const handleDeletePmtMethodBtnClick = async () => { + if (!currentOrg?.id || !pmtMethodToRemove) return; + try { + await deleteOrgPmtMethod.mutateAsync({ + organizationId: currentOrg.id, + pmtMethodId: pmtMethodToRemove.id + }); + createNotification({ + type: "success", + text: "Successfully removed payment method" + }); + handlePopUpClose("removeCard"); + } catch (error: any) { + createNotification({ + type: "error", + text: error.message ?? "Error removing payment method" + }); + } }; return ( - - - - - - - - - - - - {!isLoading && - data && - data?.length > 0 && - data.map(({ id, brand, exp_month, exp_year, funding, last4 }) => ( - - - - - - - - ))} - {isLoading && } - {!isLoading && data && data?.length === 0 && ( + <> + +
BrandTypeLast 4 DigitsExpiration -
{brand.charAt(0).toUpperCase() + brand.slice(1)}{funding.charAt(0).toUpperCase() + funding.slice(1)}{last4}{`${exp_month}/${exp_year}`} - - {(isAllowed) => ( - { - await handleDeletePmtMethodBtnClick(id); - }} - size="lg" - isDisabled={!isAllowed} - colorSchema="danger" - variant="plain" - ariaLabel="update" - > - - - )} - -
+ - + + + + + - )} - -
- - BrandTypeLast 4 DigitsExpiration
-
+ + + {!isLoading && + data && + data?.length > 0 && + data.map(({ _id: id, brand, exp_month, exp_year, funding, last4 }) => ( + + {brand.charAt(0).toUpperCase() + brand.slice(1)} + {funding.charAt(0).toUpperCase() + funding.slice(1)} + {last4} + {`${exp_month}/${exp_year}`} + + + {(isAllowed) => ( + handlePopUpOpen("removeCard", { id, last4 })} + size="lg" + isDisabled={!isAllowed} + colorSchema="danger" + variant="plain" + ariaLabel="update" + > + + + )} + + + + ))} + {isLoading && } + {!isLoading && data && data?.length === 0 && ( + + + + + + )} + + + + handlePopUpToggle("removeCard", isOpen)} + title={`Remove payment method ending in *${pmtMethodToRemove?.last4}?`} + onDeleteApproved={handleDeletePmtMethodBtnClick} + /> + ); };