feat: implement beautiful jsx-email templates for OTP and team invites (#196)
Co-authored-by: opencode <noreply@opencode.ai>
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
"@trpc/server": "^11.1.1",
|
||||
"@unsend/email-editor": "workspace:*",
|
||||
"@unsend/ui": "workspace:*",
|
||||
"jsx-email": "^2.7.1",
|
||||
"bullmq": "^5.51.1",
|
||||
"chrono-node": "^2.8.0",
|
||||
"date-fns": "^4.1.0",
|
||||
|
47
apps/web/src/app/api/dev/email-preview/route.ts
Normal file
47
apps/web/src/app/api/dev/email-preview/route.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import {
|
||||
renderOtpEmail,
|
||||
renderTeamInviteEmail,
|
||||
} from "~/server/email-templates";
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const type = searchParams.get("type") || "otp";
|
||||
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
return NextResponse.json({ error: "Not Found" }, { status: 404 });
|
||||
}
|
||||
|
||||
try {
|
||||
let html: string;
|
||||
|
||||
if (type === "otp") {
|
||||
html = await renderOtpEmail({
|
||||
otpCode: "ABC123",
|
||||
loginUrl: "https://app.unsend.dev/login?token=abc123",
|
||||
hostName: "Unsend",
|
||||
});
|
||||
} else if (type === "invite") {
|
||||
html = await renderTeamInviteEmail({
|
||||
teamName: "My Awesome Team",
|
||||
inviteUrl: "https://app.unsend.dev/join-team?inviteId=123",
|
||||
inviterName: "John Doe",
|
||||
role: "admin",
|
||||
});
|
||||
} else {
|
||||
return NextResponse.json({ error: "Invalid type" }, { status: 400 });
|
||||
}
|
||||
|
||||
return new NextResponse(html, {
|
||||
headers: {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error rendering email template:", error);
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to render email template" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
99
apps/web/src/server/email-templates/OtpEmail.tsx
Normal file
99
apps/web/src/server/email-templates/OtpEmail.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import React from "react";
|
||||
import { Container, Text } from "jsx-email";
|
||||
import { render } from "jsx-email";
|
||||
import { EmailLayout } from "./components/EmailLayout";
|
||||
import { EmailHeader } from "./components/EmailHeader";
|
||||
import { EmailFooter } from "./components/EmailFooter";
|
||||
import { EmailButton } from "./components/EmailButton";
|
||||
|
||||
interface OtpEmailProps {
|
||||
otpCode: string;
|
||||
loginUrl: string;
|
||||
hostName?: string;
|
||||
logoUrl?: string;
|
||||
}
|
||||
|
||||
export function OtpEmail({
|
||||
otpCode,
|
||||
loginUrl,
|
||||
hostName = "Unsend",
|
||||
logoUrl,
|
||||
}: OtpEmailProps) {
|
||||
return (
|
||||
<EmailLayout preview={`Your verification code: ${otpCode}`}>
|
||||
<EmailHeader logoUrl={logoUrl} title="Sign in to your account" />
|
||||
|
||||
<Container style={{ padding: "20px 0", textAlign: "left" as const }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
color: "#374151",
|
||||
margin: "0 0 24px 0",
|
||||
lineHeight: "1.6",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
Hi there,
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
color: "#374151",
|
||||
margin: "0 0 32px 0",
|
||||
lineHeight: "1.6",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
Use the verification code below to sign in to your Unsend account:
|
||||
</Text>
|
||||
|
||||
<Container
|
||||
style={{
|
||||
backgroundColor: "#f8f9fa",
|
||||
padding: "16px",
|
||||
margin: "0 0 32px 0",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "24px",
|
||||
fontWeight: "700",
|
||||
color: "#000000",
|
||||
letterSpacing: "4px",
|
||||
margin: "0",
|
||||
fontFamily: "monospace",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
{otpCode}
|
||||
</Text>
|
||||
</Container>
|
||||
|
||||
<Container style={{ margin: "0 0 32px 0", textAlign: "left" as const }}>
|
||||
<EmailButton href={loginUrl}>Sign in with one click</EmailButton>
|
||||
</Container>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
color: "#6b7280",
|
||||
margin: "0",
|
||||
lineHeight: "1.5",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
If you didn't request this email, you can safely ignore it. The
|
||||
verification code will expire automatically.
|
||||
</Text>
|
||||
</Container>
|
||||
|
||||
<EmailFooter />
|
||||
</EmailLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export async function renderOtpEmail(props: OtpEmailProps): Promise<string> {
|
||||
return render(<OtpEmail {...props} />);
|
||||
}
|
90
apps/web/src/server/email-templates/TeamInviteEmail.tsx
Normal file
90
apps/web/src/server/email-templates/TeamInviteEmail.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import React from "react";
|
||||
import { Container, Text } from "jsx-email";
|
||||
import { render } from "jsx-email";
|
||||
import { EmailLayout } from "./components/EmailLayout";
|
||||
import { EmailHeader } from "./components/EmailHeader";
|
||||
import { EmailFooter } from "./components/EmailFooter";
|
||||
import { EmailButton } from "./components/EmailButton";
|
||||
|
||||
interface TeamInviteEmailProps {
|
||||
teamName: string;
|
||||
inviteUrl: string;
|
||||
inviterName?: string;
|
||||
logoUrl?: string;
|
||||
role?: string;
|
||||
}
|
||||
|
||||
export function TeamInviteEmail({
|
||||
teamName,
|
||||
inviteUrl,
|
||||
inviterName,
|
||||
logoUrl,
|
||||
role = "member",
|
||||
}: TeamInviteEmailProps) {
|
||||
return (
|
||||
<EmailLayout preview={`You've been invited to join ${teamName} on Unsend`}>
|
||||
<EmailHeader logoUrl={logoUrl} title="You're invited!" />
|
||||
|
||||
<Container style={{ padding: "20px 0", textAlign: "left" as const }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
color: "#374151",
|
||||
margin: "0 0 24px 0",
|
||||
lineHeight: "1.6",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
Hi there,
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
color: "#374151",
|
||||
margin: "0 0 32px 0",
|
||||
lineHeight: "1.6",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
{inviterName
|
||||
? `${inviterName} has invited you to join `
|
||||
: "You have been invited to join "}
|
||||
<strong style={{ color: "#000000" }}>{teamName}</strong> on Unsend
|
||||
{role && role !== "member" && (
|
||||
<span>
|
||||
{" "}
|
||||
as a <strong style={{ color: "#000000" }}>{role}</strong>
|
||||
</span>
|
||||
)}
|
||||
.
|
||||
</Text>
|
||||
|
||||
<Container style={{ margin: "0 0 32px 0", textAlign: "left" as const }}>
|
||||
<EmailButton href={inviteUrl}>Accept invitation</EmailButton>
|
||||
</Container>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
color: "#6b7280",
|
||||
margin: "0",
|
||||
lineHeight: "1.5",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
If you weren't expecting this invitation or don't want to join this
|
||||
team, you can safely ignore this email.
|
||||
</Text>
|
||||
</Container>
|
||||
|
||||
<EmailFooter />
|
||||
</EmailLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export async function renderTeamInviteEmail(
|
||||
props: TeamInviteEmailProps
|
||||
): Promise<string> {
|
||||
return render(<TeamInviteEmail {...props} />);
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
import React from "react";
|
||||
import { Link } from "jsx-email";
|
||||
|
||||
interface EmailButtonProps {
|
||||
href: string;
|
||||
children: React.ReactNode;
|
||||
variant?: "primary" | "secondary";
|
||||
}
|
||||
|
||||
export function EmailButton({
|
||||
href,
|
||||
children,
|
||||
variant = "primary"
|
||||
}: EmailButtonProps) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
style={{
|
||||
backgroundColor: "#000000",
|
||||
color: "#ffffff",
|
||||
border: "1px solid #000000",
|
||||
borderRadius: "4px",
|
||||
fontSize: "16px",
|
||||
fontWeight: "500",
|
||||
padding: "12px 24px",
|
||||
textDecoration: "none",
|
||||
display: "inline-block",
|
||||
textAlign: "center" as const,
|
||||
minWidth: "120px",
|
||||
boxSizing: "border-box" as const,
|
||||
float: "left" as const,
|
||||
clear: "both" as const,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
import React from "react";
|
||||
import { Container, Text } from "jsx-email";
|
||||
|
||||
interface EmailFooterProps {
|
||||
companyName?: string;
|
||||
supportUrl?: string;
|
||||
}
|
||||
|
||||
export function EmailFooter({
|
||||
companyName = "Unsend",
|
||||
supportUrl = "https://unsend.dev"
|
||||
}: EmailFooterProps) {
|
||||
return (
|
||||
<Container
|
||||
style={{
|
||||
padding: "20px 0",
|
||||
backgroundColor: "#ffffff",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
color: "#6b7280",
|
||||
textAlign: "left" as const,
|
||||
margin: "0",
|
||||
lineHeight: "1.5",
|
||||
}}
|
||||
>
|
||||
This email was sent by {companyName}. If you have any questions, please{" "}
|
||||
<a
|
||||
href={supportUrl}
|
||||
style={{
|
||||
color: "#000000",
|
||||
textDecoration: "underline",
|
||||
}}
|
||||
>
|
||||
contact our support team
|
||||
</a>
|
||||
.
|
||||
</Text>
|
||||
</Container>
|
||||
);
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
import React from "react";
|
||||
import { Container, Heading, Img } from "jsx-email";
|
||||
|
||||
interface EmailHeaderProps {
|
||||
logoUrl?: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export function EmailHeader({ logoUrl, title }: EmailHeaderProps) {
|
||||
return (
|
||||
<Container
|
||||
style={{
|
||||
padding: "20px 0",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
{logoUrl && (
|
||||
<Img
|
||||
src={logoUrl}
|
||||
alt="Unsend"
|
||||
style={{
|
||||
width: "48px",
|
||||
height: "48px",
|
||||
margin: "0 0 16px 0",
|
||||
display: "block",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{title && (
|
||||
<Heading
|
||||
style={{
|
||||
fontSize: "24px",
|
||||
fontWeight: "600",
|
||||
color: "#111827",
|
||||
margin: "0",
|
||||
lineHeight: "1.3",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Html,
|
||||
Head,
|
||||
Body,
|
||||
Container,
|
||||
Font,
|
||||
Preview,
|
||||
} from "jsx-email";
|
||||
|
||||
interface EmailLayoutProps {
|
||||
preview?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function EmailLayout({ preview, children }: EmailLayoutProps) {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<Font
|
||||
fallbackFontFamily="sans-serif"
|
||||
fontFamily="Inter"
|
||||
fontStyle="normal"
|
||||
fontWeight={400}
|
||||
webFont={{
|
||||
url: "https://rsms.me/inter/font-files/Inter-Regular.woff2?v=3.19",
|
||||
format: "woff2",
|
||||
}}
|
||||
/>
|
||||
<style
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #374151;
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
<meta content="width=device-width" name="viewport" />
|
||||
<meta content="IE=edge" httpEquiv="X-UA-Compatible" />
|
||||
<meta name="x-apple-disable-message-reformatting" />
|
||||
<meta
|
||||
content="telephone=no,address=no,email=no,date=no,url=no"
|
||||
name="format-detection"
|
||||
/>
|
||||
<meta content="light" name="color-scheme" />
|
||||
<meta content="light" name="supported-color-schemes" />
|
||||
</Head>
|
||||
{preview && <Preview>{preview}</Preview>}
|
||||
<Body style={{ backgroundColor: "#ffffff", padding: "20px" }}>
|
||||
<Container
|
||||
className="email-container"
|
||||
style={{
|
||||
maxWidth: "600px",
|
||||
backgroundColor: "#ffffff",
|
||||
textAlign: "left" as const,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
</Body>
|
||||
</Html>
|
||||
);
|
||||
}
|
7
apps/web/src/server/email-templates/index.ts
Normal file
7
apps/web/src/server/email-templates/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export { OtpEmail, renderOtpEmail } from "./OtpEmail";
|
||||
export { TeamInviteEmail, renderTeamInviteEmail } from "./TeamInviteEmail";
|
||||
|
||||
export * from "./components/EmailLayout";
|
||||
export * from "./components/EmailHeader";
|
||||
export * from "./components/EmailFooter";
|
||||
export * from "./components/EmailButton";
|
36
apps/web/src/server/email-templates/test.ts
Normal file
36
apps/web/src/server/email-templates/test.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { renderOtpEmail, renderTeamInviteEmail } from './index';
|
||||
|
||||
async function testEmailTemplates() {
|
||||
console.log('Testing email templates...\n');
|
||||
|
||||
try {
|
||||
// Test OTP email
|
||||
const otpHtml = await renderOtpEmail({
|
||||
otpCode: 'ABC123',
|
||||
loginUrl: 'https://app.unsend.dev/login?token=abc123',
|
||||
hostName: 'Unsend',
|
||||
});
|
||||
|
||||
console.log('✅ OTP Email rendered successfully');
|
||||
console.log(`Length: ${otpHtml.length} characters\n`);
|
||||
|
||||
// Test Team Invite email
|
||||
const inviteHtml = await renderTeamInviteEmail({
|
||||
teamName: 'My Awesome Team',
|
||||
inviteUrl: 'https://app.unsend.dev/join-team?inviteId=123',
|
||||
});
|
||||
|
||||
console.log('✅ Team Invite Email rendered successfully');
|
||||
console.log(`Length: ${inviteHtml.length} characters\n`);
|
||||
|
||||
console.log('🎉 All email templates are working correctly!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error testing email templates:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
testEmailTemplates();
|
||||
}
|
@@ -5,6 +5,7 @@ import { db } from "./db";
|
||||
import { getDomains } from "./service/domain-service";
|
||||
import { sendEmail } from "./service/email-service";
|
||||
import { logger } from "./logger/log";
|
||||
import { renderOtpEmail, renderTeamInviteEmail } from "./email-templates";
|
||||
|
||||
let unsend: Unsend | undefined;
|
||||
|
||||
@@ -28,8 +29,16 @@ export async function sendSignUpEmail(
|
||||
}
|
||||
|
||||
const subject = "Sign in to Unsend";
|
||||
|
||||
// Use jsx-email template for beautiful HTML
|
||||
const html = await renderOtpEmail({
|
||||
otpCode: token.toUpperCase(),
|
||||
loginUrl: url,
|
||||
hostName: host,
|
||||
});
|
||||
|
||||
// Fallback text version
|
||||
const text = `Hey,\n\nYou can sign in to Unsend by clicking the below URL:\n${url}\n\nYou can also use this OTP: ${token}\n\nThanks,\nUnsend Team`;
|
||||
const html = `<p>Hey,</p> <p>You can sign in to Unsend by clicking the below URL:</p><p><a href="${url}">Sign in to ${host}</a></p><p>You can also use this OTP: <b>${token}</b></p<br /><br /><p>Thanks,</p><p>Unsend Team</p>`;
|
||||
|
||||
await sendMail(email, subject, text, html);
|
||||
}
|
||||
@@ -47,8 +56,15 @@ export async function sendTeamInviteEmail(
|
||||
}
|
||||
|
||||
const subject = "You have been invited to join a team";
|
||||
|
||||
// Use jsx-email template for beautiful HTML
|
||||
const html = await renderTeamInviteEmail({
|
||||
teamName,
|
||||
inviteUrl: url,
|
||||
});
|
||||
|
||||
// Fallback text version
|
||||
const text = `Hey,\n\nYou have been invited to join the team ${teamName} on Unsend.\n\nYou can accept the invitation by clicking the below URL:\n${url}\n\nThanks,\nUnsend Team`;
|
||||
const html = `<p>Hey,</p> <p>You have been invited to join the team <b>${teamName}</b> on Unsend.</p><p>You can accept the invitation by clicking the below URL:</p><p><a href="${url}">Accept invitation</a></p><br /><br /><p>Thanks,</p><p>Unsend Team</p>`;
|
||||
|
||||
await sendMail(email, subject, text, html);
|
||||
}
|
||||
|
122
pnpm-lock.yaml
generated
122
pnpm-lock.yaml
generated
@@ -50,7 +50,7 @@ importers:
|
||||
version: 0.503.0(react@19.1.0)
|
||||
next:
|
||||
specifier: 15.3.1
|
||||
version: 15.3.1(react-dom@19.1.0)(react@19.1.0)
|
||||
version: 15.3.1(@babel/core@7.26.10)(react-dom@19.1.0)(react@19.1.0)
|
||||
react:
|
||||
specifier: ^19.1.0
|
||||
version: 19.1.0
|
||||
@@ -209,6 +209,9 @@ importers:
|
||||
ioredis:
|
||||
specifier: ^5.6.1
|
||||
version: 5.6.1
|
||||
jsx-email:
|
||||
specifier: ^2.7.1
|
||||
version: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/node@22.15.2)(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
lucide-react:
|
||||
specifier: ^0.503.0
|
||||
version: 0.503.0(react@19.1.0)
|
||||
@@ -220,7 +223,7 @@ importers:
|
||||
version: 5.1.5
|
||||
next:
|
||||
specifier: ^15.3.1
|
||||
version: 15.3.1(react-dom@19.1.0)(react@19.1.0)
|
||||
version: 15.3.1(@babel/core@7.26.10)(react-dom@19.1.0)(react@19.1.0)
|
||||
next-auth:
|
||||
specifier: ^4.24.11
|
||||
version: 4.24.11(next@15.3.1)(nodemailer@7.0.3)(react-dom@19.1.0)(react@19.1.0)
|
||||
@@ -401,7 +404,7 @@ importers:
|
||||
version: 9.25.1
|
||||
jsx-email:
|
||||
specifier: ^2.7.1
|
||||
version: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
version: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/node@22.15.2)(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
lucide-react:
|
||||
specifier: ^0.503.0
|
||||
version: 0.503.0(react@19.1.0)
|
||||
@@ -3612,7 +3615,7 @@ packages:
|
||||
'@adobe/css-tools': 4.4.2
|
||||
hast-util-select: 6.0.4
|
||||
hast-util-to-string: 3.0.1
|
||||
jsx-email: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
jsx-email: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/node@22.15.2)(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
unist-util-remove: 4.0.0
|
||||
unist-util-visit: 5.0.0
|
||||
dev: false
|
||||
@@ -3623,7 +3626,7 @@ packages:
|
||||
peerDependencies:
|
||||
jsx-email: ^2.6.1
|
||||
dependencies:
|
||||
jsx-email: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
jsx-email: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/node@22.15.2)(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
rehype-minify-attribute-whitespace: 4.0.1
|
||||
rehype-minify-css-style: 4.0.1
|
||||
rehype-minify-enumerated-attribute: 5.0.2
|
||||
@@ -3650,7 +3653,7 @@ packages:
|
||||
peerDependencies:
|
||||
jsx-email: ^2.0.0
|
||||
dependencies:
|
||||
jsx-email: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
jsx-email: 2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/node@22.15.2)(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
pretty: 2.0.0
|
||||
dev: false
|
||||
|
||||
@@ -4436,7 +4439,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-arrow@1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-arrow@1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -4449,8 +4452,9 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -4499,7 +4503,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-collapsible@1.1.1(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-collapsible@1.1.1(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -4516,11 +4520,12 @@ packages:
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-context': 1.1.1(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-id': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-presence': 1.1.1(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-presence': 1.1.1(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -4552,7 +4557,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-collection@1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-collection@1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -4567,9 +4572,10 @@ packages:
|
||||
dependencies:
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-context': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-slot': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -4721,7 +4727,7 @@ packages:
|
||||
react: 19.1.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-dismissable-layer@1.1.1(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -4736,10 +4742,11 @@ packages:
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.0
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -4820,7 +4827,7 @@ packages:
|
||||
react: 19.1.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-focus-scope@1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-focus-scope@1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -4834,9 +4841,10 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -4990,7 +4998,7 @@ packages:
|
||||
react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popover@1.1.2(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-popover@1.1.2(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5006,24 +5014,25 @@ packages:
|
||||
'@radix-ui/primitive': 1.1.0
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-context': 1.1.1(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-dismissable-layer': 1.1.1(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-focus-guards': 1.1.1(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-focus-scope': 1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-id': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-popper': 1.2.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-portal': 1.1.2(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-presence': 1.1.1(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-popper': 1.2.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-portal': 1.1.2(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-presence': 1.1.1(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-slot': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
aria-hidden: 1.2.4
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
react-remove-scroll: 2.6.0(@types/react@19.1.2)(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popper@1.2.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-popper@1.2.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5037,16 +5046,17 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@floating-ui/react-dom': 2.1.2(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-arrow': 1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-arrow': 1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-context': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-rect': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-size': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/rect': 1.1.0
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -5080,7 +5090,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-portal@1.1.2(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-portal@1.1.2(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5093,9 +5103,10 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -5121,7 +5132,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-presence@1.1.1(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-presence@1.1.1(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5137,6 +5148,7 @@ packages:
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -5162,7 +5174,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-primitive@2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-primitive@2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5177,6 +5189,7 @@ packages:
|
||||
dependencies:
|
||||
'@radix-ui/react-slot': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -5242,7 +5255,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-roving-focus@1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-roving-focus@1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5256,15 +5269,16 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.0
|
||||
'@radix-ui/react-collection': 1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-collection': 1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-context': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-direction': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-id': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -5452,7 +5466,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-toggle-group@1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-toggle-group@1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-PpTJV68dZU2oqqgq75Uzto5o/XfOVgkrJ9rulVmfTKxWp3HfUjHE6CP/WLRR4AzPX9HWxw7vFow2me85Yu+Naw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5468,16 +5482,17 @@ packages:
|
||||
'@radix-ui/primitive': 1.1.0
|
||||
'@radix-ui/react-context': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-direction': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-roving-focus': 1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-toggle': 1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-toggle': 1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-toggle@1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
/@radix-ui/react-toggle@1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@@ -5491,9 +5506,10 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.0
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@types/react': 19.1.2
|
||||
'@types/react-dom': 19.1.2(@types/react@19.1.2)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
@@ -7533,7 +7549,7 @@ packages:
|
||||
'@trpc/client': 11.1.1(@trpc/server@11.1.1)(typescript@5.8.3)
|
||||
'@trpc/react-query': 11.1.1(@tanstack/react-query@5.74.4)(@trpc/client@11.1.1)(@trpc/server@11.1.1)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3)
|
||||
'@trpc/server': 11.1.1(typescript@5.8.3)
|
||||
next: 15.3.1(react-dom@19.1.0)(react@19.1.0)
|
||||
next: 15.3.1(@babel/core@7.26.10)(react-dom@19.1.0)(react@19.1.0)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
typescript: 5.8.3
|
||||
@@ -8491,7 +8507,7 @@ packages:
|
||||
'@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10)
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.17.0
|
||||
vite: 5.4.18
|
||||
vite: 5.4.18(@types/node@22.15.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
@@ -12815,7 +12831,7 @@ packages:
|
||||
object.values: 1.2.1
|
||||
dev: true
|
||||
|
||||
/jsx-email@2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3):
|
||||
/jsx-email@2.7.1(@jsx-email/plugin-inline@1.0.1)(@jsx-email/plugin-minify@1.0.2)(@jsx-email/plugin-pretty@1.0.0)(@types/node@22.15.2)(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)(typescript@5.8.3):
|
||||
resolution: {integrity: sha512-N958st14J3W5HrfO5/DKawdgTnCZTdl0xewCcjOnYudv81VI2iAO7BGK7nbDSBnFD7T2+Fzo4RwQWuZzSAZSyA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
@@ -12833,12 +12849,12 @@ packages:
|
||||
'@jsx-email/plugin-pretty': 1.0.0(jsx-email@2.7.1)
|
||||
'@parcel/watcher': 2.5.1
|
||||
'@radix-ui/colors': 3.0.0
|
||||
'@radix-ui/react-collapsible': 1.1.1(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-collapsible': 1.1.1(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-icons': 1.3.2(react@19.1.0)
|
||||
'@radix-ui/react-popover': 1.1.2(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-popover': 1.1.2(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-select': 2.2.2(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-slot': 1.1.0(@types/react@19.1.2)(react@19.1.0)
|
||||
'@radix-ui/react-toggle-group': 1.1.0(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@radix-ui/react-toggle-group': 1.1.0(@types/react-dom@19.1.2)(@types/react@19.1.2)(react-dom@19.1.0)(react@19.1.0)
|
||||
'@unocss/core': 0.65.4
|
||||
'@unocss/preset-rem-to-px': 0.65.4
|
||||
'@unocss/preset-typography': 0.65.4
|
||||
@@ -12878,7 +12894,7 @@ packages:
|
||||
titleize: 4.0.0
|
||||
unist-util-visit: 5.0.0
|
||||
valibot: 0.42.1(typescript@5.8.3)
|
||||
vite: 5.4.18
|
||||
vite: 5.4.18(@types/node@22.15.2)
|
||||
yargs-parser: 21.1.1
|
||||
transitivePeerDependencies:
|
||||
- '@emotion/is-prop-valid'
|
||||
@@ -14025,7 +14041,7 @@ packages:
|
||||
'@panva/hkdf': 1.2.1
|
||||
cookie: 0.7.2
|
||||
jose: 4.15.9
|
||||
next: 15.3.1(react-dom@19.1.0)(react@19.1.0)
|
||||
next: 15.3.1(@babel/core@7.26.10)(react-dom@19.1.0)(react@19.1.0)
|
||||
nodemailer: 7.0.3
|
||||
oauth: 0.9.15
|
||||
openid-client: 5.7.1
|
||||
@@ -14068,7 +14084,7 @@ packages:
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
dev: false
|
||||
|
||||
/next@15.3.1(react-dom@19.1.0)(react@19.1.0):
|
||||
/next@15.3.1(@babel/core@7.26.10)(react-dom@19.1.0)(react@19.1.0):
|
||||
resolution: {integrity: sha512-8+dDV0xNLOgHlyBxP1GwHGVaNXsmp+2NhZEYrXr24GWLHtt27YrBPbPuHvzlhi7kZNYjeJNR93IF5zfFu5UL0g==}
|
||||
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
|
||||
hasBin: true
|
||||
@@ -14097,7 +14113,7 @@ packages:
|
||||
postcss: 8.4.31
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
styled-jsx: 5.1.6(react@19.1.0)
|
||||
styled-jsx: 5.1.6(@babel/core@7.26.10)(react@19.1.0)
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 15.3.1
|
||||
'@next/swc-darwin-x64': 15.3.1
|
||||
@@ -16919,7 +16935,7 @@ packages:
|
||||
dependencies:
|
||||
inline-style-parser: 0.2.4
|
||||
|
||||
/styled-jsx@5.1.6(react@19.1.0):
|
||||
/styled-jsx@5.1.6(@babel/core@7.26.10)(react@19.1.0):
|
||||
resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
peerDependencies:
|
||||
@@ -16932,6 +16948,7 @@ packages:
|
||||
babel-plugin-macros:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/core': 7.26.10
|
||||
client-only: 0.0.1
|
||||
react: 19.1.0
|
||||
dev: false
|
||||
@@ -17772,7 +17789,7 @@ packages:
|
||||
d3-timer: 3.0.1
|
||||
dev: false
|
||||
|
||||
/vite@5.4.18:
|
||||
/vite@5.4.18(@types/node@22.15.2):
|
||||
resolution: {integrity: sha512-1oDcnEp3lVyHCuQ2YFelM4Alm2o91xNoMncRm1U7S+JdYfYOvbiGZ3/CxGttrOu2M/KcGz7cRC2DoNUA6urmMA==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
@@ -17803,6 +17820,7 @@ packages:
|
||||
terser:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/node': 22.15.2
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.5.3
|
||||
rollup: 4.40.0
|
||||
|
Reference in New Issue
Block a user