This commit is contained in:
2025-10-20 17:08:35 +05:00
parent 4f0e5b9898
commit 56ed2221c8
5 changed files with 145 additions and 0 deletions
@@ -0,0 +1,61 @@
import clsx from "clsx";
import React from "react";
import Button from "../ui/Button";
import useToastsStore from "../../store/toastsStore";
export interface ToastLayoutProps {
id: string;
type: "notification" | "warning";
title: string;
message: string;
onDeny: () => void;
onAllow: () => void;
image?: string;
icon?: React.ReactNode;
}
export default function ToastLayout({
id,
type,
title,
message,
onDeny,
onAllow,
}: ToastLayoutProps) {
const { removeToast } = useToastsStore();
function handleDeny() {
onDeny();
removeToast(id);
}
function handleAllow() {
onAllow();
removeToast(id);
}
return (
<div className="flex w-[20.833vw] rounded-[1.944vw] p-[0.556vw] bg-white shadow-[0_4px_40px_0_rgba(15,16,17,0.1)]">
<div className="flex flex-col gap-[0.556vw]">
<div
className={clsx(
"button-m",
type === "notification" ? "text-[#7D7D7D]" : "text-[#FF4517]"
)}
>
{title}
</div>
<div className="text-m">{message}</div>
<div className="flex gap-[0.556vw]">
<Button variant="critical" size="small" onClick={handleDeny}>
Отклонить
</Button>
<Button variant="primary" size="small" onClick={handleAllow}>
Разрешить
</Button>
</div>
</div>
</div>
);
}
@@ -0,0 +1,31 @@
import useToastsStore from "../../store/toastsStore";
import ToastLayout from "./ToastLayout";
import { AnimatePresence, motion } from "motion/react";
export default function ToastsContainer() {
const { toasts } = useToastsStore();
return (
<div className="fixed w-full flex flex-col-reverse justify-center items-center top-[1.111vw] left-1/2 -translate-x-1/2 z-50 gap-[0.278vw] ">
<AnimatePresence mode="popLayout">
{toasts.map((toast) => (
<motion.div
key={toast.id}
layout
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{
duration: 0.5,
type: "spring",
damping: 20,
stiffness: 300,
}}
>
<ToastLayout {...toast} />
</motion.div>
))}
</AnimatePresence>
</div>
);
}