Feat/tailwind v4 shadcn update (#4706)

* feat: update dependencies and enhance UI components in Dokploy

- Updated various package versions in pnpm-lock.yaml to improve compatibility and performance, including React and Tailwind CSS.
- Modified components.json to change the styling to "radix-nova" and added new properties for icon library and menu color.
- Refactored multiple components to use updated class names for better styling consistency and responsiveness.
- Removed unused Radix UI components from package.json to streamline dependencies.
- Adjusted layout and styling in several dashboard components for improved user experience and visual appeal.
- Enhanced tooltip and form item components for better accessibility and usability.

* refactor: enhance UI components in HandleCertificate and SidebarLogo

- Updated the HandleCertificate component to improve dialog content height and textarea styling for better usability.
- Adjusted the SidebarLogo component layout to enhance alignment and spacing, ensuring a more consistent appearance across the sidebar.
- Implemented responsive design adjustments to textarea elements, preventing overflow and improving user experience.

* refactor: improve UI consistency and styling across dashboard components

- Updated Card components in ShowDeployments, ShowSchedules, and ShowVolumeBackups to remove unnecessary border styles for a cleaner look.
- Enhanced TabsList components in ShowProviderForm and ShowProviderFormCompose by adding a variant for improved visual distinction.
- Adjusted spacing in AdvancedEnvironmentSelector for better layout and readability.
- Removed redundant border classes in Service component for a more streamlined design.

* [autofix.ci] apply automated fixes

* chore: update package dependencies and refactor email rendering

- Upgraded React and React DOM to version 19.2.7 across multiple packages for improved performance and compatibility.
- Updated TSX to version 4.22.4 in various package.json files.
- Refactored email rendering from `renderAsync` to `render` in notification utilities and email templates for consistency.
- Adjusted Tailwind configuration usage in email templates to utilize a centralized configuration file.

These changes enhance the overall stability and maintainability of the codebase.

* refactor: update badge variants across dashboard components

- Changed badge variant from "outline-solid" to "outline" in multiple components including columns, show-domains, and various deployment tables for consistency in styling.
- Updated button variants in billing and project templates to align with the new badge styling.
- Enhanced input components to support password generation and error messaging, improving user experience.

These changes streamline the UI and ensure a cohesive design across the application.

* refactor: clean up calendar component imports and structure

- Removed redundant imports of icons from lucide-react and streamlined the import statements for better readability.
- Adjusted the placement of type imports to enhance code organization.

These changes improve the maintainability and clarity of the calendar component.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Mauricio Siu
2026-06-30 15:45:23 -06:00
committed by GitHub
parent 8b6481501e
commit 3ca5afd49f
202 changed files with 7857 additions and 5747 deletions

View File

@@ -45,7 +45,7 @@
"@octokit/rest": "^20.1.2",
"@oslojs/crypto": "1.0.1",
"@oslojs/encoding": "1.1.0",
"@react-email/components": "^0.0.21",
"@react-email/components": "^1.0.12",
"@trpc/server": "11.10.0",
"adm-zip": "^0.5.16",
"ai": "^6.0.86",
@@ -74,8 +74,8 @@
"postgres": "3.4.4",
"public-ip": "6.0.2",
"qrcode": "^1.5.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"react": "19.2.7",
"react-dom": "19.2.7",
"resend": "^6.0.2",
"semver": "7.7.3",
"shell-quote": "^1.8.1",
@@ -97,8 +97,8 @@
"@types/node-schedule": "2.1.6",
"@types/nodemailer": "^6.4.17",
"@types/qrcode": "^1.5.5",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@types/semver": "7.7.1",
"@types/shell-quote": "^1.7.5",
"@types/ssh2": "1.15.1",
@@ -110,7 +110,7 @@
"rimraf": "6.1.3",
"tailwindcss": "^3.4.17",
"tsc-alias": "1.8.10",
"tsx": "^4.16.2",
"tsx": "^4.22.4",
"typescript": "^5.8.3"
},
"packageManager": "pnpm@10.22.0",

View File

