Add shuffle options
This commit is contained in:
parent
683cd039e7
commit
90fba17a1e
1 changed files with 78 additions and 3 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { ArrowLeft, Save, Plus, Play, AlertTriangle } from 'lucide-react';
|
||||
import { ArrowLeft, Save, Plus, Play, AlertTriangle, Shuffle } from 'lucide-react';
|
||||
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, DragEndEvent } from '@dnd-kit/core';
|
||||
import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
||||
import { Quiz, Question } from '../types';
|
||||
|
|
@ -31,6 +31,8 @@ export const QuizEditor: React.FC<QuizEditorProps> = ({
|
|||
const [editingQuestion, setEditingQuestion] = useState<Question | null>(null);
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState<string | null>(null);
|
||||
const [titleEditing, setTitleEditing] = useState(false);
|
||||
const [shuffleQuestions, setShuffleQuestions] = useState(false);
|
||||
const [shuffleAnswers, setShuffleAnswers] = useState(false);
|
||||
|
||||
useBodyScrollLock(!!showDeleteConfirm);
|
||||
|
||||
|
|
@ -112,6 +114,33 @@ export const QuizEditor: React.FC<QuizEditorProps> = ({
|
|||
q.options.some(o => o.isCorrect)
|
||||
);
|
||||
|
||||
const handleStartGame = () => {
|
||||
let questions = [...quiz.questions];
|
||||
|
||||
if (shuffleQuestions) {
|
||||
questions = questions.sort(() => Math.random() - 0.5);
|
||||
}
|
||||
|
||||
if (shuffleAnswers) {
|
||||
const shapes = ['triangle', 'diamond', 'circle', 'square'] as const;
|
||||
const colors = ['red', 'blue', 'yellow', 'green'] as const;
|
||||
|
||||
questions = questions.map(q => {
|
||||
const shuffledOptions = [...q.options].sort(() => Math.random() - 0.5);
|
||||
return {
|
||||
...q,
|
||||
options: shuffledOptions.map((opt, idx) => ({
|
||||
...opt,
|
||||
shape: shapes[idx % 4],
|
||||
color: colors[idx % 4]
|
||||
}))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
onStartGame({ ...quiz, questions });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100 text-gray-900 p-4 md:p-8 flex flex-col items-center">
|
||||
<div className="max-w-4xl w-full bg-white rounded-[2rem] shadow-xl overflow-hidden border-4 border-white">
|
||||
|
|
@ -212,9 +241,55 @@ export const QuizEditor: React.FC<QuizEditorProps> = ({
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="p-6 bg-gray-50 border-t-2 border-gray-100">
|
||||
<div className="p-6 bg-gray-50 border-t-2 border-gray-100 space-y-4">
|
||||
<div className="space-y-2">
|
||||
<label className="flex items-center justify-between p-4 bg-white rounded-xl border-2 border-gray-200 cursor-pointer hover:border-theme-primary transition group">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`p-2 rounded-lg transition ${shuffleQuestions ? 'bg-theme-primary text-white' : 'bg-gray-100 text-gray-500 group-hover:bg-gray-200'}`}>
|
||||
<Shuffle size={20} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-bold text-gray-900">Shuffle Questions</p>
|
||||
<p className="text-sm text-gray-500">Randomize question order when starting</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={shuffleQuestions}
|
||||
onChange={(e) => setShuffleQuestions(e.target.checked)}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 rounded-full peer peer-checked:bg-theme-primary transition-colors"></div>
|
||||
<div className="absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform peer-checked:translate-x-5"></div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label className="flex items-center justify-between p-4 bg-white rounded-xl border-2 border-gray-200 cursor-pointer hover:border-theme-primary transition group">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`p-2 rounded-lg transition ${shuffleAnswers ? 'bg-theme-primary text-white' : 'bg-gray-100 text-gray-500 group-hover:bg-gray-200'}`}>
|
||||
<Shuffle size={20} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-bold text-gray-900">Shuffle Answers</p>
|
||||
<p className="text-sm text-gray-500">Randomize answer positions for each question</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={shuffleAnswers}
|
||||
onChange={(e) => setShuffleAnswers(e.target.checked)}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 rounded-full peer peer-checked:bg-theme-primary transition-colors"></div>
|
||||
<div className="absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform peer-checked:translate-x-5"></div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => onStartGame(quiz)}
|
||||
onClick={handleStartGame}
|
||||
disabled={!canStartGame}
|
||||
className="w-full bg-green-500 text-white py-4 rounded-2xl text-xl font-black shadow-[0_6px_0_#16a34a] active:shadow-none active:translate-y-[6px] transition-all hover:bg-green-600 flex items-center justify-center gap-3 disabled:opacity-50 disabled:cursor-not-allowed disabled:active:translate-y-0 disabled:active:shadow-[0_6px_0_#16a34a]"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue