Skip to content

Commit 6086219

Browse files
committed
Show networkStatus badge in PartnerRowItem
1 parent 1e65ea2 commit 6086219

10 files changed

Lines changed: 103 additions & 134 deletions

File tree

apps/web/app/(ee)/api/partners/route.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { getPartners } from "@/lib/api/partners/get-partners";
33
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
44
import { getProgramOrThrow } from "@/lib/api/programs/get-program-or-throw";
55
import { parseRequestBody } from "@/lib/api/utils";
6-
import { applicationEventSchema } from "@/lib/application-events/schema";
76
import { withWorkspace } from "@/lib/auth";
87
import { throwIfPartnersLimitExceeded } from "@/lib/partners/throw-if-partners-limit-exceeded";
98
import { polyfillSocialMediaFields } from "@/lib/social-utils";
@@ -102,16 +101,11 @@ export const GET = withWorkspace(
102101
saleAmount: z.number().default(0),
103102
});
104103

105-
const responseSchema =
106-
parsedParams.includeApplicationEvent ||
107-
parsedParams.includePartnerPlatforms
108-
? baseSchema.extend({
109-
platforms: z.array(partnerPlatformSchema),
110-
applicationEvent: applicationEventSchema
111-
.pick({ referralSource: true })
112-
.nullish(),
113-
})
114-
: baseSchema;
104+
const responseSchema = parsedParams.includePartnerPlatforms
105+
? baseSchema.extend({
106+
platforms: z.array(partnerPlatformSchema),
107+
})
108+
: baseSchema;
115109

