Files
SerpentRace/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx
T
GitG0r0 edca8f84cd Fix: Kártya típus kezelés javítása és joker kártyák megjelenítése
- Hozzáadva react-toastify a notifyWarning használatához
- Javítva a CardEditor fejléc hogy helyesen jelenítse meg az új kártya típusát
- Javítva a CardsList 'szerkesztés folyamatban' rész hogy QUESTION/JOKER/LUCK értékeket használjon
- Implementálva az automatikus nem megfelelő típusú kártyák törlése új kártya mentésekor
- Hozzáadva hibakezelés a kártya mentési logikához
- Joker típus címke változtatva 'Szórakozás'-ról 'Joker'-re
- Joker kártya szín változtatva citromsárgára (#FFD700)
- Docker watch mode volume konfiguráció javítása a hot reload-hoz
2025-10-22 23:21:19 +02:00

221 lines
10 KiB
React
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// src/components/DeckCreator/DeckHeader.jsx
// Deck alapadatok szerkesztése és mentés
import React, { useState, useRef, useEffect } from "react"
import { FaSave, FaArrowLeft, FaGlobe, FaLock, FaQuestionCircle, FaDice, FaLaughBeam } from "react-icons/fa"
const deckTypes = [
{ value: "QUESTION", label: "Kérdés", icon: FaQuestionCircle, color: "var(--color-question)" },
{ value: "LUCK", label: "Szerencse", icon: FaDice, color: "var(--color-luck)" },
{ value: "JOKER", label: "Joker", icon: FaLaughBeam, color: "var(--color-fun)" }
]
const privacyOptions = [
{ value: "private", label: "Privát", icon: FaLock },
{ value: "public", label: "Publikus", icon: FaGlobe }
]
export default function DeckHeader({ deck, onUpdate, onSave, onBack }) {
const [isTypeDropdownOpen, setIsTypeDropdownOpen] = useState(false);
const [isPrivacyDropdownOpen, setIsPrivacyDropdownOpen] = useState(false);
const typeDropdownRef = useRef(null);
const privacyDropdownRef = useRef(null);
const currentDeckType = deckTypes.find(type => type.value === deck.type) || deckTypes[0]
const currentPrivacy = privacyOptions.find(option => option.value === deck.privacy) || privacyOptions[0]
useEffect(() => {
function handleClickOutside(event) {
if (typeDropdownRef.current && !typeDropdownRef.current.contains(event.target)) {
setIsTypeDropdownOpen(false);
}
if (privacyDropdownRef.current && !privacyDropdownRef.current.contains(event.target)) {
setIsPrivacyDropdownOpen(false);
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const handleInputChange = (field, value) => {
onUpdate({ [field]: value })
}
// Remove unused card count variables
return (
<div className="bg-[color:var(--color-surface)] border-b border-[color:var(--color-surface-selected)] px-6 py-4">
{/* Top Row - Title and Actions */}
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-4">
<button
onClick={onBack}
className="flex items-center gap-2 px-4 py-2 rounded-xl bg-[color:var(--color-background)] hover:bg-[color:var(--color-surface-selected)] text-[color:var(--color-text)] transition-all duration-200"
>
<FaArrowLeft />
Vissza
</button>
<h1 className="text-2xl font-bold text-[color:var(--color-text)]">
📝 Pakli Szerkesztés
</h1>
</div>
<button
onClick={onSave}
className="flex items-center gap-2 px-6 py-2 rounded-xl bg-[color:var(--color-success)] hover:bg-[color:var(--color-success)]/80 text-[color:var(--color-text-inverse)] font-semibold transition-all duration-200 hover:scale-105 shadow-lg"
>
<FaSave />
Mentés
</button>
</div>
{/* Main Content Row */}
<div className="space-y-4">
{/* Two Column Layout */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{/* Deck Name - Takes up 2 columns */}
<div className="md:col-span-2">
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
📦 Pakli neve
</label>
<input
type="text"
value={deck.name}
onChange={(e) => handleInputChange('name', e.target.value)}
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
placeholder="Add meg a pakli nevét..."
/>
</div>
{/* Empty space for visual balance */}
<div className="hidden md:block"></div>
</div>
{/* Type, Privacy and Description Row */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{/* Deck Type */}
<div>
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
🎯 Típus
</label>
<div className="relative">
<button
type="button"
onClick={() => setIsTypeDropdownOpen(!isTypeDropdownOpen)}
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 flex items-center"
style={{
paddingLeft: "2.5rem"
}}
>
<div className="absolute left-4 top-1/2 -translate-y-1/2">
{React.createElement(currentDeckType.icon, {
style: { color: currentDeckType.color }
})}
</div>
{currentDeckType.label}
<div className="absolute right-4 top-1/2 -translate-y-1/2">
<svg className={`w-4 h-4 text-[color:var(--color-text-muted)] transform transition-transform ${isTypeDropdownOpen ? 'rotate-180' : ''}`} viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
</svg>
</div>
</button>
{isTypeDropdownOpen && (
<div
className="absolute z-10 w-full mt-1 bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] rounded-xl shadow-lg overflow-hidden"
ref={typeDropdownRef}
>
{deckTypes.map(type => (
<button
key={type.value}
onClick={() => {
handleInputChange('type', type.value);
setIsTypeDropdownOpen(false);
}}
className={`w-full px-4 py-2 flex items-center gap-3 hover:bg-[color:var(--color-surface-selected)] transition-colors text-[color:var(--color-text)] ${deck.type === type.value ? 'bg-[color:var(--color-surface-selected)]' : ''}`}
>
{React.createElement(type.icon, {
style: { color: type.color }
})}
<span>{type.label}</span>
</button>
))}
</div>
)}
</div>
</div>
{/* Privacy */}
<div>
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
👁 Láthatóság
</label>
<div className="relative">
<button
type="button"
onClick={() => setIsPrivacyDropdownOpen(!isPrivacyDropdownOpen)}
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200 flex items-center"
style={{
paddingLeft: "2.5rem"
}}
>
<div className="absolute left-4 top-1/2 -translate-y-1/2">
{React.createElement(currentPrivacy.icon, {
className: "text-[color:var(--color-text)]"
})}
</div>
{currentPrivacy.label}
<div className="absolute right-4 top-1/2 -translate-y-1/2">
<svg className={`w-4 h-4 text-[color:var(--color-text-muted)] transform transition-transform ${isPrivacyDropdownOpen ? 'rotate-180' : ''}`} viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
</svg>
</div>
</button>
{isPrivacyDropdownOpen && (
<div
className="absolute z-10 w-full mt-1 bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] rounded-xl shadow-lg overflow-hidden"
ref={privacyDropdownRef}
>
{privacyOptions.map(option => (
<button
key={option.value}
onClick={() => {
handleInputChange('privacy', option.value);
setIsPrivacyDropdownOpen(false);
}}
className={`w-full px-4 py-2 flex items-center gap-3 hover:bg-[color:var(--color-surface-selected)] transition-colors text-[color:var(--color-text)] ${deck.privacy === option.value ? 'bg-[color:var(--color-surface-selected)]' : ''}`}
>
{React.createElement(option.icon, {
className: "text-[color:var(--color-text)]"
})}
<span>{option.label}</span>
</button>
))}
</div>
)}
</div>
</div>
{/* Description */}
<div>
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
📝 Leírás
</label>
<input
type="text"
value={deck.description}
onChange={(e) => handleInputChange('description', e.target.value)}
className="w-full px-4 py-2 rounded-xl bg-[color:var(--color-background)] border border-[color:var(--color-surface-selected)] text-[color:var(--color-text)] focus:ring-2 focus:ring-[color:var(--color-success)] focus:border-transparent outline-none transition-all duration-200"
placeholder="Rövid leírás..."
/>
</div>
</div>
</div>
</div>
)
}