diff --git a/apps/web/app/api/embed/leaderboard/route.ts b/apps/web/app/api/embed/leaderboard/route.ts new file mode 100644 index 0000000000..09b59449d2 --- /dev/null +++ b/apps/web/app/api/embed/leaderboard/route.ts @@ -0,0 +1,40 @@ +import { withEmbedToken } from "@/lib/embed/auth"; +import { LeaderboardPartnerSchema } from "@/lib/zod/schemas/partners"; +import { prisma } from "@dub/prisma"; +import { NextResponse } from "next/server"; +import z from "node_modules/zod/lib"; + +// GET /api/embed/sales – get sales for a link from an embed token +export const GET = withEmbedToken(async ({ program, searchParams }) => { + const programEnrollments = await prisma.programEnrollment.findMany({ + where: { + programId: program.id, + }, + orderBy: [ + { + link: { + saleAmount: "desc", + }, + }, + { + link: { + leads: "desc", + }, + }, + { + link: { + clicks: "desc", + }, + }, + ], + select: { + partner: true, + link: true, + }, + take: 10, + }); + + return NextResponse.json( + z.array(LeaderboardPartnerSchema).parse(programEnrollments), + ); +}); diff --git a/apps/web/app/api/embed/sales/route.ts b/apps/web/app/api/embed/sales/route.ts index 720b209116..7ea7b25dd9 100644 --- a/apps/web/app/api/embed/sales/route.ts +++ b/apps/web/app/api/embed/sales/route.ts @@ -1,11 +1,16 @@ import { withEmbedToken } from "@/lib/embed/auth"; +import { SALES_PAGE_SIZE } from "@/lib/partners/constants"; import z from "@/lib/zod"; import { PartnerSaleResponseSchema } from "@/lib/zod/schemas/partners"; import { prisma } from "@dub/prisma"; import { NextResponse } from "next/server"; // GET /api/embed/sales – get sales for a link from an embed token -export const GET = withEmbedToken(async ({ link }) => { +export const GET = withEmbedToken(async ({ link, searchParams }) => { + const { page } = z + .object({ page: z.coerce.number().optional().default(1) }) + .parse(searchParams); + const sales = await prisma.sale.findMany({ where: { linkId: link.id, @@ -25,7 +30,8 @@ export const GET = withEmbedToken(async ({ link }) => { }, }, }, - take: 3, + take: SALES_PAGE_SIZE, + skip: (page - 1) * SALES_PAGE_SIZE, orderBy: { createdAt: "desc", }, diff --git a/apps/web/app/api/workspaces/[idOrSlug]/billing/upgrade/route.ts b/apps/web/app/api/workspaces/[idOrSlug]/billing/upgrade/route.ts index e1a0b05063..95ae990915 100644 --- a/apps/web/app/api/workspaces/[idOrSlug]/billing/upgrade/route.ts +++ b/apps/web/app/api/workspaces/[idOrSlug]/billing/upgrade/route.ts @@ -1,4 +1,5 @@ import { withWorkspace } from "@/lib/auth"; +import { getDubCustomer } from "@/lib/dub"; import { stripe } from "@/lib/stripe"; import { APP_DOMAIN } from "@dub/utils"; import { NextResponse } from "next/server"; @@ -46,6 +47,10 @@ export const POST = withWorkspace(async ({ req, workspace, session }) => { }); return NextResponse.json({ url }); } else { + const customer = await getDubCustomer(session.user.id); + const isReferral = + customer?.link?.programId === "prog_d8pl69xXCv4AoHNT281pHQdo"; + // For both new users and users with canceled subscriptions const stripeSession = await stripe.checkout.sessions.create({ ...(workspace.stripeId @@ -64,7 +69,18 @@ export const POST = withWorkspace(async ({ req, workspace, session }) => { success_url: `${APP_DOMAIN}/${workspace.slug}?${onboarding ? "onboarded" : "upgraded"}=true&plan=${plan}&period=${period}`, cancel_url: baseUrl, line_items: [{ price: prices.data[0].id, quantity: 1 }], - allow_promotion_codes: true, + ...(isReferral + ? { + discounts: [ + { + coupon: + process.env.NODE_ENV === "production" + ? "pEVpzGQE" + : "k8v8KtqG", + }, + ], + } + : { allow_promotion_codes: true }), automatic_tax: { enabled: true, }, diff --git a/apps/web/app/app.dub.co/embed/activity.tsx b/apps/web/app/app.dub.co/embed/activity.tsx index 2e848c1336..0ca76ac4e8 100644 --- a/apps/web/app/app.dub.co/embed/activity.tsx +++ b/apps/web/app/app.dub.co/embed/activity.tsx @@ -1,30 +1,44 @@ -import { currencyFormatter, nFormatter } from "@dub/utils"; +import { InfoTooltip } from "@dub/ui"; +import { nFormatter } from "@dub/utils"; -export function Activity({ +export function EmbedActivity({ clicks, leads, - earnings, + sales, }: { clicks: number; leads: number; - earnings: number; + sales: number; }) { return ( -
Powered by
Payouts
+- To withdraw your earnings or view all of your sales, create a free - Dub partner account below. -
- )} -- No sales yet. When you refer a friend and they make a purchase, they'll - show up here. -
-+ No sales yet. When you refer a friend and they make a purchase, + they'll show up here. +
+