- {cardData.type === 'task' && '📋'}
- {cardData.type === 'joker' && '🃏'}
- {cardData.type === 'luck' && '🎲'}
+ {cardData.type === 'QUESTION' && '📋'}
+ {cardData.type === 'JOKER' && '🃏'}
+ {cardData.type === 'LUCK' && '🎲'}
{isCreating ? 'Új' : 'Szerkesztés'} {' '}
- {cardData.type === 'task' && 'Feladat kártya'}
- {cardData.type === 'joker' && 'Joker kártya'}
- {cardData.type === 'luck' && 'Szerencse kártya'}
+ {cardData.type === 'QUESTION' && 'Feladat kártya'}
+ {cardData.type === 'JOKER' && 'Joker kártya'}
+ {cardData.type === 'LUCK' && 'Szerencse kártya'}
- {cardData.type === 'task' && cardData.subType && (
+ {cardData.type === 'QUESTION' && cardData.subType && (
<>
{cardData.subType === 'quiz' && 'Quiz (A/B/C/D)'}
{cardData.subType === 'truefalse' && 'Igaz/Hamis'}
@@ -196,21 +196,21 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
) : (
/* Edit Mode */
- {cardData.type === 'task' && (
+ {cardData.type === 'QUESTION' && (
)}
- {cardData.type === 'joker' && (
+ {cardData.type === 'JOKER' && (
)}
- {cardData.type === 'luck' && (
+ {cardData.type === 'LUCK' && (
{
- if (card.type === 'task') {
+ if (card.type === 'QUESTION') {
return card.question || card.statement || 'Új feladat kártya'
}
- if (card.type === 'joker') {
+ if (card.type === 'JOKER') {
return card.text || 'Új joker kártya'
}
- if (card.type === 'luck') {
+ if (card.type === 'LUCK') {
return card.text || 'Új szerencse kártya'
}
return 'Ismeretlen kártya'
}
const getCardTypeLabel = (card) => {
- if (card.type === 'task') {
+ if (card.type === 'QUESTION') {
if (card.subType) {
return cardSubTypeLabels[card.subType] || 'Feladat'
}
return 'Feladat'
}
- if (card.type === 'joker') {
+ if (card.type === 'JOKER') {
return 'Joker'
}
- if (card.type === 'luck') {
+ if (card.type === 'LUCK') {
return 'Szerencse'
}
return 'Ismeretlen'
@@ -64,40 +65,18 @@ export default function CardsList({
🃏 Kártyák
- {/* New Card Dropdown */}
-
-
-
- {/* Dropdown Menu */}
-
-
-
-
-
-
-
-
+ {/* New Card Button */}
+
{/* Cards List */}
@@ -218,9 +197,9 @@ export default function CardsList({
{cards.length > 0 && (
- 📋 {cards.filter(c => c.type === 'task').length}
- 🃏 {cards.filter(c => c.type === 'joker').length}
- 🎲 {cards.filter(c => c.type === 'luck').length}
+ 📋 {cards.filter(c => c.type === 'QUESTION').length}
+ 🃏 {cards.filter(c => c.type === 'JOKER').length}
+ 🎲 {cards.filter(c => c.type === 'LUCK').length}
)}
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx b/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx
index a0f65d2a..79dda370 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx
@@ -5,9 +5,9 @@ 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: "Fun", label: "Szórakozás", icon: FaLaughBeam, color: "var(--color-fun)" }
+ { 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: "Szórakozás", icon: FaLaughBeam, color: "var(--color-fun)" }
]
const privacyOptions = [
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx
index c902cade..3d23a1af 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx
@@ -6,14 +6,14 @@ import { FaTheaterMasks, FaInfoCircle, FaUsers } from 'react-icons/fa'
export default function JokerCardEditor({ card, onChange }) {
const [cardData, setCardData] = useState({
- type: 'joker',
+ type: 'JOKER',
text: ''
})
useEffect(() => {
if (card) {
setCardData({
- type: 'joker',
+ type: 'JOKER',
text: card.text || ''
})
}
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx
index e1edd2b6..f0dbb093 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx
@@ -6,14 +6,14 @@ import { FaDice, FaInfoCircle } from 'react-icons/fa'
export default function LuckCardEditor({ card, onChange }) {
const [cardData, setCardData] = useState({
- type: 'luck',
+ type: 'LUCK',
text: ''
})
useEffect(() => {
if (card) {
setCardData({
- type: 'luck',
+ type: 'LUCK',
text: card.text || ''
})
}
diff --git a/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx b/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
index 60c13986..396c1dd7 100644
--- a/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
+++ b/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
@@ -17,7 +17,7 @@ export default function DeckCreator() {
const [deck, setDeck] = useState({
id: null,
name: "Új Pakli",
- type: "Question", // Question, Luck, Fun
+ type: "QUESTION", // QUESTION, LUCK, JOKER - backend formátum
privacy: "private", // private, public
description: "",
cards: []
@@ -26,19 +26,18 @@ export default function DeckCreator() {
// UI állapotok
const [selectedCard, setSelectedCard] = useState(null)
const [isCreatingCard, setIsCreatingCard] = useState(false)
- const [newCardType, setNewCardType] = useState(null) // task, joker, luck
+ const [newCardType, setNewCardType] = useState(null)
- // Betöltés (később API-ból)
+ // Betöltés API-ból
useEffect(() => {
if (deckId) {
// TODO: Betöltés API-ból
- loadDeck(deckId)
} else {
// Új deck
setDeck({
id: null,
name: "Új Pakli",
- type: "Question",
+ type: "QUESTION",
privacy: "private",
description: "",
cards: []
@@ -46,60 +45,27 @@ export default function DeckCreator() {
}
}, [deckId])
- const loadDeck = async (id) => {
- // Mock deck betöltés
- const mockDeck = {
- id: id,
- name: "Quiz Night",
- type: "Question",
- privacy: "public",
- description: "Szórakoztató kvíz este",
- cards: [
- {
- id: 1,
- type: "task",
- subType: "quiz",
- question: "Mi Magyarország fővárosa?",
- options: ["Budapest", "Debrecen", "Szeged", "Pécs"],
- correctAnswer: 0,
- points: 10,
- timeLimit: 30,
- explanation: "Budapest 1873 óta Magyarország fővárosa."
- },
- {
- id: 2,
- type: "task",
- subType: "truefalse",
- statement: "A Duna Magyarország leghosszabb folyója.",
- isTrue: false,
- points: 5,
- timeLimit: 15,
- explanation: "A Tisza a leghosszabb folyó Magyarországon."
- }
- ]
- }
- setDeck(mockDeck)
- }
-
const handleDeckUpdate = (updates) => {
setDeck(prev => ({ ...prev, ...updates }))
}
const handleSaveDeck = async () => {
try {
- console.log("Deck mentése:", deck)
-
const payload = {
name: deck.name,
- type: (deck.type || 'Question').toString().toUpperCase(),
+ type: deck.type,
ctype: deck.privacy === 'public' ? 'PUBLIC' : 'PRIVATE',
description: deck.description || '',
- cards: deck.cards.map(c => ({ ...c, text: c.question || c.statement || c.text || '' }))
+ cards: deck.cards
}
const saved = await createDeck(payload)
- setDeck(prev => ({ ...prev, id: saved.id ?? prev.id, creationdate: saved.creationdate ?? prev.creationdate, updatedate: saved.updatedate ?? prev.updatedate }))
- console.log('Deck saved (backend):', saved)
+ setDeck(prev => ({
+ ...prev,
+ id: saved.id ?? prev.id,
+ creationdate: saved.creationdate ?? prev.creationdate,
+ updatedate: saved.updatedate ?? prev.updatedate
+ }))
alert('✅ Deck sikeresen mentve!')
} catch (error) {
console.error('Mentési hiba:', error)
@@ -126,29 +92,21 @@ export default function DeckCreator() {
}
const handleSaveCard = (cardData) => {
- if (isCreatingCard) {
- // Új kártya hozzáadása
- const newCard = {
- ...cardData,
- id: Date.now(), // Temporary ID
- }
- setDeck(prev => ({
- ...prev,
- cards: [...prev.cards, newCard]
- }))
- setIsCreatingCard(false)
- setNewCardType(null)
- setSelectedCard(newCard)
- } else {
- // Meglévő kártya frissítése
- setDeck(prev => ({
- ...prev,
- cards: prev.cards.map(card =>
- card.id === cardData.id ? cardData : card
- )
- }))
- setSelectedCard(cardData)
+ const updatedCard = {
+ ...cardData,
+ id: isCreatingCard ? Date.now() : cardData.id
}
+
+ setDeck(prev => ({
+ ...prev,
+ cards: isCreatingCard
+ ? [...prev.cards, updatedCard]
+ : prev.cards.map(card => card.id === updatedCard.id ? updatedCard : card)
+ }))
+
+ setSelectedCard(updatedCard)
+ setIsCreatingCard(false)
+ setNewCardType(null)
}
const handleDeleteCard = (cardId) => {
@@ -184,6 +142,7 @@ export default function DeckCreator() {
Date: Wed, 22 Oct 2025 23:21:19 +0200
Subject: [PATCH 7/9] =?UTF-8?q?Fix:=20K=C3=A1rtya=20t=C3=ADpus=20kezel?=
=?UTF-8?q?=C3=A9s=20jav=C3=ADt=C3=A1sa=20=C3=A9s=20joker=20k=C3=A1rty?=
=?UTF-8?q?=C3=A1k=20megjelen=C3=ADt=C3=A9se?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 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
---
SerpentRace_Docker/docker-compose.watch.yml | 4 +-
SerpentRace_Frontend/package-lock.json | 23 ++++
SerpentRace_Frontend/package.json | 1 +
.../src/components/DeckCreator/CardEditor.jsx | 111 +++++++++++-------
.../src/components/DeckCreator/CardsList.jsx | 94 +++------------
.../src/components/DeckCreator/DeckHeader.jsx | 2 +-
.../components/DeckCreator/DeckManager.jsx | 8 +-
.../src/components/PopUp/DeckInfoPopUp.jsx | 2 +-
SerpentRace_Frontend/src/index.css | 2 +-
.../src/pages/DeckCreator/DeckCreator.jsx | 89 ++++++--------
10 files changed, 160 insertions(+), 176 deletions(-)
diff --git a/SerpentRace_Docker/docker-compose.watch.yml b/SerpentRace_Docker/docker-compose.watch.yml
index b7e523ca..8d026a06 100644
--- a/SerpentRace_Docker/docker-compose.watch.yml
+++ b/SerpentRace_Docker/docker-compose.watch.yml
@@ -75,7 +75,9 @@ services:
environment:
- NODE_ENV=development
- VITE_API_URL=http://localhost:3000
- volumes: []
+ volumes:
+ - ../SerpentRace_Frontend:/app
+ - /app/node_modules
develop:
watch:
- action: sync
diff --git a/SerpentRace_Frontend/package-lock.json b/SerpentRace_Frontend/package-lock.json
index e8e4cd88..02104eac 100644
--- a/SerpentRace_Frontend/package-lock.json
+++ b/SerpentRace_Frontend/package-lock.json
@@ -15,6 +15,7 @@
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-router-dom": "^7.6.0",
+ "react-toastify": "^11.0.5",
"tailwindcss": "^4.1.7"
},
"devDependencies": {
@@ -1816,6 +1817,15 @@
"node": ">=18"
}
},
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -3363,6 +3373,19 @@
"node": ">=18"
}
},
+ "node_modules/react-toastify": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz",
+ "integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==",
+ "license": "MIT",
+ "dependencies": {
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19",
+ "react-dom": "^18 || ^19"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
diff --git a/SerpentRace_Frontend/package.json b/SerpentRace_Frontend/package.json
index 5bb119a6..d06aa2d6 100644
--- a/SerpentRace_Frontend/package.json
+++ b/SerpentRace_Frontend/package.json
@@ -17,6 +17,7 @@
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-router-dom": "^7.6.0",
+ "react-toastify": "^11.0.5",
"tailwindcss": "^4.1.7"
},
"devDependencies": {
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx
index 9d853d24..ff6e2293 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx
@@ -58,38 +58,55 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
// Kártya adatok inicializálása
useEffect(() => {
- if (isCreating && cardType) {
- setCardData(getDefaultCardData(cardType))
- } else if (card) {
- setCardData({ ...card })
- } else {
+ try {
+ if (isCreating && cardType) {
+ const defaultData = getDefaultCardData(cardType)
+ setCardData(defaultData)
+ } else if (card) {
+ setCardData({ ...card })
+ } else {
+ setCardData(null)
+ }
+ } catch (error) {
+ console.error('Kártya inicializálási hiba:', error)
setCardData(null)
}
}, [card, isCreating, cardType])
const validateCard = (data) => {
- if (data.type === 'QUESTION') {
- if (!data.question && !data.statement) {
- notifyError("Kérdés vagy állítás megadása kötelező!")
+ try {
+ if (!data || !data.type) {
+ notifyError("Érvénytelen kártya adatok!")
return false
}
- if (data.subType === 'quiz' && data.options.some(opt => !opt.trim())) {
- notifyError("Minden válaszlehetőséget ki kell tölteni!")
- return false
- }
- } else if (data.type === 'JOKER') {
- if (!data.text || !data.text.trim()) {
- notifyError("Joker kártya szövege nem lehet üres!")
- return false
- }
- } else if (data.type === 'LUCK') {
- if (!data.text || !data.text.trim()) {
- notifyError("Szerencse kártya szövege nem lehet üres!")
- return false
+
+ if (data.type === 'QUESTION') {
+ if (!data.question && !data.statement) {
+ notifyError("Kérdés vagy állítás megadása kötelező!")
+ return false
+ }
+ if (data.subType === 'quiz' && data.options && data.options.some(opt => !opt.trim())) {
+ notifyError("Minden válaszlehetőséget ki kell tölteni!")
+ return false
+ }
+ } else if (data.type === 'JOKER') {
+ if (!data.text || !data.text.trim()) {
+ notifyError("Joker kártya szövege nem lehet üres!")
+ return false
+ }
+ } else if (data.type === 'LUCK') {
+ if (!data.text || !data.text.trim()) {
+ notifyError("Szerencse kártya szövege nem lehet üres!")
+ return false
+ }
}
+
+ return true
+ } catch (error) {
+ console.error('Validálási hiba:', error)
+ notifyError("Hiba történt a kártya ellenőrzése során")
+ return false
}
-
- return true
}
const updateCardData = (updates) => {
@@ -97,16 +114,14 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
}
const handleSave = () => {
- if (!cardData) return
+ if (!cardData) {
+ notifyError("Nincs mentendő kártya adat!")
+ return
+ }
if (!validateCard(cardData)) return
- try {
- onSave(cardData)
- notifySuccess('Kártya sikeresen mentve!')
- } catch (error) {
- notifyError('Hiba történt a kártya mentése során: ' + (error?.message || String(error)))
- }
+ onSave(cardData)
}
// Ha nincs kiválasztott kártya vagy új kártya létrehozás
@@ -129,6 +144,29 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
return (
+ {/* Type Mismatch Warning */}
+ {cardData?.type && cardType && cardData.type !== cardType && !isCreating && (
+
+
+
⚠️
+
+
+ Figyelmeztetés: Nem megfelelő kártya típus
+
+
+ {`Ez egy ${
+ cardData.type === 'QUESTION' ? 'Feladat' :
+ cardData.type === 'JOKER' ? 'Joker' : 'Szerencse'
+ } kártya, de a pakli típusa ${
+ cardType === 'QUESTION' ? 'Feladat' :
+ cardType === 'JOKER' ? 'Joker' : 'Szerencse'
+ }.`}
+
+
+
+
+ )}
+
{/* Header */}
@@ -140,17 +178,10 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
-<<<<<<< HEAD
{isCreating ? 'Új' : 'Szerkesztés'} {' '}
- {cardData.type === 'QUESTION' && 'Feladat kártya'}
- {cardData.type === 'JOKER' && 'Joker kártya'}
- {cardData.type === 'LUCK' && 'Szerencse kártya'}
-=======
- {isCreating ? 'Új' : 'Szerkesztés'} {' '}
- {cardData.type === 'QUESTION' && 'Feladat kártya'}
- {cardData.type === 'JOKER' && 'Joker kártya'}
- {cardData.type === 'LUCK' && 'Szerencse kártya'}
->>>>>>> main
+ {(isCreating ? cardType : cardData.type) === 'QUESTION' && 'Feladat kártya'}
+ {(isCreating ? cardType : cardData.type) === 'JOKER' && 'Joker kártya'}
+ {(isCreating ? cardType : cardData.type) === 'LUCK' && 'Szerencse kártya'}
{cardData.type === 'QUESTION' && cardData.subType && (
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx b/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx
index f56d8dfe..b391b5cc 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx
@@ -27,20 +27,12 @@ const cardSubTypeLabels = {
text: "Szöveges válasz"
}
-<<<<<<< HEAD
export default function CardsList({
cards,
selectedCard,
deckType,
onSelectCard,
- onCreateCard,
-=======
-export default function CardsList({
- cards,
- selectedCard,
- onSelectCard,
onCreateCard,
->>>>>>> main
onDeleteCard,
isCreatingCard,
newCardType
@@ -48,7 +40,6 @@ export default function CardsList({
const [confirmingDelete, setConfirmingDelete] = useState(null)
const getCardPreview = (card) => {
-<<<<<<< HEAD
if (card.type === 'QUESTION') {
return card.question || card.statement || 'Új feladat kártya'
}
@@ -57,44 +48,22 @@ export default function CardsList({
}
if (card.type === 'LUCK') {
return card.text || 'Új szerencse kártya'
-=======
- if (card.type === 'QUESTION') {
- return card.question || card.statement || 'Új feladat kártya'
- }
- if (card.type === 'JOKER') {
- return card.text || 'Új joker kártya'
- }
- if (card.type === 'LUCK') {
- return card.text || 'Új szerencse kártya'
->>>>>>> main
}
return "Ismeretlen kártya"
}
const getCardTypeLabel = (card) => {
-<<<<<<< HEAD
if (card.type === 'QUESTION') {
-=======
- if (card.type === "task") {
->>>>>>> main
if (card.subType) {
return cardSubTypeLabels[card.subType] || "Feladat"
}
return "Feladat"
}
-<<<<<<< HEAD
if (card.type === 'JOKER') {
return 'Joker'
}
if (card.type === 'LUCK') {
return 'Szerencse'
-=======
- if (card.type === "joker") {
- return "Joker"
- }
- if (card.type === "luck") {
- return "Szerencse"
->>>>>>> main
}
return "Ismeretlen"
}
@@ -119,11 +88,14 @@ export default function CardsList({
🃏 Kártyák
-<<<<<<< HEAD
{/* New Card Button */}
-=======
- {/* New Card Dropdown */}
-
-
-
- {/* Dropdown Menu */}
-
-
-
-
-
-
-
-
->>>>>>> main
{/* Cards List */}
@@ -185,7 +121,7 @@ export default function CardsList({
)}
- Új {newCardType === "task" ? "feladat" : newCardType === "joker" ? "joker" : "szerencse"} kártya
+ Új {newCardType === "QUESTION" ? "feladat" : newCardType === "JOKER" ? "joker" : "szerencse"} kártya
Szerkesztés folyamatban...
@@ -205,14 +141,24 @@ export default function CardsList({
key={card.id}
onClick={() => onSelectCard(card)}
className={`
- p-4 rounded-xl border cursor-pointer transition-all duration-200 hover:scale-105 group
+ p-4 rounded-xl border cursor-pointer transition-all duration-200 hover:scale-105 group relative
${
isSelected
? "bg-[color:var(--color-success)]/10 border-[color:var(--color-success)] shadow-lg"
: "bg-[color:var(--color-background)]/50 border-[color:var(--color-surface-selected)] hover:bg-[color:var(--color-background)]/80"
}
+ ${card.type !== deckType ? "opacity-70" : ""}
`}
>
+ {card.type !== deckType && (
+
+
+
+
+ ⚠️ Nem megfelelő típus
+
+
+ )}
{/* Card Header */}
@@ -320,15 +266,9 @@ export default function CardsList({
{cards.length > 0 && (
-<<<<<<< HEAD
📋 {cards.filter(c => c.type === 'QUESTION').length}
🃏 {cards.filter(c => c.type === 'JOKER').length}
🎲 {cards.filter(c => c.type === 'LUCK').length}
-=======
- 📋 {cards.filter(c => c.type === 'QUESTION').length}
- 🃏 {cards.filter(c => c.type === 'JOKER').length}
- 🎲 {cards.filter(c => c.type === 'LUCK').length}
->>>>>>> main
)}
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx b/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx
index 79dda370..b285dd5e 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/DeckHeader.jsx
@@ -7,7 +7,7 @@ import { FaSave, FaArrowLeft, FaGlobe, FaLock, FaQuestionCircle, FaDice, FaLaugh
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: "Szórakozás", icon: FaLaughBeam, color: "var(--color-fun)" }
+ { value: "JOKER", label: "Joker", icon: FaLaughBeam, color: "var(--color-fun)" }
]
const privacyOptions = [
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/DeckManager.jsx b/SerpentRace_Frontend/src/components/DeckCreator/DeckManager.jsx
index 0b1eddac..6aa60f09 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/DeckManager.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/DeckManager.jsx
@@ -17,7 +17,7 @@ import DeckInfoPopUp from "../PopUp/DeckInfoPopUp"
const deckTypes = [
{ label: "Luck", color: "var(--color-luck)" },
{ label: "Question", color: "var(--color-question)" },
- { label: "Fun", color: "var(--color-fun)" },
+ { label: "Joker", color: "var(--color-fun)" },
]
// initial state will be fetched from backend
@@ -163,8 +163,8 @@ const DeckManager = () => {
? "Szerencse"
: type.label === "Question"
? "Kérdés"
- : type.label === "Fun"
- ? "Szórakozás"
+ : type.label === "Joker"
+ ? "Joker"
: type.label}
))}
@@ -303,7 +303,7 @@ const DeckManager = () => {
: deck.type === "Question"
? "Kérdés"
: deck.type === "Fun"
- ? "Szórakozás"
+ ? "Joker"
: deck.type}
diff --git a/SerpentRace_Frontend/src/components/PopUp/DeckInfoPopUp.jsx b/SerpentRace_Frontend/src/components/PopUp/DeckInfoPopUp.jsx
index 9d5ed97f..1db050ea 100644
--- a/SerpentRace_Frontend/src/components/PopUp/DeckInfoPopUp.jsx
+++ b/SerpentRace_Frontend/src/components/PopUp/DeckInfoPopUp.jsx
@@ -32,7 +32,7 @@ export default function DeckInfoPopUp({ deck, onClose }) {
const deckTypes = {
"Luck": { label: "Szerencse", color: "var(--color-luck)" },
"Question": { label: "Kérdés", color: "var(--color-question)" },
- "Fun": { label: "Szórakozás", color: "var(--color-fun)" }
+ "Fun": { label: "Joker", color: "var(--color-fun)" }
}
const currentDeckType = deckTypes[deck.type] || { label: deck.type, color: "var(--color-success)" }
diff --git a/SerpentRace_Frontend/src/index.css b/SerpentRace_Frontend/src/index.css
index a73bc306..e6db465c 100644
--- a/SerpentRace_Frontend/src/index.css
+++ b/SerpentRace_Frontend/src/index.css
@@ -31,7 +31,7 @@
/* Deck típus színek */
--color-luck: #5fa985; /* zöld, mint a success */
--color-question: #4f7be6; /* új kék, illik az oldalhoz */
- --color-fun: #e15b64; /* piros, mint az error */
+ --color-fun: #FFD700; /* citromsárga a joker kártyákhoz */
/* Háttérszínek */
--color-background: #181d23;
diff --git a/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx b/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
index 0b68151e..f3d382b3 100644
--- a/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
+++ b/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
@@ -8,7 +8,7 @@ import DeckHeader from "../../components/DeckCreator/DeckHeader.jsx"
import CardsList from "../../components/DeckCreator/CardsList.jsx"
import CardEditor from "../../components/DeckCreator/CardEditor.jsx"
import { createDeck } from '../../api/deckApi'
-import { notifySuccess, notifyError } from "../../components/Toastify/toastifyServices"
+import { notifySuccess, notifyError, notifyWarning } from "../../components/Toastify/toastifyServices"
export default function DeckCreator() {
const { deckId } = useParams() // URL-ből deck ID (új deck esetén undefined)
@@ -32,11 +32,7 @@ export default function DeckCreator() {
// Betöltés API-ból
useEffect(() => {
if (deckId) {
-<<<<<<< HEAD
- // TODO: Betöltés API-ból
-=======
loadDeck(deckId)
->>>>>>> main
} else {
setDeck({
id: null,
@@ -64,15 +60,6 @@ export default function DeckCreator() {
}
const saved = await createDeck(payload)
-<<<<<<< HEAD
- setDeck(prev => ({
- ...prev,
- id: saved.id ?? prev.id,
- creationdate: saved.creationdate ?? prev.creationdate,
- updatedate: saved.updatedate ?? prev.updatedate
- }))
- alert('✅ Deck sikeresen mentve!')
-=======
setDeck(prev => ({
...prev,
id: saved.id ?? prev.id,
@@ -82,7 +69,6 @@ export default function DeckCreator() {
console.log('Deck saved (backend):', saved)
notifySuccess('Deck sikeresen mentve!')
->>>>>>> main
} catch (error) {
console.error('Mentési hiba:', error)
notifyError('Hiba történt a mentés során: ' + (error?.response?.data?.error || error.message || String(error)))
@@ -108,46 +94,47 @@ export default function DeckCreator() {
}
const handleSaveCard = (cardData) => {
-<<<<<<< HEAD
- const updatedCard = {
- ...cardData,
- id: isCreatingCard ? Date.now() : cardData.id
-=======
- if (isCreatingCard) {
- // Új kártya hozzáadása
- const newCard = {
+ try {
+ const updatedCard = {
...cardData,
- id: Date.now(), // Temporary ID
+ id: isCreatingCard ? Date.now() : cardData.id
}
- setDeck(prev => ({
- ...prev,
- cards: [...prev.cards, newCard]
- }))
+
+ setDeck(prev => {
+ // Ellenőrizzük, vannak-e nem megfelelő típusú kártyák
+ const invalidCards = prev.cards.filter(card => card.type !== prev.type)
+
+ // Ha új kártyát mentünk megfelelő típussal és vannak nem megfelelők
+ if (isCreatingCard && cardData.type === prev.type && invalidCards.length > 0) {
+ notifyWarning(`${invalidCards.length} db nem megfelelő típusú kártya törlésre került`)
+
+ return {
+ ...prev,
+ cards: [
+ ...prev.cards.filter(card => card.type === prev.type),
+ updatedCard
+ ]
+ }
+ }
+
+ // Alap mentési logika
+ return {
+ ...prev,
+ cards: isCreatingCard
+ ? [...prev.cards, updatedCard]
+ : prev.cards.map(card => card.id === updatedCard.id ? updatedCard : card)
+ }
+ })
+
+ setSelectedCard(updatedCard)
setIsCreatingCard(false)
setNewCardType(null)
- setSelectedCard(newCard)
- } else {
- // Meglévő kártya frissítése
- setDeck(prev => ({
- ...prev,
- cards: prev.cards.map(card =>
- card.id === cardData.id ? cardData : card
- )
- }))
- setSelectedCard(cardData)
->>>>>>> main
+
+ notifySuccess('Kártya sikeresen mentve!')
+ } catch (error) {
+ console.error('Kártya mentési hiba:', error)
+ notifyError('Hiba történt a kártya mentése során')
}
-
- setDeck(prev => ({
- ...prev,
- cards: isCreatingCard
- ? [...prev.cards, updatedCard]
- : prev.cards.map(card => card.id === updatedCard.id ? updatedCard : card)
- }))
-
- setSelectedCard(updatedCard)
- setIsCreatingCard(false)
- setNewCardType(null)
}
// 🔧 Itt is confirm() volt — most a CardsList popupja kezeli a megerősítést
@@ -196,7 +183,7 @@ export default function DeckCreator() {
{
setIsCreatingCard(false)
--
2.52.0
From f2a54154f55dcfc3e28f8cec0fb6b17b3dc7368d Mon Sep 17 00:00:00 2001
From: GitG0r0 <145980798+GitG0r0@users.noreply.github.com>
Date: Wed, 22 Oct 2025 23:34:34 +0200
Subject: [PATCH 8/9] =?UTF-8?q?UI:=20Be=C3=A1ll=C3=ADt=C3=A1sok=20szekci?=
=?UTF-8?q?=C3=B3=20letilt=C3=A1sa=20a=20feladat=20k=C3=A1rty=C3=A1kn?=
=?UTF-8?q?=C3=A1l?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Pontszám, Időlimit és Karakterlimit mezők letiltva
- Magyarázat mező is letiltva
- Szöveges válasz típusnál a beállítások (kis/nagy betű, pontos egyezés, stb.) letiltva
- Egységes 'Hamarosan elérhető' effekt az összes letiltott szekción
- Tipp mező továbbra is opcionális és használható
- Ezek a beállítások nem kötelezőek a kártya mentéséhez
---
.../components/DeckCreator/TaskCardEditor.jsx | 198 ++++++++++--------
1 file changed, 108 insertions(+), 90 deletions(-)
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx
index 9c98c89a..0bbd0a16 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx
@@ -374,37 +374,48 @@ export default function TaskCardEditor({ card, onChange }) {
- {/* Beállítások */}
-
-
+ {/* Beállítások - Később elérhető */}
+
{/* Tipp */}
@@ -423,76 +434,83 @@ export default function TaskCardEditor({ card, onChange }) {
)}
- {/* Közös beállítások */}
-
+ {/* Közös beállítások - Később elérhető */}
+
⚙️ Beállítások
-
- {/* Pontszám */}
-
-
- updateField('points', parseInt(e.target.value) || 0)}
- 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"
- min="0"
- max="1000"
- />
-
+
+
+
+ {/* Pontszám */}
+
+
+
+
- {/* Időlimit */}
-
-
-
-
+ {/* Időlimit */}
+
+
+
+
- {/* Karakterlimit (csak szöveges válasznál) */}
- {card.subType === 'text' && (
-
+ {/* Karakterlimit (csak szöveges válasznál) */}
+ {card.subType === 'text' && (
+
+
+
+
+ )}
+
+
+ {/* Magyarázat */}
+
- updateField('characterLimit', parseInt(e.target.value) || 0)}
- 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"
- min="10"
- max="500"
+
- )}
-
-
- {/* Magyarázat */}
-
-
-
+
+ {/* Hamarosan elérhető felület */}
+
+
+
+ 🚧 Hamarosan elérhető
+
+
+
--
2.52.0
From 3bbd3f1e8a8054ee60109b85f56262951cd1d361 Mon Sep 17 00:00:00 2001
From: GitG0r0 <145980798+GitG0r0@users.noreply.github.com>
Date: Thu, 23 Oct 2025 00:31:33 +0200
Subject: [PATCH 9/9] =?UTF-8?q?Feature:=20Consequence=20rendszer=20impleme?=
=?UTF-8?q?nt=C3=A1l=C3=A1sa=20minden=20k=C3=A1rtya=20t=C3=ADpushoz?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- TaskCardEditor: Consequence és wrongConsequence kezelés hozzáadva
- JokerCardEditor: Teljesítés és nem teljesítés consequence-ek
- LuckCardEditor: Szerencse kártyák consequence kezelése
- CardEditor: Alapértelmezett consequence értékek az új kártyákhoz
- DeckCreator: Consequence mezők biztosítása mentéskor
- CardsList: Következmény típusok megjelenítése
- UI javítás: Mind a három editor külön szekciókba rendezve (info, szöveg, következmények)
- Egységes struktúra és design az összes kártya szerkesztőnél
---
.../src/components/DeckCreator/CardEditor.jsx | 9 +-
.../src/components/DeckCreator/CardsList.jsx | 8 -
.../DeckCreator/JokerCardEditor.jsx | 201 +++++++++++++++---
.../components/DeckCreator/LuckCardEditor.jsx | 138 +++++++++---
.../components/DeckCreator/TaskCardEditor.jsx | 122 +++++++++++
.../src/pages/DeckCreator/DeckCreator.jsx | 33 ++-
6 files changed, 427 insertions(+), 84 deletions(-)
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx
index ff6e2293..2fc5cbe3 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/CardEditor.jsx
@@ -20,7 +20,8 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
id: null,
type: type,
points: 10,
- timeLimit: 30
+ timeLimit: 30,
+ consequence: { type: 0, value: 1 }
}
switch (type) {
@@ -31,7 +32,8 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
question: '',
options: ['', '', '', ''],
correctAnswer: 0,
- explanation: ''
+ explanation: '',
+ wrongConsequence: { type: 1, value: 1 }
}
case 'JOKER':
return {
@@ -40,7 +42,8 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
description: '',
effect: '',
actionType: 'skip',
- usage: 'once'
+ usage: 'once',
+ wrongConsequence: { type: 1, value: 1 }
}
case 'LUCK':
return {
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx b/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx
index b391b5cc..30ea9d16 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/CardsList.jsx
@@ -263,14 +263,6 @@ export default function CardsList({
📊 Összesen: {cards.length} kártya
-
- {cards.length > 0 && (
-
- 📋 {cards.filter(c => c.type === 'QUESTION').length}
- 🃏 {cards.filter(c => c.type === 'JOKER').length}
- 🎲 {cards.filter(c => c.type === 'LUCK').length}
-
- )}
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx
index 3d23a1af..5f8118e6 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/JokerCardEditor.jsx
@@ -4,17 +4,29 @@
import React, { useState, useEffect } from 'react'
import { FaTheaterMasks, FaInfoCircle, FaUsers } from 'react-icons/fa'
+const consequenceTypes = [
+ { value: 0, label: '⬆️ Előre lépés', description: 'A játékos előre lép X mezőt' },
+ { value: 1, label: '⬇️ Hátra lépés', description: 'A játékos hátra lép X mezőt' },
+ { value: 2, label: '⏸️ Kör kihagyás', description: 'A játékos kihagy egy kört' },
+ { value: 3, label: '⏩ Extra kör', description: 'A játékos kap egy extra kört' },
+ { value: 5, label: '🏁 Vissza a starthoz', description: 'A játékos visszakerül a starthoz' }
+]
+
export default function JokerCardEditor({ card, onChange }) {
const [cardData, setCardData] = useState({
type: 'JOKER',
- text: ''
+ text: '',
+ consequence: { type: 0, value: 1 },
+ wrongConsequence: { type: 1, value: 1 }
})
useEffect(() => {
if (card) {
setCardData({
type: 'JOKER',
- text: card.text || ''
+ text: card.text || '',
+ consequence: card.consequence || { type: 0, value: 1 },
+ wrongConsequence: card.wrongConsequence || { type: 1, value: 1 }
})
}
}, [card])
@@ -31,6 +43,36 @@ export default function JokerCardEditor({ card, onChange }) {
}
}
+ const updateConsequence = (field, value) => {
+ const newCardData = {
+ ...cardData,
+ consequence: {
+ ...cardData.consequence,
+ [field]: value
+ }
+ }
+ setCardData(newCardData)
+
+ if (onChange) {
+ onChange(newCardData)
+ }
+ }
+
+ const updateWrongConsequence = (field, value) => {
+ const newCardData = {
+ ...cardData,
+ wrongConsequence: {
+ ...cardData.wrongConsequence,
+ [field]: value
+ }
+ }
+ setCardData(newCardData)
+
+ if (onChange) {
+ onChange(newCardData)
+ }
+ }
+
// Példa joker kártyák
const exampleCards = [
"Felelsz vagy mersz? (Az előző játékos kérdez)",
@@ -57,18 +99,10 @@ export default function JokerCardEditor({ card, onChange }) {
}
return (
-
+
+ {/* Info box */}
- {/* Header */}
-
-
-
- Joker Kártya Szerkesztő
-
-
-
- {/* Info box */}
-
+
@@ -86,28 +120,33 @@ export default function JokerCardEditor({ card, onChange }) {
+
- {/* Card text input */}
-
-
-
-
-
-
- Maximális hossz: 150 karakter
-
-
- {cardData.text.length}/150
-
-
+ {/* Kártya szövege */}
+
+
+
+ Kártya szövege
+
+
+
+
+
+
+
+ Maximális hossz: 150 karakter
+
+
+ {cardData.text.length}/150
+
@@ -147,6 +186,100 @@ export default function JokerCardEditor({ card, onChange }) {
)}
+
+ {/* Következmények (teljesítés esetén) */}
+
+
+ 🎯 Következmények (teljesítés esetén)
+
+
+
+ {/* Consequence Type */}
+
+
+
+
+ {consequenceTypes.find(t => t.value === (cardData.consequence?.type ?? 0))?.description}
+
+
+
+ {/* Consequence Value - csak ha előre/hátra lépés */}
+ {(cardData.consequence?.type === 0 || cardData.consequence?.type === 1) && (
+
+
+ updateConsequence('value', parseInt(e.target.value) || 1)}
+ 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"
+ min="1"
+ max="10"
+ />
+
+ )}
+
+
+
+ {/* Következmények (nem teljesítés esetén) */}
+
+
+ ❌ Következmények (nem teljesítés esetén)
+
+
+
+ {/* Wrong Consequence Type */}
+
+
+
+
+ {consequenceTypes.find(t => t.value === (cardData.wrongConsequence?.type ?? 1))?.description}
+
+
+
+ {/* Wrong Consequence Value - csak ha előre/hátra lépés */}
+ {(cardData.wrongConsequence?.type === 0 || cardData.wrongConsequence?.type === 1) && (
+
+
+ updateWrongConsequence('value', parseInt(e.target.value) || 1)}
+ 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-danger)] focus:border-transparent outline-none transition-all duration-200"
+ min="1"
+ max="10"
+ />
+
+ )}
+
+
)
}
\ No newline at end of file
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx
index f0dbb093..f59fcb76 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/LuckCardEditor.jsx
@@ -4,17 +4,27 @@
import React, { useState, useEffect } from 'react'
import { FaDice, FaInfoCircle } from 'react-icons/fa'
+const consequenceTypes = [
+ { value: 0, label: '⬆️ Előre lépés', description: 'A játékos előre lép X mezőt' },
+ { value: 1, label: '⬇️ Hátra lépés', description: 'A játékos hátra lép X mezőt' },
+ { value: 2, label: '⏸️ Kör kihagyás', description: 'A játékos kihagy egy kört' },
+ { value: 3, label: '⏩ Extra kör', description: 'A játékos kap egy extra kört' },
+ { value: 5, label: '🏁 Vissza a starthoz', description: 'A játékos visszakerül a starthoz' }
+]
+
export default function LuckCardEditor({ card, onChange }) {
const [cardData, setCardData] = useState({
type: 'LUCK',
- text: ''
+ text: '',
+ consequence: { type: 0, value: 1 }
})
useEffect(() => {
if (card) {
setCardData({
type: 'LUCK',
- text: card.text || ''
+ text: card.text || '',
+ consequence: card.consequence || { type: 0, value: 1 }
})
}
}, [card])
@@ -31,19 +41,26 @@ export default function LuckCardEditor({ card, onChange }) {
}
}
- return (
-
-
- {/* Header */}
-
-
-
- Szerencse Kártya Szerkesztő
-
-
+ const updateConsequence = (field, value) => {
+ const newCardData = {
+ ...cardData,
+ consequence: {
+ ...cardData.consequence,
+ [field]: value
+ }
+ }
+ setCardData(newCardData)
+
+ if (onChange) {
+ onChange(newCardData)
+ }
+ }
- {/* Info box */}
-
+ return (
+
+ {/* Info box */}
+
+
@@ -60,28 +77,32 @@ export default function LuckCardEditor({ card, onChange }) {
+
- {/* Card text input */}
-
-
-
-
-
-
- Maximális hossz: 200 karakter
-
-
- {cardData.text.length}/200
-
-
+ {/* Kártya szövege */}
+
+
+
+ Kártya szövege
+
+
+
+
+
+
+ Maximális hossz: 200 karakter
+
+
+ {cardData.text.length}/200
+
@@ -100,6 +121,53 @@ export default function LuckCardEditor({ card, onChange }) {
)}
+
+ {/* Következmények */}
+
+
+ 🎯 Következmények
+
+
+
+ {/* Consequence Type */}
+
+
+
+
+ {consequenceTypes.find(t => t.value === (cardData.consequence?.type ?? 0))?.description}
+
+
+
+ {/* Consequence Value - csak ha előre/hátra lépés */}
+ {(cardData.consequence?.type === 0 || cardData.consequence?.type === 1) && (
+
+
+ updateConsequence('value', parseInt(e.target.value) || 1)}
+ 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-luck)] focus:border-transparent outline-none transition-all duration-200"
+ />
+
+ )}
+
+
)
}
\ No newline at end of file
diff --git a/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx b/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx
index 0bbd0a16..cace7ed8 100644
--- a/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx
+++ b/SerpentRace_Frontend/src/components/DeckCreator/TaskCardEditor.jsx
@@ -20,6 +20,14 @@ const timeLimits = [
{ value: 120, label: '2 perc' }
]
+const consequenceTypes = [
+ { value: 0, label: '⬆️ Előre lépés', description: 'A játékos előre lép X mezőt' },
+ { value: 1, label: '⬇️ Hátra lépés', description: 'A játékos hátra lép X mezőt' },
+ { value: 2, label: '⏸️ Kör kihagyás', description: 'A játékos kihagy egy kört' },
+ { value: 3, label: '⏩ Extra kör', description: 'A játékos kap egy extra kört' },
+ { value: 5, label: '🏁 Vissza a starthoz', description: 'A játékos visszakerül a starthoz' }
+]
+
export default function TaskCardEditor({ card, onChange }) {
const updateField = (field, value) => {
@@ -81,6 +89,26 @@ export default function TaskCardEditor({ card, onChange }) {
onChange({ acceptedAnswers: newAnswers })
}
+ const updateConsequence = (field, value) => {
+ const currentConsequence = card.consequence || { type: 0, value: 1 }
+ onChange({
+ consequence: {
+ ...currentConsequence,
+ [field]: value
+ }
+ })
+ }
+
+ const updateWrongConsequence = (field, value) => {
+ const currentWrongConsequence = card.wrongConsequence || { type: 1, value: 1 }
+ onChange({
+ wrongConsequence: {
+ ...currentWrongConsequence,
+ [field]: value
+ }
+ })
+ }
+
return (
{/* Feladat típus választó */}
@@ -513,6 +541,100 @@ export default function TaskCardEditor({ card, onChange }) {
+
+ {/* Következmények (helyes válasz esetén) */}
+
+
+ 🎯 Következmények (helyes válasz esetén)
+
+
+
+ {/* Consequence Type */}
+
+
+
+
+ {consequenceTypes.find(t => t.value === (card.consequence?.type ?? 0))?.description}
+
+
+
+ {/* Consequence Value - csak ha előre/hátra lépés */}
+ {(card.consequence?.type === 0 || card.consequence?.type === 1) && (
+
+
+ updateConsequence('value', parseInt(e.target.value) || 1)}
+ 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"
+ min="1"
+ max="10"
+ />
+
+ )}
+
+
+
+ {/* Következmények (rossz válasz esetén) */}
+
+
+ ❌ Következmények (rossz válasz esetén)
+
+
+
+ {/* Wrong Consequence Type */}
+
+
+
+
+ {consequenceTypes.find(t => t.value === (card.wrongConsequence?.type ?? 1))?.description}
+
+
+
+ {/* Wrong Consequence Value - csak ha előre/hátra lépés */}
+ {(card.wrongConsequence?.type === 0 || card.wrongConsequence?.type === 1) && (
+
+
+ updateWrongConsequence('value', parseInt(e.target.value) || 1)}
+ 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-danger)] focus:border-transparent outline-none transition-all duration-200"
+ min="1"
+ max="10"
+ />
+
+ )}
+
+
)
}
\ No newline at end of file
diff --git a/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx b/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
index f3d382b3..5226cc2e 100644
--- a/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
+++ b/SerpentRace_Frontend/src/pages/DeckCreator/DeckCreator.jsx
@@ -51,9 +51,16 @@ export default function DeckCreator() {
const handleSaveDeck = async () => {
try {
+ // Konvertálás: Frontend string -> Backend enum number
+ const typeMapping = {
+ 'LUCK': 0,
+ 'JOKER': 1,
+ 'QUESTION': 2
+ }
+
const payload = {
name: deck.name,
- type: deck.type,
+ type: typeMapping[deck.type] ?? 2, // Alapértelmezett: QUESTION
ctype: deck.privacy === 'public' ? 'PUBLIC' : 'PRIVATE',
description: deck.description || '',
cards: deck.cards
@@ -95,18 +102,30 @@ export default function DeckCreator() {
const handleSaveCard = (cardData) => {
try {
+ // Biztosítjuk az alapértelmezett consequence értékeket
+ const defaultConsequence = { type: 0, value: 1 }
+ const defaultWrongConsequence = { type: 1, value: 1 }
+
const updatedCard = {
...cardData,
- id: isCreatingCard ? Date.now() : cardData.id
+ id: isCreatingCard ? Date.now() : cardData.id,
+ consequence: cardData.consequence || defaultConsequence,
+ // wrongConsequence csak QUESTION és JOKER típusoknál
+ ...(cardData.type === 'QUESTION' || cardData.type === 'JOKER'
+ ? { wrongConsequence: cardData.wrongConsequence || defaultWrongConsequence }
+ : {}
+ )
}
+ let wasInvalidCardDeleted = false
+
setDeck(prev => {
// Ellenőrizzük, vannak-e nem megfelelő típusú kártyák
const invalidCards = prev.cards.filter(card => card.type !== prev.type)
// Ha új kártyát mentünk megfelelő típussal és vannak nem megfelelők
if (isCreatingCard && cardData.type === prev.type && invalidCards.length > 0) {
- notifyWarning(`${invalidCards.length} db nem megfelelő típusú kártya törlésre került`)
+ wasInvalidCardDeleted = true
return {
...prev,
@@ -130,7 +149,13 @@ export default function DeckCreator() {
setIsCreatingCard(false)
setNewCardType(null)
- notifySuccess('Kártya sikeresen mentve!')
+ // Csak egy értesítés
+ if (wasInvalidCardDeleted) {
+ const invalidCount = deck.cards.filter(card => card.type !== deck.type).length
+ notifyWarning(`Kártya mentve! ${invalidCount} db nem megfelelő típusú kártya törlésre került.`)
+ } else {
+ notifySuccess('Kártya sikeresen mentve!')
+ }
} catch (error) {
console.error('Kártya mentési hiba:', error)
notifyError('Hiba történt a kártya mentése során')
--
2.52.0