marketing/src/components/Cart/ProductModal.tsx

162 lines
3.7 KiB
TypeScript
Raw Normal View History

2026-08-24 10:07:16 +00:00
import styled from 'styled-components';
import { formatCurrency } from '../../utils/formatCurrency';
import { getLargeProductImage } from '../../utils/product';
import type { Product } from '../../types/cart';
2026-09-03 10:50:12 +00:00
import {useEffect} from "react";
2026-09-04 15:57:54 +00:00
import {reachGoal} from "../../hooks/useYM";
2026-08-24 10:07:16 +00:00
interface ProductModalProps {
product: Product | null;
onClose: () => void;
onReplace: (product: Product) => void;
2026-08-30 11:47:34 +00:00
onDelete: (product: Product) => void;
2026-08-24 10:07:16 +00:00
}
export function ProductModal({
product,
onClose,
onReplace,
2026-08-30 11:47:34 +00:00
onDelete,
2026-08-24 10:07:16 +00:00
}: ProductModalProps) {
2026-09-03 10:50:12 +00:00
useEffect(() => {
if (product !== null) {
2026-09-04 15:57:54 +00:00
reachGoal('ac_open_popup')
2026-09-03 10:50:12 +00:00
}
}, [product]);
2026-08-24 10:07:16 +00:00
if (!product) return null;
return (
<Overlay onClick={onClose}>
<Window onClick={event => event.stopPropagation()}>
<CloseButton type="button" aria-label="Закрыть" onClick={onClose}>
&times;
</CloseButton>
<ImageWrap>
<img src={getLargeProductImage(product)} alt={product.name} />
</ImageWrap>
<Title>{product.name}</Title>
<Details>
<span>{product.n}</span> · <span>{formatCurrency(product.total_price)}</span>
</Details>
<ActionButton type="button" onClick={() => onReplace(product)}>
Заменить
</ActionButton>
<AnotherButton
href="#"
onClick={event => {
event.preventDefault();
2026-08-30 11:47:34 +00:00
onDelete(product);
2026-08-24 10:07:16 +00:00
}}
>
2026-08-30 11:47:34 +00:00
Удалить
2026-08-24 10:07:16 +00:00
</AnotherButton>
</Window>
</Overlay>
);
}
const Overlay = styled.div`
2026-09-04 15:57:54 +00:00
height: 100vh;
2026-08-24 10:07:16 +00:00
position: fixed;
display: flex;
inset: 0;
background-color: rgba(0, 0, 0, 0.4);
justify-content: center;
align-items: center;
z-index: 1000;
`;
const Window = styled.div`
background-color: #ffffff;
border-radius: 12px;
width: 100%;
max-width: 340px;
padding: 20px 24px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
position: relative;
2026-09-02 06:41:12 +00:00
max-height: 90vh;
overflow: auto;
2026-08-24 10:07:16 +00:00
`;
const CloseButton = styled.button`
position: absolute;
top: 15px;
right: 15px;
background: none;
border: none;
2026-08-31 08:55:33 +00:00
color: #CEDFD0;
2026-08-24 10:07:16 +00:00
font-size: 24px;
line-height: 1;
cursor: pointer;
padding: 5px;
&:hover {
color: #777;
}
`;
const ImageWrap = styled.div`
display: flex;
justify-content: center;
margin: 20px 0;
img {
width: 160px;
height: auto;
object-fit: contain;
}
`;
const Title = styled.h2`
font-size: 18px;
font-weight: 700;
text-align: center;
color: #222222;
line-height: 1.4;
margin: 0 0 10px;
`;
const Details = styled.p`
font-size: 15px;
text-align: center;
color: #555555;
margin: 0 0 24px;
`;
const ActionButton = styled.button`
display: block;
width: 100%;
background-color: #5ba653;
color: #ffffff;
font-size: 16px;
font-weight: 600;
padding: 14px 0;
border: none;
border-radius: 8px;
cursor: pointer;
&:hover {
background-color: #4e9247;
}
`;
const AnotherButton = styled.a`
display: block;
text-align: center;
margin-top: 15px;
color: #5ba653;
font-size: 14px;
text-decoration: none;
font-weight: 500;
&:hover {
text-decoration: underline;
}
`;