feat: add next-themes and sonner for improved theming and notifications

This commit is contained in:
Mauricio Siu
2025-03-23 13:38:32 -06:00
parent 7df27e67b0
commit 56037ef88e
5 changed files with 86 additions and 5 deletions

View File

@@ -6,6 +6,7 @@ import copy from "copy-to-clipboard";
import {
CheckCircle2,
Copy,
CopyIcon,
Loader2,
Mail,
RefreshCcw,
@@ -14,6 +15,7 @@ import {
import Link from "next/link";
import { redirect, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import { toast } from "sonner";
interface LicenseSessionResponse {
type: "basic" | "professional" | "business";
@@ -70,6 +72,7 @@ export default function LicenseSuccess() {
copy(data?.key ?? "");
setCopied(true);
setTimeout(() => setCopied(false), 2000);
toast.success("Copied to clipboard");
};
return (
@@ -169,15 +172,30 @@ export default function LicenseSuccess() {
Steps to enable paid features
</p>
<ul>
<li>
<span>1. Web Server</span>
<li className="flex items-center gap-2">
<span>1. Install Dokploy Instance on your server</span>
<code className="text-green-500 font-mono bg-black rounded-lg p-1">
curl -sSL https://dokploy.com/install.sh | sh
</code>
<CopyIcon
className="w-4 h-4 cursor-pointer"
onClick={() => {
copy(
"curl -sSL https://dokploy.com/install.sh | sh",
);
toast.success("Copied to clipboard");
}}
/>
</li>
<li>
<span>2. Enable Paid Features</span>
<span>2. Go to your web server section</span>
</li>
<li>
<span>3. Enable Paid Features</span>
</li>
<li>
<span>
3. Copy the Key Below and Paste it in the license key
4. Copy the Key Below and Paste it in the license key
field and click on validate
</span>
</li>

View File

@@ -1,3 +1,4 @@
import { Toaster } from "@/components/ui/sonner";
import clsx from "clsx";
import type { Metadata } from "next";
import { NextIntlClientProvider } from "next-intl";
@@ -63,6 +64,7 @@ export default async function RootLayout({
<body>
<NextIntlClientProvider messages={messages}>
{children}
<Toaster />
</NextIntlClientProvider>
</body>
</html>

View File

@@ -0,0 +1,31 @@
"use client";
import { useTheme } from "next-themes";
import { Toaster as Sonner } from "sonner";
type ToasterProps = React.ComponentProps<typeof Sonner>;
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme();
return (
<Sonner
theme={theme as ToasterProps["theme"]}
className="toaster group"
toastOptions={{
classNames: {
toast:
"group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
description: "group-[.toast]:text-muted-foreground",
actionButton:
"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
cancelButton:
"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
},
}}
{...props}
/>
);
};
export { Toaster };

View File

@@ -12,7 +12,6 @@
},
"browserslist": "defaults, not ie <= 11",
"dependencies": {
"copy-to-clipboard": "3.3.3",
"@headlessui/react": "^2.2.0",
"@headlessui/tailwindcss": "^0.2.0",
"@prettier/plugin-xml": "^3.4.1",
@@ -34,11 +33,13 @@
"canvas-confetti": "^1.9.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"copy-to-clipboard": "3.3.3",
"framer-motion": "^11.3.19",
"hast-util-to-jsx-runtime": "2.3.5",
"lucide-react": "0.364.0",
"next": "15.2.0",
"next-intl": "^3.26.5",
"next-themes": "^0.4.6",
"prettier": "^3.3.3",
"react": "18.2.0",
"react-dom": "18.2.0",
@@ -52,6 +53,7 @@
"sharp": "^0.33.5",
"shiki": "1.22.2",
"slugify": "^1.6.6",
"sonner": "^2.0.1",
"tailwind-merge": "^2.2.2",
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "^1.0.7",

28
pnpm-lock.yaml generated
View File

@@ -172,6 +172,9 @@ importers:
next-intl:
specifier: ^3.26.5
version: 3.26.5(next@15.2.0(@babel/core@7.26.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)
next-themes:
specifier: ^0.4.6
version: 0.4.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
prettier:
specifier: ^3.3.3
version: 3.3.3
@@ -211,6 +214,9 @@ importers:
slugify:
specifier: ^1.6.6
version: 1.6.6
sonner:
specifier: ^2.0.1
version: 2.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
tailwind-merge:
specifier: ^2.2.2
version: 2.4.0
@@ -3001,6 +3007,12 @@ packages:
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
next-themes@0.4.6:
resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
peerDependencies:
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
next@15.0.3:
resolution: {integrity: sha512-ontCbCRKJUIoivAdGB34yCaOcPgYXr9AAkV/IwqFfWWTXEPUgLYkSkqBhIk9KK7gGmgjc64B+RdoeIDM13Irnw==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
@@ -3512,6 +3524,12 @@ packages:
resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==}
engines: {node: '>=8.0.0'}
sonner@2.0.1:
resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==}
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.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@@ -7144,6 +7162,11 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
next-themes@0.4.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
dependencies:
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
next@15.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@next/env': 15.0.3
@@ -7712,6 +7735,11 @@ snapshots:
slugify@1.6.6: {}
sonner@2.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
dependencies:
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
source-map-js@1.2.1: {}
source-map@0.7.4: {}