@thanh01.pmt/interactive-quiz-kit 1.0.72 → 1.0.74
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/ai.cjs +24 -14
- package/dist/ai.mjs +24 -14
- package/dist/authoring.cjs +89 -87
- package/dist/authoring.d.cts +1 -1
- package/dist/authoring.d.ts +1 -1
- package/dist/authoring.mjs +89 -87
- package/dist/react-ui.cjs +89 -87
- package/dist/react-ui.d.cts +1 -1
- package/dist/react-ui.d.ts +1 -1
- package/dist/react-ui.mjs +89 -87
- package/dist/{toaster-DAXYZdrz.d.ts → toaster-B2MPZYhi.d.ts} +2 -1
- package/dist/{toaster-6AR8w2TO.d.cts → toaster-Bvhmyef9.d.cts} +2 -1
- package/package.json +1 -1
package/dist/react-ui.cjs
CHANGED
|
@@ -98269,21 +98269,30 @@ var EditableCombobox = ({
|
|
|
98269
98269
|
disabled = false
|
|
98270
98270
|
}) => {
|
|
98271
98271
|
const [open, setOpen] = React169__namespace.useState(false);
|
|
98272
|
-
const [inputValue, setInputValue] = React169__namespace.useState(
|
|
98272
|
+
const [inputValue, setInputValue] = React169__namespace.useState("");
|
|
98273
98273
|
React169__namespace.useEffect(() => {
|
|
98274
|
-
|
|
98275
|
-
|
|
98276
|
-
|
|
98277
|
-
|
|
98278
|
-
|
|
98279
|
-
|
|
98274
|
+
if (value) {
|
|
98275
|
+
const selectedOption = options.find((option) => option.value.toLowerCase() === value.toLowerCase());
|
|
98276
|
+
setInputValue(selectedOption ? selectedOption.label : value);
|
|
98277
|
+
} else {
|
|
98278
|
+
setInputValue("");
|
|
98279
|
+
}
|
|
98280
|
+
}, [value, options, open]);
|
|
98281
|
+
const handleSelect = (selectedValue) => {
|
|
98282
|
+
onChange(selectedValue);
|
|
98280
98283
|
setOpen(false);
|
|
98281
98284
|
};
|
|
98282
|
-
const
|
|
98283
|
-
|
|
98285
|
+
const handleOpenChange = (isOpen) => {
|
|
98286
|
+
if (!isOpen) {
|
|
98287
|
+
const match2 = options.find((option) => option.label.toLowerCase() === inputValue.toLowerCase());
|
|
98288
|
+
if (!match2 && inputValue !== (options.find((opt) => opt.value === value)?.label || value)) {
|
|
98289
|
+
onChange(inputValue);
|
|
98290
|
+
}
|
|
98291
|
+
}
|
|
98292
|
+
setOpen(isOpen);
|
|
98284
98293
|
};
|
|
98285
98294
|
const displayLabel = options.find((option) => option.value.toLowerCase() === value?.toLowerCase())?.label || value;
|
|
98286
|
-
return /* @__PURE__ */ React169__namespace.createElement(Popover2, { open, onOpenChange:
|
|
98295
|
+
return /* @__PURE__ */ React169__namespace.createElement(Popover2, { open, onOpenChange: handleOpenChange }, /* @__PURE__ */ React169__namespace.createElement(PopoverTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.createElement(
|
|
98287
98296
|
Button,
|
|
98288
98297
|
{
|
|
98289
98298
|
variant: "outline",
|
|
@@ -98299,8 +98308,7 @@ var EditableCombobox = ({
|
|
|
98299
98308
|
{
|
|
98300
98309
|
placeholder: searchPlaceholder,
|
|
98301
98310
|
value: inputValue,
|
|
98302
|
-
onValueChange: setInputValue
|
|
98303
|
-
onBlur: handleBlur
|
|
98311
|
+
onValueChange: setInputValue
|
|
98304
98312
|
}
|
|
98305
98313
|
), /* @__PURE__ */ React169__namespace.createElement(CommandList, null, /* @__PURE__ */ React169__namespace.createElement(CommandEmpty, null, noResultsMessage), /* @__PURE__ */ React169__namespace.createElement(CommandGroup, null, options.map((option) => /* @__PURE__ */ React169__namespace.createElement(
|
|
98306
98314
|
CommandItem,
|
|
@@ -101237,6 +101245,10 @@ var supportedQuestionTypesForAI = [
|
|
|
101237
101245
|
{ value: "sequence", label: "Sequence" },
|
|
101238
101246
|
{ value: "matching", label: "Matching" }
|
|
101239
101247
|
];
|
|
101248
|
+
var availableLanguages = [
|
|
101249
|
+
{ value: "English", label: "English" },
|
|
101250
|
+
{ value: "Vietnamese", label: "Ti\u1EBFng Vi\u1EC7t" }
|
|
101251
|
+
];
|
|
101240
101252
|
var AIQuestionGeneratorModal = ({
|
|
101241
101253
|
isOpen,
|
|
101242
101254
|
onClose,
|
|
@@ -101246,51 +101258,65 @@ var AIQuestionGeneratorModal = ({
|
|
|
101246
101258
|
subjects = [],
|
|
101247
101259
|
topics = [],
|
|
101248
101260
|
gradeLevels = [],
|
|
101249
|
-
bloomLevels = []
|
|
101261
|
+
bloomLevels = [],
|
|
101262
|
+
categories = []
|
|
101250
101263
|
}) => {
|
|
101251
|
-
const [
|
|
101264
|
+
const [additionalInfo, setAdditionalInfo] = React169.useState("");
|
|
101252
101265
|
const [isLoading, setIsLoading] = React169.useState(false);
|
|
101253
101266
|
const [error, setError] = React169.useState(null);
|
|
101254
101267
|
const { toast: toast2 } = useToast();
|
|
101255
101268
|
const [subjectCode, setSubjectCode] = React169.useState("");
|
|
101269
|
+
const [categoryCode, setCategoryCode] = React169.useState("");
|
|
101256
101270
|
const [topicCode, setTopicCode] = React169.useState("");
|
|
101257
101271
|
const [gradeBand, setGradeBand] = React169.useState("");
|
|
101258
101272
|
const [bloomLevelCode, setBloomLevelCode] = React169.useState("");
|
|
101259
101273
|
const [selectedQuestionType, setSelectedQuestionType] = React169.useState("multiple_choice");
|
|
101274
|
+
const [selectedLanguage, setSelectedLanguage] = React169.useState(language3);
|
|
101260
101275
|
const [numberOfOptions, setNumberOfOptions] = React169.useState(4);
|
|
101261
|
-
const [minCorrectAnswers, setMinCorrectAnswers] = React169.useState(2);
|
|
101262
|
-
const [maxCorrectAnswers, setMaxCorrectAnswers] = React169.useState(3);
|
|
101263
|
-
const [isCaseSensitive, setIsCaseSensitive] = React169.useState(false);
|
|
101264
|
-
const [numberOfBlanks, setNumberOfBlanks] = React169.useState(2);
|
|
101265
|
-
const [numberOfSequenceItems, setNumberOfSequenceItems] = React169.useState(4);
|
|
101266
|
-
const [numberOfMatchingPairs, setNumberOfMatchingPairs] = React169.useState(4);
|
|
101267
101276
|
const [isApiKeyManagerModalOpen, setIsApiKeyManagerModalOpen] = React169.useState(false);
|
|
101268
101277
|
const [geminiApiKeyExists, setGeminiApiKeyExists] = React169.useState(false);
|
|
101269
101278
|
const finalQuestionType = questionTypeProp || selectedQuestionType;
|
|
101270
101279
|
React169.useEffect(() => {
|
|
101271
101280
|
if (isOpen) {
|
|
101272
|
-
|
|
101281
|
+
setAdditionalInfo("");
|
|
101273
101282
|
setError(null);
|
|
101274
101283
|
setIsLoading(false);
|
|
101275
101284
|
setSubjectCode("");
|
|
101285
|
+
setCategoryCode("");
|
|
101276
101286
|
setTopicCode("");
|
|
101277
101287
|
setGradeBand("");
|
|
101278
101288
|
setBloomLevelCode("");
|
|
101279
101289
|
setSelectedQuestionType(questionTypeProp || "multiple_choice");
|
|
101290
|
+
setSelectedLanguage(language3);
|
|
101280
101291
|
setGeminiApiKeyExists(APIKeyService.hasAPIKey(GEMINI_API_KEY_SERVICE_NAME));
|
|
101281
101292
|
}
|
|
101282
|
-
}, [isOpen, questionTypeProp]);
|
|
101293
|
+
}, [isOpen, questionTypeProp, language3]);
|
|
101294
|
+
const filteredCategories = React169.useMemo(() => {
|
|
101295
|
+
return categories;
|
|
101296
|
+
}, [categories]);
|
|
101283
101297
|
const filteredTopics = React169.useMemo(() => {
|
|
101284
|
-
if (!subjectCode) return [];
|
|
101285
|
-
return topics.filter(
|
|
101286
|
-
|
|
101298
|
+
if (!subjectCode || !categoryCode) return [];
|
|
101299
|
+
return topics.filter(
|
|
101300
|
+
(t4) => t4.subjectCode === subjectCode
|
|
101301
|
+
/* && t.categoryCode === categoryCode */
|
|
101302
|
+
);
|
|
101303
|
+
}, [subjectCode, categoryCode, topics]);
|
|
101304
|
+
const handleSubjectChange = (newSubjectCode) => {
|
|
101305
|
+
setSubjectCode(newSubjectCode);
|
|
101306
|
+
setCategoryCode("");
|
|
101307
|
+
setTopicCode("");
|
|
101308
|
+
};
|
|
101309
|
+
const handleCategoryChange = (newCategoryCode) => {
|
|
101310
|
+
setCategoryCode(newCategoryCode);
|
|
101311
|
+
setTopicCode("");
|
|
101312
|
+
};
|
|
101287
101313
|
const handleApiKeyModalClose = () => {
|
|
101288
101314
|
setIsApiKeyManagerModalOpen(false);
|
|
101289
101315
|
setGeminiApiKeyExists(APIKeyService.hasAPIKey(GEMINI_API_KEY_SERVICE_NAME));
|
|
101290
101316
|
};
|
|
101291
101317
|
const handleSubmit = async () => {
|
|
101292
|
-
if (!
|
|
101293
|
-
setError("Please
|
|
101318
|
+
if (!subjectCode || !categoryCode || !topicCode || !gradeBand || !bloomLevelCode) {
|
|
101319
|
+
setError("Please fill in all required metadata fields: Subject, Category, Topic, Grade Level, and Bloom's Level.");
|
|
101294
101320
|
return;
|
|
101295
101321
|
}
|
|
101296
101322
|
const geminiKey = APIKeyService.getAPIKey(GEMINI_API_KEY_SERVICE_NAME);
|
|
@@ -101304,14 +101330,15 @@ var AIQuestionGeneratorModal = ({
|
|
|
101304
101330
|
setIsLoading(true);
|
|
101305
101331
|
try {
|
|
101306
101332
|
const quizContext = {
|
|
101307
|
-
plannedTopic:
|
|
101333
|
+
plannedTopic: additionalInfo.trim() || topicCode,
|
|
101308
101334
|
originalSubject: subjectCode,
|
|
101309
101335
|
originalTopic: topicCode,
|
|
101336
|
+
originalCategory: categoryCode,
|
|
101310
101337
|
gradeBand,
|
|
101311
101338
|
plannedBloomLevel: bloomLevelCode
|
|
101312
101339
|
};
|
|
101313
101340
|
const baseClientInput = {
|
|
101314
|
-
language:
|
|
101341
|
+
language: selectedLanguage,
|
|
101315
101342
|
difficulty: "Medium",
|
|
101316
101343
|
quizContext
|
|
101317
101344
|
};
|
|
@@ -101324,33 +101351,32 @@ var AIQuestionGeneratorModal = ({
|
|
|
101324
101351
|
generatedResult = await generateMCQQuestion({ ...baseClientInput, numberOfOptions }, geminiKey);
|
|
101325
101352
|
break;
|
|
101326
101353
|
case "multiple_response":
|
|
101327
|
-
generatedResult = await generateMRQQuestion({ ...baseClientInput, numberOfOptions, minCorrectAnswers, maxCorrectAnswers }, geminiKey);
|
|
101354
|
+
generatedResult = await generateMRQQuestion({ ...baseClientInput, numberOfOptions: 5, minCorrectAnswers: 2, maxCorrectAnswers: 3 }, geminiKey);
|
|
101328
101355
|
break;
|
|
101329
101356
|
case "short_answer":
|
|
101330
|
-
generatedResult = await generateShortAnswerQuestion({ ...baseClientInput, isCaseSensitive }, geminiKey);
|
|
101357
|
+
generatedResult = await generateShortAnswerQuestion({ ...baseClientInput, isCaseSensitive: false }, geminiKey);
|
|
101331
101358
|
break;
|
|
101332
101359
|
case "numeric":
|
|
101333
101360
|
generatedResult = await generateNumericQuestion({ ...baseClientInput, allowDecimals: true, tolerance: 0 }, geminiKey);
|
|
101334
101361
|
break;
|
|
101335
101362
|
case "fill_in_the_blanks":
|
|
101336
|
-
generatedResult = await generateFillInTheBlanksQuestion({ ...baseClientInput, numberOfBlanks, isCaseSensitive }, geminiKey);
|
|
101363
|
+
generatedResult = await generateFillInTheBlanksQuestion({ ...baseClientInput, numberOfBlanks: 2, isCaseSensitive: false }, geminiKey);
|
|
101337
101364
|
break;
|
|
101338
101365
|
case "sequence":
|
|
101339
|
-
generatedResult = await generateSequenceQuestion({ ...baseClientInput, numberOfItems:
|
|
101366
|
+
generatedResult = await generateSequenceQuestion({ ...baseClientInput, numberOfItems: 4 }, geminiKey);
|
|
101340
101367
|
break;
|
|
101341
101368
|
case "matching":
|
|
101342
|
-
generatedResult = await generateMatchingQuestion({ ...baseClientInput, numberOfPairs:
|
|
101369
|
+
generatedResult = await generateMatchingQuestion({ ...baseClientInput, numberOfPairs: 4, shuffleOptions: true }, geminiKey);
|
|
101343
101370
|
break;
|
|
101344
101371
|
default:
|
|
101345
101372
|
throw new Error(`AI generation for '${finalQuestionType}' is not implemented in this flow.`);
|
|
101346
101373
|
}
|
|
101347
|
-
if (generatedResult.error)
|
|
101348
|
-
throw new Error(generatedResult.error);
|
|
101349
|
-
}
|
|
101374
|
+
if (generatedResult.error) throw new Error(generatedResult.error);
|
|
101350
101375
|
if (generatedResult.question) {
|
|
101351
101376
|
const completeQuestion = generatedResult.question;
|
|
101352
101377
|
completeQuestion.subject = subjectCode;
|
|
101353
101378
|
completeQuestion.topic = topicCode;
|
|
101379
|
+
completeQuestion.category = categoryCode;
|
|
101354
101380
|
completeQuestion.gradeBand = gradeBand;
|
|
101355
101381
|
completeQuestion.bloomLevel = bloomLevelCode;
|
|
101356
101382
|
if (completeQuestion.points === void 0) completeQuestion.points = 10;
|
|
@@ -101376,47 +101402,13 @@ var AIQuestionGeneratorModal = ({
|
|
|
101376
101402
|
const comboboxOptions = {
|
|
101377
101403
|
subjects: subjects.map((s4) => ({ value: s4.code, label: s4.name })),
|
|
101378
101404
|
topics: filteredTopics.map((t4) => ({ value: t4.code, label: t4.name })),
|
|
101405
|
+
categories: filteredCategories.map((c4) => ({ value: c4.code, label: c4.name })),
|
|
101379
101406
|
gradeLevels: gradeLevels.map((g) => ({ value: g.code, label: g.name })),
|
|
101380
101407
|
bloomLevels: bloomLevels.map((b2) => ({ value: b2.code, label: b2.name }))
|
|
101381
101408
|
};
|
|
101382
|
-
const renderSpecificParams = () => {
|
|
101383
|
-
switch (finalQuestionType) {
|
|
101384
|
-
case "multiple_choice":
|
|
101385
|
-
case "multiple_response":
|
|
101386
|
-
return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-num-options" }, "Number of Options (2-8)"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
101387
|
-
Input,
|
|
101388
|
-
{
|
|
101389
|
-
id: "ai-num-options",
|
|
101390
|
-
type: "number",
|
|
101391
|
-
value: numberOfOptions,
|
|
101392
|
-
onChange: (e3) => setNumberOfOptions(parseInt(e3.target.value, 10)),
|
|
101393
|
-
min: 2,
|
|
101394
|
-
max: 8
|
|
101395
|
-
}
|
|
101396
|
-
), finalQuestionType === "multiple_response" && /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-min-correct" }, "Min Correct Answers"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "ai-min-correct", type: "number", value: minCorrectAnswers, onChange: (e3) => setMinCorrectAnswers(parseInt(e3.target.value, 10)), min: 1, max: numberOfOptions }), /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-max-correct" }, "Max Correct Answers"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "ai-max-correct", type: "number", value: maxCorrectAnswers, onChange: (e3) => setMaxCorrectAnswers(parseInt(e3.target.value, 10)), min: minCorrectAnswers, max: numberOfOptions })));
|
|
101397
|
-
case "short_answer":
|
|
101398
|
-
case "fill_in_the_blanks":
|
|
101399
|
-
return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-2 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement("input", { type: "checkbox", id: "ai-case-sensitive", checked: isCaseSensitive, onChange: (e3) => setIsCaseSensitive(e3.target.checked), className: "h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" }), /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-case-sensitive" }, "Case Sensitive Answers"), finalQuestionType === "fill_in_the_blanks" && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1 ml-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-num-blanks" }, "Number of Blanks (1-5)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "ai-num-blanks", type: "number", value: numberOfBlanks, onChange: (e3) => setNumberOfBlanks(parseInt(e3.target.value, 10)), min: 1, max: 5 })));
|
|
101400
|
-
case "sequence":
|
|
101401
|
-
return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-num-seq-items" }, "Number of Items to Sequence (2-10)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "ai-num-seq-items", type: "number", value: numberOfSequenceItems, onChange: (e3) => setNumberOfSequenceItems(parseInt(e3.target.value, 10)), min: 2, max: 10 }));
|
|
101402
|
-
case "matching":
|
|
101403
|
-
return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-num-match-pairs" }, "Number of Pairs to Match (2-8)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "ai-num-match-pairs", type: "number", value: numberOfMatchingPairs, onChange: (e3) => setNumberOfMatchingPairs(parseInt(e3.target.value, 10)), min: 2, max: 8 }));
|
|
101404
|
-
default:
|
|
101405
|
-
return null;
|
|
101406
|
-
}
|
|
101407
|
-
};
|
|
101408
101409
|
return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => {
|
|
101409
101410
|
if (!open) onClose();
|
|
101410
|
-
} }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-[
|
|
101411
|
-
Textarea,
|
|
101412
|
-
{
|
|
101413
|
-
id: "ai-prompt",
|
|
101414
|
-
value: prompt,
|
|
101415
|
-
onChange: (e3) => setPrompt(e3.target.value),
|
|
101416
|
-
placeholder: "e.g., The process of photosynthesis, The causes of World War II, Basic Algebra Equations",
|
|
101417
|
-
className: "min-h-[100px]"
|
|
101418
|
-
}
|
|
101419
|
-
)), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.subjects, value: subjectCode, onChange: setSubjectCode, placeholder: "Select or type a Subject..." })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.topics, value: topicCode, onChange: setTopicCode, placeholder: "Select or type a Topic...", disabled: !subjectCode })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Grade Level"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.gradeLevels, value: gradeBand, onChange: setGradeBand, placeholder: "Select or type a Grade..." })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Bloom's Level"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.bloomLevels, value: bloomLevelCode, onChange: setBloomLevelCode, placeholder: "Select a Bloom's Level..." }))), renderSpecificParams(), error && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-destructive flex items-center mt-2" }, /* @__PURE__ */ React169__namespace.default.createElement(TriangleAlert, { className: "mr-1 h-4 w-4" }), " ", error)), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", onClick: handleSubmit, disabled: isLoading || !prompt.trim() || !geminiApiKeyExists }, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__namespace.default.createElement(WandSparkles, { className: "mr-2 h-4 w-4" }), "Generate Question")))), /* @__PURE__ */ React169__namespace.default.createElement(APIKeyManagerModal, { isOpen: isApiKeyManagerModalOpen, onClose: handleApiKeyModalClose }));
|
|
101411
|
+
} }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-[700px]" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, { className: "flex items-center font-headline text-2xl" }, /* @__PURE__ */ React169__namespace.default.createElement(WandSparkles, { className: "mr-2 h-6 w-6 text-primary" }), " AI Question Generator"), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, "Provide metadata and optional info to generate a '", finalQuestionType, "' question.")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 py-4 max-h-[60vh] overflow-y-auto px-2" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-4" }, !questionTypeProp && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Question Type"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: selectedQuestionType, onValueChange: (v) => setSelectedQuestionType(v) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, supportedQuestionTypesForAI.map((type) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: type.value, value: type.value }, type.label))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Language"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: selectedLanguage, onValueChange: setSelectedLanguage }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, availableLanguages.map((lang) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: lang.value, value: lang.value }, lang.label)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-additional-info" }, "Additional Info (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "ai-additional-info", value: additionalInfo, onChange: (e3) => setAdditionalInfo(e3.target.value), placeholder: "Provide extra context, a specific topic, or a detailed prompt for the AI...", className: "min-h-[100px]" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Subject *"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.subjects, value: subjectCode, onChange: handleSubjectChange, placeholder: "Select Subject..." })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Category *"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.categories, value: categoryCode, onChange: handleCategoryChange, placeholder: "Select Category...", disabled: !subjectCode })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Topic *"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.topics, value: topicCode, onChange: setTopicCode, placeholder: "Select Topic...", disabled: !categoryCode })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Grade Level *"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.gradeLevels, value: gradeBand, onChange: setGradeBand, placeholder: "Select Grade..." })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Bloom's Level *"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: comboboxOptions.bloomLevels, value: bloomLevelCode, onChange: setBloomLevelCode, placeholder: "Select Bloom's Level..." }))), finalQuestionType === "multiple_choice" && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "ai-num-options" }, "Number of Options (2-8)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "ai-num-options", type: "number", value: numberOfOptions, onChange: (e3) => setNumberOfOptions(parseInt(e3.target.value, 10)), min: 2, max: 8 })), error && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-destructive flex items-center mt-2" }, /* @__PURE__ */ React169__namespace.default.createElement(TriangleAlert, { className: "mr-1 h-4 w-4" }), " ", error)), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", onClick: handleSubmit, disabled: isLoading || !geminiApiKeyExists || !subjectCode || !categoryCode || !topicCode || !gradeBand || !bloomLevelCode }, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__namespace.default.createElement(WandSparkles, { className: "mr-2 h-4 w-4" }), "Generate Question")))), /* @__PURE__ */ React169__namespace.default.createElement(APIKeyManagerModal, { isOpen: isApiKeyManagerModalOpen, onClose: handleApiKeyModalClose }));
|
|
101420
101412
|
};
|
|
101421
101413
|
|
|
101422
101414
|
// src/react-ui/components/authoring/AIFullQuizGeneratorModal.tsx
|
|
@@ -101917,12 +101909,10 @@ init_react_shim();
|
|
|
101917
101909
|
// src/services/TopicDataService.ts
|
|
101918
101910
|
init_react_shim();
|
|
101919
101911
|
var TopicDataService = class {
|
|
101920
|
-
// ... saveData, mergeData, getData, clearData methods remain the same ...
|
|
101921
101912
|
static saveData(data) {
|
|
101922
101913
|
try {
|
|
101923
101914
|
if (typeof window === "undefined") return;
|
|
101924
|
-
|
|
101925
|
-
localStorage.setItem(this.STORAGE_KEY, serializedData);
|
|
101915
|
+
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data));
|
|
101926
101916
|
} catch (error) {
|
|
101927
101917
|
console.error("Error saving learning objectives to Local Storage:", error);
|
|
101928
101918
|
}
|
|
@@ -101933,8 +101923,7 @@ var TopicDataService = class {
|
|
|
101933
101923
|
newData.forEach((newLo) => {
|
|
101934
101924
|
loMap.set(newLo.code, newLo);
|
|
101935
101925
|
});
|
|
101936
|
-
|
|
101937
|
-
this.saveData(mergedData);
|
|
101926
|
+
this.saveData(Array.from(loMap.values()));
|
|
101938
101927
|
}
|
|
101939
101928
|
static getData() {
|
|
101940
101929
|
try {
|
|
@@ -101949,7 +101938,7 @@ var TopicDataService = class {
|
|
|
101949
101938
|
}
|
|
101950
101939
|
static clearData() {
|
|
101951
101940
|
try {
|
|
101952
|
-
if (typeof window
|
|
101941
|
+
if (typeof window !== "undefined") return;
|
|
101953
101942
|
localStorage.removeItem(this.STORAGE_KEY);
|
|
101954
101943
|
} catch (error) {
|
|
101955
101944
|
console.error("Error clearing learning objectives from Local Storage:", error);
|
|
@@ -101963,6 +101952,12 @@ var TopicDataService = class {
|
|
|
101963
101952
|
const headerLine = lines.shift();
|
|
101964
101953
|
const headers = headerLine.split(" ").map((h3) => h3.trim());
|
|
101965
101954
|
const headerMap = headers.map((h3) => this.HEADER_MAP[h3] || null);
|
|
101955
|
+
const requiredHeaders = ["LO ID", "LO Name", "Subject", "Subject Code", "Category", "Category Code", "Topic", "Topic Code", "Grade", "Grade Code"];
|
|
101956
|
+
const missingHeaders = requiredHeaders.filter((h3) => !headers.includes(h3));
|
|
101957
|
+
if (missingHeaders.length > 0) {
|
|
101958
|
+
const errorMsg = `Invalid TSV header. Missing required columns: ${missingHeaders.join(", ")}`;
|
|
101959
|
+
return { data: [], errors: [errorMsg] };
|
|
101960
|
+
}
|
|
101966
101961
|
const data = [];
|
|
101967
101962
|
const errors2 = [];
|
|
101968
101963
|
lines.forEach((line, index3) => {
|
|
@@ -101971,29 +101966,30 @@ var TopicDataService = class {
|
|
|
101971
101966
|
headerMap.forEach((propName, i2) => {
|
|
101972
101967
|
if (propName) {
|
|
101973
101968
|
const value = values[i2]?.trim() || "";
|
|
101974
|
-
if (
|
|
101969
|
+
if (["keywords", "stemElements", "bloomLevelsGuideline"].includes(propName)) {
|
|
101975
101970
|
rowObject[propName] = value.split(",").map((s4) => s4.trim()).filter(Boolean);
|
|
101976
101971
|
} else {
|
|
101977
101972
|
rowObject[propName] = value;
|
|
101978
101973
|
}
|
|
101979
101974
|
}
|
|
101980
101975
|
});
|
|
101981
|
-
if (!rowObject.code) {
|
|
101982
|
-
errors2.push(`Line ${index3 + 2}: Missing required
|
|
101976
|
+
if (!rowObject.code || !rowObject.name) {
|
|
101977
|
+
errors2.push(`Line ${index3 + 2}: Missing required values for 'LO ID' or 'LO Name'.`);
|
|
101983
101978
|
return;
|
|
101984
101979
|
}
|
|
101985
|
-
if (!rowObject.name) {
|
|
101986
|
-
rowObject.name = rowObject.code;
|
|
101987
|
-
}
|
|
101988
101980
|
const learningObjective = {
|
|
101989
101981
|
id: generateUniqueId("lo_"),
|
|
101990
101982
|
code: rowObject.code,
|
|
101991
101983
|
name: rowObject.name,
|
|
101992
101984
|
description: rowObject.description,
|
|
101993
101985
|
subject: rowObject.subject || "",
|
|
101986
|
+
subjectCode: rowObject.subjectCode,
|
|
101994
101987
|
category: rowObject.category || "",
|
|
101988
|
+
categoryCode: rowObject.categoryCode,
|
|
101995
101989
|
topic: rowObject.topic || "",
|
|
101990
|
+
topicCode: rowObject.topicCode,
|
|
101996
101991
|
grade: rowObject.grade || "",
|
|
101992
|
+
gradeCode: rowObject.gradeCode,
|
|
101997
101993
|
keywords: rowObject.keywords || [],
|
|
101998
101994
|
stemElements: rowObject.stemElements || [],
|
|
101999
101995
|
bloomLevelsGuideline: rowObject.bloomLevelsGuideline || []
|
|
@@ -102024,17 +102020,23 @@ var TopicDataService = class {
|
|
|
102024
102020
|
}
|
|
102025
102021
|
};
|
|
102026
102022
|
TopicDataService.STORAGE_KEY = "interactive_quiz_kit_learning_objectives";
|
|
102027
|
-
// Define a map for flexible header mapping
|
|
102028
102023
|
TopicDataService.HEADER_MAP = {
|
|
102029
102024
|
"LO ID": "code",
|
|
102030
102025
|
"LO Name": "name",
|
|
102031
|
-
// Ready for future addition
|
|
102032
102026
|
"LO Description": "description",
|
|
102033
102027
|
"Subject": "subject",
|
|
102028
|
+
"Subject Code": "subjectCode",
|
|
102029
|
+
// New
|
|
102034
102030
|
"Category": "category",
|
|
102031
|
+
"Category Code": "categoryCode",
|
|
102032
|
+
// New
|
|
102035
102033
|
"Topic": "topic",
|
|
102034
|
+
"Topic Code": "topicCode",
|
|
102035
|
+
// New
|
|
102036
102036
|
"Keywords": "keywords",
|
|
102037
102037
|
"Grade": "grade",
|
|
102038
|
+
"Grade Code": "gradeCode",
|
|
102039
|
+
// New
|
|
102038
102040
|
"STEM Element(s)": "stemElements",
|
|
102039
102041
|
"Bloom\u2019s Level(s) Guideline": "bloomLevelsGuideline"
|
|
102040
102042
|
};
|
package/dist/react-ui.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { Q as QuizResultType, U as UserAnswerType, n as PracticeSession, o as Pr
|
|
|
5
5
|
export { j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, q as PracticeTopicSummary, g as QuestionReview, R as RoadmapItem, T as TestCaseResult, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-DyQYZbyX.cjs';
|
|
6
6
|
import * as React$1 from 'react';
|
|
7
7
|
import React__default, { ReactNode } from 'react';
|
|
8
|
-
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
8
|
+
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-Bvhmyef9.cjs';
|
|
9
9
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
10
10
|
import { VariantProps } from 'class-variance-authority';
|
|
11
11
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
package/dist/react-ui.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Q as QuizResultType, U as UserAnswerType, n as PracticeSession, o as Pr
|
|
|
5
5
|
export { j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, q as PracticeTopicSummary, g as QuestionReview, R as RoadmapItem, T as TestCaseResult, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-Qa_SdE2T.js';
|
|
6
6
|
import * as React$1 from 'react';
|
|
7
7
|
import React__default, { ReactNode } from 'react';
|
|
8
|
-
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
8
|
+
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-B2MPZYhi.js';
|
|
9
9
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
10
10
|
import { VariantProps } from 'class-variance-authority';
|
|
11
11
|
import * as LabelPrimitive from '@radix-ui/react-label';
|