From 52e51209d220ba85db57282243d5c8df4fbeb2bd Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Wed, 2 Jul 2025 17:18:59 -0700 Subject: [PATCH 1/4] Allow updating partner email --- .../(dashboard)/profile/page-client.tsx | 110 +++++++++++++----- .../partners/update-partner-profile.ts | 51 +++++--- 2 files changed, 112 insertions(+), 49 deletions(-) diff --git a/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx b/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx index 5a2f7281e4f..16633cde9bb 100644 --- a/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx +++ b/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx @@ -12,6 +12,7 @@ import { Button, buttonVariants, DotsPattern, + DynamicTooltipWrapper, FileUpload, LoadingSpinner, ToggleGroup, @@ -89,6 +90,7 @@ function FormWrapper({ type ProfileFormData = { name: string; + email: string; image: string | null; description: string | null; country: string; @@ -103,6 +105,7 @@ function FormProvider({ const form = useForm({ defaultValues: { name: partner.name, + email: partner.email ?? "", image: partner.image, description: partner.description ?? null, country: partner.country ?? "", @@ -115,6 +118,8 @@ function FormProvider({ } function Controls({ formRef }: { formRef: RefObject }) { + const { partner } = usePartnerProfile(); + const { MergePartnerAccountsModal, setShowMergePartnerAccountsModal } = useMergePartnerAccountsModal(); @@ -135,7 +140,19 @@ function Controls({ formRef }: { formRef: RefObject }) { text="Save changes" className="h-8 w-fit px-2.5" loading={isSubmitting} - onClick={() => formRef.current?.requestSubmit()} + onClick={() => { + if (partner?.stripeConnectId) { + const confirmed = window.confirm( + "Updating your email, country, or profile type will reset your Stripe account, which will require you to restart the payouts connection process. Are you sure you want to continue?", + ); + + if (!confirmed) { + return; + } + } + + formRef.current?.requestSubmit(); + }} /> ); @@ -186,6 +203,7 @@ function ProfileForm({
{ + console.log({ data }); const imageChanged = data.image !== partner.image; await executeAsync({ @@ -252,29 +270,57 @@ function ProfileForm({ /> + @@ -378,14 +434,6 @@ function ProfileForm({ - {/*
-
*/}
); } diff --git a/apps/web/lib/actions/partners/update-partner-profile.ts b/apps/web/lib/actions/partners/update-partner-profile.ts index 9bffa2db3f1..2d73649f13d 100644 --- a/apps/web/lib/actions/partners/update-partner-profile.ts +++ b/apps/web/lib/actions/partners/update-partner-profile.ts @@ -19,6 +19,7 @@ import { authPartnerActionClient } from "../safe-action"; const updatePartnerProfileSchema = z .object({ name: z.string(), + email: z.string().email(), image: uploadedImageSchema.nullish(), description: z.string().nullable(), country: z.enum(Object.keys(COUNTRIES) as [string, ...string[]]).nullable(), @@ -48,8 +49,17 @@ export const updatePartnerProfileAction = authPartnerActionClient .schema(updatePartnerProfileSchema) .action(async ({ ctx, parsedInput }) => { const { partner } = ctx; - const { name, image, description, country, profileType, companyName } = - parsedInput; + const { + name, + email, + image, + description, + country, + profileType, + companyName, + } = parsedInput; + + const emailChanged = partner.email !== email; const countryChanged = partner.country?.toLowerCase() !== country?.toLowerCase(); @@ -60,7 +70,13 @@ export const updatePartnerProfileAction = authPartnerActionClient const companyNameChanged = partner.companyName?.toLowerCase() !== companyName?.toLowerCase(); - if (countryChanged || profileTypeChanged || companyNameChanged) { + if ( + (emailChanged || + countryChanged || + profileTypeChanged || + companyNameChanged) && + partner.stripeConnectId + ) { // Partner is only able to update their country, profile type, or company name // as long as they don't have any completed payouts const completedPayoutsCount = await prisma.payout.count({ @@ -72,24 +88,22 @@ export const updatePartnerProfileAction = authPartnerActionClient if (completedPayoutsCount > 0) { throw new Error( - "Since you've already received payouts on Dub, you cannot change your country or profile type. Please contact support to update those fields.", + "Since you've already received payouts on Dub, you cannot change your email, country or profile type. Please contact support to update those fields.", ); } - if (partner.stripeConnectId) { - const response = await stripe.accounts.del(partner.stripeConnectId); - - if (response.deleted) { - await prisma.partner.update({ - where: { - id: partner.id, - }, - data: { - stripeConnectId: null, - payoutsEnabledAt: null, - }, - }); - } + const response = await stripe.accounts.del(partner.stripeConnectId); + + if (response.deleted) { + await prisma.partner.update({ + where: { + id: partner.id, + }, + data: { + stripeConnectId: null, + payoutsEnabledAt: null, + }, + }); } } @@ -108,6 +122,7 @@ export const updatePartnerProfileAction = authPartnerActionClient }, data: { name, + email, description, ...(imageUrl && { image: imageUrl }), country, From e405ed747835117e7769a5c450e5e3d8603bd25f Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Wed, 2 Jul 2025 17:20:25 -0700 Subject: [PATCH 2/4] Update update-partner-profile.ts --- apps/web/lib/actions/partners/update-partner-profile.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/web/lib/actions/partners/update-partner-profile.ts b/apps/web/lib/actions/partners/update-partner-profile.ts index 2d73649f13d..8f6b736ce51 100644 --- a/apps/web/lib/actions/partners/update-partner-profile.ts +++ b/apps/web/lib/actions/partners/update-partner-profile.ts @@ -75,10 +75,11 @@ export const updatePartnerProfileAction = authPartnerActionClient countryChanged || profileTypeChanged || companyNameChanged) && - partner.stripeConnectId + partner.stripeConnectId && + partner.payoutsEnabledAt ) { - // Partner is only able to update their country, profile type, or company name - // as long as they don't have any completed payouts + // Partner is not able to update their country, profile type, or company name + // if they have a verified Stripe Express account + any completed payouts const completedPayoutsCount = await prisma.payout.count({ where: { partnerId: partner.id, From 31c92793f7436517143408aa663d95cdb4682728 Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Wed, 2 Jul 2025 17:26:09 -0700 Subject: [PATCH 3/4] Update page-client.tsx --- .../app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx b/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx index 16633cde9bb..b9e3978a902 100644 --- a/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx +++ b/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx @@ -203,7 +203,6 @@ function ProfileForm({
{ - console.log({ data }); const imageChanged = data.image !== partner.image; await executeAsync({ From 2aa48e22952891e58e6ea89311fe67aa055aa61f Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Wed, 2 Jul 2025 17:26:22 -0700 Subject: [PATCH 4/4] Update page-client.tsx --- .../(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx b/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx index b9e3978a902..f6e5765477b 100644 --- a/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx +++ b/apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx @@ -285,7 +285,7 @@ function ProfileForm({ type="email" className={cn( "block w-full rounded-md focus:outline-none sm:text-sm", - errors.name + errors.email ? "border-red-300 pr-10 text-red-900 placeholder-red-300 focus:border-red-500 focus:ring-red-500" : "border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:ring-neutral-500", completedPayoutsCount > 0 &&