116110
return NextResponse.json(
117111
z.array(responseSchema).parse(

apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/analytics/applications/application-referral-source-icon.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import { Globe, Shop, UserArrowRight } from "@dub/ui/icons";
33

44
export function ApplicationReferralSourceIcon({
55
referralSource,
6+
className,
67
}: {
78
referralSource: string;
9+
className?: string;
810
}) {
911
switch (referralSource) {
1012
case "marketplace":
11-
return <Shop />;
13+
return <Shop className={className} />;
1214
case "direct":
13-
return <Globe />;
15+
return <Globe className={className} />;
1416
case "manual":
15-
return <UserArrowRight />;
17+
return <UserArrowRight className={className} />;
1618
default:
17-
return <ReferrerIcon display={referralSource} />;
19+
return <ReferrerIcon display={referralSource} className={className} />;
1820
}
1921
}

apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/applications/page-client.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ export function ProgramPartnersApplicationsPageClient() {
103103
status: "pending",
104104
sortBy,
105105
sortOrder,
106-
includeApplicationEvent: true,
107106
includePartnerPlatforms: true,
108107
},
109108
{ exclude: ["partnerId"] },
@@ -196,17 +195,6 @@ export function ProgramPartnersApplicationsPageClient() {
196195
header: "Applied",
197196
accessorFn: (d) => formatDate(d.createdAt, { month: "short" }),
198197
},
199-
// TODO: add source column back once we fix application source display
200-
// {
201-
// id: "source",
202-
// header: "Source",
203-
// minSize: 170,
204-
// cell: ({ row }) => (
205-
// <PartnerApplicationSource
206-
// referralSource={row.original.applicationEvent?.referralSource}
207-
// />
208-
// ),
209-
// },
210198
{
211199
id: "group",
212200
header: "Group",

apps/web/lib/api/partners/get-partners.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export async function getPartners(filters: PartnerFilters) {
1919
sortBy,
2020
sortOrder,
2121
programId,
22-
includeApplicationEvent,
2322
includePartnerPlatforms: _includePartnerPlatforms,
2423
includeGroup = false,
2524
...enrollmentRest
@@ -45,7 +44,6 @@ export async function getPartners(filters: PartnerFilters) {
4544
},
4645
},
4746
links: true,
48-
...(includeApplicationEvent ? { applicationEvent: true } : {}),
4947
...(includeGroup
5048
? {
5149
partnerGroup: {

apps/web/lib/zod/schemas/partners.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ export const getPartnersQuerySchemaExtended = getPartnersQuerySchema.extend({
212212
country: z.union([z.string(), z.array(z.string())]).optional(),
213213
referredByPartnerId: z.string().optional(),
214214
includePartnerPlatforms: booleanQuerySchema.optional(),
215-
includeApplicationEvent: booleanQuerySchema.optional(),
216215
// metric range query fields (TODO: Add to public API once we finalize the syntax)
217216
totalClicksMin: z.coerce
218217
.number()
@@ -593,11 +592,6 @@ export const EnrolledPartnerSchemaExtended = EnrolledPartnerSchema.extend({
593592
customerDataSharingEnabledAt: z.date().nullish(),
594593
groupMoveDisabledAt: z.date().nullish(),
595594
platforms: z.array(partnerPlatformSchema).nullable(),
596-
applicationEvent: z
597-
.object({
598-
referralSource: z.string(),
599-
})
600-
.nullish(),
601595
discount: DiscountSchema.pick({
602596
id: true,
603597
provider: true,

apps/web/ui/partners/partner-application-source.tsx

Lines changed: 0 additions & 59 deletions
This file was deleted.

apps/web/ui/partners/partner-info-cards.tsx

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {
4646
} from "./fraud-risks/partner-fraud-banner";
4747
import { PartnerFraudIndicator } from "./fraud-risks/partner-fraud-indicator";
4848
import { PartnerAvatar } from "./partner-avatar";
49+
import { PartnerNetworkStatusBadge } from "./partner-network/partner-network-status-badge";
4950
import { PartnerInfoGroup } from "./partner-info-group";
5051
import { PartnerStarButton } from "./partner-star-button";
5152
import { PartnerStatusBadgeWithTooltip } from "./partner-status-badge-with-tooltip";
@@ -154,8 +155,6 @@ export function PartnerInfoCards({
154155
if ((isEnrolled || isAdmin) && partner) {
155156
const isPendingApplication =
156157
"status" in partner && partner.status === "pending";
157-
const applicationReferralSource =
158-
isEnrolled && partner.applicationEvent?.referralSource;
159158

160159
basicFields = basicFields.concat([
161160
{
@@ -175,24 +174,11 @@ export function PartnerInfoCards({
175174
>
176175
<span>Applied {formatDate(partner.createdAt)}</span>
177176
</TimestampTooltip>
178-
{/* TODO: add source column back once we fix application source display */}
179-
{/* {applicationReferralSource && (
180-
<>
181-
<span>via</span>
182-
<PartnerApplicationSource
183-
referralSource={applicationReferralSource}
184-
variant="inline"
185-
/>
186-
</>
187-
)} */}
188177
</span>
189178
) : (
190179
`${isPendingApplication ? "Applied" : "Partner since"} ${formatDate(partner.createdAt)}`
191180
),
192-
timestamp:
193-
isPendingApplication && applicationReferralSource
194-
? undefined
195-
: partner.createdAt,
181+
timestamp: isPendingApplication ? undefined : partner.createdAt,
196182
},
197183
{
198184
id: "payoutMethod" as const,
@@ -306,6 +292,12 @@ export function PartnerInfoCards({
306292
{partner.name}
307293
</span>
308294

295+
{"networkStatus" in partner && partner.networkStatus && (
296+
<PartnerNetworkStatusBadge
297+
networkStatus={partner.networkStatus}
298+
/>
299+
)}
300+
309301
{showFraudIndicator && (
310302
<PartnerFraudIndicator partnerId={partner.id} />
311303
)}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { PartnerNetworkStatus } from "@dub/prisma/client";
2+
import { BadgeCheck2Fill, Tooltip } from "@dub/ui";
3+
import { TrustedPartnerBadge } from "../trusted-partner-badge";
4+
5+
export function PartnerNetworkStatusBadge({
6+
networkStatus,
7+
}: {
8+
networkStatus: PartnerNetworkStatus;
9+
}) {
10+
if (networkStatus === "trusted") {
11+
return <TrustedPartnerBadge variant="inline" />;
12+
}
13+
14+
if (networkStatus === "approved") {
15+
return (
16+
<Tooltip
17+
content={
18+
<div className="flex max-w-xs items-start gap-1.5 p-3">
19+
<BadgeCheck2Fill className="mt-0.5 size-5 shrink-0 text-blue-500" />
20+
<div className="flex flex-col gap-1">
21+
<span className="text-sm font-semibold text-neutral-900">
22+
Approved Partner
23+
</span>
24+
<span className="text-sm font-normal text-neutral-600">
25+
This partner is approved in the Dub Partner Network.
26+
</span>
27+
</div>
28+
</div>
29+
}
30+
>
31+
<BadgeCheck2Fill className="size-3.5 shrink-0 text-blue-500" />
32+
</Tooltip>
33+
);
34+
}
35+
36+
return null;
37+
}

apps/web/ui/partners/partner-row-item.tsx

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import useProgram from "@/lib/swr/use-program";
2-
import { PartnerPayoutMethod } from "@dub/prisma/client";
2+
import { PartnerNetworkStatus, PartnerPayoutMethod } from "@dub/prisma/client";
33
import { CircleArrowRight, DynamicTooltipWrapper, GreekTemple } from "@dub/ui";
44
import { cn, formatDateTimeSmart } from "@dub/utils";
55
import { CircleMinus } from "lucide-react";
66
import Link from "next/link";
77
import { useParams } from "next/navigation";
88
import type { ReactNode } from "react";
99
import { PartnerFraudIndicator } from "./fraud-risks/partner-fraud-indicator";
10+
import { PartnerNetworkStatusBadge } from "./partner-network/partner-network-status-badge";
1011
import { PartnerAvatar } from "./partner-avatar";
1112
import {
1213
getPayoutMethodIconConfig,
@@ -21,6 +22,7 @@ interface PartnerRowItemProps {
2122
id: string;
2223
name: string;
2324
image?: string | null;
25+
networkStatus?: PartnerNetworkStatus | null;
2426
defaultPayoutMethod?: PartnerPayoutMethod | null;
2527
payoutsEnabledAt?: Date | null;
2628
};
@@ -208,19 +210,25 @@ export function PartnerRowItem({
208210
</DynamicTooltipWrapper>
209211
</div>
210212

211-
<As
212-
href={`/${slug}/program/partners/${partner.id}`}
213-
{...(showPermalink && { target: "_blank" })}
214-
onClick={showPermalink ? (e) => e.stopPropagation() : undefined}
215-
onAuxClick={showPermalink ? (e) => e.stopPropagation() : undefined}
216-
className={cn(
217-
"min-w-0 truncate",
218-
showPermalink && "cursor-alias decoration-dotted hover:underline",
213+
<div className="flex min-w-0 items-center gap-1">
214+
<As
215+
href={`/${slug}/program/partners/${partner.id}`}
216+
{...(showPermalink && { target: "_blank" })}
217+
onClick={showPermalink ? (e) => e.stopPropagation() : undefined}
218+
onAuxClick={showPermalink ? (e) => e.stopPropagation() : undefined}
219+
className={cn(
220+
"min-w-0 truncate",
221+
showPermalink && "cursor-alias decoration-dotted hover:underline",
222+
)}
223+
title={partner.name}
224+
>
225+
{partner.name}
226+
</As>
227+
228+
{"networkStatus" in partner && partner.networkStatus && (
229+
<PartnerNetworkStatusBadge networkStatus={partner.networkStatus} />
219230
)}
220-
title={partner.name}
221-
>
222-
{partner.name}
223-
</As>
231+
</div>
224232

225233
{suffix}
226234

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
import { Tooltip } from "@dub/ui";
2+
import { cn } from "@dub/utils";
3+
4+
const TRUSTED_BADGE_SRC = "https://assets.dub.co/icons/trusted-badge.svg";
5+
6+
export function TrustedPartnerBadge({
7+
variant = "overlay",
8+
}: {
9+
variant?: "overlay" | "inline";
10+
}) {
11+
const badge = (
12+
<img
13+
alt="Trusted partner badge"
14+
src={TRUSTED_BADGE_SRC}
15+
className={cn("shrink-0", variant === "inline" ? "size-3.5" : "size-6")}
16+
/>
17+
);
218

3-
export function TrustedPartnerBadge() {
419
return (
520
<Tooltip
621
content={
7-
<div className="flex max-w-xs items-start gap-2 p-3">
22+
<div className="flex max-w-xs items-start gap-1.5 p-3">
823
<img
924
alt="Trusted partner badge"
10-
src="https://assets.dub.co/icons/trusted-badge.svg"
11-
className="size-6 shrink-0"
25+
src={TRUSTED_BADGE_SRC}
26+
className="size-5 shrink-0"
1227
/>
1328
<div className="flex flex-col gap-1">
1429
<span className="text-sm font-semibold text-neutral-900">
@@ -22,13 +37,13 @@ export function TrustedPartnerBadge() {
2237
</div>
2338
}
2439
>
25-
<div className="absolute -bottom-1 -right-1 overflow-hidden transition-transform duration-100 hover:scale-[1.15]">
26-
<img
27-
alt="Trusted partner badge"
28-
src="https://assets.dub.co/icons/trusted-badge.svg"
29-
className="size-6"
30-
/>
31-
</div>
40+
{variant === "inline" ? (
41+
<span className="shrink-0">{badge}</span>
42+
) : (
43+
<div className="absolute -bottom-1 -right-1 overflow-hidden transition-transform duration-100 hover:scale-[1.15]">
44+
{badge}
45+
</div>
46+
)}
3247
</Tooltip>
3348
);
3449
}

0 commit comments

Comments
 (0)