Files
popa-launcher/src/renderer/components/ShopItem.tsx
2025-12-13 00:12:32 +05:00

242 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/renderer/components/ShopItem.tsx
import React, { useState } from 'react';
import {
Card,
CardMedia,
CardContent,
Box,
Typography,
Button,
IconButton,
} from '@mui/material';
import CoinsDisplay from './CoinsDisplay';
import { CapePreview } from './CapePreview';
import VisibilityIcon from '@mui/icons-material/Visibility';
import CapePreviewModal from './PlayerPreviewModal';
export type ShopItemType = 'case' | 'cape';
export interface ShopItemProps {
type: ShopItemType;
id: string;
name: string;
description?: string;
imageUrl?: string;
price?: number;
itemsCount?: number;
isOpening?: boolean;
playerSkinUrl?: string;
disabled?: boolean;
onClick: () => void;
}
export default function ShopItem({
type,
name,
description,
imageUrl,
price,
itemsCount,
isOpening,
disabled,
playerSkinUrl,
onClick,
}: ShopItemProps) {
const buttonText =
type === 'case' ? (isOpening ? 'Открываем...' : 'Открыть кейс') : 'Купить';
const [previewOpen, setPreviewOpen] = useState(false);
return (
<Card
sx={{
position: 'relative',
width: '100%',
maxWidth: 300,
height: 440,
display: 'flex',
flexDirection: 'column',
background: 'rgba(20,20,20,0.9)',
borderRadius: '2.5vw',
border: '1px solid rgba(255,255,255,0.08)',
boxShadow: '0 10px 40px rgba(0,0,0,0.8)',
overflow: 'hidden',
transition: 'transform 0.35s ease, box-shadow 0.35s ease',
'&:hover': {
transform: 'scale(1.01)',
boxShadow: '0 20px 20px rgba(242,113,33,0.1)',
},
}}
>
{/* Градиентный свет сверху */}
<Box
sx={{
position: 'absolute',
inset: 0,
pointerEvents: 'none',
background:
'radial-gradient(circle at top, rgba(242,113,33,0.25), transparent 60%)',
}}
/>
{imageUrl && (
<Box sx={{ position: 'relative', p: 1.5, pb: 0 }}>
{type === 'case' ? (
<Box
sx={{
borderRadius: '1.8vw',
overflow: 'hidden',
border: '1px solid rgba(255,255,255,0.12)',
background:
'linear-gradient(135deg, rgba(40,40,40,0.9), rgba(15,15,15,0.9))',
}}
>
<CardMedia
component="img"
image={imageUrl}
alt={name}
sx={{
width: '100%',
height: 160,
objectFit: 'cover',
}}
/>
</Box>
) : (
<CapePreview imageUrl={imageUrl} alt={name} />
)}
{/* Кнопка предпросмотра плаща */}
{type === 'cape' && (
<IconButton
onClick={(e) => {
e.stopPropagation();
setPreviewOpen(true);
}}
sx={{
position: 'absolute',
top: 10,
right: 10,
color: 'white',
background:
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
'&:hover': {
transform: 'scale(1.05)',
},
transition: 'all 0.5s ease'
}}
>
<VisibilityIcon fontSize="small" />
</IconButton>
)}
</Box>
)}
<CardContent
sx={{
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
pt: 2,
pb: 2,
}}
>
<Box>
<Typography
sx={{
fontFamily: 'Benzin-Bold',
fontSize: '1.05rem',
mb: 1,
backgroundImage:
'linear-gradient(136deg, rgb(242,113,33), rgb(233,64,87), rgb(138,35,135))',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
}}
>
{name}
</Typography>
{description && (
<Typography
sx={{
color: 'rgba(255,255,255,0.75)',
fontSize: '0.85rem',
minHeight: 42,
maxHeight: 42,
overflow: 'hidden',
}}
>
{description}
</Typography>
)}
{typeof price === 'number' && (
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
mt: 1.2,
}}
>
<Typography
sx={{ color: 'rgba(255,255,255,0.7)', fontSize: '0.8rem' }}
>
Цена
</Typography>
<CoinsDisplay value={price} size="small" />
</Box>
)}
{type === 'case' && typeof itemsCount === 'number' && (
<Typography
sx={{
color: 'rgba(255,255,255,0.6)',
fontSize: '0.75rem',
mt: 1,
}}
>
Предметов в кейсе: {itemsCount}
</Typography>
)}
</Box>
{/* Кнопка как в Registration */}
<Button
variant="contained"
fullWidth
disabled={disabled}
onClick={onClick}
sx={{
mt: 2,
transition: 'transform 0.3s ease',
background:
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
fontFamily: 'Benzin-Bold',
borderRadius: '2.5vw',
fontSize: '0.85rem',
'&:hover': {
transform: 'scale(1.02)',
},
}}
>
{buttonText}
</Button>
</CardContent>
{type === 'cape' && imageUrl && (
<CapePreviewModal
open={previewOpen}
onClose={() => setPreviewOpen(false)}
capeUrl={imageUrl}
skinUrl={playerSkinUrl}
/>
)}
</Card>
);
}