@schoolio/player 1.4.3 → 1.4.4

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.mjs CHANGED
@@ -158,15 +158,16 @@ function checkAnswer(question, selectedAnswer) {
158
158
  return { isCorrect, pointsEarned: isCorrect ? points : 0 };
159
159
  }
160
160
  case "essay":
161
- case "assessment":
162
161
  return { isCorrect: false, pointsEarned: 0 };
162
+ case "assessment":
163
+ return { isCorrect: true, pointsEarned: points };
163
164
  default:
164
165
  return { isCorrect: false, pointsEarned: 0 };
165
166
  }
166
167
  }
167
168
  function createAnswerDetail(question, selectedAnswer) {
168
169
  const { isCorrect, pointsEarned } = checkAnswer(question, selectedAnswer);
169
- return {
170
+ const detail = {
170
171
  questionId: question.id,
171
172
  questionText: question.question,
172
173
  questionType: question.type,
@@ -178,6 +179,14 @@ function createAnswerDetail(question, selectedAnswer) {
178
179
  explanation: question.explanation,
179
180
  hint: question.hint
180
181
  };
182
+ if (question.type === "sorting") {
183
+ detail.items = question.items;
184
+ detail.correctOrder = question.correctOrder;
185
+ } else if (question.type === "matrix") {
186
+ detail.leftItems = question.leftItems;
187
+ detail.rightItems = question.rightItems;
188
+ }
189
+ return detail;
181
190
  }
182
191
  function calculateScore(answers) {
183
192
  const totalPoints = answers.reduce((sum, a) => sum + a.points, 0);
@@ -1316,6 +1325,13 @@ var defaultStyles = {
1316
1325
  backgroundColor: "#fef2f2",
1317
1326
  borderColor: "#ef4444"
1318
1327
  },
1328
+ feedbackNeutral: {
1329
+ backgroundColor: "#f0f9ff",
1330
+ borderColor: "#0ea5e9"
1331
+ },
1332
+ feedbackTitleNeutral: {
1333
+ color: "#0369a1"
1334
+ },
1319
1335
  feedbackTitle: {
1320
1336
  fontSize: "16px",
1321
1337
  fontWeight: "600",
@@ -1336,6 +1352,290 @@ var defaultStyles = {
1336
1352
  lineHeight: "1.5"
1337
1353
  }
1338
1354
  };
1355
+ function SortingDragDrop({ items, currentOrder, correctOrder, showFeedback, onOrderChange }) {
1356
+ const [draggedIndex, setDraggedIndex] = useState3(null);
1357
+ const [dragOverIndex, setDragOverIndex] = useState3(null);
1358
+ const handleDragStart = (e, position) => {
1359
+ if (showFeedback) return;
1360
+ setDraggedIndex(position);
1361
+ e.dataTransfer.effectAllowed = "move";
1362
+ e.dataTransfer.setData("text/plain", position.toString());
1363
+ };
1364
+ const handleDragOver = (e, position) => {
1365
+ e.preventDefault();
1366
+ if (showFeedback) return;
1367
+ e.dataTransfer.dropEffect = "move";
1368
+ setDragOverIndex(position);
1369
+ };
1370
+ const handleDragLeave = () => {
1371
+ setDragOverIndex(null);
1372
+ };
1373
+ const handleDrop = (e, toPosition) => {
1374
+ e.preventDefault();
1375
+ if (showFeedback) return;
1376
+ const fromPosition = parseInt(e.dataTransfer.getData("text/plain"), 10);
1377
+ if (fromPosition !== toPosition) {
1378
+ const newOrder = [...currentOrder];
1379
+ const [movedItem] = newOrder.splice(fromPosition, 1);
1380
+ newOrder.splice(toPosition, 0, movedItem);
1381
+ onOrderChange(newOrder);
1382
+ }
1383
+ setDraggedIndex(null);
1384
+ setDragOverIndex(null);
1385
+ };
1386
+ const handleDragEnd = () => {
1387
+ setDraggedIndex(null);
1388
+ setDragOverIndex(null);
1389
+ };
1390
+ return /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentOrder.map((itemIndex, position) => {
1391
+ const isCorrectPosition = correctOrder?.[position] === itemIndex;
1392
+ const isDragging = draggedIndex === position;
1393
+ const isDragOver = dragOverIndex === position;
1394
+ let itemStyle = {
1395
+ ...defaultStyles.option,
1396
+ display: "flex",
1397
+ alignItems: "center",
1398
+ gap: "12px",
1399
+ cursor: showFeedback ? "default" : "grab",
1400
+ opacity: isDragging ? 0.5 : 1,
1401
+ transition: "all 0.2s ease",
1402
+ transform: isDragOver && !showFeedback ? "scale(1.02)" : "scale(1)"
1403
+ };
1404
+ if (showFeedback) {
1405
+ if (isCorrectPosition) {
1406
+ itemStyle = { ...itemStyle, ...defaultStyles.optionCorrect };
1407
+ } else {
1408
+ itemStyle = { ...itemStyle, ...defaultStyles.optionIncorrect };
1409
+ }
1410
+ } else if (isDragOver) {
1411
+ itemStyle = { ...itemStyle, borderColor: "#6366f1", backgroundColor: "#eef2ff" };
1412
+ }
1413
+ return /* @__PURE__ */ jsxs3(
1414
+ "div",
1415
+ {
1416
+ style: itemStyle,
1417
+ "data-testid": `sorting-item-${position}`,
1418
+ draggable: !showFeedback,
1419
+ onDragStart: (e) => handleDragStart(e, position),
1420
+ onDragOver: (e) => handleDragOver(e, position),
1421
+ onDragLeave: handleDragLeave,
1422
+ onDrop: (e) => handleDrop(e, position),
1423
+ onDragEnd: handleDragEnd,
1424
+ children: [
1425
+ !showFeedback && /* @__PURE__ */ jsx3("div", { style: {
1426
+ cursor: "grab",
1427
+ padding: "4px",
1428
+ display: "flex",
1429
+ alignItems: "center",
1430
+ color: "#9ca3af"
1431
+ }, children: /* @__PURE__ */ jsxs3("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1432
+ /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "5", r: "1" }),
1433
+ /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "12", r: "1" }),
1434
+ /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "19", r: "1" }),
1435
+ /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "5", r: "1" }),
1436
+ /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "12", r: "1" }),
1437
+ /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "19", r: "1" })
1438
+ ] }) }),
1439
+ showFeedback && /* @__PURE__ */ jsx3("div", { style: {
1440
+ display: "flex",
1441
+ alignItems: "center",
1442
+ color: isCorrectPosition ? "#22c55e" : "#ef4444"
1443
+ }, children: isCorrectPosition ? /* @__PURE__ */ jsxs3("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1444
+ /* @__PURE__ */ jsx3("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
1445
+ /* @__PURE__ */ jsx3("polyline", { points: "22 4 12 14.01 9 11.01" })
1446
+ ] }) : /* @__PURE__ */ jsxs3("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1447
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10" }),
1448
+ /* @__PURE__ */ jsx3("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
1449
+ /* @__PURE__ */ jsx3("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
1450
+ ] }) }),
1451
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: items[itemIndex] }),
1452
+ /* @__PURE__ */ jsx3("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx3(TextToSpeech, { text: items[itemIndex], size: "sm" }) })
1453
+ ]
1454
+ },
1455
+ itemIndex
1456
+ );
1457
+ }) });
1458
+ }
1459
+ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatches, showFeedback, onMatchChange }) {
1460
+ const [draggedItem, setDraggedItem] = useState3(null);
1461
+ const [dragOverLeft, setDragOverLeft] = useState3(null);
1462
+ const matchedRightItems = Object.values(currentMatches);
1463
+ const unmatchedRightItems = rightItems.filter((item) => !matchedRightItems.includes(item));
1464
+ const handleDragStart = (e, rightItem) => {
1465
+ if (showFeedback) return;
1466
+ setDraggedItem(rightItem);
1467
+ e.dataTransfer.effectAllowed = "move";
1468
+ e.dataTransfer.setData("text/plain", rightItem);
1469
+ };
1470
+ const handleDragOver = (e, leftItem) => {
1471
+ e.preventDefault();
1472
+ if (showFeedback) return;
1473
+ e.dataTransfer.dropEffect = "move";
1474
+ setDragOverLeft(leftItem);
1475
+ };
1476
+ const handleDragLeave = () => {
1477
+ setDragOverLeft(null);
1478
+ };
1479
+ const handleDrop = (e, leftItem) => {
1480
+ e.preventDefault();
1481
+ if (showFeedback) return;
1482
+ const rightItem = e.dataTransfer.getData("text/plain");
1483
+ if (rightItem) {
1484
+ const newMatches = { ...currentMatches };
1485
+ Object.keys(newMatches).forEach((key) => {
1486
+ if (newMatches[key] === rightItem) {
1487
+ delete newMatches[key];
1488
+ }
1489
+ });
1490
+ newMatches[leftItem] = rightItem;
1491
+ onMatchChange(newMatches);
1492
+ }
1493
+ setDraggedItem(null);
1494
+ setDragOverLeft(null);
1495
+ };
1496
+ const handleDragEnd = () => {
1497
+ setDraggedItem(null);
1498
+ setDragOverLeft(null);
1499
+ };
1500
+ const handleClearMatch = (leftItem) => {
1501
+ if (showFeedback) return;
1502
+ const newMatches = { ...currentMatches };
1503
+ delete newMatches[leftItem];
1504
+ onMatchChange(newMatches);
1505
+ };
1506
+ return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "24px", flexWrap: "wrap" }, children: [
1507
+ /* @__PURE__ */ jsxs3("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1508
+ /* @__PURE__ */ jsx3("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Match these items:" }),
1509
+ leftItems.map((leftItem, idx) => {
1510
+ const matchedRight = currentMatches[leftItem];
1511
+ const correctMatch = correctMatches?.[leftItem];
1512
+ const isCorrect = matchedRight === correctMatch;
1513
+ const isDragOver = dragOverLeft === leftItem;
1514
+ let rowStyle = {
1515
+ display: "flex",
1516
+ alignItems: "center",
1517
+ gap: "12px",
1518
+ padding: "12px 16px",
1519
+ border: "2px dashed #e5e7eb",
1520
+ borderRadius: "8px",
1521
+ backgroundColor: "#ffffff",
1522
+ minHeight: "56px",
1523
+ transition: "all 0.2s ease"
1524
+ };
1525
+ if (showFeedback) {
1526
+ rowStyle.borderStyle = "solid";
1527
+ if (isCorrect) {
1528
+ rowStyle = { ...rowStyle, borderColor: "#22c55e", backgroundColor: "#f0fdf4" };
1529
+ } else {
1530
+ rowStyle = { ...rowStyle, borderColor: "#ef4444", backgroundColor: "#fef2f2" };
1531
+ }
1532
+ } else if (isDragOver) {
1533
+ rowStyle = { ...rowStyle, borderColor: "#6366f1", backgroundColor: "#eef2ff", borderStyle: "solid" };
1534
+ } else if (matchedRight) {
1535
+ rowStyle = { ...rowStyle, borderStyle: "solid", borderColor: "#22c55e" };
1536
+ }
1537
+ return /* @__PURE__ */ jsxs3(
1538
+ "div",
1539
+ {
1540
+ style: rowStyle,
1541
+ "data-testid": `matrix-row-${idx}`,
1542
+ onDragOver: (e) => handleDragOver(e, leftItem),
1543
+ onDragLeave: handleDragLeave,
1544
+ onDrop: (e) => handleDrop(e, leftItem),
1545
+ children: [
1546
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1, fontWeight: "500" }, children: leftItem }),
1547
+ /* @__PURE__ */ jsx3("span", { style: { color: "#6b7280" }, children: "\u2192" }),
1548
+ matchedRight ? /* @__PURE__ */ jsxs3("div", { style: {
1549
+ display: "flex",
1550
+ alignItems: "center",
1551
+ gap: "8px",
1552
+ padding: "6px 12px",
1553
+ backgroundColor: showFeedback ? isCorrect ? "#dcfce7" : "#fee2e2" : "#e0e7ff",
1554
+ borderRadius: "6px",
1555
+ fontSize: "14px"
1556
+ }, children: [
1557
+ /* @__PURE__ */ jsx3("span", { children: matchedRight }),
1558
+ !showFeedback && /* @__PURE__ */ jsx3(
1559
+ "button",
1560
+ {
1561
+ onClick: () => handleClearMatch(leftItem),
1562
+ style: {
1563
+ background: "none",
1564
+ border: "none",
1565
+ cursor: "pointer",
1566
+ padding: "2px",
1567
+ display: "flex",
1568
+ color: "#6b7280"
1569
+ },
1570
+ "aria-label": "Remove match",
1571
+ children: /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1572
+ /* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1573
+ /* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1574
+ ] })
1575
+ }
1576
+ ),
1577
+ showFeedback && (isCorrect ? /* @__PURE__ */ jsx3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#22c55e", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx3("polyline", { points: "20 6 9 17 4 12" }) }) : /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#ef4444", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1578
+ /* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1579
+ /* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1580
+ ] }))
1581
+ ] }) : /* @__PURE__ */ jsx3("span", { style: { color: "#9ca3af", fontSize: "14px", fontStyle: "italic" }, children: "Drop here" }),
1582
+ showFeedback && !isCorrect && correctMatch && /* @__PURE__ */ jsxs3("span", { style: { color: "#166534", fontSize: "13px", marginLeft: "8px" }, children: [
1583
+ "(Correct: ",
1584
+ correctMatch,
1585
+ ")"
1586
+ ] })
1587
+ ]
1588
+ },
1589
+ idx
1590
+ );
1591
+ })
1592
+ ] }),
1593
+ /* @__PURE__ */ jsxs3("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1594
+ /* @__PURE__ */ jsx3("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Drag to match:" }),
1595
+ unmatchedRightItems.length > 0 ? unmatchedRightItems.map((rightItem, idx) => {
1596
+ const isDragging = draggedItem === rightItem;
1597
+ return /* @__PURE__ */ jsxs3(
1598
+ "div",
1599
+ {
1600
+ style: {
1601
+ padding: "12px 16px",
1602
+ border: "2px solid #e5e7eb",
1603
+ borderRadius: "8px",
1604
+ backgroundColor: "#ffffff",
1605
+ cursor: showFeedback ? "default" : "grab",
1606
+ opacity: isDragging ? 0.5 : 1,
1607
+ display: "flex",
1608
+ alignItems: "center",
1609
+ gap: "8px",
1610
+ transition: "all 0.2s ease"
1611
+ },
1612
+ draggable: !showFeedback,
1613
+ onDragStart: (e) => handleDragStart(e, rightItem),
1614
+ onDragEnd: handleDragEnd,
1615
+ "data-testid": `draggable-right-${idx}`,
1616
+ children: [
1617
+ !showFeedback && /* @__PURE__ */ jsx3("div", { style: { color: "#9ca3af", display: "flex" }, children: /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1618
+ /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "5", r: "1" }),
1619
+ /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "12", r: "1" }),
1620
+ /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "19", r: "1" }),
1621
+ /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "5", r: "1" }),
1622
+ /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "12", r: "1" }),
1623
+ /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "19", r: "1" })
1624
+ ] }) }),
1625
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: rightItem })
1626
+ ]
1627
+ },
1628
+ idx
1629
+ );
1630
+ }) : /* @__PURE__ */ jsx3("div", { style: {
1631
+ padding: "16px",
1632
+ textAlign: "center",
1633
+ color: "#22c55e",
1634
+ fontSize: "14px"
1635
+ }, children: "All items matched!" })
1636
+ ] })
1637
+ ] });
1638
+ }
1339
1639
  function Spinner({ size = 16, color = "#ffffff" }) {
1340
1640
  return /* @__PURE__ */ jsx3(
1341
1641
  "span",
@@ -2212,14 +2512,123 @@ function QuizPlayer({
2212
2512
  },
2213
2513
  idx
2214
2514
  )) }),
