Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions apps/web/app/(ee)/api/programs/[programId]/discounts/route.ts

This file was deleted.

30 changes: 0 additions & 30 deletions apps/web/app/(ee)/api/programs/[programId]/rewards/route.ts

This file was deleted.

2 changes: 0 additions & 2 deletions apps/web/app/(ee)/api/programs/[programId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ export const GET = withWorkspace(
programId: params.programId,
},
{
includeDefaultDiscount: true,
includeDefaultRewards: true,
includeLanderData: includeLanderData || false,
},
);
Expand Down
43 changes: 15 additions & 28 deletions apps/web/lib/actions/partners/create-program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import { toltImporter } from "@/lib/tolt/importer";
import { WorkspaceProps } from "@/lib/types";
import { DEFAULT_PARTNER_GROUP } from "@/lib/zod/schemas/groups";
import { programDataSchema } from "@/lib/zod/schemas/program-onboarding";
import { REWARD_EVENT_COLUMN_MAPPING } from "@/lib/zod/schemas/rewards";
import { sendEmail } from "@dub/email";
import PartnerInvite from "@dub/email/templates/partner-invite";
import ProgramWelcome from "@dub/email/templates/program-welcome";
import { prisma } from "@dub/prisma";
import { generateRandomString, nanoid, R2_URL } from "@dub/utils";
import { Program, Project, Reward, User } from "@prisma/client";
import { Program, Project, User } from "@prisma/client";
import { waitUntil } from "@vercel/functions";
import { redirect } from "next/navigation";

