Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SessionProvider } from 'next-auth/react'; // 1. Import the Provider
import { auth } from '@/auth'; // 2. Import your auth config
import './globals.css';
import { ThemeProvider } from '@/components/theme-provider';
import { Toaster } from '@/components/ui/toaster';

export const metadata: Metadata = {
title: 'SecureFlow | AI Security Gatekeeper',
Expand Down Expand Up @@ -34,6 +35,7 @@ export default async function RootLayout({
{/* 4. Wrap your app in the SessionProvider */}
<SessionProvider session={session}>
<ThemeProvider>{children}</ThemeProvider>
<Toaster />
</SessionProvider>
</body>
</html>
Expand Down
30 changes: 27 additions & 3 deletions src/components/ui/toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import * as React from "react"
import * as ToastPrimitives from "@radix-ui/react-toast"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
import { X, PhoneIncoming, ShieldCheck } from "lucide-react"

import { cn } from "@/lib/utils"

Expand Down Expand Up @@ -31,7 +31,9 @@ const toastVariants = cva(
variant: {
default: "border bg-background text-foreground",
destructive:
"destructive group border-destructive bg-destructive text-destructive-foreground",
"destructive group border-2 border-destructive bg-destructive text-destructive-foreground [animation:pulse_2s_ease-in-out_infinite]",
success:
"success group border-green-600/50 bg-background text-foreground",
},
},
defaultVariants: {
Expand Down Expand Up @@ -112,6 +114,27 @@ const ToastDescription = React.forwardRef<
))
ToastDescription.displayName = ToastPrimitives.Description.displayName

// Renders a themed icon based on toast variant:
// - destructive -> "Police Intercept" incoming call icon
// - success -> "Plan Executed" shield check icon
// - default -> no icon
const ToastIcon = ({
variant,
}: {
variant?: "default" | "destructive" | "success" | null
}) => {
if (variant === "destructive") {
return (
<PhoneIncoming className="h-5 w-5 shrink-0 text-destructive-foreground" />
)
}
if (variant === "success") {
return <ShieldCheck className="h-5 w-5 shrink-0 text-green-500" />
}
return null
}
ToastIcon.displayName = "ToastIcon"

type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>

type ToastActionElement = React.ReactElement<typeof ToastAction>
Expand All @@ -126,4 +149,5 @@ export {
ToastDescription,
ToastClose,
ToastAction,
}
ToastIcon,
}
20 changes: 12 additions & 8 deletions src/components/ui/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Toast,
ToastClose,
ToastDescription,
ToastIcon,
ToastProvider,
ToastTitle,
ToastViewport,
Expand All @@ -15,14 +16,17 @@ export function Toaster() {

return (
<ToastProvider>
{toasts.map(function ({ id, title, description, action, ...props }) {
{toasts.map(function ({ id, title, description, action, variant, ...props }) {
return (
<Toast key={id} {...props}>
<div className="grid gap-1">
{title && <ToastTitle>{title}</ToastTitle>}
{description && (
<ToastDescription>{description}</ToastDescription>
)}
<Toast key={id} variant={variant} {...props}>
<div className="flex items-start gap-3">
<ToastIcon variant={variant} />
<div className="grid gap-1">
{title && <ToastTitle>{title}</ToastTitle>}
{description && (
<ToastDescription>{description}</ToastDescription>
)}
</div>
</div>
{action}
<ToastClose />
Expand All @@ -32,4 +36,4 @@ export function Toaster() {
<ToastViewport />
</ToastProvider>
)
}
}
Loading