feat(deck-creator): dropdown menük fejlesztése

- Típus és láthatóság dropdown menük átalakítása
- Ikonok hozzáadása mindkét dropdown menühöz
- Szöveg színek javítása a jobb láthatóságért
- Hover és kijelölési állapotok hozzáadása
- Dropdown menük egységes stílusának kialakítása
This commit is contained in:
GitG0r0
2025-10-22 19:35:08 +02:00
parent 0a811741c7
commit c207fa5961
@@ -1,7 +1,7 @@
// src/components/DeckCreator/DeckHeader.jsx // src/components/DeckCreator/DeckHeader.jsx
// Deck alapadatok szerkesztése és mentés // Deck alapadatok szerkesztése és mentés
import React from "react" import React, { useState, useRef, useEffect } from "react"
import { FaSave, FaArrowLeft, FaGlobe, FaLock, FaQuestionCircle, FaDice, FaLaughBeam } from "react-icons/fa" import { FaSave, FaArrowLeft, FaGlobe, FaLock, FaQuestionCircle, FaDice, FaLaughBeam } from "react-icons/fa"
const deckTypes = [ const deckTypes = [
@@ -16,9 +16,30 @@ const privacyOptions = [
] ]
export default function DeckHeader({ deck, onUpdate, onSave, onBack }) { 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 currentDeckType = deckTypes.find(type => type.value === deck.type) || deckTypes[0]
const currentPrivacy = privacyOptions.find(option => option.value === deck.privacy) || privacyOptions[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) => { const handleInputChange = (field, value) => {
onUpdate({ [field]: value }) onUpdate({ [field]: value })
} }
@@ -80,17 +101,51 @@ export default function DeckHeader({ deck, onUpdate, onSave, onBack }) {
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2"> <label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
🎯 Típus 🎯 Típus
</label> </label>
<select <div className="relative">
value={deck.type} <button
onChange={(e) => handleInputChange('type', e.target.value)} type="button"
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" 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"
{deckTypes.map(type => ( style={{
<option key={type.value} value={type.value}> paddingLeft: "2.5rem"
{type.label} }}
</option> >
))} <div className="absolute left-4 top-1/2 -translate-y-1/2">
</select> {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> </div>
{/* Privacy */} {/* Privacy */}
@@ -98,17 +153,51 @@ export default function DeckHeader({ deck, onUpdate, onSave, onBack }) {
<label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2"> <label className="block text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
👁 Láthatóság 👁 Láthatóság
</label> </label>
<select <div className="relative">
value={deck.privacy} <button
onChange={(e) => handleInputChange('privacy', e.target.value)} type="button"
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" 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"
{privacyOptions.map(option => ( style={{
<option key={option.value} value={option.value}> paddingLeft: "2.5rem"
{option.label} }}
</option> >
))} <div className="absolute left-4 top-1/2 -translate-y-1/2">
</select> {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> </div>
{/* Description */} {/* Description */}