diff --git a/apps/web/app/(ee)/api/cron/discount-codes/delete/route.ts b/apps/web/app/(ee)/api/cron/discount-codes/disable/route.ts
similarity index 92%
rename from apps/web/app/(ee)/api/cron/discount-codes/delete/route.ts
rename to apps/web/app/(ee)/api/cron/discount-codes/disable/route.ts
index 8a81938c602..7b4792d8c51 100644
--- a/apps/web/app/(ee)/api/cron/discount-codes/delete/route.ts
+++ b/apps/web/app/(ee)/api/cron/discount-codes/disable/route.ts
@@ -14,7 +14,7 @@ const inputSchema = z.object({
provider: z.enum(DiscountProvider),
});
-// POST /api/cron/discount-codes/delete
+// POST /api/cron/discount-codes/disable – disable a discount code from the provider (Stripe, Shopify, etc.)
export const POST = withCron(async ({ rawBody }) => {
const { provider, code, programId } = inputSchema.parse(JSON.parse(rawBody));
diff --git a/apps/web/app/(ee)/api/cron/partners/ban/route.ts b/apps/web/app/(ee)/api/cron/partners/ban/route.ts
index 84bd7d69a48..89ac41c8851 100644
--- a/apps/web/app/(ee)/api/cron/partners/ban/route.ts
+++ b/apps/web/app/(ee)/api/cron/partners/ban/route.ts
@@ -138,7 +138,7 @@ export const POST = withCron(async ({ rawBody }) => {
recordLink(links, { deleted: true }),
// Queue discount code deletions
- deleteDiscountCodes(discountCodes),
+ deleteDiscountCodes(discountCodes, { isSoftDelete: true }),
]);
// Send email
diff --git a/apps/web/app/(ee)/api/cron/partners/deactivate/route.ts b/apps/web/app/(ee)/api/cron/partners/deactivate/route.ts
index a2db6546a77..2658f91a608 100644
--- a/apps/web/app/(ee)/api/cron/partners/deactivate/route.ts
+++ b/apps/web/app/(ee)/api/cron/partners/deactivate/route.ts
@@ -58,7 +58,7 @@ export const POST = withCron(async ({ rawBody }) => {
const discountCodes = programEnrollments.flatMap(({ discountCodes }) =>
discountCodes.map((dc) => dc),
);
- await deleteDiscountCodes(discountCodes);
+ await deleteDiscountCodes(discountCodes, { isSoftDelete: true });
console.log("[bulkDeactivatePartners] Queued discount code deletions.");
// Find the program
diff --git a/apps/web/app/(ee)/api/discount-codes/route.ts b/apps/web/app/(ee)/api/discount-codes/route.ts
index db5f9870a55..9b2c81de3c9 100644
--- a/apps/web/app/(ee)/api/discount-codes/route.ts
+++ b/apps/web/app/(ee)/api/discount-codes/route.ts
@@ -11,6 +11,7 @@ import {
DiscountCodeSchema,
getDiscountCodesQuerySchema,
} from "@/lib/zod/schemas/discount";
+import { APP_DOMAIN } from "@dub/utils";
import { waitUntil } from "@vercel/functions";
import { NextResponse } from "next/server";
@@ -100,12 +101,15 @@ export const POST = withWorkspace(
code,
},
},
+ include: {
+ partner: true,
+ },
});
if (duplicateByCode) {
throw new DubApiError({
- code: "bad_request",
- message: `A discount with the code ${code} already exists in the program. Please choose a different code.`,
+ code: "conflict",
+ message: `This discount code "${code}" is already in use by [${duplicateByCode.partner.email}](${APP_DOMAIN}/${workspace.slug}/program/partners/${duplicateByCode.partner.id}). Please choose a different code.`,
});
}
}
diff --git a/apps/web/app/(ee)/api/partner-profile/programs/[programId]/links/route.ts b/apps/web/app/(ee)/api/partner-profile/programs/[programId]/links/route.ts
index a068d86f35d..fb1f32983df 100644
--- a/apps/web/app/(ee)/api/partner-profile/programs/[programId]/links/route.ts
+++ b/apps/web/app/(ee)/api/partner-profile/programs/[programId]/links/route.ts
@@ -37,6 +37,7 @@ export const GET = withPartnerProfile(async ({ partner, params }) => {
return {
...link,
discountCode: discountCode?.code,
+ discountCodeDisabledAt: discountCode?.disabledAt ?? null,
};
});
diff --git a/apps/web/app/(ee)/api/stripe/integration/webhook/utils/attribute-via-promotion-code-id.ts b/apps/web/app/(ee)/api/stripe/integration/webhook/utils/attribute-via-promotion-code-id.ts
index d7465ab9c01..3376fbc1acf 100644
--- a/apps/web/app/(ee)/api/stripe/integration/webhook/utils/attribute-via-promotion-code-id.ts
+++ b/apps/web/app/(ee)/api/stripe/integration/webhook/utils/attribute-via-promotion-code-id.ts
@@ -70,14 +70,21 @@ export async function attributeViaPromotionCodeId({
code: promotionCode.code,
},
},
- select: {
+ include: {
link: true,
},
});
if (!discountCode) {
console.log(
- `Couldn't find link associated with promotion code ${promotionCode.code}, skipping...`,
+ `Couldn't find discount code "${promotionCode.code}" in program "${workspace.defaultProgramId}", skipping...`,
+ );
+ return null;
+ }
+
+ if (discountCode.disabledAt) {
+ console.log(
+ `Discount code "${discountCode.code}" is disabled, skipping...`,
);
return null;
}
diff --git a/apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/partner-link-card.tsx b/apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/partner-link-card.tsx
index aa2bcde4361..9bb044a58ce 100644
--- a/apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/partner-link-card.tsx
+++ b/apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/partner-link-card.tsx
@@ -28,6 +28,7 @@ import {
getApexDomain,
getPrettyUrl,
nFormatter,
+ PARTNERS_DOMAIN,
} from "@dub/utils";
import NumberFlow from "@number-flow/react";
import Link from "next/link";
@@ -75,6 +76,19 @@ export function PartnerLinkCard({ link }: { link: PartnerProfileLinkProps }) {
const isDeactivated = programEnrollment?.status === "deactivated";
+ const discountCodeSection = link.discountCode ? (
+
+
+ Discount code
+
+
+
+ ) : null;
+
return (
);
})()}
- {link.discountCode && (
-
-
-
- Discount code
-
-
-
-
- )}
+ {discountCodeSection &&
+ (link.discountCodeDisabledAt ? (
+ discountCodeSection
+ ) : (
+
+ {discountCodeSection}
+
+ ))}
{displayOption === "cards" && }
diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page.tsx
index 80704276aa0..11256da1407 100644
--- a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page.tsx
+++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page.tsx
@@ -333,7 +333,12 @@ const PartnerDiscountCodes = ({
{
id: "code",
header: "Code",
- cell: ({ row }) => ,
+ cell: ({ row }) => (
+
+ ),
},
{
id: "shortLink",
diff --git a/apps/web/lib/discounts/delete-discount-code.ts b/apps/web/lib/discounts/delete-discount-code.ts
index e02953d0bf1..33c0232b363 100644
--- a/apps/web/lib/discounts/delete-discount-code.ts
+++ b/apps/web/lib/discounts/delete-discount-code.ts
@@ -17,6 +17,7 @@ type DeleteDiscountCodesParams = Pick<
// 4. When a partner is moved to a different group
export async function deleteDiscountCodes(
input: (DeleteDiscountCodesParams | null | undefined)[],
+ { isSoftDelete = false }: { isSoftDelete?: boolean } = {},
) {
const discountCodes = input.filter(
(dc): dc is NonNullable => dc != null,
@@ -29,18 +30,36 @@ export async function deleteDiscountCodes(
return;
}
- // Delete the discount codes from the database
- const deletedDiscountCodes = await prisma.discountCode.deleteMany({
- where: {
- id: {
- in: discountCodes.map(({ id }) => id),
+ if (isSoftDelete) {
+ // Soft delete the discount codes from the database (mark them as disabled)
+ const disabledDiscountCodes = await prisma.discountCode.updateMany({
+ where: {
+ id: {
+ in: discountCodes.map(({ id }) => id),
+ },
+ },
+ data: {
+ disabledAt: new Date(),
},
- },
- });
+ });
- console.log(
- `[deleteDiscountCodes] Deleted ${deletedDiscountCodes.count} discount codes.`,
- );
+ console.log(
+ `[deleteDiscountCodes] Disabled ${disabledDiscountCodes.count} discount codes.`,
+ );
+ } else {
+ // Delete the discount codes from the database
+ const deletedDiscountCodes = await prisma.discountCode.deleteMany({
+ where: {
+ id: {
+ in: discountCodes.map(({ id }) => id),
+ },
+ },
+ });
+
+ console.log(
+ `[deleteDiscountCodes] Deleted ${deletedDiscountCodes.count} discount codes.`,
+ );
+ }
// Only enqueue external-provider cleanup for codes whose provider is known.
// Orphaned codes (discount relation is null) still get deleted locally above
@@ -63,7 +82,7 @@ export async function deleteDiscountCodes(
for (const chunkOfCodes of chunks) {
await enqueueBatchJobs(
chunkOfCodes.map((discountCode) => ({
- url: `${APP_DOMAIN_WITH_NGROK}/api/cron/discount-codes/delete`,
+ url: `${APP_DOMAIN_WITH_NGROK}/api/cron/discount-codes/disable`,
method: "POST",
queueName: "delete-discount-code",
body: {
diff --git a/apps/web/lib/zod/schemas/discount.ts b/apps/web/lib/zod/schemas/discount.ts
index 44c773972b2..194d6d422f2 100644
--- a/apps/web/lib/zod/schemas/discount.ts
+++ b/apps/web/lib/zod/schemas/discount.ts
@@ -62,6 +62,12 @@ export const DiscountCodeSchema = z.object({
discountId: z.string().nullable(),
partnerId: z.string(),
linkId: z.string(),
+ disabledAt: z.coerce
+ .date()
+ .nullish()
+ .describe(
+ "When this discount code was disabled, which happens when a partner is banned or deactivated.",
+ ),
});
export const createDiscountCodeSchema = z.object({
diff --git a/apps/web/lib/zod/schemas/partner-profile.ts b/apps/web/lib/zod/schemas/partner-profile.ts
index 608d98a1faf..303279daf98 100644
--- a/apps/web/lib/zod/schemas/partner-profile.ts
+++ b/apps/web/lib/zod/schemas/partner-profile.ts
@@ -100,6 +100,7 @@ export const PartnerProfileLinkSchema = LinkSchema.pick({
createdAt: z.string().or(z.date()),
partnerGroupDefaultLinkId: z.string().nullish(),
discountCode: z.string().nullable().default(null),
+ discountCodeDisabledAt: z.coerce.date().nullable().default(null),
});
export const PartnerProfileCustomerSchema = CustomerEnrichedSchema.pick({
diff --git a/apps/web/package.json b/apps/web/package.json
index 32181801d15..ca16b4d5978 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -129,7 +129,7 @@
"remark-gfm": "^4.0.0",
"sanitize-html": "^2.17.0",
"shiki": "^1.14.1",
- "sonner": "^1.4.41",
+ "sonner": "^2.0.7",
"streamdown": "^2.3.0",
"stripe": "^18.2.0",
"svix": "^1.76.1",
diff --git a/apps/web/prisma/schema/discount.prisma b/apps/web/prisma/schema/discount.prisma
index 937d56377fe..296dc260438 100644
--- a/apps/web/prisma/schema/discount.prisma
+++ b/apps/web/prisma/schema/discount.prisma
@@ -34,6 +34,7 @@ model DiscountCode {
linkId String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
+ disabledAt DateTime?
program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
discount Discount? @relation(fields: [discountId], references: [id], onDelete: SetNull)
diff --git a/apps/web/ui/modals/add-discount-code-modal.tsx b/apps/web/ui/modals/add-discount-code-modal.tsx
index 5c361cd8c82..bbdf5ac6b87 100644
--- a/apps/web/ui/modals/add-discount-code-modal.tsx
+++ b/apps/web/ui/modals/add-discount-code-modal.tsx
@@ -18,7 +18,8 @@ import { toast } from "sonner";
import { useDebounce } from "use-debounce";
import * as z from "zod/v4";
import { ERROR_MAP } from "../partners/constants";
-import { X } from "../shared/icons";
+import { CustomToast } from "../shared/custom-toast";
+import { AlertCircleFill, X } from "../shared/icons";
import { UpgradeRequiredToast } from "../shared/upgrade-required-toast";
type FormData = z.infer;
@@ -87,28 +88,30 @@ const AddDiscountCodeModal = ({
toast.success("Discount code created and copied to clipboard!");
},
onError: (error) => {
- if (error) {
- const code = Object.keys(ERROR_MAP).find((key) =>
- error.startsWith(key),
- );
+ const code = Object.keys(ERROR_MAP).find((key) =>
+ error.startsWith(key),
+ );
- if (code) {
- const { title, ctaLabel, ctaUrl } = ERROR_MAP[code];
- const message = error.replace(`${code}: `, "");
+ if (code) {
+ const { title, ctaLabel, ctaUrl } = ERROR_MAP[code];
+ const message = error.replace(`${code}: `, "");
- toast.custom(() => (
-
- ));
- return;
- }
+ toast.custom(() => (
+
+ ));
+ return;
+ } else if (error.includes("already in use")) {
+ toast.custom(() => (
+ {error}
+ ));
+ } else {
+ toast.error(error);
}
-
- toast.error(error);
},
});
};
diff --git a/apps/web/ui/partners/discounts/discount-code-badge.tsx b/apps/web/ui/partners/discounts/discount-code-badge.tsx
index a51d3a01081..e91310f4aef 100644
--- a/apps/web/ui/partners/discounts/discount-code-badge.tsx
+++ b/apps/web/ui/partners/discounts/discount-code-badge.tsx
@@ -1,9 +1,51 @@
-import { Tag, useCopyToClipboard } from "@dub/ui";
+import { Tag, Tooltip, useCopyToClipboard } from "@dub/ui";
import { cn } from "@dub/utils";
import { toast } from "sonner";
-export function DiscountCodeBadge({ code }: { code: string }) {
+export function DiscountCodeBadge({
+ code,
+ disabledAt,
+ disabledTooltip = "This discount code was disabled because the partner was banned or deactivated. To re-enable it, delete this code and create a new one.",
+}: {
+ code: string;
+ disabledAt?: Date | string | null;
+ disabledTooltip?: string;
+}) {
const [copied, copyToClipboard] = useCopyToClipboard();
+ const isDisabled = !!disabledAt;
+
+ const content = (
+ <>
+
+
+ {code}
+
+ >
+ );
+
+ if (isDisabled) {
+ return (
+
+
+ {content}
+
+
+ );
+ }
+
return (
);
}
diff --git a/apps/web/ui/shared/custom-toast.tsx b/apps/web/ui/shared/custom-toast.tsx
index e6dc298b4f1..5666c6d6d93 100644
--- a/apps/web/ui/shared/custom-toast.tsx
+++ b/apps/web/ui/shared/custom-toast.tsx
@@ -1,4 +1,4 @@
-import ReactMarkdown from "react-markdown";
+import { MarkdownDescription } from "./markdown-description";
export function CustomToast({
icon: Icon,
@@ -10,20 +10,9 @@ export function CustomToast({
return (
{Icon &&
}
-
(
-
- ),
- }}
- >
+
{children}
-
+
);
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bf6031bf853..1925b54eefb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -366,8 +366,8 @@ importers:
specifier: ^1.14.1
version: 1.14.1
sonner:
- specifier: ^1.4.41
- version: 1.4.41(react-dom@19.1.3(react@19.1.3))(react@19.1.3)
+ specifier: ^2.0.7
+ version: 2.0.7(react-dom@19.1.3(react@19.1.3))(react@19.1.3)
streamdown:
specifier: ^2.3.0
version: 2.3.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3)
@@ -672,7 +672,7 @@ importers:
dependencies:
'@hubspot/cli':
specifier: ^7.6.2
- version: 7.6.2(@babel/core@7.28.4)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)(typescript@5.6.2)(vite@5.4.8(@types/node@18.11.9)(terser@5.27.0))
+ version: 7.6.2(@babel/core@7.24.5)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)(typescript@5.6.2)(vite@5.4.8(@types/node@18.11.9)(terser@5.27.0))
devDependencies:
'@types/node':
specifier: 18.11.9
@@ -11964,6 +11964,12 @@ packages:
react: ^18.0.0
react-dom: ^18.0.0
+ sonner@2.0.7:
+ resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+
source-map-js@1.2.0:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
@@ -14502,9 +14508,9 @@ snapshots:
'@babel/core': 7.24.5
'@babel/helper-plugin-utils': 7.25.9
- '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)':
+ '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.24.5)':
dependencies:
- '@babel/core': 7.28.4
+ '@babel/core': 7.24.5
'@babel/helper-plugin-utils': 7.27.1
optional: true
@@ -15334,7 +15340,7 @@ snapshots:
- encoding
- supports-color
- '@hubspot/cli@7.6.2(@babel/core@7.28.4)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)(typescript@5.6.2)(vite@5.4.8(@types/node@18.11.9)(terser@5.27.0))':
+ '@hubspot/cli@7.6.2(@babel/core@7.24.5)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)(typescript@5.6.2)(vite@5.4.8(@types/node@18.11.9)(terser@5.27.0))':
dependencies:
'@hubspot/local-dev-lib': 3.19.1
'@hubspot/project-parsing-lib': 0.8.6(@hubspot/local-dev-lib@3.19.1)
@@ -15365,7 +15371,7 @@ snapshots:
yargs: 17.7.2
yargs-parser: 21.1.1
optionalDependencies:
- '@hubspot/cms-dev-server': 1.0.38(@babel/core@7.28.4)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)
+ '@hubspot/cms-dev-server': 1.0.38(@babel/core@7.24.5)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)
'@modelcontextprotocol/sdk': 1.13.3
transitivePeerDependencies:
- '@babel/core'
@@ -15403,7 +15409,7 @@ snapshots:
react-dom: 18.3.1(react@18.3.1)
optional: true
- '@hubspot/cms-dev-server@1.0.38(@babel/core@7.28.4)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)':
+ '@hubspot/cms-dev-server@1.0.38(@babel/core@7.24.5)(@types/node@18.11.9)(@types/react-dom@19.1.9(@types/react@19.1.15))(@types/react@19.1.15)(encoding@0.1.13)(prettier@3.6.2)(rollup@4.52.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.27.0)':
dependencies:
'@babel/code-frame': 7.26.2
'@babel/parser': 7.26.2
@@ -15430,7 +15436,7 @@ snapshots:
'@vitejs/plugin-react': 4.7.0(vite@5.4.8(@types/node@18.11.9)(terser@5.27.0))
ansi-to-html: 0.7.2
babel-plugin-macros: 3.1.0
- babel-plugin-styled-components: 2.1.4(@babel/core@7.28.4)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
+ babel-plugin-styled-components: 2.1.4(@babel/core@7.24.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
chalk: 5.4.1
class-variance-authority: 0.7.0
cli-progress: 3.12.0
@@ -15449,7 +15455,7 @@ snapshots:
react-dom: 18.3.1(react@18.3.1)
request: 2.88.2
storybook: 8.6.14(prettier@3.6.2)
- styled-jsx: 5.1.2(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(react@18.3.1)
+ styled-jsx: 5.1.2(@babel/core@7.24.5)(babel-plugin-macros@3.1.0)(react@18.3.1)
tailwind-merge: 2.6.0
tailwindcss-animate: 1.0.7
typescript: 4.7.4
@@ -20478,11 +20484,11 @@ snapshots:
resolve: 1.22.6
optional: true
- babel-plugin-styled-components@2.1.4(@babel/core@7.28.4)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
+ babel-plugin-styled-components@2.1.4(@babel/core@7.24.5)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
dependencies:
'@babel/helper-annotate-as-pure': 7.27.3
'@babel/helper-module-imports': 7.25.9
- '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4)
+ '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.24.5)
lodash: 4.17.21
picomatch: 2.3.1
styled-components: 6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -27267,6 +27273,11 @@ snapshots:
react: 19.1.3
react-dom: 19.1.3(react@19.1.3)
+ sonner@2.0.7(react-dom@19.1.3(react@19.1.3))(react@19.1.3):
+ dependencies:
+ react: 19.1.3
+ react-dom: 19.1.3(react@19.1.3)
+
source-map-js@1.2.0: {}
source-map-js@1.2.1: {}
@@ -27566,12 +27577,12 @@ snapshots:
tslib: 2.6.2
optional: true
- styled-jsx@5.1.2(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(react@18.3.1):
+ styled-jsx@5.1.2(@babel/core@7.24.5)(babel-plugin-macros@3.1.0)(react@18.3.1):
dependencies:
client-only: 0.0.1
react: 18.3.1
optionalDependencies:
- '@babel/core': 7.28.4
+ '@babel/core': 7.24.5
babel-plugin-macros: 3.1.0
optional: true