fix: redesign

This commit is contained in:
2026-07-10 16:01:27 +03:30
parent 05262b7636
commit a447222201
31 changed files with 1426 additions and 1738 deletions
+69
View File
@@ -0,0 +1,69 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import { CheckCircleIcon, ExclamationCircleIcon, XMarkIcon } from '@heroicons/react/24/outline';
export interface Toast {
id: string;
type: 'success' | 'error';
message: string;
}
let toastListeners: ((toast: Toast) => void)[] = [];
export function showToast(type: 'success' | 'error', message: string) {
const toast: Toast = {
id: Math.random().toString(36).slice(2),
type,
message,
};
toastListeners.forEach((fn) => fn(toast));
}
export default function ToastContainer() {
const [toasts, setToasts] = useState<Toast[]>([]);
const addToast = useCallback((toast: Toast) => {
setToasts((prev) => [...prev, toast]);
setTimeout(() => {
setToasts((prev) => prev.filter((t) => t.id !== toast.id));
}, 4000);
}, []);
useEffect(() => {
toastListeners.push(addToast);
return () => {
toastListeners = toastListeners.filter((fn) => fn !== addToast);
};
}, [addToast]);
if (toasts.length === 0) return null;
return (
<div className="fixed top-4 left-1/2 -translate-x-1/2 z-[100] flex flex-col gap-2 w-full max-w-md pointer-events-none">
{toasts.map((toast) => (
<div
key={toast.id}
className={`pointer-events-auto flex items-center gap-3 px-4 py-3 rounded-xl shadow-xl ring-1 animate-in fade-in slide-in-from-top-4 duration-300 ${
toast.type === 'success'
? 'bg-green-50 dark:bg-green-950/80 ring-green-200 dark:ring-green-800 text-green-800 dark:text-green-200'
: 'bg-red-50 dark:bg-red-950/80 ring-red-200 dark:ring-red-800 text-red-800 dark:text-red-200'
}`}
>
{toast.type === 'success' ? (
<CheckCircleIcon className="h-5 w-5 text-green-500 dark:text-green-400 flex-shrink-0" />
) : (
<ExclamationCircleIcon className="h-5 w-5 text-red-500 dark:text-red-400 flex-shrink-0" />
)}
<p className="flex-1 text-sm font-medium">{toast.message}</p>
<button
onClick={() => setToasts((prev) => prev.filter((t) => t.id !== toast.id))}
className="flex-shrink-0 p-0.5 rounded-lg hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
>
<XMarkIcon className="h-4 w-4" />
</button>
</div>
))}
</div>
);
}