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
// 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"
const deckTypes = [
@@ -16,9 +16,30 @@ const privacyOptions = [
]
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 })
}
@@ -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">
🎯 Típus
</label>
<select
value={deck.type}
onChange={(e) => handleInputChange('type', 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"
>
{deckTypes.map(type => (
<option key={type.value} value={type.value}>
{type.label}
</option>
))}
</select>
<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 */}
@@ -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">
👁 Láthatóság
</label>
<select
value={deck.privacy}
onChange={(e) => handleInputChange('privacy', 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"
>
{privacyOptions.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<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 */}