Skip to content

Commit df128bf

Browse files
committed
Open Share Modal after applying freewallets coupon (#5085)
## Problem solved Short description of the bug fixed or feature added <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces a new modal component, `ShareFreeWalletsModal`, to facilitate sharing free wallet offers via social media or email. It also updates the `CouponCard` to handle coupon applications and trigger the modal. ### Detailed summary - Added `ShareFreeWalletsModal` component for sharing options. - Created Storybook stories for `ShareFreeWalletsModal` in `share-free-wallets-modal.stories.tsx`. - Updated `ApplyCouponCard` to include an additional parameter for coupon application callback. - Integrated lazy loading for `ShareFreeWalletsModal` in `CouponCard`. - Implemented state management for modal visibility in `CouponSection`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent f2d1085 commit df128bf

File tree

3 files changed

+506
-31
lines changed

3 files changed

+506
-31
lines changed

apps/dashboard/src/components/settings/Account/Billing/CouponCard.tsx

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,24 @@ import { zodResolver } from "@hookform/resolvers/zod";
1616
import { useMutation, useQuery } from "@tanstack/react-query";
1717
import { format, fromUnixTime } from "date-fns";
1818
import { TagIcon } from "lucide-react";
19+
import dynamic from "next/dynamic";
1920
import { useSearchParams } from "next/navigation";
2021
import { Suspense, useEffect, useRef, useState } from "react";
2122
import { useForm } from "react-hook-form";
2223
import { toast } from "sonner";
2324
import { z } from "zod";
2425

26+
const LazyShareFreeWalletsModal = dynamic(
27+
() =>
28+
import("./share-free-wallets-modal.client").then(
29+
(mod) => mod.ShareFreeWalletsModal,
30+
),
31+
{
32+
ssr: false,
33+
loading: () => null,
34+
},
35+
);
36+
2537
export type ActiveCouponResponse = {
2638
id: string;
2739
start: number;
@@ -36,7 +48,10 @@ export type ActiveCouponResponse = {
3648

3749
function ApplyCouponCard(props: {
3850
teamId: string | undefined;
39-
onCouponApplied: (data: ActiveCouponResponse) => void;
51+
onCouponApplied: (
52+
data: ActiveCouponResponse,
53+
isFreeWalletsCoupon: boolean,
54+
) => void;
4055
isPaymentSetup: boolean;
4156
onAddPayment: () => void;
4257
}) {
@@ -87,7 +102,9 @@ export function ApplyCouponCardUI(props: {
87102
status: number;
88103
data: null | ActiveCouponResponse;
89104
}>;
90-
onCouponApplied: ((data: ActiveCouponResponse) => void) | undefined;
105+
onCouponApplied:
106+
| ((data: ActiveCouponResponse, isFreeWalletsCoupon: boolean) => void)
107+
| undefined;
91108
prefillPromoCode?: string;
92109
scrollIntoView?: boolean;
93110
isPaymentSetup: boolean;
@@ -130,7 +147,12 @@ export function ApplyCouponCardUI(props: {
130147
case 200: {
131148
toast.success("Coupon applied successfully");
132149
if (res.data) {
133-
props.onCouponApplied?.(res.data);
150+
props.onCouponApplied?.(
151+
res.data,
152+
// prod & dev
153+
values.promoCode === "FREEWALLETS" ||
154+
values.promoCode === "TESTFREEWALLETS",
155+
);
134156
}
135157
break;
136158
}
@@ -258,6 +280,7 @@ export function CouponSection(props: {
258280
isPaymentSetup: boolean;
259281
onAddPayment: () => void;
260282
}) {
283+
const [showShareModal, setShowShareModal] = useState(false);
261284
const loggedInUser = useLoggedInUser();
262285
const [optimisticCouponData, setOptimisticCouponData] = useState<
263286
| {
@@ -319,35 +342,46 @@ export function CouponSection(props: {
319342
? optimisticCouponData.data
320343
: activeCoupon.data;
321344

322-
if (couponData) {
323-
return (
324-
<CouponDetailsCardUI
325-
activeCoupon={couponData}
326-
deleteCoupon={{
327-
mutateAsync: deleteActiveCoupon.mutateAsync,
328-
isPending: deleteActiveCoupon.isPending,
329-
}}
330-
/>
331-
);
332-
}
333-
334345
return (
335-
<Suspense fallback={<LoadingCouponSection />}>
336-
<ApplyCouponCard
337-
teamId={props.teamId}
338-
onCouponApplied={(coupon) => {
339-
setOptimisticCouponData({
340-
type: "added",
341-
data: coupon,
342-
});
343-
activeCoupon.refetch().then(() => {
344-
setOptimisticCouponData(undefined);
345-
});
346-
}}
347-
isPaymentSetup={props.isPaymentSetup}
348-
onAddPayment={props.onAddPayment}
349-
/>
350-
</Suspense>
346+
<>
347+
{couponData ? (
348+
<CouponDetailsCardUI
349+
activeCoupon={couponData}
350+
deleteCoupon={{
351+
mutateAsync: deleteActiveCoupon.mutateAsync,
352+
isPending: deleteActiveCoupon.isPending,
353+
}}
354+
/>
355+
) : (
356+
<Suspense fallback={<LoadingCouponSection />}>
357+
<ApplyCouponCard
358+
teamId={props.teamId}
359+
onCouponApplied={(coupon, isFreeWalletsCoupon) => {
360+
setOptimisticCouponData({
361+
type: "added",
362+
data: coupon,
363+
});
364+
365+
if (isFreeWalletsCoupon) {
366+
setShowShareModal(true);
367+
}
368+
activeCoupon.refetch().then(() => {
369+
setOptimisticCouponData(undefined);
370+
});
371+
}}
372+
isPaymentSetup={props.isPaymentSetup}
373+
onAddPayment={props.onAddPayment}
374+
/>
375+
</Suspense>
376+
)}
377+
378+
{showShareModal && (
379+
<LazyShareFreeWalletsModal
380+
isOpen={showShareModal}
381+
onOpenChange={setShowShareModal}
382+
/>
383+
)}
384+
</>
351385
);
352386
}
353387

0 commit comments

Comments
 (0)