10.23 zsola hibák + Deckek listázása megoldva
This commit is contained in:
@@ -33,6 +33,19 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
|
|||||||
options: ['', '', '', ''],
|
options: ['', '', '', ''],
|
||||||
correctAnswer: 0,
|
correctAnswer: 0,
|
||||||
explanation: '',
|
explanation: '',
|
||||||
|
acceptedAnswers: [''],
|
||||||
|
wrongConsequence: { type: 1, value: 1 }
|
||||||
|
}
|
||||||
|
case 'PAIRING':
|
||||||
|
case 'MATCHING':
|
||||||
|
return {
|
||||||
|
...baseData,
|
||||||
|
type: 'QUESTION',
|
||||||
|
subType: 'matching',
|
||||||
|
taskDescription: '',
|
||||||
|
leftItems: ['', ''],
|
||||||
|
rightItems: ['', ''],
|
||||||
|
correctPairs: { 0: 0, 1: 1 },
|
||||||
wrongConsequence: { type: 1, value: 1 }
|
wrongConsequence: { type: 1, value: 1 }
|
||||||
}
|
}
|
||||||
case 'JOKER':
|
case 'JOKER':
|
||||||
@@ -84,13 +97,60 @@ export default function CardEditor({ card, isCreating, cardType, onSave, onCance
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data.type === 'QUESTION') {
|
if (data.type === 'QUESTION') {
|
||||||
if (!data.question && !data.statement) {
|
// Quiz típus validálás
|
||||||
notifyError("Kérdés vagy állítás megadása kötelező!")
|
if (data.subType === 'quiz') {
|
||||||
return false
|
if (!data.question || !data.question.trim()) {
|
||||||
|
notifyError("Kérdés megadása kötelező!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (data.options && data.options.some(opt => !opt.trim())) {
|
||||||
|
notifyError("Minden válaszlehetőséget ki kell tölteni!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (data.subType === 'quiz' && data.options && data.options.some(opt => !opt.trim())) {
|
// Igaz/Hamis típus validálás
|
||||||
notifyError("Minden válaszlehetőséget ki kell tölteni!")
|
else if (data.subType === 'truefalse') {
|
||||||
return false
|
if (!data.statement || !data.statement.trim()) {
|
||||||
|
notifyError("Állítás megadása kötelező!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (data.isTrue === undefined || data.isTrue === null) {
|
||||||
|
notifyError("Válaszd ki, hogy az állítás igaz vagy hamis!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Párosítás típus validálás
|
||||||
|
else if (data.subType === 'matching') {
|
||||||
|
if (!data.taskDescription || !data.taskDescription.trim()) {
|
||||||
|
notifyError("Feladat leírása kötelező!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!data.leftItems || data.leftItems.length === 0) {
|
||||||
|
notifyError("Legalább egy párosítást meg kell adni!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (data.leftItems.some(item => !item.trim()) || data.rightItems.some(item => !item.trim())) {
|
||||||
|
notifyError("Minden párosítási elemet ki kell tölteni!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Szöveges válasz típus validálás
|
||||||
|
else if (data.subType === 'text') {
|
||||||
|
if (!data.question || !data.question.trim()) {
|
||||||
|
notifyError("Kérdés megadása kötelező!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!data.acceptedAnswers || data.acceptedAnswers.length === 0 || data.acceptedAnswers.every(ans => !ans.trim())) {
|
||||||
|
notifyError("Legalább egy elfogadott választ meg kell adni!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Általános validálás (ha nincs subType megadva)
|
||||||
|
else {
|
||||||
|
if (!data.question && !data.statement) {
|
||||||
|
notifyError("Kérdés vagy állítás megadása kötelező!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (data.type === 'JOKER') {
|
} else if (data.type === 'JOKER') {
|
||||||
if (!data.text || !data.text.trim()) {
|
if (!data.text || !data.text.trim()) {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import {
|
|||||||
FaSortAlphaDown,
|
FaSortAlphaDown,
|
||||||
FaSortAlphaUp,
|
FaSortAlphaUp,
|
||||||
FaQuestionCircle,
|
FaQuestionCircle,
|
||||||
|
FaChevronLeft,
|
||||||
|
FaChevronRight,
|
||||||
} from "react-icons/fa"
|
} from "react-icons/fa"
|
||||||
import SearchBox from "../Search/SearchBox"
|
import SearchBox from "../Search/SearchBox"
|
||||||
import PopUp from "../PopUp/PopUp"
|
import PopUp from "../PopUp/PopUp"
|
||||||
@@ -70,18 +72,25 @@ const DeckManager = () => {
|
|||||||
const [search, setSearch] = useState("")
|
const [search, setSearch] = useState("")
|
||||||
const [showSortHelp, setShowSortHelp] = useState(false)
|
const [showSortHelp, setShowSortHelp] = useState(false)
|
||||||
const [selectedDeck, setSelectedDeck] = useState(null)
|
const [selectedDeck, setSelectedDeck] = useState(null)
|
||||||
const [decks, setDecks] = useState([])
|
const [allDecks, setAllDecks] = useState([]) // Összes pakli
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [itemsPerPage, setItemsPerPage] = useState(20)
|
||||||
|
const [currentPage, setCurrentPage] = useState(1)
|
||||||
|
|
||||||
|
// Load all decks once
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let mounted = true
|
let mounted = true
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
const result = await import('../../api/deckApi').then(m => m.getDecksPage(0, 49))
|
// Load all decks (0-99 is the max limit = 100 decks)
|
||||||
|
const result = await import('../../api/deckApi').then(m => m.getDecksPage(0, 99))
|
||||||
if (!mounted) return
|
if (!mounted) return
|
||||||
// map backend deck shape to UI shape
|
|
||||||
const mapped = result.decks.map(d => ({
|
console.log('Loaded decks:', result) // Debug
|
||||||
|
|
||||||
|
// Map backend deck shape to UI shape
|
||||||
|
const mapped = (result.decks || []).map(d => ({
|
||||||
id: d.id,
|
id: d.id,
|
||||||
name: d.name,
|
name: d.name,
|
||||||
type: d.type === 2 ? 'Question' : d.type === 1 ? 'Joker' : 'Luck',
|
type: d.type === 2 ? 'Question' : d.type === 1 ? 'Joker' : 'Luck',
|
||||||
@@ -89,7 +98,9 @@ const DeckManager = () => {
|
|||||||
origin: d.ctype === 2 ? 'Vállalati' : d.ctype === 0 ? 'Mind' : 'Saját',
|
origin: d.ctype === 2 ? 'Vállalati' : d.ctype === 0 ? 'Mind' : 'Saját',
|
||||||
raw: d
|
raw: d
|
||||||
}))
|
}))
|
||||||
setDecks(mapped)
|
|
||||||
|
console.log('Mapped decks:', mapped) // Debug
|
||||||
|
setAllDecks(mapped)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to load decks', err)
|
console.error('Failed to load decks', err)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -101,8 +112,7 @@ const DeckManager = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// Filter logic
|
// Filter logic
|
||||||
const sourceDecks = decks
|
let filteredDecks = allDecks.filter((deck) => {
|
||||||
let filteredDecks = sourceDecks.filter((deck) => {
|
|
||||||
const typeMatch = selectedType === "All" || deck.type === selectedType
|
const typeMatch = selectedType === "All" || deck.type === selectedType
|
||||||
const originMatch = selectedOrigin === "Mind" || deck.origin === selectedOrigin
|
const originMatch = selectedOrigin === "Mind" || deck.origin === selectedOrigin
|
||||||
const searchMatch = !search || deck.name.toLowerCase().includes(search.toLowerCase())
|
const searchMatch = !search || deck.name.toLowerCase().includes(search.toLowerCase())
|
||||||
@@ -123,6 +133,18 @@ const DeckManager = () => {
|
|||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Pagination logic - frontend only
|
||||||
|
const totalDecks = filteredDecks.length
|
||||||
|
const totalPages = Math.ceil(totalDecks / itemsPerPage)
|
||||||
|
const startIndex = (currentPage - 1) * itemsPerPage
|
||||||
|
const endIndex = startIndex + itemsPerPage
|
||||||
|
const paginatedDecks = filteredDecks.slice(startIndex, endIndex)
|
||||||
|
|
||||||
|
// Reset to page 1 when filters or items per page change
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentPage(1)
|
||||||
|
}, [selectedType, selectedOrigin, search, sortBy, itemsPerPage])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col bg-[color:var(--color-background)]">
|
<div className="w-full flex flex-col bg-[color:var(--color-background)]">
|
||||||
<div className="w-full max-w-[1200px] mx-auto px-4 py-10">
|
<div className="w-full max-w-[1200px] mx-auto px-4 py-10">
|
||||||
@@ -263,6 +285,36 @@ const DeckManager = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Items per page selector and pagination info */}
|
||||||
|
<div className="flex flex-col md:flex-row gap-4 justify-between items-center mb-6 bg-[color:var(--color-surface)]/60 backdrop-blur-lg rounded-xl px-6 py-3 shadow">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<span className="text-[color:var(--color-text-muted)] text-sm font-medium">
|
||||||
|
Elemek oldalanként:
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
value={itemsPerPage}
|
||||||
|
onChange={(e) => setItemsPerPage(Number(e.target.value))}
|
||||||
|
className="px-3 py-1.5 rounded-lg bg-[color:var(--color-background)] text-[color:var(--color-text)] border border-[color:var(--color-surface-selected)] focus:ring-2 focus:ring-[color:var(--color-success)] outline-none transition-all duration-200"
|
||||||
|
>
|
||||||
|
<option value={20}>20</option>
|
||||||
|
<option value={30}>30</option>
|
||||||
|
<option value={40}>40</option>
|
||||||
|
<option value={50}>50</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-[color:var(--color-text-muted)] text-sm">
|
||||||
|
{totalDecks > 0 ? (
|
||||||
|
<>
|
||||||
|
{startIndex + 1}-{Math.min(endIndex, totalDecks)} / {totalDecks} pakli
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>0 pakli</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Decks Grid */}
|
{/* Decks Grid */}
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-8 mt-8">
|
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-8 mt-8">
|
||||||
{/* Create New Deck (Mockup) */}
|
{/* Create New Deck (Mockup) */}
|
||||||
@@ -280,7 +332,7 @@ const DeckManager = () => {
|
|||||||
{!loading && filteredDecks.length === 0 && (
|
{!loading && filteredDecks.length === 0 && (
|
||||||
<div className="col-span-full text-center text-[color:var(--color-text-muted)]">Nincsenek mentett paklik.</div>
|
<div className="col-span-full text-center text-[color:var(--color-text-muted)]">Nincsenek mentett paklik.</div>
|
||||||
)}
|
)}
|
||||||
{!loading && filteredDecks.map((deck) => {
|
{!loading && paginatedDecks.map((deck) => {
|
||||||
const deckType = deckTypes.find((t) => t.label === deck.type)
|
const deckType = deckTypes.find((t) => t.label === deck.type)
|
||||||
const borderColor = deckType ? deckType.color : "var(--color-success)"
|
const borderColor = deckType ? deckType.color : "var(--color-success)"
|
||||||
return (
|
return (
|
||||||
@@ -317,6 +369,73 @@ const DeckManager = () => {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Pagination Controls */}
|
||||||
|
{totalPages > 1 && (
|
||||||
|
<div className="flex justify-center items-center gap-2 mt-8">
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}
|
||||||
|
disabled={currentPage === 1}
|
||||||
|
className={`px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2 ${
|
||||||
|
currentPage === 1
|
||||||
|
? 'bg-[color:var(--color-surface)] text-[color:var(--color-text-muted)] cursor-not-allowed'
|
||||||
|
: 'bg-[color:var(--color-success)] text-[color:var(--color-text-inverse)] hover:bg-[color:var(--color-success)]/80 hover:scale-105'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<FaChevronLeft />
|
||||||
|
Előző
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{[...Array(totalPages)].map((_, index) => {
|
||||||
|
const pageNum = index + 1
|
||||||
|
// Show first page, last page, current page and neighbors
|
||||||
|
if (
|
||||||
|
pageNum === 1 ||
|
||||||
|
pageNum === totalPages ||
|
||||||
|
(pageNum >= currentPage - 1 && pageNum <= currentPage + 1)
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={pageNum}
|
||||||
|
onClick={() => setCurrentPage(pageNum)}
|
||||||
|
className={`w-10 h-10 rounded-lg font-medium transition-all duration-200 ${
|
||||||
|
currentPage === pageNum
|
||||||
|
? 'bg-[color:var(--color-success)] text-[color:var(--color-text-inverse)] scale-110 shadow-lg'
|
||||||
|
: 'bg-[color:var(--color-surface)] text-[color:var(--color-text)] hover:bg-[color:var(--color-surface-selected)]'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{pageNum}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
} else if (
|
||||||
|
pageNum === currentPage - 2 ||
|
||||||
|
pageNum === currentPage + 2
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<span key={pageNum} className="text-[color:var(--color-text-muted)]">
|
||||||
|
...
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(prev => Math.min(totalPages, prev + 1))}
|
||||||
|
disabled={currentPage === totalPages}
|
||||||
|
className={`px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2 ${
|
||||||
|
currentPage === totalPages
|
||||||
|
? 'bg-[color:var(--color-surface)] text-[color:var(--color-text-muted)] cursor-not-allowed'
|
||||||
|
: 'bg-[color:var(--color-success)] text-[color:var(--color-text-inverse)] hover:bg-[color:var(--color-success)]/80 hover:scale-105'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
Következő
|
||||||
|
<FaChevronRight />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Deck Info Popup */}
|
{/* Deck Info Popup */}
|
||||||
|
|||||||
@@ -79,13 +79,16 @@ export default function TaskCardEditor({ card, onChange }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const updateAcceptedAnswer = (index, value) => {
|
const updateAcceptedAnswer = (index, value) => {
|
||||||
const newAnswers = [...card.acceptedAnswers]
|
const currentAnswers = card.acceptedAnswers || ['']
|
||||||
|
const newAnswers = [...currentAnswers]
|
||||||
newAnswers[index] = value
|
newAnswers[index] = value
|
||||||
onChange({ acceptedAnswers: newAnswers })
|
onChange({ acceptedAnswers: newAnswers })
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeAcceptedAnswer = (index) => {
|
const removeAcceptedAnswer = (index) => {
|
||||||
const newAnswers = card.acceptedAnswers.filter((_, i) => i !== index)
|
const currentAnswers = card.acceptedAnswers || ['']
|
||||||
|
if (currentAnswers.length <= 1) return // Legalább egy válasz maradjon
|
||||||
|
const newAnswers = currentAnswers.filter((_, i) => i !== index)
|
||||||
onChange({ acceptedAnswers: newAnswers })
|
onChange({ acceptedAnswers: newAnswers })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +378,7 @@ export default function TaskCardEditor({ card, onChange }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{(card.acceptedAnswers || ['', '', '']).map((answer, index) => (
|
{(card.acceptedAnswers || ['']).map((answer, index) => (
|
||||||
<div key={index} className="flex gap-2">
|
<div key={index} className="flex gap-2">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -385,7 +388,7 @@ export default function TaskCardEditor({ card, onChange }) {
|
|||||||
placeholder={`Elfogadott válasz ${index + 1}...`}
|
placeholder={`Elfogadott válasz ${index + 1}...`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{(card.acceptedAnswers?.length || 0) > 1 && (
|
{(card.acceptedAnswers?.length || 1) > 1 && (
|
||||||
<button
|
<button
|
||||||
onClick={() => removeAcceptedAnswer(index)}
|
onClick={() => removeAcceptedAnswer(index)}
|
||||||
className="p-2 rounded-lg bg-[color:var(--color-error)]/10 text-[color:var(--color-error)] hover:bg-[color:var(--color-error)]/20 transition-all duration-200"
|
className="p-2 rounded-lg bg-[color:var(--color-error)]/10 text-[color:var(--color-error)] hover:bg-[color:var(--color-error)]/20 transition-all duration-200"
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ import { createDeck } from '../../api/deckApi'
|
|||||||
import { notifySuccess, notifyError, notifyWarning } from "../../components/Toastify/toastifyServices"
|
import { notifySuccess, notifyError, notifyWarning } from "../../components/Toastify/toastifyServices"
|
||||||
|
|
||||||
export default function DeckCreator() {
|
export default function DeckCreator() {
|
||||||
const { deckId } = useParams() // URL-ből deck ID (új deck esetén undefined)
|
const { deckId } = useParams()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
// Deck alapadatok
|
// Deck alapadatok
|
||||||
const [deck, setDeck] = useState({
|
const [deck, setDeck] = useState({
|
||||||
id: null,
|
id: null,
|
||||||
name: "Új Pakli",
|
name: "Új Pakli",
|
||||||
type: "QUESTION", // QUESTION, LUCK, JOKER - backend formátum
|
type: "QUESTION",
|
||||||
privacy: "private", // private, public
|
privacy: "private",
|
||||||
description: "",
|
description: "",
|
||||||
cards: []
|
cards: []
|
||||||
})
|
})
|
||||||
@@ -45,13 +45,26 @@ export default function DeckCreator() {
|
|||||||
}
|
}
|
||||||
}, [deckId])
|
}, [deckId])
|
||||||
|
|
||||||
|
const loadDeck = async (id) => {
|
||||||
|
// Mock adatok – később backendből jön majd
|
||||||
|
const mockDeck = {
|
||||||
|
id,
|
||||||
|
name: "Demo Deck",
|
||||||
|
type: "QUESTION",
|
||||||
|
privacy: "public",
|
||||||
|
description: "Ez egy teszt deck",
|
||||||
|
cards: []
|
||||||
|
}
|
||||||
|
setDeck(mockDeck)
|
||||||
|
}
|
||||||
|
|
||||||
const handleDeckUpdate = (updates) => {
|
const handleDeckUpdate = (updates) => {
|
||||||
setDeck(prev => ({ ...prev, ...updates }))
|
setDeck(prev => ({ ...prev, ...updates }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSaveDeck = async () => {
|
const handleSaveDeck = async () => {
|
||||||
try {
|
try {
|
||||||
// Konvertálás: Frontend string -> Backend enum number
|
// Típus konverzió backendhez
|
||||||
const typeMapping = {
|
const typeMapping = {
|
||||||
'LUCK': 0,
|
'LUCK': 0,
|
||||||
'JOKER': 1,
|
'JOKER': 1,
|
||||||
@@ -59,11 +72,11 @@ export default function DeckCreator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
name: deck.name,
|
name: deck.name?.trim() || "Névtelen pakli",
|
||||||
type: typeMapping[deck.type] ?? 2, // Alapértelmezett: QUESTION
|
type: typeMapping[deck.type] ?? 2,
|
||||||
ctype: deck.privacy === 'public' ? 'PUBLIC' : 'PRIVATE',
|
ctype: deck.privacy === 'public' ? 'PUBLIC' : 'PRIVATE',
|
||||||
description: deck.description || '',
|
description: deck.description || "",
|
||||||
cards: deck.cards
|
cards: deck.cards || []
|
||||||
}
|
}
|
||||||
|
|
||||||
const saved = await createDeck(payload)
|
const saved = await createDeck(payload)
|
||||||
@@ -75,16 +88,14 @@ export default function DeckCreator() {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
console.log('Deck saved (backend):', saved)
|
console.log('Deck saved (backend):', saved)
|
||||||
notifySuccess('Deck sikeresen mentve!')
|
notifySuccess('Pakli sikeresen elmentve!')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Mentési hiba:', 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)))
|
notifyError('Hiba történt a mentés során: ' + (error?.response?.data?.error || error.message))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 Itt korábban volt confirm(), de most eltávolítottuk
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
// Egyszerű visszalépés — ha akarsz, később adhatunk hozzá saját modalt
|
|
||||||
navigate("/decks")
|
navigate("/decks")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,9 +111,14 @@ export default function DeckCreator() {
|
|||||||
setNewCardType(null)
|
setNewCardType(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 💡 Demo verzió: beállítások szekció kihagyva
|
||||||
const handleSaveCard = (cardData) => {
|
const handleSaveCard = (cardData) => {
|
||||||
try {
|
try {
|
||||||
// Biztosítjuk az alapértelmezett consequence értékeket
|
if (cardData.section === "settings") {
|
||||||
|
console.log("Beállítások szekció kihagyva (demo verzió)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const defaultConsequence = { type: 0, value: 1 }
|
const defaultConsequence = { type: 0, value: 1 }
|
||||||
const defaultWrongConsequence = { type: 1, value: 1 }
|
const defaultWrongConsequence = { type: 1, value: 1 }
|
||||||
|
|
||||||
@@ -110,8 +126,7 @@ export default function DeckCreator() {
|
|||||||
...cardData,
|
...cardData,
|
||||||
id: isCreatingCard ? Date.now() : cardData.id,
|
id: isCreatingCard ? Date.now() : cardData.id,
|
||||||
consequence: cardData.consequence || defaultConsequence,
|
consequence: cardData.consequence || defaultConsequence,
|
||||||
// wrongConsequence csak QUESTION és JOKER típusoknál
|
...(cardData.type === 'QUESTION' || cardData.type === 'JOKER' || cardData.type === 'PAIRING'
|
||||||
...(cardData.type === 'QUESTION' || cardData.type === 'JOKER'
|
|
||||||
? { wrongConsequence: cardData.wrongConsequence || defaultWrongConsequence }
|
? { wrongConsequence: cardData.wrongConsequence || defaultWrongConsequence }
|
||||||
: {}
|
: {}
|
||||||
)
|
)
|
||||||
@@ -120,13 +135,10 @@ export default function DeckCreator() {
|
|||||||
let wasInvalidCardDeleted = false
|
let wasInvalidCardDeleted = false
|
||||||
|
|
||||||
setDeck(prev => {
|
setDeck(prev => {
|
||||||
// Ellenőrizzük, vannak-e nem megfelelő típusú kártyák
|
|
||||||
const invalidCards = prev.cards.filter(card => card.type !== prev.type)
|
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) {
|
if (isCreatingCard && cardData.type === prev.type && invalidCards.length > 0) {
|
||||||
wasInvalidCardDeleted = true
|
wasInvalidCardDeleted = true
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
cards: [
|
cards: [
|
||||||
@@ -136,7 +148,6 @@ export default function DeckCreator() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alap mentési logika
|
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
cards: isCreatingCard
|
cards: isCreatingCard
|
||||||
@@ -149,7 +160,6 @@ export default function DeckCreator() {
|
|||||||
setIsCreatingCard(false)
|
setIsCreatingCard(false)
|
||||||
setNewCardType(null)
|
setNewCardType(null)
|
||||||
|
|
||||||
// Csak egy értesítés
|
|
||||||
if (wasInvalidCardDeleted) {
|
if (wasInvalidCardDeleted) {
|
||||||
const invalidCount = deck.cards.filter(card => card.type !== deck.type).length
|
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.`)
|
notifyWarning(`Kártya mentve! ${invalidCount} db nem megfelelő típusú kártya törlésre került.`)
|
||||||
@@ -162,8 +172,11 @@ export default function DeckCreator() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 Itt is confirm() volt — most a CardsList popupja kezeli a megerősítést
|
// 💬 Felugró ablak törlés előtt
|
||||||
const handleDeleteCard = (cardId) => {
|
const handleDeleteCard = (cardId) => {
|
||||||
|
const confirmDelete = window.confirm("Biztosan törölni szeretnéd ezt a kártyát?")
|
||||||
|
if (!confirmDelete) return
|
||||||
|
|
||||||
setDeck(prev => ({
|
setDeck(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
cards: prev.cards.filter(card => card.id !== cardId)
|
cards: prev.cards.filter(card => card.id !== cardId)
|
||||||
@@ -172,6 +185,8 @@ export default function DeckCreator() {
|
|||||||
if (selectedCard?.id === cardId) {
|
if (selectedCard?.id === cardId) {
|
||||||
setSelectedCard(null)
|
setSelectedCard(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notifySuccess("Kártya törölve a pakliból!")
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user