diff --git a/frontend/app/(sidebar)/layout.tsx b/frontend/app/(sidebar)/layout.tsx index 3e79b13..98a524b 100644 --- a/frontend/app/(sidebar)/layout.tsx +++ b/frontend/app/(sidebar)/layout.tsx @@ -7,6 +7,7 @@ import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/s import DynamicBreadcrumb from "./dynamic-breadcrumb"; import { extractRoute } from "@/lib/utils"; import { usePathname } from "next/navigation"; +import { Toaster } from "@/components/ui/sonner"; export default function AppLayout({ children, @@ -29,6 +30,7 @@ export default function AppLayout({ {children} + ); diff --git a/frontend/app/(sidebar)/setup/page.tsx b/frontend/app/(sidebar)/setup/page.tsx index 271cb64..4febef6 100644 --- a/frontend/app/(sidebar)/setup/page.tsx +++ b/frontend/app/(sidebar)/setup/page.tsx @@ -10,6 +10,8 @@ import { } from "@/schemas/application.schema"; import { z } from "zod"; import { Button } from "@/components/ui/button"; +import { toast } from "sonner"; + type PlantingSchema = z.infer; type HarvestSchema = z.infer; @@ -34,11 +36,27 @@ export default function SetupPage() { const handleNext = () => { 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; } 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; } setStep((prev) => prev + 1); @@ -50,7 +68,12 @@ export default function SetupPage() { const handleSubmit = () => { 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; } diff --git a/frontend/components/ui/sonner.tsx b/frontend/components/ui/sonner.tsx new file mode 100644 index 0000000..452f4d9 --- /dev/null +++ b/frontend/components/ui/sonner.tsx @@ -0,0 +1,31 @@ +"use client" + +import { useTheme } from "next-themes" +import { Toaster as Sonner } from "sonner" + +type ToasterProps = React.ComponentProps + +const Toaster = ({ ...props }: ToasterProps) => { + const { theme = "system" } = useTheme() + + return ( + + ) +} + +export { Toaster } diff --git a/frontend/package.json b/frontend/package.json index 4da49cc..13595d5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -40,12 +40,13 @@ "lucide-react": "^0.475.0", "next": "15.1.0", "next-auth": "^4.24.11", - "next-themes": "^0.4.4", + "next-themes": "^0.4.6", "react": "^19.0.0", "react-day-picker": "8.10.1", "react-dom": "^19.0.0", "react-hook-form": "^7.54.2", "recharts": "^2.15.1", + "sonner": "^2.0.1", "tailwind-merge": "^3.0.1", "tailwindcss-animate": "^1.0.7", "zod": "^3.24.2" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 7635441..cd38842 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -1,9 +1,5 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - dependencies: '@hookform/resolvers': specifier: ^4.0.0 @@ -99,7 +95,7 @@ dependencies: specifier: ^4.24.11 version: 4.24.11(next@15.1.0)(react-dom@19.0.0)(react@19.0.0) next-themes: - specifier: ^0.4.4 + specifier: ^0.4.6 version: 0.4.6(react-dom@19.0.0)(react@19.0.0) react: specifier: ^19.0.0 @@ -116,6 +112,9 @@ dependencies: recharts: specifier: ^2.15.1 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: specifier: ^3.0.1 version: 3.0.2 @@ -4334,6 +4333,16 @@ packages: dev: false 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: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -4834,3 +4843,7 @@ packages: /zod@3.24.2: resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} dev: false + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false