# Документация по переносу компонента GamePort (Порт игры) ## Общая структура в React - **Файл**: client/src/components/GamePort.tsx - **Тип**: React.memo функциональный компонент с props (portNumber, onStartGame, movingGame/Player, onStartMovingGame/Player, onMoveGameTo/PlayerTo). - **Зависимости**: react-redux (useSelector/dispatch), hooks (useWebSocketNew, useAuth, useIsMobile, useDeviceType, useNotifications), icons (Io*, Fa*), components (Button, Card, Badge, BonusProgress, modals). - **State**: timer, showConfirmation (type: endGame/cancelGame/forceEndGame), showDeleteModal, isDragging, dragType, forceDragEffect, showTechConfirm. - **Template (JSX)**: Card relative w-full h-full (bg по статусу, border, cursor-pointer), absolute элементы (gun icon, timer, buttons), main div flex-col justify-center, modals (ConfirmationModal, PlayerDeleteModal, tech confirm). - **Computed**: isActive, hasPlayer, canHaveBonus, isPaused, highlight, isMovingDestination/Source, canDropHere, canManageGame/Player, canDragGame/Player, canCloseGame, isLockedForTechnic/Operator. - **Effects**: useEffect for timer (interval 1000), drag events (start/end/over/enter/leave/drop), debug logs. ## Элементы - **Статус порта**: Card class "game-port-card" (bg-slate-700 idle, bg-gray-700 player, bg-blue/green/orange/cyan active), relative, draggable, onClick handlePortClick, onDrag* handlers. - Gun icon: absolute top-1 left-1, FaGun green (connected) or gray line-through + FaBan red (disconnected). - Timer: absolute top-1 left-8, div bg-black text-white rounded p-2 text-xs monospace. - Lock overlay: absolute inset-0 bg-slate-900/70 flex center FaLock (for restricted access). - Drag overlay: absolute inset-0 bg-green-500/30 flex center arrow-down text (if canDropHere). - **Контент**: - Number: div text-4xl font-bold {portNumber}. - Game name: div text-xs font-semibold {getGameName(port.game)} (e.g., "Пристрелка", "Игра 3"). - Bonus: div text-xs "Бонусная". - Player: div text-xs "Игрок #{gamerId}". - Stats: div flex space-x-2, badges "🎯 {patrOk}", "➕ {patrAdd}". - Patron controls: flex space-x-2, MinusButton/PlusButton (disabled if paused/0), div {patr} text-2xl. - Buttons (absolute top-1 right-1 flex gap-2, z-10): - Move game: Button bg-gray-600 hover:bg-gray-700, IoSwapHorizontalOutline, title "Перенести игру", disabled paused, onClick handleStartMovingGame. - Cancel: Button bg-orange-600 hover:bg-orange-700, IoClose, title "Отменить игру", disabled paused, onClick handleCancelGame. - Delete player: Button bg-red-600 hover:bg-red-700, IoTrashOutline, title "Удалить", disabled paused, onClick handleRemovePlayer. - For empty port: "Свободен", "Нажмите для создания" green if smena open. - For player port: "Игрок", "Игр: {gameCounter}", pause badge if paused. - For active: game name, bonus, player, patron controls, stats. - **Modals**: - Tech confirm: fixed inset-0 bg-black/60 flex center, content bg-slate-800 p-8, h2 "Техническая пристрелка", buttons "Запустить пристрелку" green, "Отмена" gray. - ConfirmationModal: isOpen=showConfirmation.show, type (endGame/cancel/forceEnd), portNumber, onConfirm. - PlayerDeleteModal: isOpen=showDeleteModal, gamerId, portNumber, gameCounter, onConfirm. - **Drag&Drop**: draggable=true, data-port={portNumber}, classes (port-dragging, drag-over, can-drop), effects (scale, opacity). ## Стили (Tailwind примеры) - Card: relative border-2 cursor-pointer w-full h-full min-h-[160px] mobile, [220px] desktop, flex flex-col justify-between, bg-slate-700 border-slate-600 (idle), bg-gray-700 (player), bg-blue-600 (game), bg-orange-600 (tech shot), bg-cyan-500 (shot), transition-all hover:border-white hover:shadow-xl. - Absolute buttons: top-1 right-1 flex gap-2 z-10, Button size="sm" variant="ghost" bg-gray-600 hover:bg-gray-700 rounded text-white. - Patron: flex justify-center space-x-2, Button size="sm" variant="ghost" rounded text-white hover:bg-opacity-60, div text-2xl font-bold min-w-[45px]. - Responsive: @media min-width 769px — min-h-[300px], desktop-port-card; mobile — min-h-[120px], game-port-card; tablet — game-port-card-tablet min-h-[180px]. - Drag: .port-dragging opacity-50 scale-98, .drag-over ring-4 ring-green-400 bg-green-500/20 scale-101, .can-drop border-yellow-400 bg-yellow-600. - Animations: animate-pulse for highlight (ring-4 ring-*-400), grayscale opacity-50 for paused/locked. ## Взаимодействие - onClick port: handlePortClick — check role/pause/smena/ESP, open modal or start game, drag if moving. - Buttons: handleStartMovingGame/Player (dispatch movingStarted), handlePatronChange (+/-1 via WebSocket 'addp'), handleStopGame/Cancel/ForceEnd (set showConfirmation), handleRemovePlayer (set showDeleteModal). - Drag: handleDragStart (set data, class dragging), handleDrop (send 'move'/'moveGamer' via WebSocket, animation with createFlyingPortAnimation), handleDragOver/Enter/Leave (preventDefault, set isDragOver). - Modals: Confirmation for end/cancel/forceEnd (onConfirm send 'endGame'/'cancelGame'/'forceEndGame'), PlayerDelete (send 'deleteGamer'), TechConfirm for tech shot (send 'start' game=2). - Effects: timer interval if active, drag end cancel moving, logs for debug. - In Dashboard: . ## Vue маппинг -