@moontra/moonui-pro 2.7.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +65 -6
- package/dist/index.mjs +604 -371
- package/package.json +1 -1
- package/src/components/index.ts +12 -1
- package/src/components/moonui-quiz-form/index.tsx +817 -0
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { twMerge } from 'tailwind-merge';
|
|
|
3
3
|
import * as t from 'react';
|
|
4
4
|
import t__default, { useState, useRef, useCallback, forwardRef, createContext, useEffect, useContext, useMemo, useLayoutEffect, useDebugValue, Component } from 'react';
|
|
5
5
|
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
6
|
-
import { ChevronDown, Info, AlertCircle, AlertTriangle, Check, X, MoreHorizontal, Loader2, Minus, Search, ChevronRight, Circle, ChevronUp, Lock, Sparkles, Plus, CreditCard, Globe, ChevronLeft, Calendar as Calendar$1, Edit, Trash2,
|
|
6
|
+
import { ChevronDown, Info, AlertCircle, AlertTriangle, Check, X, MoreHorizontal, Loader2, Minus, Search, ChevronRight, Circle, ChevronUp, Lock, Sparkles, Plus, CreditCard, Globe, CheckCircle2, XCircle, RotateCcw, Download, Clock, HelpCircle, ChevronLeft, Calendar as Calendar$1, Edit, Trash2, MapPin, User, GripVertical, MessageCircle, Paperclip, Bold as Bold$1, Italic as Italic$1, Underline as Underline$1, Strikethrough, Code as Code$1, Type, Heading1, Heading2, Heading3, AlignLeft, AlignCenter, AlignRight, AlignJustify, List, ListOrdered, CheckSquare, Quote, Palette, Highlighter, Link2, Image as Image$1, Table as Table$1, Settings, Undo, Redo, Eye, RefreshCw, Wand2, Maximize, FileText, Languages, TrendingUp, TrendingDown, ZoomOut, ZoomIn, FileSpreadsheet, FileJson, Maximize2, Move, Menu, Bell, CheckCheck, CheckCircle, Settings2, LogOut, Edit3, LayoutGrid, Upload, Share2, Save, Filter, FileDown, ArrowUp, ArrowDown, ArrowUpDown, ChevronsLeft, ChevronsRight, Pin, Sun, Moon, Monitor, Star, ExternalLink, CalendarIcon, DollarSign, Users, Github, GitFork, Activity, Server, EyeOff, RotateCw, Zap, Timer, Cpu, MemoryStick, HardDrive, Network, BarChart3, Video, Music, Archive, File as File$1, Columns, Grip, Unlock, Minimize2, Map as Map$1, Target, MoreVertical, BellOff, ArrowDownRight, ArrowUpRight } from 'lucide-react';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { cva } from 'class-variance-authority';
|
|
9
9
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
@@ -72208,376 +72208,6 @@ function MoonUIMultiStepFormPro({
|
|
|
72208
72208
|
function cn2(...classes) {
|
|
72209
72209
|
return classes.filter(Boolean).join(" ");
|
|
72210
72210
|
}
|
|
72211
|
-
function shuffleArray(array2) {
|
|
72212
|
-
const shuffled = [...array2];
|
|
72213
|
-
for (let i3 = shuffled.length - 1; i3 > 0; i3--) {
|
|
72214
|
-
const j = Math.floor(Math.random() * (i3 + 1));
|
|
72215
|
-
[shuffled[i3], shuffled[j]] = [shuffled[j], shuffled[i3]];
|
|
72216
|
-
}
|
|
72217
|
-
return shuffled;
|
|
72218
|
-
}
|
|
72219
|
-
var MoonUIQuizFormPro = ({
|
|
72220
|
-
title,
|
|
72221
|
-
description,
|
|
72222
|
-
questions: initialQuestions,
|
|
72223
|
-
onComplete,
|
|
72224
|
-
showTimer = true,
|
|
72225
|
-
totalTimeLimit,
|
|
72226
|
-
showProgress = true,
|
|
72227
|
-
showQuestionNumbers = true,
|
|
72228
|
-
allowReview = true,
|
|
72229
|
-
allowSkip = true,
|
|
72230
|
-
shuffleQuestions = false,
|
|
72231
|
-
shuffleOptions = false,
|
|
72232
|
-
passingScore = 70,
|
|
72233
|
-
instantFeedback = false,
|
|
72234
|
-
showHints = false,
|
|
72235
|
-
className
|
|
72236
|
-
}) => {
|
|
72237
|
-
const [questions] = useState(
|
|
72238
|
-
() => shuffleQuestions ? shuffleArray(initialQuestions) : initialQuestions
|
|
72239
|
-
);
|
|
72240
|
-
const [answers, setAnswers] = useState({});
|
|
72241
|
-
const [results, setResults] = useState([]);
|
|
72242
|
-
const [timeRemaining, setTimeRemaining] = useState(totalTimeLimit || 0);
|
|
72243
|
-
const [questionStartTime, setQuestionStartTime] = useState({});
|
|
72244
|
-
const [showResults, setShowResults] = useState(false);
|
|
72245
|
-
const [currentQuestionTime, setCurrentQuestionTime] = useState(0);
|
|
72246
|
-
useEffect(() => {
|
|
72247
|
-
if (!showTimer || !totalTimeLimit || showResults)
|
|
72248
|
-
return;
|
|
72249
|
-
const interval = setInterval(() => {
|
|
72250
|
-
setTimeRemaining((prev) => {
|
|
72251
|
-
if (prev <= 1) {
|
|
72252
|
-
handleQuizComplete();
|
|
72253
|
-
return 0;
|
|
72254
|
-
}
|
|
72255
|
-
return prev - 1;
|
|
72256
|
-
});
|
|
72257
|
-
}, 1e3);
|
|
72258
|
-
return () => clearInterval(interval);
|
|
72259
|
-
}, [showTimer, totalTimeLimit, showResults]);
|
|
72260
|
-
useEffect(() => {
|
|
72261
|
-
if (!showTimer || showResults)
|
|
72262
|
-
return;
|
|
72263
|
-
const interval = setInterval(() => {
|
|
72264
|
-
setCurrentQuestionTime((prev) => prev + 1);
|
|
72265
|
-
}, 1e3);
|
|
72266
|
-
return () => clearInterval(interval);
|
|
72267
|
-
}, [showTimer, showResults]);
|
|
72268
|
-
const calculateScore = useCallback(() => {
|
|
72269
|
-
let score = 0;
|
|
72270
|
-
let totalScore = 0;
|
|
72271
|
-
const quizResults = questions.map((question) => {
|
|
72272
|
-
const answer = answers[question.id];
|
|
72273
|
-
const points = question.points || 1;
|
|
72274
|
-
totalScore += points;
|
|
72275
|
-
let isCorrect = false;
|
|
72276
|
-
if (answer !== void 0 && answer !== null && answer !== "") {
|
|
72277
|
-
if (question.type === "single-choice" || question.type === "true-false") {
|
|
72278
|
-
isCorrect = answer === question.correctAnswer;
|
|
72279
|
-
} else if (question.type === "multiple-choice") {
|
|
72280
|
-
const userAnswers = Array.isArray(answer) ? answer : [];
|
|
72281
|
-
const correctAnswers = Array.isArray(question.correctAnswer) ? question.correctAnswer : [];
|
|
72282
|
-
isCorrect = userAnswers.length === correctAnswers.length && userAnswers.every((a2) => correctAnswers.includes(a2));
|
|
72283
|
-
}
|
|
72284
|
-
}
|
|
72285
|
-
const earnedPoints = isCorrect ? points : 0;
|
|
72286
|
-
score += earnedPoints;
|
|
72287
|
-
return {
|
|
72288
|
-
questionId: question.id,
|
|
72289
|
-
answer,
|
|
72290
|
-
isCorrect,
|
|
72291
|
-
points: earnedPoints,
|
|
72292
|
-
timeSpent: questionStartTime[question.id] || 0
|
|
72293
|
-
};
|
|
72294
|
-
});
|
|
72295
|
-
return { results: quizResults, score, totalScore };
|
|
72296
|
-
}, [questions, answers, questionStartTime]);
|
|
72297
|
-
const handleQuizComplete = async () => {
|
|
72298
|
-
const { results: results2, score, totalScore } = calculateScore();
|
|
72299
|
-
setResults(results2);
|
|
72300
|
-
setShowResults(true);
|
|
72301
|
-
if (onComplete) {
|
|
72302
|
-
await onComplete(results2, score, totalScore);
|
|
72303
|
-
}
|
|
72304
|
-
};
|
|
72305
|
-
const formatTime = (seconds) => {
|
|
72306
|
-
const mins = Math.floor(seconds / 60);
|
|
72307
|
-
const secs = seconds % 60;
|
|
72308
|
-
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
72309
|
-
};
|
|
72310
|
-
const wizardSteps = questions.map((question, index2) => ({
|
|
72311
|
-
id: question.id,
|
|
72312
|
-
title: `Question ${index2 + 1}`,
|
|
72313
|
-
description: question.tags?.join(", "),
|
|
72314
|
-
content: ({ updateStepData, goToNext }) => {
|
|
72315
|
-
const currentAnswer = answers[question.id];
|
|
72316
|
-
const questionOptions = shuffleOptions && question.options ? shuffleArray(question.options) : question.options;
|
|
72317
|
-
useEffect(() => {
|
|
72318
|
-
if (!questionStartTime[question.id]) {
|
|
72319
|
-
setQuestionStartTime((prev) => ({
|
|
72320
|
-
...prev,
|
|
72321
|
-
[question.id]: currentQuestionTime
|
|
72322
|
-
}));
|
|
72323
|
-
}
|
|
72324
|
-
}, []);
|
|
72325
|
-
const handleAnswerChange = (value) => {
|
|
72326
|
-
setAnswers((prev) => ({ ...prev, [question.id]: value }));
|
|
72327
|
-
if (instantFeedback && question.type !== "text") ;
|
|
72328
|
-
};
|
|
72329
|
-
return /* @__PURE__ */ jsxs(MoonUICardPro, { className: "border-0 shadow-none", children: [
|
|
72330
|
-
/* @__PURE__ */ jsxs(MoonUICardHeaderPro, { children: [
|
|
72331
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
|
|
72332
|
-
showQuestionNumbers && /* @__PURE__ */ jsxs(MoonUIBadgePro, { variant: "secondary", children: [
|
|
72333
|
-
"Question ",
|
|
72334
|
-
index2 + 1,
|
|
72335
|
-
" of ",
|
|
72336
|
-
questions.length
|
|
72337
|
-
] }),
|
|
72338
|
-
question.points && question.points > 1 && /* @__PURE__ */ jsxs(MoonUIBadgePro, { variant: "outline", children: [
|
|
72339
|
-
question.points,
|
|
72340
|
-
" points"
|
|
72341
|
-
] })
|
|
72342
|
-
] }),
|
|
72343
|
-
/* @__PURE__ */ jsx(MoonUICardTitlePro, { className: "text-xl", children: question.question }),
|
|
72344
|
-
question.description && /* @__PURE__ */ jsx(MoonUICardDescriptionPro, { children: question.description })
|
|
72345
|
-
] }),
|
|
72346
|
-
/* @__PURE__ */ jsxs(MoonUICardContentPro, { className: "space-y-4", children: [
|
|
72347
|
-
question.image && /* @__PURE__ */ jsx(
|
|
72348
|
-
"img",
|
|
72349
|
-
{
|
|
72350
|
-
src: question.image,
|
|
72351
|
-
alt: "Question illustration",
|
|
72352
|
-
className: "w-full rounded-lg"
|
|
72353
|
-
}
|
|
72354
|
-
),
|
|
72355
|
-
question.type === "single-choice" && questionOptions && /* @__PURE__ */ jsx(
|
|
72356
|
-
MoonUIRadioGroupPro,
|
|
72357
|
-
{
|
|
72358
|
-
value: currentAnswer || "",
|
|
72359
|
-
onValueChange: handleAnswerChange,
|
|
72360
|
-
children: questionOptions.map((option, optionIndex) => /* @__PURE__ */ jsxs(
|
|
72361
|
-
motion.div,
|
|
72362
|
-
{
|
|
72363
|
-
initial: { opacity: 0, x: -20 },
|
|
72364
|
-
animate: { opacity: 1, x: 0 },
|
|
72365
|
-
transition: { delay: optionIndex * 0.1 },
|
|
72366
|
-
className: "flex items-center space-x-2 p-3 rounded-lg hover:bg-muted/50 transition-colors",
|
|
72367
|
-
children: [
|
|
72368
|
-
/* @__PURE__ */ jsx(MoonUIRadioGroupItemPro, { value: String(option.value), id: `${question.id}-${option.value}` }),
|
|
72369
|
-
/* @__PURE__ */ jsx(
|
|
72370
|
-
MoonUILabelPro,
|
|
72371
|
-
{
|
|
72372
|
-
htmlFor: `${question.id}-${option.value}`,
|
|
72373
|
-
className: "flex-1 cursor-pointer",
|
|
72374
|
-
children: option.label || option.value
|
|
72375
|
-
}
|
|
72376
|
-
)
|
|
72377
|
-
]
|
|
72378
|
-
},
|
|
72379
|
-
String(option.value)
|
|
72380
|
-
))
|
|
72381
|
-
}
|
|
72382
|
-
),
|
|
72383
|
-
question.type === "multiple-choice" && questionOptions && /* @__PURE__ */ jsx("div", { className: "space-y-2", children: questionOptions.map((option, optionIndex) => /* @__PURE__ */ jsxs(
|
|
72384
|
-
motion.div,
|
|
72385
|
-
{
|
|
72386
|
-
initial: { opacity: 0, x: -20 },
|
|
72387
|
-
animate: { opacity: 1, x: 0 },
|
|
72388
|
-
transition: { delay: optionIndex * 0.1 },
|
|
72389
|
-
className: "flex items-center space-x-2 p-3 rounded-lg hover:bg-muted/50 transition-colors",
|
|
72390
|
-
children: [
|
|
72391
|
-
/* @__PURE__ */ jsx(
|
|
72392
|
-
MoonUICheckboxPro,
|
|
72393
|
-
{
|
|
72394
|
-
id: `${question.id}-${option.value}`,
|
|
72395
|
-
checked: (currentAnswer || []).includes(option.value),
|
|
72396
|
-
onCheckedChange: (checked) => {
|
|
72397
|
-
const current = currentAnswer || [];
|
|
72398
|
-
if (checked) {
|
|
72399
|
-
handleAnswerChange([...current, option.value]);
|
|
72400
|
-
} else {
|
|
72401
|
-
handleAnswerChange(current.filter((v) => v !== option.value));
|
|
72402
|
-
}
|
|
72403
|
-
}
|
|
72404
|
-
}
|
|
72405
|
-
),
|
|
72406
|
-
/* @__PURE__ */ jsx(
|
|
72407
|
-
MoonUILabelPro,
|
|
72408
|
-
{
|
|
72409
|
-
htmlFor: `${question.id}-${option.value}`,
|
|
72410
|
-
className: "flex-1 cursor-pointer",
|
|
72411
|
-
children: option.label || option.value
|
|
72412
|
-
}
|
|
72413
|
-
)
|
|
72414
|
-
]
|
|
72415
|
-
},
|
|
72416
|
-
String(option.value)
|
|
72417
|
-
)) }),
|
|
72418
|
-
question.type === "true-false" && /* @__PURE__ */ jsxs(
|
|
72419
|
-
MoonUIRadioGroupPro,
|
|
72420
|
-
{
|
|
72421
|
-
value: currentAnswer?.toString() || "",
|
|
72422
|
-
onValueChange: (value) => handleAnswerChange(value === "true"),
|
|
72423
|
-
children: [
|
|
72424
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2 p-3 rounded-lg hover:bg-muted/50", children: [
|
|
72425
|
-
/* @__PURE__ */ jsx(MoonUIRadioGroupItemPro, { value: "true", id: `${question.id}-true` }),
|
|
72426
|
-
/* @__PURE__ */ jsx(MoonUILabelPro, { htmlFor: `${question.id}-true`, className: "flex-1 cursor-pointer", children: "True" })
|
|
72427
|
-
] }),
|
|
72428
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2 p-3 rounded-lg hover:bg-muted/50", children: [
|
|
72429
|
-
/* @__PURE__ */ jsx(MoonUIRadioGroupItemPro, { value: "false", id: `${question.id}-false` }),
|
|
72430
|
-
/* @__PURE__ */ jsx(MoonUILabelPro, { htmlFor: `${question.id}-false`, className: "flex-1 cursor-pointer", children: "False" })
|
|
72431
|
-
] })
|
|
72432
|
-
]
|
|
72433
|
-
}
|
|
72434
|
-
),
|
|
72435
|
-
question.type === "text" && /* @__PURE__ */ jsx(
|
|
72436
|
-
MoonUITextareaPro,
|
|
72437
|
-
{
|
|
72438
|
-
value: currentAnswer || "",
|
|
72439
|
-
onChange: (e2) => handleAnswerChange(e2.target.value),
|
|
72440
|
-
placeholder: "Type your answer here...",
|
|
72441
|
-
className: "min-h-[120px]"
|
|
72442
|
-
}
|
|
72443
|
-
),
|
|
72444
|
-
question.type === "rating" && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
72445
|
-
/* @__PURE__ */ jsx(
|
|
72446
|
-
MoonUISliderPro,
|
|
72447
|
-
{
|
|
72448
|
-
value: [currentAnswer || 5],
|
|
72449
|
-
onValueChange: ([value]) => handleAnswerChange(value),
|
|
72450
|
-
max: 10,
|
|
72451
|
-
min: 1,
|
|
72452
|
-
step: 1,
|
|
72453
|
-
className: "w-full"
|
|
72454
|
-
}
|
|
72455
|
-
),
|
|
72456
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center text-2xl font-bold", children: [
|
|
72457
|
-
currentAnswer || 5,
|
|
72458
|
-
"/10"
|
|
72459
|
-
] })
|
|
72460
|
-
] }),
|
|
72461
|
-
showHints && question.hint && /* @__PURE__ */ jsx(MoonUIAlertPro, { children: /* @__PURE__ */ jsxs(MoonUIAlertDescriptionPro, { children: [
|
|
72462
|
-
/* @__PURE__ */ jsx("strong", { children: "Hint:" }),
|
|
72463
|
-
" ",
|
|
72464
|
-
question.hint
|
|
72465
|
-
] }) })
|
|
72466
|
-
] })
|
|
72467
|
-
] });
|
|
72468
|
-
},
|
|
72469
|
-
validation: () => {
|
|
72470
|
-
if (question.required && !answers[question.id]) {
|
|
72471
|
-
return false;
|
|
72472
|
-
}
|
|
72473
|
-
return true;
|
|
72474
|
-
},
|
|
72475
|
-
isOptional: !question.required
|
|
72476
|
-
}));
|
|
72477
|
-
if (showResults) {
|
|
72478
|
-
const { score, totalScore } = calculateScore();
|
|
72479
|
-
const percentage = Math.round(score / totalScore * 100);
|
|
72480
|
-
const passed = percentage >= passingScore;
|
|
72481
|
-
return /* @__PURE__ */ jsx(
|
|
72482
|
-
motion.div,
|
|
72483
|
-
{
|
|
72484
|
-
initial: { opacity: 0, scale: 0.9 },
|
|
72485
|
-
animate: { opacity: 1, scale: 1 },
|
|
72486
|
-
className: cn("w-full max-w-2xl mx-auto", className),
|
|
72487
|
-
children: /* @__PURE__ */ jsxs(MoonUICardPro, { children: [
|
|
72488
|
-
/* @__PURE__ */ jsxs(MoonUICardHeaderPro, { className: "text-center", children: [
|
|
72489
|
-
/* @__PURE__ */ jsx("div", { className: "mx-auto mb-4", children: /* @__PURE__ */ jsx(Trophy, { className: cn(
|
|
72490
|
-
"w-16 h-16",
|
|
72491
|
-
passed ? "text-yellow-500" : "text-muted-foreground"
|
|
72492
|
-
) }) }),
|
|
72493
|
-
/* @__PURE__ */ jsx(MoonUICardTitlePro, { className: "text-3xl", children: "Quiz Complete!" }),
|
|
72494
|
-
/* @__PURE__ */ jsx(MoonUICardDescriptionPro, { children: "Here's how you performed" })
|
|
72495
|
-
] }),
|
|
72496
|
-
/* @__PURE__ */ jsxs(MoonUICardContentPro, { className: "space-y-6", children: [
|
|
72497
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
72498
|
-
/* @__PURE__ */ jsxs("div", { className: "text-5xl font-bold mb-2", children: [
|
|
72499
|
-
percentage,
|
|
72500
|
-
"%"
|
|
72501
|
-
] }),
|
|
72502
|
-
/* @__PURE__ */ jsx(MoonUIProgressPro, { value: percentage, className: "h-3 mb-4" }),
|
|
72503
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm text-muted-foreground", children: [
|
|
72504
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
72505
|
-
"Score: ",
|
|
72506
|
-
score,
|
|
72507
|
-
"/",
|
|
72508
|
-
totalScore
|
|
72509
|
-
] }),
|
|
72510
|
-
/* @__PURE__ */ jsx("span", { children: passed ? /* @__PURE__ */ jsx(MoonUIBadgePro, { variant: "success", children: "Passed" }) : /* @__PURE__ */ jsx(MoonUIBadgePro, { variant: "destructive", children: "Failed" }) })
|
|
72511
|
-
] })
|
|
72512
|
-
] }),
|
|
72513
|
-
allowReview && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
72514
|
-
/* @__PURE__ */ jsx("h3", { className: "font-semibold", children: "Review Answers" }),
|
|
72515
|
-
results.map((result, index2) => {
|
|
72516
|
-
const question = questions.find((q) => q.id === result.questionId);
|
|
72517
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-2 rounded-lg bg-muted/50", children: [
|
|
72518
|
-
/* @__PURE__ */ jsxs("span", { className: "text-sm", children: [
|
|
72519
|
-
showQuestionNumbers && `Q${index2 + 1}: `,
|
|
72520
|
-
question?.question.substring(0, 50),
|
|
72521
|
-
"..."
|
|
72522
|
-
] }),
|
|
72523
|
-
/* @__PURE__ */ jsxs(MoonUIBadgePro, { variant: result.isCorrect ? "success" : "destructive", children: [
|
|
72524
|
-
result.points,
|
|
72525
|
-
"/",
|
|
72526
|
-
question?.points || 1
|
|
72527
|
-
] })
|
|
72528
|
-
] }, result.questionId);
|
|
72529
|
-
})
|
|
72530
|
-
] }),
|
|
72531
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
72532
|
-
/* @__PURE__ */ jsxs(MoonUIButtonPro, { className: "flex-1", onClick: () => window.location.reload(), children: [
|
|
72533
|
-
/* @__PURE__ */ jsx(RotateCcw, { className: "w-4 h-4 mr-2" }),
|
|
72534
|
-
"Retake Quiz"
|
|
72535
|
-
] }),
|
|
72536
|
-
/* @__PURE__ */ jsxs(MoonUIButtonPro, { variant: "outline", children: [
|
|
72537
|
-
/* @__PURE__ */ jsx(Download, { className: "w-4 h-4 mr-2" }),
|
|
72538
|
-
"Download Results"
|
|
72539
|
-
] }),
|
|
72540
|
-
/* @__PURE__ */ jsxs(MoonUIButtonPro, { variant: "outline", children: [
|
|
72541
|
-
/* @__PURE__ */ jsx(Share2, { className: "w-4 h-4 mr-2" }),
|
|
72542
|
-
"Share"
|
|
72543
|
-
] })
|
|
72544
|
-
] })
|
|
72545
|
-
] })
|
|
72546
|
-
] })
|
|
72547
|
-
}
|
|
72548
|
-
);
|
|
72549
|
-
}
|
|
72550
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
|
|
72551
|
-
showTimer && totalTimeLimit && /* @__PURE__ */ jsxs("div", { className: "mb-6 flex items-center justify-between", children: [
|
|
72552
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
72553
|
-
/* @__PURE__ */ jsx(Clock, { className: "w-4 h-4" }),
|
|
72554
|
-
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", children: [
|
|
72555
|
-
"Time Remaining: ",
|
|
72556
|
-
formatTime(timeRemaining)
|
|
72557
|
-
] })
|
|
72558
|
-
] }),
|
|
72559
|
-
/* @__PURE__ */ jsx(
|
|
72560
|
-
MoonUIProgressPro,
|
|
72561
|
-
{
|
|
72562
|
-
value: timeRemaining / totalTimeLimit * 100,
|
|
72563
|
-
className: "w-32 h-2"
|
|
72564
|
-
}
|
|
72565
|
-
)
|
|
72566
|
-
] }),
|
|
72567
|
-
/* @__PURE__ */ jsx(
|
|
72568
|
-
MoonUIFormWizardPro,
|
|
72569
|
-
{
|
|
72570
|
-
steps: wizardSteps,
|
|
72571
|
-
onComplete: handleQuizComplete,
|
|
72572
|
-
allowStepSkip: allowSkip,
|
|
72573
|
-
validateOnStepChange: true,
|
|
72574
|
-
showProgressBar: showProgress,
|
|
72575
|
-
progressType: "dots",
|
|
72576
|
-
animationType: "slide"
|
|
72577
|
-
}
|
|
72578
|
-
)
|
|
72579
|
-
] });
|
|
72580
|
-
};
|
|
72581
72211
|
var cardPatterns = {
|
|
72582
72212
|
visa: /^4/,
|
|
72583
72213
|
mastercard: /^5[1-5]/,
|
|
@@ -73109,6 +72739,609 @@ var MoonUIPhoneNumberInputPro = t__default.forwardRef(({
|
|
|
73109
72739
|
] });
|
|
73110
72740
|
});
|
|
73111
72741
|
MoonUIPhoneNumberInputPro.displayName = "MoonUIPhoneNumberInputPro";
|
|
72742
|
+
var quizFormVariants = cva(
|
|
72743
|
+
"relative w-full rounded-lg border bg-card text-card-foreground shadow-sm",
|
|
72744
|
+
{
|
|
72745
|
+
variants: {
|
|
72746
|
+
variant: {
|
|
72747
|
+
default: "border-border",
|
|
72748
|
+
exam: "border-primary/20 bg-primary/5",
|
|
72749
|
+
personality: "border-secondary/20 bg-secondary/5"
|
|
72750
|
+
},
|
|
72751
|
+
size: {
|
|
72752
|
+
sm: "p-4",
|
|
72753
|
+
md: "p-6",
|
|
72754
|
+
lg: "p-8"
|
|
72755
|
+
}
|
|
72756
|
+
},
|
|
72757
|
+
defaultVariants: {
|
|
72758
|
+
variant: "default",
|
|
72759
|
+
size: "md"
|
|
72760
|
+
}
|
|
72761
|
+
}
|
|
72762
|
+
);
|
|
72763
|
+
var MoonUIQuizFormPro = t__default.forwardRef(({
|
|
72764
|
+
className,
|
|
72765
|
+
variant,
|
|
72766
|
+
size: size4,
|
|
72767
|
+
questions: initialQuestions,
|
|
72768
|
+
settings = {},
|
|
72769
|
+
onComplete,
|
|
72770
|
+
onProgress,
|
|
72771
|
+
title,
|
|
72772
|
+
description,
|
|
72773
|
+
...props
|
|
72774
|
+
}, ref) => {
|
|
72775
|
+
const [questions, setQuestions] = useState([]);
|
|
72776
|
+
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
|
|
72777
|
+
const [userAnswers, setUserAnswers] = useState({});
|
|
72778
|
+
const [showResults, setShowResults] = useState(false);
|
|
72779
|
+
const [quizResult, setQuizResult] = useState(null);
|
|
72780
|
+
const [timeLeft, setTimeLeft] = useState(
|
|
72781
|
+
settings.timeLimit ? settings.timeLimit * 60 : null
|
|
72782
|
+
);
|
|
72783
|
+
const [questionStartTime, setQuestionStartTime] = useState(Date.now());
|
|
72784
|
+
const [showHint, setShowHint] = useState(false);
|
|
72785
|
+
const [attempts, setAttempts] = useState(0);
|
|
72786
|
+
useEffect(() => {
|
|
72787
|
+
let processedQuestions = [...initialQuestions];
|
|
72788
|
+
if (settings.shuffleQuestions) {
|
|
72789
|
+
processedQuestions = shuffleArray(processedQuestions);
|
|
72790
|
+
}
|
|
72791
|
+
if (settings.shuffleOptions) {
|
|
72792
|
+
processedQuestions = processedQuestions.map((q) => {
|
|
72793
|
+
if (q.options) {
|
|
72794
|
+
return { ...q, options: shuffleArray([...q.options]) };
|
|
72795
|
+
}
|
|
72796
|
+
return q;
|
|
72797
|
+
});
|
|
72798
|
+
}
|
|
72799
|
+
setQuestions(processedQuestions);
|
|
72800
|
+
}, [initialQuestions, settings.shuffleQuestions, settings.shuffleOptions]);
|
|
72801
|
+
useEffect(() => {
|
|
72802
|
+
if (timeLeft === null || timeLeft <= 0 || showResults)
|
|
72803
|
+
return;
|
|
72804
|
+
const timer = setInterval(() => {
|
|
72805
|
+
setTimeLeft((prev) => {
|
|
72806
|
+
if (prev === null || prev <= 1) {
|
|
72807
|
+
handleComplete();
|
|
72808
|
+
return 0;
|
|
72809
|
+
}
|
|
72810
|
+
return prev - 1;
|
|
72811
|
+
});
|
|
72812
|
+
}, 1e3);
|
|
72813
|
+
return () => clearInterval(timer);
|
|
72814
|
+
}, [timeLeft, showResults]);
|
|
72815
|
+
useEffect(() => {
|
|
72816
|
+
if (onProgress) {
|
|
72817
|
+
onProgress(currentQuestionIndex + 1, questions.length);
|
|
72818
|
+
}
|
|
72819
|
+
}, [currentQuestionIndex, questions.length, onProgress]);
|
|
72820
|
+
const currentQuestion = questions[currentQuestionIndex];
|
|
72821
|
+
const shuffleArray = (array2) => {
|
|
72822
|
+
const newArray = [...array2];
|
|
72823
|
+
for (let i3 = newArray.length - 1; i3 > 0; i3--) {
|
|
72824
|
+
const j = Math.floor(Math.random() * (i3 + 1));
|
|
72825
|
+
[newArray[i3], newArray[j]] = [newArray[j], newArray[i3]];
|
|
72826
|
+
}
|
|
72827
|
+
return newArray;
|
|
72828
|
+
};
|
|
72829
|
+
const saveAnswer = (answer) => {
|
|
72830
|
+
const timeSpent = Date.now() - questionStartTime;
|
|
72831
|
+
setUserAnswers((prev) => ({
|
|
72832
|
+
...prev,
|
|
72833
|
+
[currentQuestion.id]: {
|
|
72834
|
+
questionId: currentQuestion.id,
|
|
72835
|
+
answer,
|
|
72836
|
+
timeSpent
|
|
72837
|
+
}
|
|
72838
|
+
}));
|
|
72839
|
+
};
|
|
72840
|
+
const handleNext = () => {
|
|
72841
|
+
if (currentQuestionIndex < questions.length - 1) {
|
|
72842
|
+
setCurrentQuestionIndex((prev) => prev + 1);
|
|
72843
|
+
setQuestionStartTime(Date.now());
|
|
72844
|
+
setShowHint(false);
|
|
72845
|
+
} else {
|
|
72846
|
+
handleComplete();
|
|
72847
|
+
}
|
|
72848
|
+
};
|
|
72849
|
+
const handlePrevious = () => {
|
|
72850
|
+
if (currentQuestionIndex > 0) {
|
|
72851
|
+
setCurrentQuestionIndex((prev) => prev - 1);
|
|
72852
|
+
setShowHint(false);
|
|
72853
|
+
}
|
|
72854
|
+
};
|
|
72855
|
+
const handleComplete = () => {
|
|
72856
|
+
const result = calculateResult();
|
|
72857
|
+
setQuizResult(result);
|
|
72858
|
+
setShowResults(true);
|
|
72859
|
+
setAttempts((prev) => prev + 1);
|
|
72860
|
+
if (onComplete) {
|
|
72861
|
+
onComplete(result);
|
|
72862
|
+
}
|
|
72863
|
+
};
|
|
72864
|
+
const calculateResult = () => {
|
|
72865
|
+
let totalScore = 0;
|
|
72866
|
+
let userScore = 0;
|
|
72867
|
+
const answers = [];
|
|
72868
|
+
questions.forEach((question) => {
|
|
72869
|
+
const userAnswer = userAnswers[question.id];
|
|
72870
|
+
const points = question.points || 1;
|
|
72871
|
+
totalScore += points;
|
|
72872
|
+
let isCorrect = false;
|
|
72873
|
+
if (userAnswer?.answer && question.correctAnswer !== void 0) {
|
|
72874
|
+
switch (question.type) {
|
|
72875
|
+
case "single-choice":
|
|
72876
|
+
case "true-false":
|
|
72877
|
+
case "text":
|
|
72878
|
+
isCorrect = userAnswer.answer === question.correctAnswer;
|
|
72879
|
+
break;
|
|
72880
|
+
case "multiple-choice":
|
|
72881
|
+
if (Array.isArray(userAnswer.answer) && Array.isArray(question.correctAnswer)) {
|
|
72882
|
+
isCorrect = userAnswer.answer.length === question.correctAnswer.length && userAnswer.answer.every((a2) => question.correctAnswer.includes(a2));
|
|
72883
|
+
}
|
|
72884
|
+
break;
|
|
72885
|
+
case "matching":
|
|
72886
|
+
if (typeof userAnswer.answer === "object" && typeof question.correctAnswer === "object") {
|
|
72887
|
+
const correct = question.correctAnswer;
|
|
72888
|
+
const user = userAnswer.answer;
|
|
72889
|
+
isCorrect = Object.keys(correct).every((key) => correct[key] === user[key]);
|
|
72890
|
+
}
|
|
72891
|
+
break;
|
|
72892
|
+
case "rating":
|
|
72893
|
+
isCorrect = true;
|
|
72894
|
+
break;
|
|
72895
|
+
}
|
|
72896
|
+
}
|
|
72897
|
+
if (isCorrect) {
|
|
72898
|
+
userScore += points;
|
|
72899
|
+
}
|
|
72900
|
+
answers.push({
|
|
72901
|
+
questionId: question.id,
|
|
72902
|
+
userAnswer: userAnswer?.answer || null,
|
|
72903
|
+
correctAnswer: question.correctAnswer,
|
|
72904
|
+
isCorrect,
|
|
72905
|
+
points: isCorrect ? points : 0
|
|
72906
|
+
});
|
|
72907
|
+
});
|
|
72908
|
+
const percentage = totalScore > 0 ? userScore / totalScore * 100 : 0;
|
|
72909
|
+
const totalTimeSpent = Object.values(userAnswers).reduce(
|
|
72910
|
+
(sum, answer) => sum + (answer.timeSpent || 0),
|
|
72911
|
+
0
|
|
72912
|
+
);
|
|
72913
|
+
return {
|
|
72914
|
+
score: userScore,
|
|
72915
|
+
totalScore,
|
|
72916
|
+
percentage,
|
|
72917
|
+
passed: settings.passingScore ? percentage >= settings.passingScore : void 0,
|
|
72918
|
+
answers,
|
|
72919
|
+
timeSpent: totalTimeSpent,
|
|
72920
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
72921
|
+
};
|
|
72922
|
+
};
|
|
72923
|
+
const handleRestart = () => {
|
|
72924
|
+
setCurrentQuestionIndex(0);
|
|
72925
|
+
setUserAnswers({});
|
|
72926
|
+
setShowResults(false);
|
|
72927
|
+
setQuizResult(null);
|
|
72928
|
+
setTimeLeft(settings.timeLimit ? settings.timeLimit * 60 : null);
|
|
72929
|
+
setQuestionStartTime(Date.now());
|
|
72930
|
+
setShowHint(false);
|
|
72931
|
+
if (settings.shuffleQuestions) {
|
|
72932
|
+
setQuestions(shuffleArray([...initialQuestions]));
|
|
72933
|
+
}
|
|
72934
|
+
};
|
|
72935
|
+
const handleDownloadResults = () => {
|
|
72936
|
+
if (!quizResult)
|
|
72937
|
+
return;
|
|
72938
|
+
const data = {
|
|
72939
|
+
title,
|
|
72940
|
+
completedAt: quizResult.completedAt,
|
|
72941
|
+
score: quizResult.score,
|
|
72942
|
+
totalScore: quizResult.totalScore,
|
|
72943
|
+
percentage: quizResult.percentage,
|
|
72944
|
+
passed: quizResult.passed,
|
|
72945
|
+
timeSpent: quizResult.timeSpent,
|
|
72946
|
+
answers: quizResult.answers.map((a2) => {
|
|
72947
|
+
const question = questions.find((q) => q.id === a2.questionId);
|
|
72948
|
+
return {
|
|
72949
|
+
question: question?.question,
|
|
72950
|
+
userAnswer: a2.userAnswer,
|
|
72951
|
+
correctAnswer: a2.correctAnswer,
|
|
72952
|
+
isCorrect: a2.isCorrect,
|
|
72953
|
+
points: a2.points
|
|
72954
|
+
};
|
|
72955
|
+
})
|
|
72956
|
+
};
|
|
72957
|
+
const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
|
|
72958
|
+
const url2 = URL.createObjectURL(blob);
|
|
72959
|
+
const link = document.createElement("a");
|
|
72960
|
+
link.href = url2;
|
|
72961
|
+
link.download = `quiz-results-${Date.now()}.json`;
|
|
72962
|
+
link.click();
|
|
72963
|
+
URL.revokeObjectURL(url2);
|
|
72964
|
+
};
|
|
72965
|
+
const formatTime = (seconds) => {
|
|
72966
|
+
const mins = Math.floor(seconds / 60);
|
|
72967
|
+
const secs = seconds % 60;
|
|
72968
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
72969
|
+
};
|
|
72970
|
+
const renderQuestion = () => {
|
|
72971
|
+
if (!currentQuestion)
|
|
72972
|
+
return null;
|
|
72973
|
+
const userAnswer = userAnswers[currentQuestion.id]?.answer;
|
|
72974
|
+
switch (currentQuestion.type) {
|
|
72975
|
+
case "single-choice":
|
|
72976
|
+
case "true-false":
|
|
72977
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-3", children: currentQuestion.options?.map((option, index2) => /* @__PURE__ */ jsx(
|
|
72978
|
+
motion.button,
|
|
72979
|
+
{
|
|
72980
|
+
initial: { opacity: 0, x: -20 },
|
|
72981
|
+
animate: { opacity: 1, x: 0 },
|
|
72982
|
+
transition: { delay: index2 * 0.1 },
|
|
72983
|
+
onClick: () => saveAnswer(option),
|
|
72984
|
+
className: cn(
|
|
72985
|
+
"w-full text-left p-4 rounded-lg border transition-colors",
|
|
72986
|
+
userAnswer === option ? "border-primary bg-primary/10" : "border-border hover:border-primary/50"
|
|
72987
|
+
),
|
|
72988
|
+
children: option
|
|
72989
|
+
},
|
|
72990
|
+
index2
|
|
72991
|
+
)) });
|
|
72992
|
+
case "multiple-choice":
|
|
72993
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-3", children: currentQuestion.options?.map((option, index2) => {
|
|
72994
|
+
const selected = Array.isArray(userAnswer) && userAnswer.includes(option);
|
|
72995
|
+
return /* @__PURE__ */ jsx(
|
|
72996
|
+
motion.button,
|
|
72997
|
+
{
|
|
72998
|
+
initial: { opacity: 0, x: -20 },
|
|
72999
|
+
animate: { opacity: 1, x: 0 },
|
|
73000
|
+
transition: { delay: index2 * 0.1 },
|
|
73001
|
+
onClick: () => {
|
|
73002
|
+
const current = userAnswer || [];
|
|
73003
|
+
const newAnswer = selected ? current.filter((a2) => a2 !== option) : [...current, option];
|
|
73004
|
+
saveAnswer(newAnswer);
|
|
73005
|
+
},
|
|
73006
|
+
className: cn(
|
|
73007
|
+
"w-full text-left p-4 rounded-lg border transition-colors",
|
|
73008
|
+
selected ? "border-primary bg-primary/10" : "border-border hover:border-primary/50"
|
|
73009
|
+
),
|
|
73010
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
73011
|
+
/* @__PURE__ */ jsx("div", { className: cn(
|
|
73012
|
+
"w-5 h-5 rounded border-2 transition-colors",
|
|
73013
|
+
selected ? "bg-primary border-primary" : "border-border"
|
|
73014
|
+
), children: selected && /* @__PURE__ */ jsx(CheckCircle2, { className: "w-full h-full text-primary-foreground" }) }),
|
|
73015
|
+
option
|
|
73016
|
+
] })
|
|
73017
|
+
},
|
|
73018
|
+
index2
|
|
73019
|
+
);
|
|
73020
|
+
}) });
|
|
73021
|
+
case "text":
|
|
73022
|
+
return /* @__PURE__ */ jsx(
|
|
73023
|
+
motion.div,
|
|
73024
|
+
{
|
|
73025
|
+
initial: { opacity: 0, y: 20 },
|
|
73026
|
+
animate: { opacity: 1, y: 0 },
|
|
73027
|
+
children: /* @__PURE__ */ jsx(
|
|
73028
|
+
"textarea",
|
|
73029
|
+
{
|
|
73030
|
+
className: "w-full p-4 rounded-lg border border-input bg-background resize-none",
|
|
73031
|
+
rows: 4,
|
|
73032
|
+
placeholder: "Type your answer here...",
|
|
73033
|
+
value: userAnswer || "",
|
|
73034
|
+
onChange: (e2) => saveAnswer(e2.target.value)
|
|
73035
|
+
}
|
|
73036
|
+
)
|
|
73037
|
+
}
|
|
73038
|
+
);
|
|
73039
|
+
case "rating":
|
|
73040
|
+
const maxRating = currentQuestion.maxRating || 5;
|
|
73041
|
+
const currentRating = typeof userAnswer === "number" ? userAnswer : 0;
|
|
73042
|
+
return /* @__PURE__ */ jsxs(
|
|
73043
|
+
motion.div,
|
|
73044
|
+
{
|
|
73045
|
+
initial: { opacity: 0, y: 20 },
|
|
73046
|
+
animate: { opacity: 1, y: 0 },
|
|
73047
|
+
className: "space-y-4",
|
|
73048
|
+
children: [
|
|
73049
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-center gap-2", children: Array.from({ length: maxRating }, (_, i3) => i3 + 1).map((rating) => /* @__PURE__ */ jsx(
|
|
73050
|
+
"button",
|
|
73051
|
+
{
|
|
73052
|
+
onClick: () => saveAnswer(rating),
|
|
73053
|
+
className: "transition-transform hover:scale-110",
|
|
73054
|
+
children: /* @__PURE__ */ jsx(
|
|
73055
|
+
Star,
|
|
73056
|
+
{
|
|
73057
|
+
className: cn(
|
|
73058
|
+
"w-10 h-10 transition-colors",
|
|
73059
|
+
rating <= currentRating ? "fill-yellow-500 text-yellow-500" : "text-muted-foreground"
|
|
73060
|
+
)
|
|
73061
|
+
}
|
|
73062
|
+
)
|
|
73063
|
+
},
|
|
73064
|
+
rating
|
|
73065
|
+
)) }),
|
|
73066
|
+
currentQuestion.ratingLabels && /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm text-muted-foreground", children: [
|
|
73067
|
+
/* @__PURE__ */ jsx("span", { children: currentQuestion.ratingLabels[0] }),
|
|
73068
|
+
/* @__PURE__ */ jsx("span", { children: currentQuestion.ratingLabels[1] })
|
|
73069
|
+
] })
|
|
73070
|
+
]
|
|
73071
|
+
}
|
|
73072
|
+
);
|
|
73073
|
+
case "matching":
|
|
73074
|
+
const matches2 = userAnswer || {};
|
|
73075
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-6", children: [
|
|
73076
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
73077
|
+
/* @__PURE__ */ jsx("h4", { className: "font-medium mb-2", children: "Match these items:" }),
|
|
73078
|
+
currentQuestion.leftOptions?.map((left, index2) => /* @__PURE__ */ jsx(
|
|
73079
|
+
motion.div,
|
|
73080
|
+
{
|
|
73081
|
+
initial: { opacity: 0, x: -20 },
|
|
73082
|
+
animate: { opacity: 1, x: 0 },
|
|
73083
|
+
transition: { delay: index2 * 0.1 },
|
|
73084
|
+
className: "p-3 rounded-lg border bg-muted/50",
|
|
73085
|
+
children: left
|
|
73086
|
+
},
|
|
73087
|
+
left
|
|
73088
|
+
))
|
|
73089
|
+
] }),
|
|
73090
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
73091
|
+
/* @__PURE__ */ jsx("h4", { className: "font-medium mb-2", children: "With these:" }),
|
|
73092
|
+
currentQuestion.leftOptions?.map((left) => /* @__PURE__ */ jsx(
|
|
73093
|
+
motion.div,
|
|
73094
|
+
{
|
|
73095
|
+
initial: { opacity: 0, x: 20 },
|
|
73096
|
+
animate: { opacity: 1, x: 0 },
|
|
73097
|
+
children: /* @__PURE__ */ jsxs(
|
|
73098
|
+
"select",
|
|
73099
|
+
{
|
|
73100
|
+
className: "w-full p-3 rounded-lg border bg-background",
|
|
73101
|
+
value: matches2[left] || "",
|
|
73102
|
+
onChange: (e2) => saveAnswer({ ...matches2, [left]: e2.target.value }),
|
|
73103
|
+
children: [
|
|
73104
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Select..." }),
|
|
73105
|
+
currentQuestion.rightOptions?.map((right) => /* @__PURE__ */ jsx("option", { value: right, children: right }, right))
|
|
73106
|
+
]
|
|
73107
|
+
}
|
|
73108
|
+
)
|
|
73109
|
+
},
|
|
73110
|
+
left
|
|
73111
|
+
))
|
|
73112
|
+
] })
|
|
73113
|
+
] });
|
|
73114
|
+
default:
|
|
73115
|
+
return null;
|
|
73116
|
+
}
|
|
73117
|
+
};
|
|
73118
|
+
if (showResults && quizResult) {
|
|
73119
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn(quizFormVariants({ variant, size: size4 }), className), ...props, children: /* @__PURE__ */ jsxs(
|
|
73120
|
+
motion.div,
|
|
73121
|
+
{
|
|
73122
|
+
initial: { opacity: 0, scale: 0.95 },
|
|
73123
|
+
animate: { opacity: 1, scale: 1 },
|
|
73124
|
+
className: "space-y-6",
|
|
73125
|
+
children: [
|
|
73126
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
73127
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold mb-2", children: "Quiz Completed!" }),
|
|
73128
|
+
/* @__PURE__ */ jsxs("div", { className: "text-5xl font-bold mb-4", children: [
|
|
73129
|
+
quizResult.percentage.toFixed(1),
|
|
73130
|
+
"%"
|
|
73131
|
+
] }),
|
|
73132
|
+
/* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
|
|
73133
|
+
"You scored ",
|
|
73134
|
+
quizResult.score,
|
|
73135
|
+
" out of ",
|
|
73136
|
+
quizResult.totalScore,
|
|
73137
|
+
" points"
|
|
73138
|
+
] }),
|
|
73139
|
+
quizResult.passed !== void 0 && /* @__PURE__ */ jsx("div", { className: cn(
|
|
73140
|
+
"mt-4 inline-flex items-center gap-2 px-4 py-2 rounded-full",
|
|
73141
|
+
quizResult.passed ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"
|
|
73142
|
+
), children: quizResult.passed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
73143
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "w-5 h-5" }),
|
|
73144
|
+
"Passed"
|
|
73145
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
73146
|
+
/* @__PURE__ */ jsx(XCircle, { className: "w-5 h-5" }),
|
|
73147
|
+
"Failed"
|
|
73148
|
+
] }) })
|
|
73149
|
+
] }),
|
|
73150
|
+
settings.allowReview && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
73151
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold", children: "Review Answers:" }),
|
|
73152
|
+
quizResult.answers.map((answer, index2) => {
|
|
73153
|
+
const question = questions.find((q) => q.id === answer.questionId);
|
|
73154
|
+
if (!question)
|
|
73155
|
+
return null;
|
|
73156
|
+
return /* @__PURE__ */ jsx("div", { className: "p-4 rounded-lg border bg-muted/50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
73157
|
+
answer.isCorrect ? /* @__PURE__ */ jsx(CheckCircle2, { className: "w-5 h-5 text-green-600 mt-0.5" }) : /* @__PURE__ */ jsx(XCircle, { className: "w-5 h-5 text-red-600 mt-0.5" }),
|
|
73158
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
73159
|
+
/* @__PURE__ */ jsxs("p", { className: "font-medium mb-2", children: [
|
|
73160
|
+
index2 + 1,
|
|
73161
|
+
". ",
|
|
73162
|
+
question.question
|
|
73163
|
+
] }),
|
|
73164
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
73165
|
+
"Your answer: ",
|
|
73166
|
+
JSON.stringify(answer.userAnswer)
|
|
73167
|
+
] }),
|
|
73168
|
+
!answer.isCorrect && question.correctAnswer !== void 0 && /* @__PURE__ */ jsxs("p", { className: "text-sm text-green-600 mt-1", children: [
|
|
73169
|
+
"Correct answer: ",
|
|
73170
|
+
JSON.stringify(question.correctAnswer)
|
|
73171
|
+
] }),
|
|
73172
|
+
question.explanation && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-2", children: question.explanation })
|
|
73173
|
+
] })
|
|
73174
|
+
] }) }, answer.questionId);
|
|
73175
|
+
})
|
|
73176
|
+
] }),
|
|
73177
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 justify-center", children: [
|
|
73178
|
+
(!settings.maxAttempts || attempts < settings.maxAttempts) && /* @__PURE__ */ jsxs(
|
|
73179
|
+
"button",
|
|
73180
|
+
{
|
|
73181
|
+
onClick: handleRestart,
|
|
73182
|
+
className: "inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90",
|
|
73183
|
+
children: [
|
|
73184
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "w-4 h-4" }),
|
|
73185
|
+
"Try Again"
|
|
73186
|
+
]
|
|
73187
|
+
}
|
|
73188
|
+
),
|
|
73189
|
+
/* @__PURE__ */ jsxs(
|
|
73190
|
+
"button",
|
|
73191
|
+
{
|
|
73192
|
+
onClick: handleDownloadResults,
|
|
73193
|
+
className: "inline-flex items-center gap-2 px-4 py-2 rounded-lg border hover:bg-muted",
|
|
73194
|
+
children: [
|
|
73195
|
+
/* @__PURE__ */ jsx(Download, { className: "w-4 h-4" }),
|
|
73196
|
+
"Download Results"
|
|
73197
|
+
]
|
|
73198
|
+
}
|
|
73199
|
+
)
|
|
73200
|
+
] })
|
|
73201
|
+
]
|
|
73202
|
+
}
|
|
73203
|
+
) });
|
|
73204
|
+
}
|
|
73205
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: cn(quizFormVariants({ variant, size: size4 }), className), ...props, children: [
|
|
73206
|
+
(title || timeLeft !== null) && /* @__PURE__ */ jsxs("div", { className: "mb-6 flex items-center justify-between", children: [
|
|
73207
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
73208
|
+
title && /* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold", children: title }),
|
|
73209
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1", children: description })
|
|
73210
|
+
] }),
|
|
73211
|
+
timeLeft !== null && /* @__PURE__ */ jsxs("div", { className: cn(
|
|
73212
|
+
"flex items-center gap-2 px-3 py-1 rounded-full text-sm font-medium",
|
|
73213
|
+
timeLeft < 60 ? "bg-red-100 text-red-700" : "bg-muted"
|
|
73214
|
+
), children: [
|
|
73215
|
+
/* @__PURE__ */ jsx(Clock, { className: "w-4 h-4" }),
|
|
73216
|
+
formatTime(timeLeft)
|
|
73217
|
+
] })
|
|
73218
|
+
] }),
|
|
73219
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
|
|
73220
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground mb-2", children: [
|
|
73221
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
73222
|
+
"Question ",
|
|
73223
|
+
currentQuestionIndex + 1,
|
|
73224
|
+
" of ",
|
|
73225
|
+
questions.length
|
|
73226
|
+
] }),
|
|
73227
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
73228
|
+
Math.round((currentQuestionIndex + 1) / questions.length * 100),
|
|
73229
|
+
"%"
|
|
73230
|
+
] })
|
|
73231
|
+
] }),
|
|
73232
|
+
/* @__PURE__ */ jsx("div", { className: "h-2 bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
73233
|
+
motion.div,
|
|
73234
|
+
{
|
|
73235
|
+
className: "h-full bg-primary",
|
|
73236
|
+
initial: { width: 0 },
|
|
73237
|
+
animate: { width: `${(currentQuestionIndex + 1) / questions.length * 100}%` },
|
|
73238
|
+
transition: { duration: 0.3 }
|
|
73239
|
+
}
|
|
73240
|
+
) })
|
|
73241
|
+
] }),
|
|
73242
|
+
/* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: currentQuestion && /* @__PURE__ */ jsxs(
|
|
73243
|
+
motion.div,
|
|
73244
|
+
{
|
|
73245
|
+
initial: { opacity: 0, x: 20 },
|
|
73246
|
+
animate: { opacity: 1, x: 0 },
|
|
73247
|
+
exit: { opacity: 0, x: -20 },
|
|
73248
|
+
className: "mb-6",
|
|
73249
|
+
children: [
|
|
73250
|
+
/* @__PURE__ */ jsxs("h3", { className: "text-lg font-semibold mb-4", children: [
|
|
73251
|
+
currentQuestion.question,
|
|
73252
|
+
currentQuestion.required && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", children: "*" })
|
|
73253
|
+
] }),
|
|
73254
|
+
renderQuestion(),
|
|
73255
|
+
settings.showHints && currentQuestion.hint && /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
|
|
73256
|
+
/* @__PURE__ */ jsxs(
|
|
73257
|
+
"button",
|
|
73258
|
+
{
|
|
73259
|
+
onClick: () => setShowHint(!showHint),
|
|
73260
|
+
className: "inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground",
|
|
73261
|
+
children: [
|
|
73262
|
+
/* @__PURE__ */ jsx(HelpCircle, { className: "w-4 h-4" }),
|
|
73263
|
+
showHint ? "Hide" : "Show",
|
|
73264
|
+
" Hint"
|
|
73265
|
+
]
|
|
73266
|
+
}
|
|
73267
|
+
),
|
|
73268
|
+
showHint && /* @__PURE__ */ jsx(
|
|
73269
|
+
motion.div,
|
|
73270
|
+
{
|
|
73271
|
+
initial: { opacity: 0, height: 0 },
|
|
73272
|
+
animate: { opacity: 1, height: "auto" },
|
|
73273
|
+
className: "mt-2 p-3 rounded-lg bg-muted/50 text-sm",
|
|
73274
|
+
children: currentQuestion.hint
|
|
73275
|
+
}
|
|
73276
|
+
)
|
|
73277
|
+
] }),
|
|
73278
|
+
settings.showInstantFeedback && userAnswers[currentQuestion.id] && currentQuestion.correctAnswer !== void 0 && /* @__PURE__ */ jsx(
|
|
73279
|
+
motion.div,
|
|
73280
|
+
{
|
|
73281
|
+
initial: { opacity: 0, y: 10 },
|
|
73282
|
+
animate: { opacity: 1, y: 0 },
|
|
73283
|
+
className: "mt-4",
|
|
73284
|
+
children: (() => {
|
|
73285
|
+
const userAnswer = userAnswers[currentQuestion.id].answer;
|
|
73286
|
+
let isCorrect = false;
|
|
73287
|
+
switch (currentQuestion.type) {
|
|
73288
|
+
case "single-choice":
|
|
73289
|
+
case "true-false":
|
|
73290
|
+
isCorrect = userAnswer === currentQuestion.correctAnswer;
|
|
73291
|
+
break;
|
|
73292
|
+
}
|
|
73293
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(
|
|
73294
|
+
"p-3 rounded-lg flex items-start gap-2",
|
|
73295
|
+
isCorrect ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"
|
|
73296
|
+
), children: [
|
|
73297
|
+
isCorrect ? /* @__PURE__ */ jsx(CheckCircle2, { className: "w-5 h-5 mt-0.5" }) : /* @__PURE__ */ jsx(XCircle, { className: "w-5 h-5 mt-0.5" }),
|
|
73298
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
73299
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: isCorrect ? "Correct!" : "Incorrect" }),
|
|
73300
|
+
currentQuestion.explanation && /* @__PURE__ */ jsx("p", { className: "text-sm mt-1", children: currentQuestion.explanation })
|
|
73301
|
+
] })
|
|
73302
|
+
] });
|
|
73303
|
+
})()
|
|
73304
|
+
}
|
|
73305
|
+
)
|
|
73306
|
+
]
|
|
73307
|
+
},
|
|
73308
|
+
currentQuestion.id
|
|
73309
|
+
) }),
|
|
73310
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
73311
|
+
/* @__PURE__ */ jsxs(
|
|
73312
|
+
"button",
|
|
73313
|
+
{
|
|
73314
|
+
onClick: handlePrevious,
|
|
73315
|
+
disabled: currentQuestionIndex === 0,
|
|
73316
|
+
className: cn(
|
|
73317
|
+
"inline-flex items-center gap-2 px-4 py-2 rounded-lg transition-colors",
|
|
73318
|
+
currentQuestionIndex === 0 ? "opacity-50 cursor-not-allowed bg-muted text-muted-foreground" : "bg-muted hover:bg-muted/80"
|
|
73319
|
+
),
|
|
73320
|
+
children: [
|
|
73321
|
+
/* @__PURE__ */ jsx(ChevronLeft, { className: "w-4 h-4" }),
|
|
73322
|
+
"Previous"
|
|
73323
|
+
]
|
|
73324
|
+
}
|
|
73325
|
+
),
|
|
73326
|
+
/* @__PURE__ */ jsxs(
|
|
73327
|
+
"button",
|
|
73328
|
+
{
|
|
73329
|
+
onClick: currentQuestionIndex === questions.length - 1 ? handleComplete : handleNext,
|
|
73330
|
+
disabled: currentQuestion?.required && !userAnswers[currentQuestion.id],
|
|
73331
|
+
className: cn(
|
|
73332
|
+
"inline-flex items-center gap-2 px-4 py-2 rounded-lg transition-colors",
|
|
73333
|
+
currentQuestion?.required && !userAnswers[currentQuestion.id] ? "opacity-50 cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90"
|
|
73334
|
+
),
|
|
73335
|
+
children: [
|
|
73336
|
+
currentQuestionIndex === questions.length - 1 ? "Complete" : "Next",
|
|
73337
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4" })
|
|
73338
|
+
]
|
|
73339
|
+
}
|
|
73340
|
+
)
|
|
73341
|
+
] })
|
|
73342
|
+
] });
|
|
73343
|
+
});
|
|
73344
|
+
MoonUIQuizFormPro.displayName = "MoonUIQuizFormPro";
|
|
73112
73345
|
|
|
73113
73346
|
// src/components/enhanced/index.ts
|
|
73114
73347
|
var enhanced_exports = {};
|