marketing/src/components/Cart/CartItem.tsx

165 lines
4.1 KiB
TypeScript
Raw Normal View History

2026-08-24 10:07:16 +00:00
import { useState } from 'react';
import styled from 'styled-components';
import { getProductAmount } from '../../utils/product';
import type { Product } from '../../types/cart';
interface CartItemProps {
product: Product;
isProcessing: boolean;
onOpen: () => void;
onReplace: () => void;
onDelete: () => void;
}
export function CartItem({
product,
isProcessing,
onOpen,
onReplace,
onDelete,
}: CartItemProps) {
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
<Item $processing={isProcessing}>
<ItemImage type="button" onClick={onOpen}>
<img src={product.image} alt="" />
</ItemImage>
<ItemDetails>
<ItemName>{product.name}</ItemName>
<ItemPrice>
{getProductAmount(product)} &times; {Math.round(product.price * 100) / 100}
</ItemPrice>
</ItemDetails>
<MenuWrapper>
<MenuButton
type="button"
onClick={() => setIsMenuOpen(value => !value)}
>
&#8942;
</MenuButton>
{isMenuOpen && (
<Dropdown>
<ul>
<li>
<button type="button" onClick={onReplace}>
Заменить
</button>
</li>
<li>
<button type="button" onClick={onDelete}>
Удалить
</button>
</li>
</ul>
</Dropdown>
)}
</MenuWrapper>
</Item>
);
}
const Item = styled.li<{ $processing: boolean }>`
display: flex;
align-items: center;
padding: 16px 0;
border-bottom: 1px solid #f0f0f0;
position: relative;
transition: opacity 0.4s, transform 0.4s;
opacity: ${({ $processing }) => ($processing ? 0.5 : 1)};
pointer-events: ${({ $processing }) => ($processing ? 'none' : 'auto')};
`;
const ItemImage = styled.button`
width: 72px;
height: 65px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16px;
flex-shrink: 0;
position: relative;
overflow: hidden;
border: 0;
background: transparent;
cursor: pointer;
img {
max-width: 100%;
max-height: 100%;
}
`;
const ItemDetails = styled.div`
flex: 1;
`;
const ItemName = styled.div`
font-size: 15px;
color: ${({ theme }) => theme.colors.darkGreen};
margin-bottom: 4px;
`;
const ItemPrice = styled.div`
font-size: 14px;
color: ${({ theme }) => theme.colors.gray};
`;
const MenuWrapper = styled.div`
position: relative;
`;
const MenuButton = styled.button`
background: none;
border: none;
color: #b0b0b0;
cursor: pointer;
padding: 4px 8px;
font-size: 20px;
letter-spacing: 2px;
border-radius: 4px;
transition: 0.2s;
&:hover {
background: #f3f4f6;
color: ${({ theme }) => theme.colors.darkGreen};
}
`;
const Dropdown = styled.div`
position: absolute;
right: 0;
top: 100%;
background: #ffffff;
border: 1px solid #eee;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
min-width: 150px;
padding: 6px 0;
z-index: 10;
margin-top: 4px;
ul {
list-style: none;
}
button {
width: 100%;
padding: 10px 16px;
font-size: 14px;
color: ${({ theme }) => theme.colors.darkGreen};
cursor: pointer;
transition: 0.2s;
background: transparent;
border: 0;
text-align: left;
&:hover {
background: #f3f4f6;
}
}
`;