From b051d9d2efb79bee55c118aa40ea556d94674a8d Mon Sep 17 00:00:00 2001 From: denshooter Date: Sat, 10 Jan 2026 02:40:50 +0100 Subject: [PATCH] style: refine admin dashboard and project management UI with cohesive color palette and improved readability - Update background colors and text styles for better contrast and legibility. - Enhance button styles and hover effects for a more modern look. - Remove unnecessary scaling effects and adjust border styles for consistency. - Introduce a cohesive design language across components to improve user experience. --- app/api/contacts/route.ts | 25 +++++ app/components/ChatWidget.tsx | 32 +++--- app/components/Projects.tsx | 109 +++++++++++-------- app/globals.css | 57 +++++++--- app/manage/page.tsx | 2 +- app/projects/page.tsx | 47 +++++--- components/AnalyticsDashboard.tsx | 162 ++++++++++++++-------------- components/EmailManager.tsx | 74 ++++++------- components/EmailResponder.tsx | 62 +++++------ components/ImportExport.tsx | 34 +++--- components/ModernAdminDashboard.tsx | 2 +- components/PerformanceDashboard.tsx | 2 +- components/ProjectManager.tsx | 87 +++++++-------- components/Toast.tsx | 6 +- 14 files changed, 387 insertions(+), 314 deletions(-) create mode 100644 app/api/contacts/route.ts diff --git a/app/api/contacts/route.ts b/app/api/contacts/route.ts new file mode 100644 index 0000000..94dec66 --- /dev/null +++ b/app/api/contacts/route.ts @@ -0,0 +1,25 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { prisma } from '@/lib/prisma'; + +export async function GET(request: NextRequest) { + try { + // In a real app, you would check for admin session here + // For now, we trust the 'x-admin-request' header if it's set by the server-side component or middleware + // but typically you'd verify the session cookie/token + + const contacts = await prisma.contact.findMany({ + orderBy: { + createdAt: 'desc', + }, + take: 100, + }); + + return NextResponse.json({ contacts }); + } catch (error) { + console.error('Error fetching contacts:', error); + return NextResponse.json( + { error: 'Failed to fetch contacts' }, + { status: 500 } + ); + } +} diff --git a/app/components/ChatWidget.tsx b/app/components/ChatWidget.tsx index 9550640..09272c8 100644 --- a/app/components/ChatWidget.tsx +++ b/app/components/ChatWidget.tsx @@ -221,11 +221,11 @@ export default function ChatWidget() { setIsOpen(true); } }} - className="fixed bottom-4 left-4 md:bottom-6 md:left-6 z-30 bg-stone-800/80 backdrop-blur-md text-stone-50 p-3.5 rounded-full shadow-[0_8px_20px_rgba(41,37,36,0.2)] hover:bg-stone-800 hover:scale-105 transition-all duration-300 group cursor-pointer border border-white/10 ring-1 ring-white/20" + className="fixed bottom-4 left-4 md:bottom-6 md:left-6 z-30 bg-[#292524] text-[#fdfcf8] p-3.5 rounded-full shadow-[0_8px_20px_rgba(41,37,36,0.25)] hover:bg-[#44403c] hover:scale-105 transition-all duration-300 group cursor-pointer border border-[#f3f1e7]/20 ring-1 ring-[#f3f1e7]/10" aria-label="Open chat" > - + {/* Tooltip */} @@ -244,16 +244,16 @@ export default function ChatWidget() { animate={{ opacity: 1, y: 0, scale: 1, filter: "blur(0px)" }} exit={{ opacity: 0, y: 20, scale: 0.95, filter: "blur(10px)" }} transition={{ type: "spring", damping: 30, stiffness: 400 }} - className="fixed bottom-20 left-4 right-4 md:bottom-24 md:left-6 md:right-auto z-30 md:w-[380px] h-[60vh] md:h-[550px] max-h-[600px] bg-[#fdfcf8]/30 backdrop-blur-2xl saturate-150 rounded-2xl shadow-[0_12px_40px_rgba(41,37,36,0.15)] flex flex-col overflow-hidden border border-white/40 ring-1 ring-white/50" + className="fixed bottom-20 left-4 right-4 md:bottom-24 md:left-6 md:right-auto z-30 md:w-[380px] h-[60vh] md:h-[550px] max-h-[600px] bg-[#fdfcf8]/95 backdrop-blur-xl saturate-100 rounded-2xl shadow-[0_12px_40px_rgba(41,37,36,0.2)] flex flex-col overflow-hidden border border-[#e7e5e4] ring-1 ring-[#f3f1e7]" > {/* Header */} -
+
-
- +
+
- +

@@ -293,14 +293,14 @@ export default function ChatWidget() { className={`flex ${message.sender === "user" ? "justify-end" : "justify-start"}`} >

{message.text}

@@ -327,7 +327,7 @@ export default function ChatWidget() { animate={{ opacity: 1, y: 0 }} className="flex justify-start" > -
+
{/* Input */} -
+
diff --git a/app/components/Projects.tsx b/app/components/Projects.tsx index bcb1df9..35f73f8 100644 --- a/app/components/Projects.tsx +++ b/app/components/Projects.tsx @@ -2,7 +2,7 @@ import { useState, useEffect } from "react"; import { motion, Variants } from "framer-motion"; -import { ExternalLink, Github, Layers, ArrowRight } from "lucide-react"; +import { ExternalLink, Github, Layers, ArrowRight, ArrowLeft, Calendar } from "lucide-react"; import Link from "next/link"; import Image from "next/image"; @@ -98,11 +98,8 @@ const Projects = () => { {/* Project Cover / Image Area */}
@@ -114,12 +111,10 @@ const Projects = () => { fill className="object-cover transition-transform duration-1000 ease-out group-hover:scale-110" /> - {/* Subtle Overlay for better text readability and depth */}
) : (
- {/* Mesh Gradient Fallback */}
@@ -141,32 +136,34 @@ const Projects = () => { {/* Featured Badge */} {project.featured && (
-
+
Featured
)} {/* Overlay Links */} -
+
{project.github && ( e.stopPropagation()} > )} - {project.live && ( + {project.live && !project.title.toLowerCase().includes('kernel panic') && ( e.stopPropagation()} > @@ -175,47 +172,67 @@ const Projects = () => {
{/* Content */} -
-
-

+
+ {/* Stretched Link covering the whole card (including image area) */} + + +
+

{project.title}

- - {new Date(project.date).getFullYear()} - +
+ + {new Date(project.date).getFullYear()} +
-

+

{project.description}

-
-
- {project.tags.slice(0, 3).map((tag, tIdx) => ( - - {tag} - - ))} - {project.tags.length > 3 && ( - - + {project.tags.length - 3} - - )} -
+
+ {project.tags.slice(0, 4).map((tag) => ( + + {tag} + + ))} + {project.tags.length > 4 && ( + + {project.tags.length - 4} + )} +
- - Read more{" "} - - +
+
+ {project.github && ( + e.stopPropagation()} + > + + + )} + {project.live && !project.title.toLowerCase().includes('kernel panic') && ( + e.stopPropagation()} + > + + + )} +
diff --git a/app/globals.css b/app/globals.css index 40c5fd2..a3c18cc 100644 --- a/app/globals.css +++ b/app/globals.css @@ -80,7 +80,7 @@ html { 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 10px 10px -5px rgba(0, 0, 0, 0.02), inset 0 0 20px rgba(255, 255, 255, 0.8); - transform: translateY(-4px) scale(1.005); + transform: translateY(-4px); border-color: #ffffff; } @@ -103,9 +103,6 @@ div { color: #44403c; } -/* Utility for the liquid melt effect container */ -/* Liquid container removed - no filters applied */ - /* Hide scrollbar but keep functionality */ ::-webkit-scrollbar { width: 8px; @@ -145,18 +142,6 @@ div { will-change: transform; } -@keyframes liquid-pulse { - 0% { - transform: scale(1); - } - 50% { - transform: scale(1.05); - } - 100% { - transform: scale(1); - } -} - /* Liquid Blobs Background */ .liquid-bg-blob { position: absolute; @@ -188,3 +173,43 @@ div { .markdown pre { @apply bg-stone-900 text-stone-50 p-4 rounded-xl overflow-x-auto mb-6; } + +/* Admin Dashboard Styles - Organic Modern */ +.animated-bg { + background: #fdfcf8; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; +} + +.admin-glass { + background: rgba(253, 252, 248, 0.9); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-bottom: 1px solid #e7e5e4; + color: #292524; +} + +.admin-glass-light { + background: #ffffff; + border: 1px solid #e7e5e4; + color: #292524; + transition: all 0.2s ease; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} + +.admin-glass-light:hover { + background: #fdfcf8; + border-color: #d6d3d1; + box-shadow: 0 4px 6px rgba(0,0,0,0.05); +} + +.admin-glass-card { + background: #ffffff; + border: 1px solid #e7e5e4; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); + color: #292524; +} diff --git a/app/manage/page.tsx b/app/manage/page.tsx index b7cea41..d37deff 100644 --- a/app/manage/page.tsx +++ b/app/manage/page.tsx @@ -276,7 +276,7 @@ const AdminPage = () => { >
-
+

Admin Access

diff --git a/app/projects/page.tsx b/app/projects/page.tsx index fc38cb1..00d8793 100644 --- a/app/projects/page.tsx +++ b/app/projects/page.tsx @@ -184,32 +184,34 @@ const ProjectsPage = () => { {project.featured && (
-
+
Featured
)} {/* Overlay Links */} -
+
{project.github && ( e.stopPropagation()} > )} - {project.live && ( + {project.live && !project.title.toLowerCase().includes('kernel panic') && ( e.stopPropagation()} > @@ -218,6 +220,13 @@ const ProjectsPage = () => {
+ {/* Stretched Link covering the whole card (including image area) */} + +

{project.title} @@ -246,27 +255,31 @@ const ProjectsPage = () => { )}

- diff --git a/components/AnalyticsDashboard.tsx b/components/AnalyticsDashboard.tsx index b71a3b1..4aa9289 100644 --- a/components/AnalyticsDashboard.tsx +++ b/components/AnalyticsDashboard.tsx @@ -177,24 +177,24 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps)
- +
-

{title}

- {description &&

{description}

} +

{title}

+ {description &&

{description}

}
-

{value}

+

{value}

{trend && trendValue && (
{trendValue} @@ -207,21 +207,21 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) const getDifficultyColor = (difficulty: string) => { switch (difficulty) { - case 'Beginner': return 'bg-green-500/30 text-green-400 border-green-500/40'; - case 'Intermediate': return 'bg-yellow-500/30 text-yellow-400 border-yellow-500/40'; - case 'Advanced': return 'bg-orange-500/30 text-orange-400 border-orange-500/40'; - case 'Expert': return 'bg-red-500/30 text-red-400 border-red-500/40'; - default: return 'bg-gray-500/30 text-gray-400 border-gray-500/40'; + case 'Beginner': return 'bg-green-50 text-green-700 border-green-200'; + case 'Intermediate': return 'bg-yellow-50 text-yellow-700 border-yellow-200'; + case 'Advanced': return 'bg-orange-50 text-orange-700 border-orange-200'; + case 'Expert': return 'bg-red-50 text-red-700 border-red-200'; + default: return 'bg-stone-50 text-stone-600 border-stone-200'; } }; const getCategoryColor = (index: number) => { const colors = [ - 'bg-blue-500/30 text-blue-400', - 'bg-purple-500/30 text-purple-400', - 'bg-green-500/30 text-green-400', - 'bg-pink-500/30 text-pink-400', - 'bg-indigo-500/30 text-indigo-400' + 'bg-stone-100 text-stone-700', + 'bg-stone-200 text-stone-800', + 'bg-stone-300 text-stone-900', + 'bg-stone-100 text-stone-700', + 'bg-stone-200 text-stone-800' ]; return colors[index % colors.length]; }; @@ -233,23 +233,23 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) {/* Header */}
-

- +

+ Analytics Dashboard

-

Portfolio performance and user engagement metrics

+

Portfolio performance and user engagement metrics

{/* Time Range Selector */} -
+
{(['7d', '30d', '90d', '1y'] as const).map((range) => (
{loading && ( -
+
- - Loading analytics data... + + Loading analytics data...
)} {error && ( -
-
+
+
Error: {error}
@@ -297,8 +297,8 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) <> {/* Overview Stats */}
-

- +

+ Overview

@@ -306,7 +306,7 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) title="Total Views" value={data.overview.totalViews.toLocaleString()} icon={Eye} - color="bg-blue-500/30" + color="bg-stone-100 text-stone-600" trend="up" trendValue="+12.5%" description="All-time page views" @@ -315,7 +315,7 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) title="Projects" value={data.overview.totalProjects} icon={Globe} - color="bg-green-500/30" + color="bg-green-100 text-green-600" trend="up" trendValue="+2" description={`${data.overview.publishedProjects} published`} @@ -324,7 +324,7 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) title="Engagement" value={data.overview.totalLikes} icon={Heart} - color="bg-pink-500/30" + color="bg-pink-100 text-pink-600" trend="up" trendValue="+8.2%" description="Total likes & shares" @@ -333,7 +333,7 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) title="Performance" value={data.overview.avgLighthouse} icon={Zap} - color="bg-orange-500/30" + color="bg-orange-100 text-orange-600" trend="up" trendValue="+5%" description="Avg Lighthouse score" @@ -342,7 +342,7 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) title="Bounce Rate" value={`${data.metrics.bounceRate}%`} icon={MousePointer} - color="bg-purple-500/30" + color="bg-stone-100 text-stone-600" trend="down" trendValue="-2.1%" description="User retention" @@ -353,9 +353,9 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) {/* Project Performance */}
{/* Top Projects */} -
-

- +
+

+ Top Performing Projects

@@ -368,20 +368,20 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: index * 0.1 }} - className="flex items-center justify-between p-4 admin-glass-light rounded-xl" + className="flex items-center justify-between p-4 bg-stone-50 rounded-xl border border-stone-100" >
-
+
#{index + 1}
-

{project.title}

-

{project.category}

+

{project.title}

+

{project.category}

-

{project.views.toLocaleString()}

-

views

+

{project.views.toLocaleString()}

+

views

))} @@ -389,9 +389,9 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps)
{/* Categories Distribution */} -
-

- +
+

+ Categories

@@ -405,16 +405,16 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) >
- {category} + {category}
-
+
- {count} + {count}
))} @@ -425,9 +425,9 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) {/* Difficulty & Engagement */}
{/* Difficulty Distribution */} -
-

