@schoolio/player 1.4.2 → 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.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +461 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +461 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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);
|
|
@@ -1021,12 +1030,14 @@ var defaultStyles = {
|
|
|
1021
1030
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1022
1031
|
width: "100%",
|
|
1023
1032
|
height: "100%",
|
|
1033
|
+
maxHeight: "calc(100vh - 40px)",
|
|
1024
1034
|
padding: "20px",
|
|
1025
1035
|
backgroundColor: "#ffffff",
|
|
1026
1036
|
borderRadius: "12px",
|
|
1027
1037
|
boxSizing: "border-box",
|
|
1028
1038
|
display: "flex",
|
|
1029
|
-
flexDirection: "column"
|
|
1039
|
+
flexDirection: "column",
|
|
1040
|
+
overflow: "hidden"
|
|
1030
1041
|
},
|
|
1031
1042
|
header: {
|
|
1032
1043
|
marginBottom: "20px",
|
|
@@ -1053,8 +1064,7 @@ var defaultStyles = {
|
|
|
1053
1064
|
color: "#6b7280"
|
|
1054
1065
|
},
|
|
1055
1066
|
progressBar: {
|
|
1056
|
-
width: "
|
|
1057
|
-
maxWidth: "300px",
|
|
1067
|
+
width: "100%",
|
|
1058
1068
|
height: "8px",
|
|
1059
1069
|
backgroundColor: "#e5e7eb",
|
|
1060
1070
|
borderRadius: "4px",
|
|
@@ -1081,6 +1091,7 @@ var defaultStyles = {
|
|
|
1081
1091
|
gap: "8px"
|
|
1082
1092
|
},
|
|
1083
1093
|
option: {
|
|
1094
|
+
width: "100%",
|
|
1084
1095
|
padding: "12px 16px",
|
|
1085
1096
|
border: "2px solid #e5e7eb",
|
|
1086
1097
|
borderRadius: "8px",
|
|
@@ -1090,7 +1101,8 @@ var defaultStyles = {
|
|
|
1090
1101
|
boxShadow: "none",
|
|
1091
1102
|
backgroundColor: "#ffffff",
|
|
1092
1103
|
WebkitTapHighlightColor: "transparent",
|
|
1093
|
-
userSelect: "none"
|
|
1104
|
+
userSelect: "none",
|
|
1105
|
+
boxSizing: "border-box"
|
|
1094
1106
|
},
|
|
1095
1107
|
optionSelected: {
|
|
1096
1108
|
borderColor: "#6721b0",
|
|
@@ -1172,18 +1184,22 @@ var defaultStyles = {
|
|
|
1172
1184
|
gap: "24px",
|
|
1173
1185
|
flex: 1,
|
|
1174
1186
|
minHeight: 0,
|
|
1175
|
-
alignItems: "stretch"
|
|
1187
|
+
alignItems: "stretch",
|
|
1188
|
+
overflow: "hidden"
|
|
1176
1189
|
},
|
|
1177
1190
|
quizContent: {
|
|
1178
1191
|
flex: 1,
|
|
1179
1192
|
minWidth: 0,
|
|
1193
|
+
minHeight: 0,
|
|
1180
1194
|
overflow: "auto"
|
|
1181
1195
|
},
|
|
1182
1196
|
chatPanel: {
|
|
1183
1197
|
width: "320px",
|
|
1184
1198
|
flexShrink: 0,
|
|
1185
1199
|
display: "flex",
|
|
1186
|
-
flexDirection: "column"
|
|
1200
|
+
flexDirection: "column",
|
|
1201
|
+
minHeight: 0,
|
|
1202
|
+
overflow: "hidden"
|
|
1187
1203
|
},
|
|
1188
1204
|
timer: {
|
|
1189
1205
|
fontSize: "14px",
|
|
@@ -1309,6 +1325,13 @@ var defaultStyles = {
|
|
|
1309
1325
|
backgroundColor: "#fef2f2",
|
|
1310
1326
|
borderColor: "#ef4444"
|
|
1311
1327
|
},
|
|
1328
|
+
feedbackNeutral: {
|
|
1329
|
+
backgroundColor: "#f0f9ff",
|
|
1330
|
+
borderColor: "#0ea5e9"
|
|
1331
|
+
},
|
|
1332
|
+
feedbackTitleNeutral: {
|
|
1333
|
+
color: "#0369a1"
|
|
1334
|
+
},
|
|
1312
1335
|
feedbackTitle: {
|
|
1313
1336
|
fontSize: "16px",
|
|
1314
1337
|
fontWeight: "600",
|
|
@@ -1329,6 +1352,290 @@ var defaultStyles = {
|
|
|
1329
1352
|
lineHeight: "1.5"
|
|
1330
1353
|
}
|
|
1331
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
|
+
}
|
|
1332
1639
|
function Spinner({ size = 16, color = "#ffffff" }) {
|
|
1333
1640
|
return /* @__PURE__ */ jsx3(
|
|
1334
1641
|
"span",
|
|
@@ -2205,14 +2512,123 @@ function QuizPlayer({
|
|
|
2205
2512
|
},
|
|
2206
2513
|
idx
|
|
2207
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
|
+
})() }),
|
|
2208
2624
|
showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs3("div", { style: {
|
|
2209
2625
|
...defaultStyles.feedback,
|
|
2210
|
-
...currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
|
|
2626
|
+
...currentQuestion.type === "assessment" ? defaultStyles.feedbackNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
|
|
2211
2627
|
}, children: [
|
|
2212
2628
|
/* @__PURE__ */ jsx3("div", { style: {
|
|
2213
2629
|
...defaultStyles.feedbackTitle,
|
|
2214
|
-
...currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
|
|
2215
|
-
}, 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" }),
|
|
2216
2632
|
currentQuestion.explanation && /* @__PURE__ */ jsx3("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
|
|
2217
2633
|
] })
|
|
2218
2634
|
] }),
|
|
@@ -2534,7 +2950,7 @@ function QuizPlayer({
|
|
|
2534
2950
|
lessonId,
|
|
2535
2951
|
courseId,
|
|
2536
2952
|
answerResult: showFeedback && currentAnswerDetail ? {
|
|
2537
|
-
wasIncorrect: !currentAnswerDetail.isCorrect,
|
|
2953
|
+
wasIncorrect: currentQuestion.type !== "assessment" && !currentAnswerDetail.isCorrect,
|
|
2538
2954
|
selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
|
|
2539
2955
|
correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
|
|
2540
2956
|
explanation: currentQuestion.explanation
|
|
@@ -2742,10 +3158,31 @@ var spinnerKeyframes = `
|
|
|
2742
3158
|
to { transform: rotate(360deg); }
|
|
2743
3159
|
}
|
|
2744
3160
|
`;
|
|
2745
|
-
function formatAnswer(answer) {
|
|
3161
|
+
function formatAnswer(answer, questionType, items, leftItems) {
|
|
2746
3162
|
if (answer === null || answer === void 0) {
|
|
2747
3163
|
return "No answer";
|
|
2748
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
|
+
}
|
|
2749
3186
|
if (typeof answer === "string") {
|
|
2750
3187
|
return answer;
|
|
2751
3188
|
}
|
|
@@ -2757,6 +3194,15 @@ function formatAnswer(answer) {
|
|
|
2757
3194
|
}
|
|
2758
3195
|
return String(answer);
|
|
2759
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
|
+
}
|
|
2760
3206
|
function AttemptViewer({
|
|
2761
3207
|
attemptId,
|
|
2762
3208
|
apiBaseUrl,
|
|
@@ -2893,11 +3339,11 @@ function AttemptViewer({
|
|
|
2893
3339
|
/* @__PURE__ */ jsx4("div", { style: defaultStyles2.questionText, children: answer.questionText }),
|
|
2894
3340
|
/* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
|
|
2895
3341
|
/* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
|
|
2896
|
-
/* @__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) })
|
|
2897
3343
|
] }),
|
|
2898
3344
|
!answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
|
|
2899
3345
|
/* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
|
|
2900
|
-
/* @__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) })
|
|
2901
3347
|
] }),
|
|
2902
3348
|
/* @__PURE__ */ jsxs4("div", { style: defaultStyles2.points, children: [
|
|
2903
3349
|
answer.pointsEarned,
|