From 95a491cf683d4a7c0e17efd77488cfbc33761d04 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 7 Mar 2025 14:15:30 -0500 Subject: [PATCH 01/12] init --- .../ui/components/Checkout/CheckoutPage.tsx | 130 +++++--------- .../ui/customizables/elementDescriptors.ts | 6 + .../clerk-js/src/ui/customizables/index.ts | 4 + .../clerk-js/src/ui/elements/LineItems.tsx | 165 ++++++++++++++++++ packages/clerk-js/src/ui/elements/index.ts | 1 + packages/clerk-js/src/ui/primitives/Dd.tsx | 24 +++ packages/clerk-js/src/ui/primitives/Dl.tsx | 26 +++ packages/clerk-js/src/ui/primitives/Dt.tsx | 24 +++ packages/clerk-js/src/ui/primitives/index.ts | 3 + .../clerk-js/src/ui/styledSystem/types.ts | 3 + packages/types/src/appearance.ts | 6 + 11 files changed, 304 insertions(+), 88 deletions(-) create mode 100644 packages/clerk-js/src/ui/elements/LineItems.tsx create mode 100644 packages/clerk-js/src/ui/primitives/Dd.tsx create mode 100644 packages/clerk-js/src/ui/primitives/Dl.tsx create mode 100644 packages/clerk-js/src/ui/primitives/Dt.tsx diff --git a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx index 940d9ab14fb..d2f36c0bcf7 100644 --- a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx +++ b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx @@ -5,7 +5,8 @@ import { loadStripe } from '@stripe/stripe-js'; import { useEffect, useRef } from 'react'; import { useCheckoutContext } from '../../contexts'; -import { Alert, Box, Button, Col, Flex, Heading, Icon, Spinner, Text } from '../../customizables'; +import { Alert, Box, Button, Col, Flex, Heading, Icon, Spinner } from '../../customizables'; +import { LineItems } from '../../elements'; import { useCheckout } from '../../hooks'; import { Close } from '../../icons'; import { CheckoutComplete } from './CheckoutComplete'; @@ -77,8 +78,8 @@ export const CheckoutPage = (props: __experimental_CheckoutProps) => { - { ); }; -const CheckoutPlanRows = ({ plan, planPeriod }: { plan: CommercePlanResource; planPeriod: string }) => { +const CheckoutPlanRows = ({ + plan, + planPeriod, + totals, +}: { + plan: CommercePlanResource; + planPeriod: string; + totals: CommerceTotals; +}) => { return ( - ({ - paddingBlockEnd: t.space.$3, - borderBottomWidth: t.borderWidths.$normal, - borderBottomStyle: t.borderStyles.$solid, - borderBottomColor: t.colors.$neutralAlpha100, - })} - > - - - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}>{plan.name} - - - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}> - {plan.currencySymbol} - {planPeriod === 'month' ? plan.amountFormatted : plan.annualMonthlyAmountFormatted} - - ({ lineHeight: t.lineHeights.$normal })} - > - per month{planPeriod === 'annual' ? ', times 12 months' : ''} - - - - - ); -}; - -const CheckoutTotalsRows = ({ totals }: { totals: CommerceTotals }) => { - return ( - <> - ({ - paddingBlockEnd: t.space.$3, - borderBottomWidth: t.borderWidths.$normal, - borderBottomStyle: t.borderStyles.$solid, - borderBottomColor: t.colors.$neutralAlpha100, - color: t.colors.$colorTextSecondary, - })} - > - - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}>Subtotal - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}> - {totals.subtotal.currencySymbol} - {totals.subtotal.amountFormatted} - - - - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}>Tax - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}> - {totals.taxTotal.currencySymbol} - {totals.taxTotal.amountFormatted} - - - - - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}> - Total{totals.totalDueNow ? ' Due Today' : ''} - - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}> + + + {plan.name} + + {plan.currencySymbol} + {planPeriod === 'month' ? plan.amountFormatted : plan.annualMonthlyAmountFormatted} + + + + + Subtotal + + {totals.subtotal.currencySymbol} + {totals.subtotal.amountFormatted} + + + + Tax + + {totals.taxTotal.currencySymbol} + {totals.taxTotal.amountFormatted} + + + + + Total{totals.totalDueNow ? ' Due Today' : ''} + {totals.totalDueNow ? `${totals.totalDueNow.currencySymbol}${totals.totalDueNow.amountFormatted}` : `${totals.grandTotal.currencySymbol}${totals.grandTotal.amountFormatted}`} - - - + + + ); }; diff --git a/packages/clerk-js/src/ui/customizables/elementDescriptors.ts b/packages/clerk-js/src/ui/customizables/elementDescriptors.ts index 66c5087fea6..2622f68a0e8 100644 --- a/packages/clerk-js/src/ui/customizables/elementDescriptors.ts +++ b/packages/clerk-js/src/ui/customizables/elementDescriptors.ts @@ -32,6 +32,12 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([ 'disclosureContentInner', 'disclosureContent', + 'lineItemsRoot', + 'lineItemsDivider', + 'lineItemsGroup', + 'lineItemsTitle', + 'lineItemsDescription', + 'actionCard', 'logoBox', diff --git a/packages/clerk-js/src/ui/customizables/index.ts b/packages/clerk-js/src/ui/customizables/index.ts index 9398fc998d5..acd5ad0fc55 100644 --- a/packages/clerk-js/src/ui/customizables/index.ts +++ b/packages/clerk-js/src/ui/customizables/index.ts @@ -61,4 +61,8 @@ export const Tr = makeCustomizable(sanitizeDomProps(Primitives.Tr)); export const Th = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Th))); export const Td = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Td))); +export const Dl = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Dl))); +export const Dd = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Dd))); +export const Dt = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Dt))); + export const Span = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Span))); diff --git a/packages/clerk-js/src/ui/elements/LineItems.tsx b/packages/clerk-js/src/ui/elements/LineItems.tsx new file mode 100644 index 00000000000..3744892cb98 --- /dev/null +++ b/packages/clerk-js/src/ui/elements/LineItems.tsx @@ -0,0 +1,165 @@ +import { Box, Dd, descriptors, Dl, Dt, Span } from '../customizables'; + +/* ------------------------------------------------------------------------------------------------- + * LineItems.Root + * -----------------------------------------------------------------------------------------------*/ + +interface RootProps { + children: React.ReactNode; +} + +function Root({ children }: RootProps) { + return ( +
({ + display: 'grid', + gridRowGap: t.space.$2, + })} + > + {children} +
+ ); +} + +/* ------------------------------------------------------------------------------------------------- + * LineItems.Divider + * -----------------------------------------------------------------------------------------------*/ + +function Divider() { + return ( + ({ + borderColor: t.colors.$neutralAlpha100, + })} + /> + ); +} + +/* ------------------------------------------------------------------------------------------------- + * LineItems.Group + * -----------------------------------------------------------------------------------------------*/ + +interface GroupProps { + children: React.ReactNode; +} + +function Group({ children }: GroupProps) { + return ( + ({ + display: 'grid', + gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', + })} + > + {children} + + ); +} + +/* ------------------------------------------------------------------------------------------------- + * LineItems.Title + * -----------------------------------------------------------------------------------------------*/ + +interface TitleProps { + children: React.ReactNode; + /** + * @default `primary` + */ + colorScheme?: 'primary' | 'secondary'; + /** + * @default `medium` + */ + weight?: 'normal' | 'medium'; +} + +function Title({ children, colorScheme = 'primary', weight = 'medium' }: TitleProps) { + return ( +
({ + fontWeight: weight === 'normal' ? t.fontWeights.$normal : t.fontWeights.$medium, + color: colorScheme === 'primary' ? t.colors.$colorText : t.colors.$colorTextSecondary, + })} + > + {children} +
+ ); +} + +/* ------------------------------------------------------------------------------------------------- + * LineItems.Description + * -----------------------------------------------------------------------------------------------*/ + +interface DescriptionProps { + children: React.ReactNode; + /** + * Render a note below the description text. + */ + note?: React.ReactNode; + /** + * Render a piece of text before the description text. + */ + prefix?: React.ReactNode; + /** + * @default `secondary` + */ + colorScheme?: 'primary' | 'secondary'; + /** + * @default `normal` + */ + weight?: 'normal' | 'medium'; +} + +function Description({ children, colorScheme = 'secondary', weight = 'normal', note, prefix }: DescriptionProps) { + return ( +
({ + display: 'grid', + justifyContent: 'end', + color: colorScheme === 'primary' ? t.colors.$colorText : t.colors.$colorTextSecondary, + })} + > + ({ + display: 'inline-flex', + justifyContent: 'flex-end', + alignItems: 'center', + gap: t.space.$1, + })} + > + {prefix ? ( + ({ + color: t.colors.$colorTextSecondary, + fontSize: t.fontSizes.$sm, + })} + > + {prefix} + + ) : null} + ({ + fontWeight: weight === 'normal' ? t.fontWeights.$normal : t.fontWeights.$medium, + })} + > + {children} + + + {note ? {note} : null} +
+ ); +} + +export const LineItems = { + Root, + Divider, + Group, + Title, + Description, +}; diff --git a/packages/clerk-js/src/ui/elements/index.ts b/packages/clerk-js/src/ui/elements/index.ts index 01a67ba4a4e..6810df6281d 100644 --- a/packages/clerk-js/src/ui/elements/index.ts +++ b/packages/clerk-js/src/ui/elements/index.ts @@ -29,6 +29,7 @@ export * from './InformationBox'; export * from './InputWithIcon'; export * from './InvisibleRootBox'; export * from './LegalConsentCheckbox'; +export * from './LineItems'; export * from './LoadingCard'; export * from './Menu'; export * from './Modal'; diff --git a/packages/clerk-js/src/ui/primitives/Dd.tsx b/packages/clerk-js/src/ui/primitives/Dd.tsx new file mode 100644 index 00000000000..f5b97550097 --- /dev/null +++ b/packages/clerk-js/src/ui/primitives/Dd.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +import type { PrimitiveProps, StyleVariants } from '../styledSystem'; +import { createVariants } from '../styledSystem'; +import type { BoxProps } from './Box'; +import { Box } from './Box'; + +const { applyVariants, filterProps } = createVariants(_ => ({ + base: {}, + variants: {}, +})); + +export type DdProps = PrimitiveProps<'dd'> & Omit & StyleVariants; + +export const Dd = React.forwardRef((props, ref) => { + return ( + + ); +}); diff --git a/packages/clerk-js/src/ui/primitives/Dl.tsx b/packages/clerk-js/src/ui/primitives/Dl.tsx new file mode 100644 index 00000000000..5e2953de29b --- /dev/null +++ b/packages/clerk-js/src/ui/primitives/Dl.tsx @@ -0,0 +1,26 @@ +import React from 'react'; + +import type { PrimitiveProps, StyleVariants } from '../styledSystem'; +import { createVariants } from '../styledSystem'; +import type { BoxProps } from './Box'; +import { Box } from './Box'; + +const { applyVariants, filterProps } = createVariants(theme => ({ + base: { + fontSize: theme.fontSizes.$md, + }, + variants: {}, +})); + +export type DlProps = PrimitiveProps<'dl'> & Omit & StyleVariants; + +export const Dl = React.forwardRef((props, ref) => { + return ( + + ); +}); diff --git a/packages/clerk-js/src/ui/primitives/Dt.tsx b/packages/clerk-js/src/ui/primitives/Dt.tsx new file mode 100644 index 00000000000..949616281b3 --- /dev/null +++ b/packages/clerk-js/src/ui/primitives/Dt.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +import type { PrimitiveProps, StyleVariants } from '../styledSystem'; +import { createVariants } from '../styledSystem'; +import type { BoxProps } from './Box'; +import { Box } from './Box'; + +const { applyVariants, filterProps } = createVariants(_ => ({ + base: {}, + variants: {}, +})); + +export type DtProps = PrimitiveProps<'dt'> & Omit & StyleVariants; + +export const Dt = React.forwardRef((props, ref) => { + return ( + + ); +}); diff --git a/packages/clerk-js/src/ui/primitives/index.ts b/packages/clerk-js/src/ui/primitives/index.ts index 4e0697a3357..94622d54c9c 100644 --- a/packages/clerk-js/src/ui/primitives/index.ts +++ b/packages/clerk-js/src/ui/primitives/index.ts @@ -3,6 +3,9 @@ export * from './AlertIcon'; export * from './Badge'; export * from './Box'; export * from './Button'; +export * from './Dl'; +export * from './Dd'; +export * from './Dt'; export * from './Flex'; export * from './Form'; export * from './FormErrorText'; diff --git a/packages/clerk-js/src/ui/styledSystem/types.ts b/packages/clerk-js/src/ui/styledSystem/types.ts index d07889b7d23..27c7984f1ab 100644 --- a/packages/clerk-js/src/ui/styledSystem/types.ts +++ b/packages/clerk-js/src/ui/styledSystem/types.ts @@ -31,6 +31,9 @@ type ElementProps = { th: React.JSX.IntrinsicElements['th']; tr: React.JSX.IntrinsicElements['tr']; td: React.JSX.IntrinsicElements['td']; + dl: React.JSX.IntrinsicElements['dl']; + dt: React.JSX.IntrinsicElements['dt']; + dd: React.JSX.IntrinsicElements['dd']; }; /** diff --git a/packages/types/src/appearance.ts b/packages/types/src/appearance.ts index bd8fda2d855..1766864f16d 100644 --- a/packages/types/src/appearance.ts +++ b/packages/types/src/appearance.ts @@ -152,6 +152,12 @@ export type ElementsConfig = { disclosureContentInner: WithOptions; disclosureContent: WithOptions; + lineItemsRoot: WithOptions; + lineItemsDivider: WithOptions; + lineItemsGroup: WithOptions; + lineItemsTitle: WithOptions<'primary' | 'secondary'>; + lineItemsDescription: WithOptions<'primary' | 'secondary'>; + logoBox: WithOptions; logoImage: WithOptions; From 331a7137072aceef2125afb4ed3814eca76667f1 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 7 Mar 2025 14:24:14 -0500 Subject: [PATCH 02/12] use border --- .../ui/components/Checkout/CheckoutPage.tsx | 6 ++-- .../clerk-js/src/ui/elements/LineItems.tsx | 33 ++++++++----------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx index d2f36c0bcf7..24b142524b8 100644 --- a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx +++ b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx @@ -149,8 +149,7 @@ const CheckoutPlanRows = ({ {planPeriod === 'month' ? plan.amountFormatted : plan.annualMonthlyAmountFormatted} - - + Subtotal {totals.subtotal.currencySymbol} @@ -164,8 +163,7 @@ const CheckoutPlanRows = ({ {totals.taxTotal.amountFormatted} - - + Total{totals.totalDueNow ? ' Due Today' : ''} {totals.totalDueNow diff --git a/packages/clerk-js/src/ui/elements/LineItems.tsx b/packages/clerk-js/src/ui/elements/LineItems.tsx index 3744892cb98..16a2dbf65ae 100644 --- a/packages/clerk-js/src/ui/elements/LineItems.tsx +++ b/packages/clerk-js/src/ui/elements/LineItems.tsx @@ -22,36 +22,32 @@ function Root({ children }: RootProps) { ); } -/* ------------------------------------------------------------------------------------------------- - * LineItems.Divider - * -----------------------------------------------------------------------------------------------*/ - -function Divider() { - return ( - ({ - borderColor: t.colors.$neutralAlpha100, - })} - /> - ); -} - /* ------------------------------------------------------------------------------------------------- * LineItems.Group * -----------------------------------------------------------------------------------------------*/ interface GroupProps { children: React.ReactNode; + /** + * @default `false` + */ + borderTop?: boolean; } -function Group({ children }: GroupProps) { +function Group({ children, borderTop = false }: GroupProps) { return ( ({ + sx={t => ({ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', + ...(borderTop + ? { + borderTopWidth: t.borderWidths.$normal, + borderTopStyle: t.borderStyles.$solid, + borderTopColor: t.colors.$neutralAlpha100, + paddingTop: t.space.$2, + } + : {}), })} > {children} @@ -158,7 +154,6 @@ function Description({ children, colorScheme = 'secondary', weight = 'normal', n export const LineItems = { Root, - Divider, Group, Title, Description, From e37bf9130bf76ffc9a107f3eae6fc4f9d6cbf36c Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 7 Mar 2025 14:28:58 -0500 Subject: [PATCH 03/12] descriptors --- .../clerk-js/src/ui/customizables/elementDescriptors.ts | 4 ++++ packages/clerk-js/src/ui/elements/LineItems.tsx | 6 +++++- packages/types/src/appearance.ts | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/customizables/elementDescriptors.ts b/packages/clerk-js/src/ui/customizables/elementDescriptors.ts index 2622f68a0e8..a640e946441 100644 --- a/packages/clerk-js/src/ui/customizables/elementDescriptors.ts +++ b/packages/clerk-js/src/ui/customizables/elementDescriptors.ts @@ -37,6 +37,10 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([ 'lineItemsGroup', 'lineItemsTitle', 'lineItemsDescription', + 'lineItemsDescriptionInner', + 'lineItemsDescriptionNote', + 'lineItemsDescriptionPrefix', + 'lineItemsDescriptionText', 'actionCard', diff --git a/packages/clerk-js/src/ui/elements/LineItems.tsx b/packages/clerk-js/src/ui/elements/LineItems.tsx index 16a2dbf65ae..8f47a1c9413 100644 --- a/packages/clerk-js/src/ui/elements/LineItems.tsx +++ b/packages/clerk-js/src/ui/elements/LineItems.tsx @@ -37,6 +37,7 @@ interface GroupProps { function Group({ children, borderTop = false }: GroupProps) { return ( ({ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', @@ -122,6 +123,7 @@ function Description({ children, colorScheme = 'secondary', weight = 'normal', n })} > ({ display: 'inline-flex', justifyContent: 'flex-end', @@ -131,6 +133,7 @@ function Description({ children, colorScheme = 'secondary', weight = 'normal', n > {prefix ? ( ({ color: t.colors.$colorTextSecondary, fontSize: t.fontSizes.$sm, @@ -140,6 +143,7 @@ function Description({ children, colorScheme = 'secondary', weight = 'normal', n ) : null} ({ fontWeight: weight === 'normal' ? t.fontWeights.$normal : t.fontWeights.$medium, })} @@ -147,7 +151,7 @@ function Description({ children, colorScheme = 'secondary', weight = 'normal', n {children} - {note ? {note} : null} + {note ? {note} : null} ); } diff --git a/packages/types/src/appearance.ts b/packages/types/src/appearance.ts index 1766864f16d..326c42d865d 100644 --- a/packages/types/src/appearance.ts +++ b/packages/types/src/appearance.ts @@ -157,6 +157,10 @@ export type ElementsConfig = { lineItemsGroup: WithOptions; lineItemsTitle: WithOptions<'primary' | 'secondary'>; lineItemsDescription: WithOptions<'primary' | 'secondary'>; + lineItemsDescriptionInner: WithOptions; + lineItemsDescriptionNote: WithOptions; + lineItemsDescriptionPrefix: WithOptions; + lineItemsDescriptionText: WithOptions; logoBox: WithOptions; logoImage: WithOptions; From 566a7304790dbf1b687e55e08fba1ca34b9e598d Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 7 Mar 2025 14:47:10 -0500 Subject: [PATCH 04/12] font size --- packages/clerk-js/src/ui/elements/LineItems.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/elements/LineItems.tsx b/packages/clerk-js/src/ui/elements/LineItems.tsx index 8f47a1c9413..1b72cfa1230 100644 --- a/packages/clerk-js/src/ui/elements/LineItems.tsx +++ b/packages/clerk-js/src/ui/elements/LineItems.tsx @@ -151,7 +151,16 @@ function Description({ children, colorScheme = 'secondary', weight = 'normal', n {children} - {note ? {note} : null} + {note ? ( + ({ + fontSize: t.fontSizes.$sm, + })} + > + {note} + + ) : null} ); } From 2865562830012f77931bfc444744745609243d34 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 7 Mar 2025 15:05:08 -0500 Subject: [PATCH 05/12] use line items --- .../components/Checkout/CheckoutComplete.tsx | 65 ++++++++----------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/packages/clerk-js/src/ui/components/Checkout/CheckoutComplete.tsx b/packages/clerk-js/src/ui/components/Checkout/CheckoutComplete.tsx index 2994f676375..d6bf7e90523 100644 --- a/packages/clerk-js/src/ui/components/Checkout/CheckoutComplete.tsx +++ b/packages/clerk-js/src/ui/components/Checkout/CheckoutComplete.tsx @@ -2,6 +2,7 @@ import type { CommerceCheckoutResource } from '@clerk/types'; import { useCheckoutContext } from '../../contexts'; import { Box, Button, Col, Flex, Icon, Text } from '../../customizables'; +import { LineItems } from '../../elements'; import { Check } from '../../icons'; import type { ThemableCssProp } from '../../styledSystem'; @@ -49,45 +50,35 @@ export const CheckoutComplete = ({ checkout, sx }: { checkout: CommerceCheckoutR borderTopColor: t.colors.$neutralAlpha100, })} > - - ({ fontWeight: t.fontWeights.$medium })}>Total paid - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}> - {checkout.invoice - ? `${checkout.invoice.totals.grandTotal.currencySymbol}${checkout.invoice.totals.grandTotal.amountFormatted}` - : '–'} - - - - ({ fontWeight: t.fontWeights.$medium })}>Payment method - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })}> - {checkout.paymentSource ? `${checkout.paymentSource.cardType} ⋯ ${checkout.paymentSource.last4}` : '–'} - - - - ({ fontWeight: t.fontWeights.$medium })}>Invoice ID - ({ fontSize: '0.875rem', fontWeight: t.fontWeights.$medium })} - > - {checkout.invoice ? checkout.invoice.id : '–'} - - + + + Total paid + + {checkout.invoice + ? `${checkout.invoice.totals.grandTotal.currencySymbol}${checkout.invoice.totals.grandTotal.amountFormatted}` + : '–'} + + + + Payment method + + {checkout.invoice + ? `${checkout.invoice.totals.grandTotal.currencySymbol}${checkout.invoice.totals.grandTotal.amountFormatted}` + : '–'} + + + + Invoice ID + + {checkout.invoice ? checkout.invoice.id : '–'} + + +