Skip to content

Commit 05b9c87

Browse files
authored
Small miscellaneous fixes (dubinc#3757)
1 parent bc936ec commit 05b9c87

File tree

10 files changed

+83
-30
lines changed

10 files changed

+83
-30
lines changed

apps/web/app/(ee)/admin.dub.co/(dashboard)/components/delete-partner-account.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function DeletePartnerAccount() {
2020
return;
2121
}
2222

23-
await fetch("/api/admin/delete-partner-account", {
23+
await fetch("/api/admin/partners/delete-account", {
2424
method: "POST",
2525
body: JSON.stringify({
2626
email: formData.get("email"),

apps/web/app/(ee)/api/admin/delete-partner-account/route.ts renamed to apps/web/app/(ee)/api/admin/partners/delete-account/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { prisma } from "@dub/prisma";
66
import { prettyPrint } from "@dub/utils";
77
import { NextResponse } from "next/server";
88

9-
// POST /api/admin/delete-partner-account
9+
// POST /api/admin/partners/delete-account
1010
export const POST = withAdmin(
1111
async ({ req }) => {
1212
const { email, deletePartnerAccount } = await req.json();

apps/web/app/(ee)/api/cron/payouts/charge-succeeded/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ export async function POST(req: Request) {
6161
// Set the method for each payout in the invoice to the corresponding partner's default payout method
6262
await prisma.$executeRaw`
6363
UPDATE Payout p
64-
INNER JOIN Partner pr ON p.partnerId = pr.id
65-
SET p.method = pr.defaultPayoutMethod
64+
INNER JOIN Partner pn ON p.partnerId = pn.id
65+
SET p.method = pn.defaultPayoutMethod
6666
WHERE p.invoiceId = ${invoice.id}
67-
AND pr.defaultPayoutMethod IS NOT NULL
67+
AND pn.defaultPayoutMethod IS NOT NULL
6868
AND p.status = 'processing'
6969
`;
7070

apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/payout-stats.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function PayoutStatsCard({
7373
<div className="flex items-center gap-2">
7474
{partner && !partner.payoutsEnabledAt && (
7575
<Tooltip
76-
content="You need to connect your payout account to be able to receive payouts from the programs you are enrolled in."
76+
content="You need to [connect your payout account](/payouts?settings=true) to be able to receive payouts from the programs you are enrolled in."
7777
side="right"
7878
>
7979
<div>
@@ -96,9 +96,11 @@ function PayoutStatsCard({
9696
className="ml-2 h-7 px-2 py-1"
9797
onClick={() => setShowForceWithdrawalModal(true)}
9898
disabledTooltip={
99-
amount < MIN_FORCE_WITHDRAWAL_AMOUNT_CENTS
100-
? `Your current processed payouts balance is less than the minimum amount required for withdrawal (${currencyFormatter(MIN_FORCE_WITHDRAWAL_AMOUNT_CENTS)}).`
101-
: undefined
99+
!partner?.payoutsEnabledAt
100+
? "You need to [connect your payout account](/payouts?settings=true) to withdraw funds."
101+
: amount < MIN_FORCE_WITHDRAWAL_AMOUNT_CENTS
102+
? `Your current processed payouts balance is less than the minimum amount required for withdrawal (${currencyFormatter(MIN_FORCE_WITHDRAWAL_AMOUNT_CENTS)}).`
103+
: undefined
102104
}
103105
/>
104106
)}

apps/web/scripts/migrations/backfill-default-payout-method.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ async function main() {
88
while (true) {
99
const partners = await prisma.partner.findMany({
1010
where: {
11-
defaultPayoutMethod: null,
11+
payoutsEnabledAt: null,
1212
OR: [
1313
{
1414
stripeConnectId: {
@@ -20,12 +20,23 @@ async function main() {
2020
not: null,
2121
},
2222
},
23+
{
24+
stripeRecipientId: {
25+
not: null,
26+
},
27+
},
2328
],
29+
payouts: {
30+
some: {
31+
status: "completed",
32+
},
33+
},
2434
},
2535
select: {
2636
id: true,
2737
stripeConnectId: true,
2838
paypalEmail: true,
39+
stripeRecipientId: true,
2940
},
3041
take: BATCH_SIZE,
3142
});
@@ -34,17 +45,34 @@ async function main() {
3445
break;
3546
}
3647

48+
const stablecoinPartners: Pick<Partner, "id" | "stripeRecipientId">[] = [];
3749
const connectPartners: Pick<Partner, "id" | "stripeConnectId">[] = [];
3850
const paypalPartners: Pick<Partner, "id" | "paypalEmail">[] = [];
3951

4052
for (const partner of partners) {
41-
if (partner.stripeConnectId) {
53+
if (partner.stripeRecipientId) {
54+
stablecoinPartners.push(partner);
55+
} else if (partner.stripeConnectId) {
4256
connectPartners.push(partner);
4357
} else if (partner.paypalEmail) {
4458
paypalPartners.push(partner);
4559
}
4660
}
4761

62+
const promise0 =
63+
stablecoinPartners.length > 0
64+
? prisma.partner.updateMany({
65+
where: {
66+
id: {
67+
in: stablecoinPartners.map((partner) => partner.id),
68+
},
69+
},
70+
data: {
71+
defaultPayoutMethod: PartnerPayoutMethod.stablecoin,
72+
},
73+
})
74+
: Promise.resolve({ count: 0 });
75+
4876
const promise1 =
4977
connectPartners.length > 0
5078
? prisma.partner.updateMany({
@@ -75,10 +103,14 @@ async function main() {
75103
})
76104
: Promise.resolve({ count: 0 });
77105

78-
const [connectRes, paypalRes] = await Promise.all([promise1, promise2]);
106+
const [stablecoinRes, connectRes, paypalRes] = await Promise.all([
107+
promise0,
108+
promise1,
109+
promise2,
110+
]);
79111

80112
console.log(
81-
`Updated ${connectRes.count} connect partners and ${paypalRes.count} paypal partners`,
113+
`Updated ${stablecoinRes.count} stablecoin partners and ${connectRes.count} connect partners and ${paypalRes.count} paypal partners`,
82114
);
83115
}
84116
}

apps/web/ui/layout/sidebar/payout-stats.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const PayoutStats = memo(() => {
4242
<div className="flex items-center gap-1">
4343
{partner && !partner.payoutsEnabledAt && (
4444
<Tooltip
45-
content="You need to connect your payout account to be able to receive payouts from the programs you are enrolled in. [Learn more](https://dub.co/help/article/receiving-payouts)"
45+
content="You need to [connect your payout account](/payouts?settings=true) to be able to receive payouts from the programs you are enrolled in. [Learn more](https://dub.co/help/article/receiving-payouts)"
4646
side="right"
4747
>
4848
<div>

apps/web/ui/modals/plan-change-confirmation-modal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ function PlanChangeConfirmationModal({
4848
"- You will lose access to your partner program.",
4949
"- Your partner program will be deactivated and partners will be notified automatically.",
5050
"- Partner links will stop tracking new activity.",
51-
`- Any [pending payouts](/${slug}/program/payouts?status=pending) must be communicated and settled directly with your partners.`,
51+
`- Any [pending payouts](https://app.dub.co/${slug}/program/payouts?status=pending) must be communicated and settled directly with your partners.`,
5252
].join("\n")}
5353
</Markdown>
5454
</div>

apps/web/ui/partners/payouts/bank-account-requirements-modal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function BankAccountRequirementsModal({
2020

2121
const BANK_ACCOUNT_REQUIREMENTS = useMemo(() => {
2222
return [
23-
`1. Bank account must be in your local currency.${partner?.country ? ` Since you're based in [${COUNTRIES[partner.country]}](/profile), you need to connect a **${COUNTRY_CURRENCY_CODES[partner.country]} bank account** to receive payouts.` : ""}`,
23+
`1. Bank account must be in your local currency.${partner?.country ? ` Since you're based in [${COUNTRIES[partner.country]}](https://partners.dub.co/profile), you need to connect a **${COUNTRY_CURRENCY_CODES[partner.country]} bank account** to receive payouts.` : ""}`,
2424
"2. Bank account must be a **checking account** (not a savings account or debit card).",
2525
"3. Bank account holder name must match your partner account name.",
2626
"4. Bank account details are 100% accurate (no typos or missing numbers).",

apps/web/ui/partners/payouts/payout-method-dropdown.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ function PayoutMethodItem({
107107
onAction: (type: PartnerPayoutMethod, isManage: boolean) => void;
108108
isActionPending: boolean;
109109
}) {
110+
const { partner } = usePartnerProfile();
110111
const { Icon, wrapperClass } = getPayoutMethodIconConfig(method.type);
111112

112113
return (
@@ -126,11 +127,15 @@ function PayoutMethodItem({
126127
{method.label}
127128
</span>
128129

129-
{method.default && (
130-
<span className="rounded-md bg-green-100 px-1.5 py-0.5 text-xs font-semibold text-green-700">
130+
{!partner?.payoutsEnabledAt ? (
131+
<span className="rounded bg-red-100 px-1.5 py-0.5 text-[0.7rem] font-medium leading-none text-red-700">
132+
Restricted
133+
</span>
134+
) : method.default ? (
135+
<span className="rounded-md bg-green-100 px-1.5 py-0.5 text-[0.7rem] font-semibold leading-none text-green-700">
131136
Default
132137
</span>
133-
)}
138+
) : null}
134139
</div>
135140
<span className="mt-0.5 block truncate text-xs text-neutral-500">
136141
{method.identifier ?? "Not connected"}
@@ -153,6 +158,7 @@ function SelectedMethodDisplay({
153158
}: {
154159
method: PartnerPayoutMethodSetting;
155160
}) {
161+
const { partner } = usePartnerProfile();
156162
const { Icon, wrapperClass } = getPayoutMethodIconConfig(method.type);
157163
return (
158164
<>
@@ -170,11 +176,15 @@ function SelectedMethodDisplay({
170176
<span className="block text-xs font-medium text-neutral-900">
171177
{method.label}
172178
</span>
173-
{method.default && (
174-
<span className="rounded bg-green-100 px-1.5 py-0.5 text-xs font-medium text-green-700">
179+
{!partner?.payoutsEnabledAt ? (
180+
<span className="rounded bg-red-100 px-1.5 py-0.5 text-[0.7rem] font-medium leading-none text-red-700">
181+
Restricted
182+
</span>
183+
) : method.default ? (
184+
<span className="rounded bg-green-100 px-1.5 py-0.5 text-[0.7rem] font-medium leading-none text-green-700">
175185
Default
176186
</span>
177-
)}
187+
) : null}
178188
</div>
179189
<span className="block truncate text-xs text-neutral-500">
180190
{method.identifier ?? "Not connected"}

packages/ui/src/tooltip.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,23 @@ const TooltipMarkdown = ({
3636
className,
3737
)}
3838
components={{
39-
a: ({ node, ...props }) => (
40-
<a
41-
{...props}
42-
target="_blank"
43-
rel="noopener noreferrer"
44-
onClick={(e) => e.stopPropagation()}
45-
/>
46-
),
39+
a: ({ node, ...props }) => {
40+
if (props.href?.startsWith("/")) {
41+
return (
42+
<Link href={props.href} onClick={(e) => e.stopPropagation()}>
43+
{props.children}
44+
</Link>
45+
);
46+
}
47+
return (
48+
<a
49+
{...props}
50+
target="_blank"
51+
rel="noopener noreferrer"
52+
onClick={(e) => e.stopPropagation()}
53+
/>
54+
);
55+
},
4756
code: ({ node, ...props }) => (
4857
<code {...props} className="rounded-md bg-neutral-100 px-1 py-0.5" />
4958
),

0 commit comments

Comments
 (0)