feat: integrate Sonner for toast notifications in setup page and layout

This commit is contained in:
Pattadon 2025-03-14 12:50:44 +07:00
parent 22449089fa
commit d9d670093a
5 changed files with 79 additions and 9 deletions

View File

@ -7,6 +7,7 @@ import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/s
import DynamicBreadcrumb from "./dynamic-breadcrumb"; import DynamicBreadcrumb from "./dynamic-breadcrumb";
import { extractRoute } from "@/lib/utils"; import { extractRoute } from "@/lib/utils";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { Toaster } from "@/components/ui/sonner";
export default function AppLayout({ export default function AppLayout({
children, children,
@ -29,6 +30,7 @@ export default function AppLayout({
</div> </div>
</header> </header>
{children} {children}
<Toaster />
</SidebarInset> </SidebarInset>
</SidebarProvider> </SidebarProvider>
); );

View File

@ -10,6 +10,8 @@ import {
} from "@/schemas/application.schema"; } from "@/schemas/application.schema";
import { z } from "zod"; import { z } from "zod";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { toast } from "sonner";
type PlantingSchema = z.infer<typeof plantingDetailsFormSchema>; type PlantingSchema = z.infer<typeof plantingDetailsFormSchema>;
type HarvestSchema = z.infer<typeof harvestDetailsFormSchema>; type HarvestSchema = z.infer<typeof harvestDetailsFormSchema>;
@ -34,11 +36,27 @@ export default function SetupPage() {
const handleNext = () => { const handleNext = () => {
if (step === 1 && !plantingDetails) { if (step === 1 && !plantingDetails) {
alert("Please complete the Planting Details before proceeding."); toast.warning(
"Please complete the Planting Details before proceeding.",
{
action: {
label: "Close",
onClick: () => toast.dismiss(),
},
}
);
return; return;
} }
if (step === 2 && !harvestDetails) { if (step === 2 && !harvestDetails) {
alert("Please complete the Harvest Details before proceeding."); toast.warning(
"Please complete the Harvest Details before proceeding.",
{
action: {
label: "Close",
onClick: () => toast.dismiss(),
},
}
);
return; return;
} }
setStep((prev) => prev + 1); setStep((prev) => prev + 1);
@ -50,7 +68,12 @@ export default function SetupPage() {
const handleSubmit = () => { const handleSubmit = () => {
if (!mapData) { if (!mapData) {
alert("Please select an area on the map before submitting."); toast.warning("Please select an area on the map before submitting.", {
action: {
label: "Close",
onClick: () => toast.dismiss(),
},
});
return; return;
} }

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

@ -40,12 +40,13 @@
"lucide-react": "^0.475.0", "lucide-react": "^0.475.0",
"next": "15.1.0", "next": "15.1.0",
"next-auth": "^4.24.11", "next-auth": "^4.24.11",
"next-themes": "^0.4.4", "next-themes": "^0.4.6",
"react": "^19.0.0", "react": "^19.0.0",
"react-day-picker": "8.10.1", "react-day-picker": "8.10.1",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-hook-form": "^7.54.2", "react-hook-form": "^7.54.2",
"recharts": "^2.15.1", "recharts": "^2.15.1",
"sonner": "^2.0.1",
"tailwind-merge": "^3.0.1", "tailwind-merge": "^3.0.1",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"zod": "^3.24.2" "zod": "^3.24.2"

View File

@ -1,9 +1,5 @@
lockfileVersion: '6.0' lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies: dependencies:
'@hookform/resolvers': '@hookform/resolvers':
specifier: ^4.0.0 specifier: ^4.0.0
@ -99,7 +95,7 @@ dependencies:
specifier: ^4.24.11 specifier: ^4.24.11
version: 4.24.11(next@15.1.0)(react-dom@19.0.0)(react@19.0.0) version: 4.24.11(next@15.1.0)(react-dom@19.0.0)(react@19.0.0)
next-themes: next-themes:
specifier: ^0.4.4 specifier: ^0.4.6
version: 0.4.6(react-dom@19.0.0)(react@19.0.0) version: 0.4.6(react-dom@19.0.0)(react@19.0.0)
react: react:
specifier: ^19.0.0 specifier: ^19.0.0
@ -116,6 +112,9 @@ dependencies:
recharts: recharts:
specifier: ^2.15.1 specifier: ^2.15.1
version: 2.15.1(react-dom@19.0.0)(react@19.0.0) version: 2.15.1(react-dom@19.0.0)(react@19.0.0)
sonner:
specifier: ^2.0.1
version: 2.0.1(react-dom@19.0.0)(react@19.0.0)
tailwind-merge: tailwind-merge:
specifier: ^3.0.1 specifier: ^3.0.1
version: 3.0.2 version: 3.0.2
@ -4334,6 +4333,16 @@ packages:
dev: false dev: false
optional: true optional: true
/sonner@2.0.1(react-dom@19.0.0)(react@19.0.0):
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
dependencies:
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
dev: false
/source-map-js@1.2.1: /source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -4834,3 +4843,7 @@ packages:
/zod@3.24.2: /zod@3.24.2:
resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==}
dev: false dev: false
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false