aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/shared/Notification.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/shared/Notification.tsx')
-rw-r--r--frontend/src/components/shared/Notification.tsx58
1 files changed, 34 insertions, 24 deletions
diff --git a/frontend/src/components/shared/Notification.tsx b/frontend/src/components/shared/Notification.tsx
index bcc11c4..68cbc7a 100644
--- a/frontend/src/components/shared/Notification.tsx
+++ b/frontend/src/components/shared/Notification.tsx
@@ -1,11 +1,29 @@
'use client';
import { useEffect, useState } from 'react';
-import { CheckCircle, AlertCircle, X } from 'lucide-react';
+import { CheckCircle, AlertCircle, Info, X } from 'lucide-react';
+import { cva, type VariantProps } from 'class-variance-authority';
+import { cn } from '@/lib/utils';
export type NotificationType = 'success' | 'error' | 'info';
-interface NotificationProps {
+const notificationVariants = cva(
+ "fixed z-50 top-4 right-4 flex items-center gap-3 p-4 rounded-lg shadow-lg border max-w-sm transition-all duration-300 animate-in fade-in slide-in-from-top-5",
+ {
+ variants: {
+ variant: {
+ success: "bg-background border-border text-foreground",
+ error: "bg-background border-border text-foreground",
+ info: "bg-background border-border text-foreground",
+ }
+ },
+ defaultVariants: {
+ variant: "info",
+ },
+ }
+);
+
+interface NotificationProps extends VariantProps<typeof notificationVariants> {
type: NotificationType;
message: string;
duration?: number;
@@ -41,38 +59,30 @@ export function Notification({
const getIcon = () => {
switch (type) {
case 'success':
- return <CheckCircle className="h-5 w-5 text-green-500" />;
+ return <CheckCircle className="h-5 w-5 text-primary" />;
case 'error':
- return <AlertCircle className="h-5 w-5 text-red-500" />;
+ return <AlertCircle className="h-5 w-5 text-destructive" />;
case 'info':
- return <AlertCircle className="h-5 w-5 text-blue-500" />;
+ return <Info className="h-5 w-5 text-primary" />;
default:
return null;
}
};
- const getContainerClasses = () => {
- const baseClasses = 'fixed top-4 right-4 z-50 flex items-center gap-3 rounded-lg p-4 shadow-md max-w-sm';
-
- switch (type) {
- case 'success':
- return `${baseClasses} bg-green-50 text-green-800 border border-green-200`;
- case 'error':
- return `${baseClasses} bg-red-50 text-red-800 border border-red-200`;
- case 'info':
- return `${baseClasses} bg-blue-50 text-blue-800 border border-blue-200`;
- default:
- return baseClasses;
- }
- };
-
return (
- <div className={getContainerClasses()}>
- {getIcon()}
- <div className="flex-1">{message}</div>
+ <div className={cn(notificationVariants({ variant: type as any }))}>
+ <div className={cn(
+ "flex h-8 w-8 items-center justify-center rounded-full",
+ type === 'success' && "bg-primary/10",
+ type === 'error' && "bg-destructive/10",
+ type === 'info' && "bg-primary/10"
+ )}>
+ {getIcon()}
+ </div>
+ <div className="flex-1 text-sm font-medium">{message}</div>
<button
onClick={handleClose}
- className="text-gray-500 hover:text-gray-700 focus:outline-none"
+ className="rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground focus:outline-none transition-colors"
aria-label="Close notification"
>
<X className="h-4 w-4" />