- +
+

+ Difficulty Levels

@@ -448,9 +448,9 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps)
{/* Recent Activity */} -
-

- +
+

+ Recent Activity

@@ -463,25 +463,25 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.1 }} - className="flex items-center space-x-4 p-3 admin-glass-light rounded-xl" + className="flex items-center space-x-4 p-3 bg-stone-50 rounded-xl border border-stone-100" > -
+
-

{project.title}

-

+

{project.title}

+

Updated {new Date(project.updatedAt).toLocaleDateString()}

{project.featured && ( - + Featured )} - {project.published ? 'Live' : 'Draft'} @@ -496,30 +496,30 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps) {/* Reset Modal */} {showResetModal && ( -
+
-
- +
+
-

Reset Analytics Data

-

This action cannot be undone

+

Reset Analytics Data

+

This action cannot be undone

- +
-
+
- -
+ +

Warning:

This will permanently delete the selected analytics data. This action cannot be reversed.

@@ -544,14 +544,14 @@ export function AnalyticsDashboard({ isAuthenticated }: AnalyticsDashboardProps)
); @@ -164,12 +164,12 @@ export const EmailManager: React.FC = () => { {/* Header */}
-

Email Manager

-

Manage your contact messages

+

Email Manager

+

Manage your contact messages

) : ( -
+

Select a message to view details

@@ -311,23 +311,23 @@ export const EmailManager: React.FC = () => { initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} - className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4" + className="fixed inset-0 bg-stone-900/20 backdrop-blur-sm z-50 flex items-center justify-center p-4" onClick={() => setShowReplyModal(false)} > e.stopPropagation()} >
-

Reply to {selectedMessage.name}

+

Reply to {selectedMessage.name}

@@ -336,20 +336,20 @@ export const EmailManager: React.FC = () => { value={replyContent} onChange={(e) => setReplyContent(e.target.value)} placeholder="Type your reply..." - className="w-full h-32 p-3 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none" + className="w-full h-32 p-3 bg-stone-50 border border-stone-200 rounded-lg text-stone-900 placeholder:text-stone-400 focus:outline-none focus:ring-2 focus:ring-stone-400 resize-none" />
diff --git a/components/EmailResponder.tsx b/components/EmailResponder.tsx index b949ed8..7c068b2 100644 --- a/components/EmailResponder.tsx +++ b/components/EmailResponder.tsx @@ -85,19 +85,19 @@ export const EmailResponder: React.FC = ({ return ( <> -
-
+
+
{/* Header */} -
+

📧 E-Mail Antwort senden

-

Wähle ein schönes Template für deine Antwort

+

Wähle ein schönes Template für deine Antwort

{/* Import Section */} -
-

Import Projekte

-

+

+

Import Projekte

+

JSON-Datei mit Projekten hochladen

-
diff --git a/components/PerformanceDashboard.tsx b/components/PerformanceDashboard.tsx index ac7f63c..6110bf3 100644 --- a/components/PerformanceDashboard.tsx +++ b/components/PerformanceDashboard.tsx @@ -75,7 +75,7 @@ export const PerformanceDashboard: React.FC = () => { setIsVisible(true); trackEvent('dashboard-toggle', { action: 'show' }); }} - className="fixed bottom-4 right-4 bg-blue-600 text-white px-4 py-2 rounded-lg shadow-lg hover:bg-blue-700 transition-colors z-50" + className="fixed bottom-4 right-4 bg-white text-stone-700 border border-stone-200 px-4 py-2 rounded-lg shadow-md hover:bg-stone-50 transition-colors z-50" > 📊 Performance diff --git a/components/ProjectManager.tsx b/components/ProjectManager.tsx index 7373dc4..86fca66 100644 --- a/components/ProjectManager.tsx +++ b/components/ProjectManager.tsx @@ -52,7 +52,6 @@ export const ProjectManager: React.FC = ({ const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid'); const [searchTerm, setSearchTerm] = useState(''); const [selectedCategory, setSelectedCategory] = useState('all'); - // Editor is now a separate page - no modal state needed const categories = ['all', 'Web Development', 'Full-Stack', 'Web Application', 'Mobile App', 'Design']; @@ -77,10 +76,6 @@ export const ProjectManager: React.FC = ({ } }; - // closeEditor removed - editor is now separate page - - // saveProject removed - editor is now separate page - const deleteProject = async (projectId: string) => { if (!confirm('Are you sure you want to delete this project?')) return; @@ -100,9 +95,9 @@ export const ProjectManager: React.FC = ({ const getStatusColor = (project: Project) => { if (project.published) { - return project.featured ? 'text-purple-400 bg-purple-500/20' : 'text-green-400 bg-green-500/20'; + return project.featured ? 'text-stone-700 bg-stone-200' : 'text-green-700 bg-green-100'; } - return 'text-yellow-400 bg-yellow-500/20'; + return 'text-yellow-700 bg-yellow-100'; }; const getStatusText = (project: Project) => { @@ -117,20 +112,20 @@ export const ProjectManager: React.FC = ({ {/* Header */}
-

Project Management

-

{projects.length} projects • {projects.filter(p => p.published).length} published

+

Project Management

+

{projects.length} projects • {projects.filter(p => p.published).length} published

@@ -225,7 +220,7 @@ export const ProjectManager: React.FC = ({ {/* Project Content */}
-

{project.description}

+

{project.description}

{/* Tags */} @@ -234,13 +229,13 @@ export const ProjectManager: React.FC = ({ {project.tags.slice(0, 3).map((tag) => ( {tag} ))} {project.tags.length > 3 && ( - + +{project.tags.length - 3} )} @@ -258,7 +253,7 @@ export const ProjectManager: React.FC = ({ href={project.github} target="_blank" rel="noopener noreferrer" - className="p-1 text-white/60 hover:text-white transition-colors" + className="p-1 text-stone-400 hover:text-stone-900 transition-colors" > @@ -268,7 +263,7 @@ export const ProjectManager: React.FC = ({ href={project.live} target="_blank" rel="noopener noreferrer" - className="p-1 text-white/60 hover:text-white transition-colors" + className="p-1 text-stone-400 hover:text-stone-900 transition-colors" > @@ -277,18 +272,18 @@ export const ProjectManager: React.FC = ({
{/* Analytics */} -
+
-

{project.analytics?.views || 0}

-

Views

+

{project.analytics?.views || 0}

+

Views

-

{project.analytics?.likes || 0}

-

Likes

+

{project.analytics?.likes || 0}

+

Likes

-

{project.performance?.lighthouse || 90}

-

Score

+

{project.performance?.lighthouse || 90}

+

Score

@@ -302,13 +297,13 @@ export const ProjectManager: React.FC = ({ key={project.id} initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} - className="admin-glass-card p-6 rounded-xl hover:scale-[1.01] transition-all duration-300 group" + className="admin-glass-card p-6 rounded-xl hover:shadow-md transition-all duration-300 group bg-white border border-stone-200" >
-

{project.title}

-

{project.category}

+

{project.title}

+

{project.category}

@@ -316,7 +311,7 @@ export const ProjectManager: React.FC = ({ {getStatusText(project)} -
+
{project.analytics?.views || 0} views • {new Date(project.updatedAt).toLocaleDateString()} @@ -324,13 +319,13 @@ export const ProjectManager: React.FC = ({
@@ -341,8 +336,6 @@ export const ProjectManager: React.FC = ({ ))}
)} - - {/* Editor is now a separate page at /editor */}
); }; diff --git a/components/Toast.tsx b/components/Toast.tsx index 7006a03..bac6fb3 100644 --- a/components/Toast.tsx +++ b/components/Toast.tsx @@ -50,9 +50,9 @@ const ToastItem = ({ toast, onRemove }: ToastProps) => { case 'warning': return ; case 'info': - return ; + return ; default: - return ; + return ; } }; @@ -112,7 +112,7 @@ const ToastItem = ({ toast, onRemove }: ToastProps) => { initial={{ width: '100%' }} animate={{ width: '0%' }} transition={{ duration: (toast.duration || 5000) / 1000, ease: "linear" }} - className="absolute bottom-0 left-0 h-1 bg-gradient-to-r from-blue-400 to-green-400 rounded-b-xl" + className="absolute bottom-0 left-0 h-1 bg-gradient-to-r from-stone-400 to-stone-600 rounded-b-xl" /> )}