import React, { useEffect, useMemo, useState } from 'react'; import { Dialog, DialogTitle, DialogContent, Box, Typography, Grid, Paper, CircularProgress, } from '@mui/material'; import type { Case, CaseItem } from '../api'; import { fetchCase } from '../api'; import CloseIcon from '@mui/icons-material/Close'; import IconButton from '@mui/material/IconButton'; const CARD_BG = 'radial-gradient(circle at 10% 10%, rgba(242,113,33,0.14), transparent 55%), radial-gradient(circle at 90% 20%, rgba(233,64,205,0.12), transparent 55%), rgba(10,10,20,0.86)'; const CardFacePaperSx = { borderRadius: '1.2vw', background: CARD_BG, border: '1px solid rgba(255,255,255,0.08)', boxShadow: '0 1.2vw 3.2vw rgba(0,0,0,0.55)', color: 'white', } as const; const GLASS_PAPER_SX = { borderRadius: '1.2vw', overflow: 'hidden', background: 'radial-gradient(circle at 10% 10%, rgba(242,113,33,0.14), transparent 55%), radial-gradient(circle at 90% 20%, rgba(233,64,205,0.12), transparent 55%), rgba(10,10,20,0.86)', border: '1px solid rgba(255,255,255,0.08)', boxShadow: '0 1.2vw 3.2vw rgba(0,0,0,0.55)', color: 'white', backdropFilter: 'blur(16px)', } as const; function stripMinecraftColors(text?: string | null): string { if (!text) return ''; return text.replace(/§[0-9A-FK-ORa-fk-or]/g, ''); } function getChancePercent(itemWeight: number, total: number) { if (!total || total <= 0) return 0; return (itemWeight / total) * 100; } function getRarityByWeight(weight?: number): 'common' | 'rare' | 'epic' | 'legendary' { if (weight === undefined || weight === null) return 'common'; if (weight <= 5) return 'legendary'; if (weight <= 20) return 'epic'; if (weight <= 50) return 'rare'; return 'common'; } function getRarityColor(weight?: number): string { const rarity = getRarityByWeight(weight); switch (rarity) { case 'legendary': return 'rgba(255, 215, 0, 1)'; // gold case 'epic': return 'rgba(186, 85, 211, 1)'; // purple case 'rare': return 'rgba(65, 105, 225, 1)'; // blue default: return 'rgba(255, 255, 255, 0.75)'; } } type Props = { open: boolean; onClose: () => void; caseId: string; caseName?: string; }; export default function CaseItemsDialog({ open, onClose, caseId, caseName }: Props) { const [loading, setLoading] = useState(false); const [caseData, setCaseData] = useState(null); const items: CaseItem[] = useMemo(() => { const list = caseData?.items ?? []; return [...list].sort((a, b) => { const wa = a.weight ?? Infinity; const wb = b.weight ?? Infinity; return wa - wb; // 🔥 по возрастанию weight (легендарки сверху) }); }, [caseData]); const totalWeight = useMemo(() => { return items.reduce((sum, it) => sum + (Number(it.weight) || 0), 0); }, [items]); useEffect(() => { if (!open) return; let cancelled = false; (async () => { try { setLoading(true); const full = await fetchCase(caseId); if (!cancelled) setCaseData(full); } catch (e) { console.error('Ошибка при загрузке предметов кейса:', e); if (!cancelled) setCaseData(null); } finally { if (!cancelled) setLoading(false); } })(); return () => { cancelled = true; }; }, [open, caseId]); return ( Предметы кейса{caseName ? ` — ${caseName}` : ''} {loading ? ( ) : !items.length ? ( Предметы не найдены (или кейс временно недоступен). ) : ( <> {items.map((it) => { const w = Number(it.weight) || 0; const chance = getChancePercent(w, totalWeight); const displayNameRaw = it.meta?.display_name ?? it.name ?? it.material ?? 'Предмет'; const displayName = stripMinecraftColors(displayNameRaw); const texture = it.material ? `https://cdn.minecraft.popa-popa.ru/textures/${it.material.toLowerCase()}.png` : ''; return ( {/* верхняя плашка (редкость) */} {displayName} {/* иконка */} {texture ? ( ) : ( ? )} {/* низ: шанс/вес/кол-во */} {chance.toFixed(2)}% ); })} )} ); }