diff --git a/apps/admin-x-design-system/src/assets/icons/layout-headline.svg b/apps/admin-x-design-system/src/assets/icons/layout-headline.svg new file mode 100644 index 0000000000..7a6cfeed7e --- /dev/null +++ b/apps/admin-x-design-system/src/assets/icons/layout-headline.svg @@ -0,0 +1 @@ +layout-headline \ No newline at end of file diff --git a/apps/admin-x-design-system/src/assets/icons/layout-module-1.svg b/apps/admin-x-design-system/src/assets/icons/layout-module-1.svg new file mode 100644 index 0000000000..88d8b62e05 --- /dev/null +++ b/apps/admin-x-design-system/src/assets/icons/layout-module-1.svg @@ -0,0 +1 @@ +layout-module-1 \ No newline at end of file diff --git a/apps/admin-x-settings/src/components/settings/membership/offers/OffersModal.tsx b/apps/admin-x-settings/src/components/settings/membership/offers/OffersModal.tsx index b142a46e43..6504893ab8 100644 --- a/apps/admin-x-settings/src/components/settings/membership/offers/OffersModal.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/offers/OffersModal.tsx @@ -15,12 +15,19 @@ const createRedemptionFilterUrl = (id: string): string => { return `${baseHref}?filter=${encodeURIComponent('offer_redemptions:' + id)}`; }; -const OfferCard: React.FC<{amount: number, cadence: string, currency: string, duration: string, name: string, offerId: string, offerTier: Tier | undefined, redemptionCount: number, type: OfferType, onClick: ()=>void}> = ({amount, cadence, currency, duration, name, offerId, offerTier, redemptionCount, type, onClick}) => { +const getOfferCadence = (cadence: string): string => { + return cadence === 'month' ? 'monthly' : 'yearly'; +}; + +const getOfferDuration = (duration: string): string => { + return (duration === 'once' ? 'First payment' : duration === 'repeating' ? 'Repeating' : 'Forever'); +}; + +const getOfferDiscount = (type: string, amount: number, cadence: string, currency: string, tier: Tier | undefined): {discountColor: string, discountOffer: string, originalPriceWithCurrency: string, updatedPriceWithCurrency: string} => { let discountColor = ''; let discountOffer = ''; - const originalPrice = cadence === 'month' ? offerTier?.monthly_price ?? 0 : offerTier?.yearly_price ?? 0; + const originalPrice = cadence === 'month' ? tier?.monthly_price ?? 0 : tier?.yearly_price ?? 0; let updatedPrice = originalPrice; - let tierName = offerTier?.name + ' ' + (cadence === 'month' ? 'Monthly' : 'Yearly') + ' — ' + (duration === 'once' ? 'First payment' : duration === 'repeating' ? 'Repeating' : 'Forever'); let originalPriceWithCurrency = getSymbol(currency) + numberWithCommas(currencyToDecimal(originalPrice)); switch (type) { @@ -41,10 +48,22 @@ const OfferCard: React.FC<{amount: number, cadence: string, currency: string, du break; default: break; - } + }; const updatedPriceWithCurrency = getSymbol(currency) + numberWithCommas(currencyToDecimal(updatedPrice)); + return { + discountColor, + discountOffer, + originalPriceWithCurrency, + updatedPriceWithCurrency + }; +}; + +const OfferCard: React.FC<{amount: number, cadence: string, currency: string, duration: string, name: string, offerId: string, offerTier: Tier | undefined, redemptionCount: number, type: OfferType, onClick: ()=>void}> = ({amount, cadence, currency, duration, name, offerId, offerTier, redemptionCount, type, onClick}) => { + let tierName = offerTier?.name + ' ' + getOfferCadence(cadence) + ' — ' + getOfferDuration(duration); + const {discountColor, discountOffer, originalPriceWithCurrency, updatedPriceWithCurrency} = getOfferDiscount(type, amount, cadence, currency || 'USD', offerTier); + return (
@@ -87,6 +106,7 @@ const OffersModal = () => { {id: 'archived', title: 'Archived'} ]; const [selectedTab, setSelectedTab] = useState('active'); + const [selectedLayout, setSelectedLayout] = useState('card'); const handleOfferEdit = (id:string) => { // TODO: implement @@ -94,6 +114,54 @@ const OffersModal = () => { updateRoute(`offers/${id}`); }; + const cardLayoutOutput =
+ {allOffers.filter(offer => offer.status === selectedTab).map((offer) => { + const offerTier = paidActiveTiers.find(tier => tier.id === offer?.tier.id); + + if (!offerTier) { + return null; + } + + return ( + handleOfferEdit(offer?.id)} + /> + ); + })} +
; + + const listLayoutOutput = + {allOffers.filter(offer => offer.status === selectedTab).map((offer) => { + const offerTier = paidActiveTiers.find(tier => tier.id === offer?.tier.id); + + if (!offerTier) { + return null; + } + + const {discountColor, discountOffer, originalPriceWithCurrency, updatedPriceWithCurrency} = getOfferDiscount(offer.type, offer.amount, offer.cadence, offer.currency || 'USD', offerTier); + + return ( + + + + + + + + ); + })} +
{offer?.name}{offerTier.name} {getOfferCadence(offer.cadence)}{discountOffer}{updatedPriceWithCurrency}{originalPriceWithCurrency}{offer.redemption_count}
; + return { updateRoute('offers'); @@ -109,6 +177,7 @@ const OffersModal = () => {
} header={false} + height='full' size='lg' testId='offers-modal' stickyFooter @@ -125,33 +194,15 @@ const OffersModal = () => { />
-

{offersTabs.find(tab => tab.id === selectedTab)?.title} offers

+
+

{offersTabs.find(tab => tab.id === selectedTab)?.title} offers

+
+
+
-
- {allOffers.filter(offer => offer.status === selectedTab).map((offer) => { - const offerTier = paidActiveTiers.find(tier => tier.id === offer?.tier.id); - - if (!offerTier) { - return null; - } - - return ( - handleOfferEdit(offer?.id)} - /> - ); - })} -
+ {selectedLayout === 'card' ? cardLayoutOutput : listLayoutOutput} ; };