2515
+ currentQuestion.type === "sorting" && currentQuestion.items && /* @__PURE__ */ jsx3(
2516
+ SortingDragDrop,
2517
+ {
2518
+ items: currentQuestion.items,
2519
+ currentOrder: Array.isArray(selectedAnswer) ? selectedAnswer : currentQuestion.items.map((_, i) => i),
2520
+ correctOrder: currentQuestion.correctOrder,
2521
+ showFeedback,
2522
+ onOrderChange: handleAnswerChange
2523
+ }
2524
+ ),
2525
+ currentQuestion.type === "matrix" && currentQuestion.leftItems && currentQuestion.rightItems && /* @__PURE__ */ jsx3(
2526
+ MatchingDragDrop,
2527
+ {
2528
+ leftItems: currentQuestion.leftItems,
2529
+ rightItems: currentQuestion.rightItems,
2530
+ currentMatches: typeof selectedAnswer === "object" && selectedAnswer !== null && !Array.isArray(selectedAnswer) ? selectedAnswer : {},
2531
+ correctMatches: currentQuestion.correctMatches,
2532
+ showFeedback,
2533
+ onMatchChange: handleAnswerChange
2534
+ }
2535
+ ),
2536
+ currentQuestion.type === "assessment" && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: (() => {
2537
+ const scaleType = currentQuestion.scaleType || "likert";
2538
+ if (scaleType === "yes-no") {
2539
+ const options = ["Yes", "No"];
2540
+ return options.map((option, idx) => {
2541
+ const isSelected = selectedAnswer === option;
2542
+ let optionStyle = { ...defaultStyles.option };
2543
+ if (isSelected) {
2544
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2545
+ }
2546
+ return /* @__PURE__ */ jsx3(
2547
+ "div",
2548
+ {
2549
+ style: {
2550
+ ...optionStyle,
2551
+ cursor: showFeedback ? "default" : "pointer",
2552
+ display: "flex",
2553
+ alignItems: "center",
2554
+ gap: "8px"
2555
+ },
2556
+ onClick: () => !showFeedback && handleAnswerChange(option),
2557
+ "data-testid": `assessment-option-${option.toLowerCase()}`,
2558
+ children: /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2559
+ },
2560
+ idx
2561
+ );
2562
+ });
2563
+ }
2564
+ if (scaleType === "rating") {
2565
+ const min = currentQuestion.scaleMin || 1;
2566
+ const max = currentQuestion.scaleMax || 5;
2567
+ const ratings = Array.from({ length: max - min + 1 }, (_, i) => min + i);
2568
+ return /* @__PURE__ */ jsx3("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", justifyContent: "center" }, children: ratings.map((rating) => {
2569
+ const isSelected = selectedAnswer === rating;
2570
+ return /* @__PURE__ */ jsx3(
2571
+ "button",
2572
+ {
2573
+ onClick: () => !showFeedback && handleAnswerChange(rating),
2574
+ disabled: showFeedback,
2575
+ style: {
2576
+ width: "48px",
2577
+ height: "48px",
2578
+ borderRadius: "50%",
2579
+ border: isSelected ? "2px solid #6721b0" : "2px solid #e5e7eb",
2580
+ backgroundColor: isSelected ? "#f3e8ff" : "#ffffff",
2581
+ cursor: showFeedback ? "not-allowed" : "pointer",
2582
+ fontSize: "18px",
2583
+ fontWeight: "600",
2584
+ color: isSelected ? "#6721b0" : "#374151"
2585
+ },
2586
+ "data-testid": `assessment-rating-${rating}`,
2587
+ children: rating
2588
+ },
2589
+ rating
2590
+ );
2591
+ }) });
2592
+ }
2593
+ const likertOptions = [
2594
+ "Strongly Disagree",
2595
+ "Disagree",
2596
+ "Neutral",
2597
+ "Agree",
2598
+ "Strongly Agree"
2599
+ ];
2600
+ return likertOptions.map((option, idx) => {
2601
+ const isSelected = selectedAnswer === option;
2602
+ let optionStyle = { ...defaultStyles.option };
2603
+ if (isSelected) {
2604
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2605
+ }
2606
+ return /* @__PURE__ */ jsx3(
2607
+ "div",
2608
+ {
2609
+ style: {
2610
+ ...optionStyle,
2611
+ cursor: showFeedback ? "default" : "pointer",
2612
+ display: "flex",
2613
+ alignItems: "center",
2614
+ gap: "8px"
2615
+ },
2616
+ onClick: () => !showFeedback && handleAnswerChange(option),
2617
+ "data-testid": `assessment-likert-${idx}`,
2618
+ children: /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2619
+ },
2620
+ idx
2621
+ );
2622
+ });
2623
+ })() }),
2215
2624
  showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs3("div", { style: {
2216
2625
  ...defaultStyles.feedback,
2217
- ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2626
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2218
2627
  }, children: [
2219
2628
  /* @__PURE__ */ jsx3("div", { style: {
2220
2629
  ...defaultStyles.feedbackTitle,
2221
- ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2222
- }, children: currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2630
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackTitleNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2631
+ }, children: currentQuestion.type === "assessment" ? "\u2713 Response recorded" : currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2223
2632
  currentQuestion.explanation && /* @__PURE__ */ jsx3("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2224
2633
  ] })
2225
2634
  ] }),