Expand Down Expand Up @@ -83,12 +84,19 @@ export const createProgram = async ({
const programId = createId({ prefix: "prog_" });
const defaultGroupId = createId({ prefix: "grp_" });

const logoUrl = uploadedLogo
? await storage
.upload(`programs/${programId}/logo_${nanoid(7)}`, uploadedLogo)
.then(({ url }) => url)
: null;

const programData = await tx.program.create({
data: {
id: programId,
workspaceId: workspace.id,
name,
slug: workspace.slug,
...(logoUrl && { logo: logoUrl }),
domain,
url,
defaultFolderId: programFolder.id,
Expand All @@ -106,7 +114,6 @@ export const createProgram = async ({
amount,
maxDuration,
event: defaultRewardType,
default: true,
},
},
}),
Expand All @@ -116,6 +123,8 @@ export const createProgram = async ({
},
});

const createdReward = programData.rewards?.[0];

await tx.partnerGroup.upsert({
where: {
programId_slug: {
Expand All @@ -129,6 +138,9 @@ export const createProgram = async ({
slug: DEFAULT_PARTNER_GROUP.slug,
name: DEFAULT_PARTNER_GROUP.name,
color: DEFAULT_PARTNER_GROUP.color,
...(createdReward && {
[REWARD_EVENT_COLUMN_MAPPING[createdReward.event]]: createdReward.id,
}),
},
update: {}, // noop
});
Expand Down Expand Up @@ -156,12 +168,6 @@ export const createProgram = async ({
return programData;
});

const logoUrl = uploadedLogo
? await storage
.upload(`programs/${program.id}/logo_${nanoid(7)}`, uploadedLogo)
.then(({ url }) => url)
: null;

// Start the import process if the import source is set
if (importSource === "rewardful" && rewardful?.id) {
await rewardfulImporter.queue({
Expand All @@ -188,8 +194,6 @@ export const createProgram = async ({
});
}

const reward = program.rewards?.[0];

waitUntil(
Promise.allSettled([
// invite partners
Expand All @@ -198,23 +202,12 @@ export const createProgram = async ({
invitePartner({
workspace,
program,
reward,
partner,
userId: user.id,
}),
)
: []),

// update the program with the logo and default reward
prisma.program.update({
where: {
id: program.id,
},
data: {
...(logoUrl && { logo: logoUrl }),
},
}),

// delete the temporary uploaded logo
uploadedLogo &&
isStored(uploadedLogo) &&
Expand All @@ -227,10 +220,7 @@ export const createProgram = async ({
react: ProgramWelcome({
email: user.email!,
workspace,
program: {
...program,
logo: logoUrl,
},
program,
}),
}),

Expand All @@ -257,13 +247,11 @@ export const createProgram = async ({
// Invite a partner to the program
async function invitePartner({
program,
reward,
workspace,
partner,
userId,
}: {
program: Program;
reward?: Pick<Reward, "id" | "event">;
workspace: Pick<Project, "id" | "plan" | "webhookEnabled">;
partner: {
email: string;
Expand All @@ -290,7 +278,6 @@ async function invitePartner({
},
skipEnrollmentCheck: true,
status: "invited",
...(reward && { reward }),
});

waitUntil(
Expand Down
2 changes: 1 addition & 1 deletion apps/web/lib/actions/partners/invite-partner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const invitePartnerAction = authActionClient
},
skipEnrollmentCheck: true,
status: "invited",
groupId: groupId || program.defaultGroupId,
groupId,
});

waitUntil(
Expand Down
1 change: 0 additions & 1 deletion apps/web/lib/actions/partners/update-program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ export const updateProgramAction = authActionClient
? [
revalidatePath(`/partners.dub.co/${program.slug}`),
revalidatePath(`/partners.dub.co/${program.slug}/apply`),
revalidatePath(`/partners.dub.co/${program.slug}/apply/form`),
revalidatePath(`/partners.dub.co/${program.slug}/apply/success`),
]
: []),
Expand Down
77 changes: 21 additions & 56 deletions apps/web/lib/api/partners/create-and-enroll-partner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import {
CreatePartnerProps,
ProgramPartnerLinkProps,
ProgramProps,
RewardProps,
WorkspaceProps,
} from "@/lib/types";
import { sendWorkspaceWebhook } from "@/lib/webhook/publish";
import { EnrolledPartnerSchema } from "@/lib/zod/schemas/partners";
import { REWARD_EVENT_COLUMN_MAPPING } from "@/lib/zod/schemas/rewards";
import { prisma } from "@dub/prisma";
import { Prisma, ProgramEnrollmentStatus } from "@dub/prisma/client";
import { nanoid } from "@dub/utils";
Expand All @@ -28,13 +26,11 @@ export const createAndEnrollPartner = async ({
workspace,
link,
partner,
reward,
discountId,
tenantId,
groupId,
status = "approved",
skipEnrollmentCheck = false,
enrolledAt,
groupId,
}: {
program: Pick<ProgramProps, "id" | "defaultFolderId" | "defaultGroupId">;
workspace: Pick<WorkspaceProps, "id" | "webhookEnabled">;
Expand All @@ -43,13 +39,11 @@ export const createAndEnrollPartner = async ({
CreatePartnerProps,
"email" | "name" | "image" | "country" | "description"
>;
reward?: Pick<RewardProps, "id" | "event">;
discountId?: string;
tenantId?: string;
groupId?: string | null;
status?: ProgramEnrollmentStatus;
skipEnrollmentCheck?: boolean;
enrolledAt?: Date;
groupId?: string | null;
}) => {
if (!skipEnrollmentCheck && partner.email) {
const programEnrollment = await prisma.programEnrollment.findFirst({
Expand Down Expand Up @@ -88,44 +82,21 @@ export const createAndEnrollPartner = async ({
}
}

const [defaultRewards, allDiscounts, group] = await Promise.all([
prisma.reward.findMany({
where: {
programId: program.id,
// if a specific reward is provided, exclude it from the default rewards because it'll be added below
...(reward && {
event: {
not: reward.event,
},
}),
default: true,
},
}),

prisma.discount.findMany({
where: {
programId: program.id,
},
}),

getGroupOrThrow({
programId: program.id,
groupId: groupId || program.defaultGroupId!,
}),
]);

const finalAssignedRewards = {
...Object.fromEntries(
defaultRewards.map((r) => [REWARD_EVENT_COLUMN_MAPPING[r.event], r.id]),
),
...(reward && {
[REWARD_EVENT_COLUMN_MAPPING[reward.event]]: reward.id,
}),
};
const finalGroupId = groupId || program.defaultGroupId;
// this should never happen, but just in case
if (!finalGroupId) {
throw new DubApiError({
message:
"There was no group ID provided, and the program does not have a default group. Please contact support.",
code: "bad_request",
});
}

const finalAssignedDiscount = discountId
? allDiscounts.find((d) => d.id === discountId)?.id // we need to filter by this in case an invalid discountId is passed
: allDiscounts.find((d) => d.default)?.id;
const group = await getGroupOrThrow({
programId: program.id,
groupId: finalGroupId,
includeRewardsAndDiscount: true,
});

const payload: Pick<Prisma.PartnerUpdateInput, "programs"> = {
programs: {
Expand All @@ -138,20 +109,14 @@ export const createAndEnrollPartner = async ({
id: link.id,
},
},
...finalAssignedRewards,
...(finalAssignedDiscount && {
discountId: finalAssignedDiscount,
}),
groupId: group.id,
clickRewardId: group.clickRewardId,
leadRewardId: group.leadRewardId,
saleRewardId: group.saleRewardId,
discountId: group.discountId,
...(enrolledAt && {
createdAt: enrolledAt,
}),
...(group && {
groupId: group.id,
clickRewardId: group.clickRewardId,
leadRewardId: group.leadRewardId,
saleRewardId: group.saleRewardId,
discountId: group.discountId,
}),
},
},
};
Expand Down
Loading