@@ -12,6 +12,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
projectName: string;
@@ -35,17 +36,7 @@ export const BuildFailedEmail = ({
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Body className="bg-white my-auto mx-auto font-sans px-2">
<Container className="border border-solid border-[#eaeaea] rounded-lg my-[40px] mx-auto p-[20px] max-w-[465px]">
<Section className="mt-[32px]">

View File

@@ -12,6 +12,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
projectName: string;
@@ -35,17 +36,7 @@ export const BuildSuccessEmail = ({
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Body className="bg-white my-auto mx-auto font-sans px-2">
<Container className="border border-solid border-[#eaeaea] rounded-lg my-[40px] mx-auto p-[20px] max-w-[465px]">
<Section className="mt-[32px]">

View File

@@ -10,6 +10,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
projectName: string;
@@ -32,17 +33,7 @@ export const DatabaseBackupEmail = ({
return (
<Html>
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Head />
<Body className="bg-white my-auto mx-auto font-sans px-2">

View File

@@ -10,6 +10,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
message: string;
@@ -24,17 +25,7 @@ export const DockerCleanupEmail = ({
return (
<Html>
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Head />
<Body className="bg-white my-auto mx-auto font-sans px-2">

View File

@@ -10,6 +10,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
type: "error" | "success";
@@ -29,17 +30,7 @@ export const DokployBackupEmail = ({
return (
<Html>
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Head />
<Body className="bg-white my-auto mx-auto font-sans px-2">
<Container className="border border-solid border-[#eaeaea] rounded-lg my-[40px] mx-auto p-[20px] max-w-[465px]">

View File

@@ -10,6 +10,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
date: string;
@@ -22,17 +23,7 @@ export const DokployRestartEmail = ({
return (
<Html>
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Head />
<Body className="bg-white my-auto mx-auto font-sans px-2">

View File

@@ -13,6 +13,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
interface InvitationEmailProps {
inviteLink: string;
@@ -30,17 +31,7 @@ export const InvitationEmail = ({
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Body className="bg-[#f4f4f5] my-auto mx-auto font-sans">
<Container className="my-[40px] mx-auto max-w-[520px]">
{/* Header */}

View File

@@ -15,6 +15,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
userName: string;
@@ -38,17 +39,7 @@ export const InvoiceNotificationEmail = ({
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Body className="bg-[#f4f4f5] my-auto mx-auto font-sans">
<Container className="my-[40px] mx-auto max-w-[520px]">
{/* Header */}

View File

@@ -15,6 +15,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
userName: string;
@@ -38,17 +39,7 @@ export const PaymentFailedEmail = ({
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Body className="bg-[#f4f4f5] my-auto mx-auto font-sans">
<Container className="my-[40px] mx-auto max-w-[520px]">
{/* Header */}

View File

@@ -12,6 +12,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
userName: string;
@@ -27,17 +28,7 @@ export const VerifyEmailTemplate = ({
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Body className="bg-[#f4f4f5] my-auto mx-auto font-sans">
<Container className="my-[40px] mx-auto max-w-[520px]">
{/* Header */}

View File

@@ -10,6 +10,7 @@ import {
Tailwind,
Text,
} from "@react-email/components";
import { emailTailwindConfig } from "../tailwind-config";
export type TemplateProps = {
projectName: string;
@@ -44,17 +45,7 @@ export const VolumeBackupEmail = ({
return (
<Html>
<Preview>{previewText}</Preview>
<Tailwind
config={{
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Tailwind config={emailTailwindConfig}>
<Head />
<Body className="bg-white my-auto mx-auto font-sans px-2">

View File

@@ -9,12 +9,13 @@
"export": "email export"
},
"dependencies": {
"@react-email/components": "0.0.21",
"react-email": "2.1.5",
"react": "^18.2.0"
"@react-email/components": "^1.0.12",
"react-email": "^6.6.5",
"react": "^19.2.7",
"react-dom": "^19.2.7"
},
"devDependencies": {
"@types/react": "18.2.33",
"@types/react-dom": "18.2.14"
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0"
}
}

View File

@@ -0,0 +1,14 @@
import type { Tailwind } from "@react-email/components";
import type { ComponentProps } from "react";
type TailwindConfig = NonNullable<ComponentProps<typeof Tailwind>["config"]>;
export const emailTailwindConfig: TailwindConfig = {
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
};

View File

@@ -1,7 +1,7 @@
import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema";
import BuildFailedEmail from "@dokploy/server/emails/emails/build-failed";
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import { format } from "date-fns";
import { and, eq } from "drizzle-orm";
import {
@@ -76,7 +76,7 @@ export const sendBuildErrorNotifications = async ({
} = notification;
try {
if (email || resend) {
const template = await renderAsync(
const template = await render(
BuildFailedEmail({
projectName,
applicationName,

View File

@@ -2,7 +2,7 @@ import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema";
import BuildSuccessEmail from "@dokploy/server/emails/emails/build-success";
import type { Domain } from "@dokploy/server/services/domain";
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import { format } from "date-fns";
import { and, eq } from "drizzle-orm";
import {
@@ -79,7 +79,7 @@ export const sendBuildSuccessNotifications = async ({
} = notification;
try {
if (email || resend) {
const template = await renderAsync(
const template = await render(
BuildSuccessEmail({
projectName,
applicationName,

View File

@@ -1,7 +1,7 @@
import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema";
import DatabaseBackupEmail from "@dokploy/server/emails/emails/database-backup";
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import { format } from "date-fns";
import { and, eq } from "drizzle-orm";
import {
@@ -76,7 +76,7 @@ export const sendDatabaseBackupNotifications = async ({
} = notification;
try {
if (email || resend) {
const template = await renderAsync(
const template = await render(
DatabaseBackupEmail({
projectName,
applicationName,

View File

@@ -1,7 +1,7 @@
import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema";
import DockerCleanupEmail from "@dokploy/server/emails/emails/docker-cleanup";
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import { format } from "date-fns";
import { and, eq } from "drizzle-orm";
import {
@@ -63,7 +63,7 @@ export const sendDockerCleanupNotifications = async (
} = notification;
try {
if (email || resend) {
const template = await renderAsync(
const template = await render(
DockerCleanupEmail({ message, date: date.toLocaleString() }),
).catch();

View File

@@ -1,7 +1,7 @@
import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema";
import DokployBackupEmail from "@dokploy/server/emails/emails/dokploy-backup";
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import { format } from "date-fns";
import { eq } from "drizzle-orm";
import {
@@ -66,7 +66,7 @@ export const sendDokployBackupNotifications = async ({
try {
if (email || resend) {
const template = await renderAsync(
const template = await render(
DokployBackupEmail({
type,
errorMessage,

View File

@@ -1,7 +1,7 @@
import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema";
import DokployRestartEmail from "@dokploy/server/emails/emails/dokploy-restart";
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import { format } from "date-fns";
import { eq } from "drizzle-orm";
import {
@@ -59,7 +59,7 @@ export const sendDokployRestartNotifications = async () => {
try {
if (email || resend) {
const template = await renderAsync(
const template = await render(
DokployRestartEmail({ date: date.toLocaleString() }),
).catch();

View File

@@ -1,7 +1,7 @@
import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema";
import { VolumeBackupEmail } from "@dokploy/server/emails/emails/volume-backup";
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import { format } from "date-fns";
import { and, eq } from "drizzle-orm";
import {
@@ -88,7 +88,7 @@ export const sendVolumeBackupNotifications = async ({
try {
if (email || resend) {
const subject = `Volume Backup ${type === "success" ? "Successful" : "Failed"} - ${applicationName}`;
const htmlContent = await renderAsync(
const htmlContent = await render(
VolumeBackupEmail({
projectName,
applicationName,

View File

@@ -1,4 +1,4 @@
import { renderAsync } from "@react-email/components";
import { render } from "@react-email/components";
import InvitationEmail from "../emails/emails/invitation";
import VerifyEmailTemplate from "../emails/emails/verify-email";
import { sendEmailNotification } from "../utils/notifications/utils";
@@ -40,7 +40,7 @@ export const sendVerificationEmail = async ({
email: string;
verificationUrl: string;
}) => {
const html = await renderAsync(
const html = await render(
VerifyEmailTemplate({
userName: userName || "User",
verificationUrl,
@@ -62,7 +62,7 @@ export const renderInvitationEmail = async ({
inviteLink: string;
organizationName: string;
}) => {
return renderAsync(
return render(
InvitationEmail({
inviteLink,
toEmail: email,