@@ -2541,7 +2950,7 @@ function QuizPlayer({
2541
2950
  lessonId,
2542
2951
  courseId,
2543
2952
  answerResult: showFeedback && currentAnswerDetail ? {
2544
- wasIncorrect: !currentAnswerDetail.isCorrect,
2953
+ wasIncorrect: currentQuestion.type !== "assessment" && !currentAnswerDetail.isCorrect,
2545
2954
  selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
2546
2955
  correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
2547
2956
  explanation: currentQuestion.explanation
@@ -2749,10 +3158,31 @@ var spinnerKeyframes = `
2749
3158
  to { transform: rotate(360deg); }
2750
3159
  }
2751
3160
  `;
2752
- function formatAnswer(answer) {
3161
+ function formatAnswer(answer, questionType, items, leftItems) {
2753
3162
  if (answer === null || answer === void 0) {
2754
3163
  return "No answer";
2755
3164
  }
3165
+ if (questionType === "sorting" && Array.isArray(answer)) {
3166
+ const indices = answer;
3167
+ if (items && items.length > 0) {
3168
+ return indices.map((idx, pos) => `${pos + 1}. ${items[idx] ?? `Item ${idx + 1}`}`).join(", ");
3169
+ }
3170
+ return indices.map((idx, pos) => `Position ${pos + 1}: Item ${idx + 1}`).join(", ");
3171
+ }
3172
+ if (questionType === "matrix" && typeof answer === "object" && !Array.isArray(answer)) {
3173
+ const matches = answer;
3174
+ if (leftItems && leftItems.length > 0) {
3175
+ return leftItems.map((left) => {
3176
+ const right = matches[left];
3177
+ return `${left} \u2192 ${right || "No answer"}`;
3178
+ }).join(", ");
3179
+ }
3180
+ const entries = Object.entries(matches);
3181
+ if (entries.length === 0) {
3182
+ return "No answer";
3183
+ }
3184
+ return entries.map(([left, right]) => `${left} \u2192 ${right || "No answer"}`).join(", ");
3185
+ }
2756
3186
  if (typeof answer === "string") {
2757
3187
  return answer;
2758
3188
  }
@@ -2764,6 +3194,15 @@ function formatAnswer(answer) {
2764
3194
  }
2765
3195
  return String(answer);
2766
3196
  }
3197
+ function formatCorrectSortingAnswer(items, correctOrder) {
3198
+ return correctOrder.map((idx, pos) => `${pos + 1}. ${items[idx] ?? `Item ${idx + 1}`}`).join(", ");
3199
+ }
3200
+ function formatCorrectMatrixAnswer(correctMatches, leftItems) {
3201
+ if (leftItems && leftItems.length > 0) {
3202
+ return leftItems.map((left) => `${left} \u2192 ${correctMatches[left] || "N/A"}`).join(", ");
3203
+ }
3204
+ return Object.entries(correctMatches).map(([left, right]) => `${left} \u2192 ${right}`).join(", ");
3205
+ }
2767
3206
  function AttemptViewer({
2768
3207
  attemptId,
2769
3208
  apiBaseUrl,
@@ -2900,11 +3339,11 @@ function AttemptViewer({
2900
3339
  /* @__PURE__ */ jsx4("div", { style: defaultStyles2.questionText, children: answer.questionText }),
2901
3340
  /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
2902
3341
  /* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
2903
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer) })
3342
+ /* @__PURE__ */ jsx4("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer, answer.questionType, answer.items, answer.leftItems) })
2904
3343
  ] }),
2905
3344
  !answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
2906
3345
  /* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
2907
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.correctAnswer, children: formatAnswer(answer.correctAnswer) })
3346
+ /* @__PURE__ */ jsx4("span", { style: defaultStyles2.correctAnswer, children: answer.questionType === "sorting" && answer.items && answer.correctOrder ? formatCorrectSortingAnswer(answer.items, answer.correctOrder) : answer.questionType === "matrix" && answer.correctAnswer && typeof answer.correctAnswer === "object" && !Array.isArray(answer.correctAnswer) ? formatCorrectMatrixAnswer(answer.correctAnswer, answer.leftItems) : formatAnswer(answer.correctAnswer, answer.questionType, answer.items, answer.leftItems) })
2908
3347
  ] }),
2909
3348
  /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.points, children: [
2910
3349
  answer.pointsEarned,