@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.
@@ -8767,12 +8767,10 @@ init_react_shim();
8767
8767
  // src/services/TopicDataService.ts
8768
8768
  init_react_shim();
8769
8769
  var TopicDataService = class {
8770
- // ... saveData, mergeData, getData, clearData methods remain the same ...
8771
8770
  static saveData(data) {
8772
8771
  try {
8773
8772
  if (typeof window === "undefined") return;
8774
- const serializedData = JSON.stringify(data);
8775
- localStorage.setItem(this.STORAGE_KEY, serializedData);
8773
+ localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data));
8776
8774
  } catch (error) {
8777
8775
  console.error("Error saving learning objectives to Local Storage:", error);
8778
8776
  }
@@ -8783,8 +8781,7 @@ var TopicDataService = class {
8783
8781
  newData.forEach((newLo) => {
8784
8782
  loMap.set(newLo.code, newLo);
8785
8783
  });
8786
- const mergedData = Array.from(loMap.values());
8787
- this.saveData(mergedData);
8784
+ this.saveData(Array.from(loMap.values()));
8788
8785
  }
8789
8786
  static getData() {
8790
8787
  try {
@@ -8799,7 +8796,7 @@ var TopicDataService = class {
8799
8796
  }
8800
8797
  static clearData() {
8801
8798
  try {
8802
- if (typeof window === "undefined") return;
8799
+ if (typeof window !== "undefined") return;
8803
8800
  localStorage.removeItem(this.STORAGE_KEY);
8804
8801
  } catch (error) {
8805
8802
  console.error("Error clearing learning objectives from Local Storage:", error);
@@ -8813,6 +8810,12 @@ var TopicDataService = class {
8813
8810
  const headerLine = lines.shift();
8814
8811
  const headers = headerLine.split(" ").map((h2) => h2.trim());
8815
8812
  const headerMap = headers.map((h2) => this.HEADER_MAP[h2] || null);
8813
+ const requiredHeaders = ["LO ID", "LO Name", "Subject", "Subject Code", "Category", "Category Code", "Topic", "Topic Code", "Grade", "Grade Code"];
8814
+ const missingHeaders = requiredHeaders.filter((h2) => !headers.includes(h2));
8815
+ if (missingHeaders.length > 0) {
8816
+ const errorMsg = `Invalid TSV header. Missing required columns: ${missingHeaders.join(", ")}`;
8817
+ return { data: [], errors: [errorMsg] };
8818
+ }
8816
8819
  const data = [];
8817
8820
  const errors2 = [];
8818
8821
  lines.forEach((line, index3) => {
@@ -8821,29 +8824,30 @@ var TopicDataService = class {
8821
8824
  headerMap.forEach((propName, i) => {
8822
8825
  if (propName) {
8823
8826
  const value = values[i]?.trim() || "";
8824
- if (propName === "keywords" || propName === "stemElements" || propName === "bloomLevelsGuideline") {
8827
+ if (["keywords", "stemElements", "bloomLevelsGuideline"].includes(propName)) {
8825
8828
  rowObject[propName] = value.split(",").map((s2) => s2.trim()).filter(Boolean);
8826
8829
  } else {
8827
8830
  rowObject[propName] = value;
8828
8831
  }
8829
8832
  }
8830
8833
  });
8831
- if (!rowObject.code) {
8832
- errors2.push(`Line ${index3 + 2}: Missing required value for 'LO ID'.`);
8834
+ if (!rowObject.code || !rowObject.name) {
8835
+ errors2.push(`Line ${index3 + 2}: Missing required values for 'LO ID' or 'LO Name'.`);
8833
8836
  return;
8834
8837
  }
8835
- if (!rowObject.name) {
8836
- rowObject.name = rowObject.code;
8837
- }
8838
8838
  const learningObjective = {
8839
8839
  id: generateUniqueId("lo_"),
8840
8840
  code: rowObject.code,
8841
8841
  name: rowObject.name,
8842
8842
  description: rowObject.description,
8843
8843
  subject: rowObject.subject || "",
8844
+ subjectCode: rowObject.subjectCode,
8844
8845
  category: rowObject.category || "",
8846
+ categoryCode: rowObject.categoryCode,
8845
8847
  topic: rowObject.topic || "",
8848
+ topicCode: rowObject.topicCode,
8846
8849
  grade: rowObject.grade || "",
8850
+ gradeCode: rowObject.gradeCode,
8847
8851
  keywords: rowObject.keywords || [],
8848
8852
  stemElements: rowObject.stemElements || [],
8849
8853
  bloomLevelsGuideline: rowObject.bloomLevelsGuideline || []
@@ -8874,17 +8878,23 @@ var TopicDataService = class {
8874
8878
  }
8875
8879
  };
8876
8880
  TopicDataService.STORAGE_KEY = "interactive_quiz_kit_learning_objectives";
8877
- // Define a map for flexible header mapping
8878
8881
  TopicDataService.HEADER_MAP = {
8879
8882
  "LO ID": "code",
8880
8883
  "LO Name": "name",
8881
- // Ready for future addition
8882
8884
  "LO Description": "description",
8883
8885
  "Subject": "subject",
8886
+ "Subject Code": "subjectCode",
8887
+ // New
8884
8888
  "Category": "category",
8889
+ "Category Code": "categoryCode",
8890
+ // New
8885
8891
  "Topic": "topic",
8892
+ "Topic Code": "topicCode",
8893
+ // New
8886
8894
  "Keywords": "keywords",
8887
8895
  "Grade": "grade",
8896
+ "Grade Code": "gradeCode",
8897
+ // New
8888
8898
  "STEM Element(s)": "stemElements",
8889
8899
  "Bloom\u2019s Level(s) Guideline": "bloomLevelsGuideline"
8890
8900
  };
@@ -71596,21 +71606,30 @@ var EditableCombobox = ({
71596
71606
  disabled = false
71597
71607
  }) => {
71598
71608
  const [open, setOpen] = React119.useState(false);
71599
- const [inputValue, setInputValue] = React119.useState(value);
71609
+ const [inputValue, setInputValue] = React119.useState("");
71600
71610
  React119.useEffect(() => {
71601
- setInputValue(value);
71602
- }, [value]);
71603
- const handleSelect = (currentValue) => {
71604
- const newValue = currentValue === value ? "" : currentValue;
71605
- onChange(newValue);
71606
- setInputValue(newValue);
71611
+ if (value) {
71612
+ const selectedOption = options.find((option) => option.value.toLowerCase() === value.toLowerCase());
71613
+ setInputValue(selectedOption ? selectedOption.label : value);
71614
+ } else {
71615
+ setInputValue("");
71616
+ }
71617
+ }, [value, options, open]);
71618
+ const handleSelect = (selectedValue) => {
71619
+ onChange(selectedValue);
71607
71620
  setOpen(false);
71608
71621
  };
71609
- const handleBlur = () => {
71610
- onChange(inputValue);
71622
+ const handleOpenChange = (isOpen) => {
71623
+ if (!isOpen) {
71624
+ const match2 = options.find((option) => option.label.toLowerCase() === inputValue.toLowerCase());
71625
+ if (!match2 && inputValue !== (options.find((opt) => opt.value === value)?.label || value)) {
71626
+ onChange(inputValue);
71627
+ }
71628
+ }
71629
+ setOpen(isOpen);
71611
71630
  };
71612
71631
  const displayLabel = options.find((option) => option.value.toLowerCase() === value?.toLowerCase())?.label || value;
71613
- return /* @__PURE__ */ React119.createElement(Popover2, { open, onOpenChange: setOpen }, /* @__PURE__ */ React119.createElement(PopoverTrigger2, { asChild: true }, /* @__PURE__ */ React119.createElement(
71632
+ return /* @__PURE__ */ React119.createElement(Popover2, { open, onOpenChange: handleOpenChange }, /* @__PURE__ */ React119.createElement(PopoverTrigger2, { asChild: true }, /* @__PURE__ */ React119.createElement(
71614
71633
  Button,
71615
71634
  {
71616
71635
  variant: "outline",
@@ -71626,8 +71645,7 @@ var EditableCombobox = ({
71626
71645
  {
71627
71646
  placeholder: searchPlaceholder,
71628
71647
  value: inputValue,
71629
- onValueChange: setInputValue,
71630
- onBlur: handleBlur
71648
+ onValueChange: setInputValue
71631
71649
  }
71632
71650
  ), /* @__PURE__ */ React119.createElement(CommandList, null, /* @__PURE__ */ React119.createElement(CommandEmpty, null, noResultsMessage), /* @__PURE__ */ React119.createElement(CommandGroup, null, options.map((option) => /* @__PURE__ */ React119.createElement(
71633
71651
  CommandItem,
@@ -72926,6 +72944,10 @@ var supportedQuestionTypesForAI = [
72926
72944
  { value: "sequence", label: "Sequence" },
72927
72945
  { value: "matching", label: "Matching" }
72928
72946
  ];
72947
+ var availableLanguages = [
72948
+ { value: "English", label: "English" },
72949
+ { value: "Vietnamese", label: "Ti\u1EBFng Vi\u1EC7t" }
72950
+ ];
72929
72951
  var AIQuestionGeneratorModal = ({
72930
72952
  isOpen,
72931
72953
  onClose,
@@ -72935,51 +72957,65 @@ var AIQuestionGeneratorModal = ({
72935
72957
  subjects = [],
72936
72958
  topics = [],
72937
72959
  gradeLevels = [],
72938
- bloomLevels = []
72960
+ bloomLevels = [],
72961
+ categories = []
72939
72962
  }) => {
72940
- const [prompt, setPrompt] = useState("");
72963
+ const [additionalInfo, setAdditionalInfo] = useState("");
72941
72964
  const [isLoading, setIsLoading] = useState(false);
72942
72965
  const [error, setError] = useState(null);
72943
72966
  const { toast: toast2 } = useToast();
72944
72967
  const [subjectCode, setSubjectCode] = useState("");
72968
+ const [categoryCode, setCategoryCode] = useState("");
72945
72969
  const [topicCode, setTopicCode] = useState("");
72946
72970
  const [gradeBand, setGradeBand] = useState("");
72947
72971
  const [bloomLevelCode, setBloomLevelCode] = useState("");
72948
72972
  const [selectedQuestionType, setSelectedQuestionType] = useState("multiple_choice");
72973
+ const [selectedLanguage, setSelectedLanguage] = useState(language3);
72949
72974
  const [numberOfOptions, setNumberOfOptions] = useState(4);
72950
- const [minCorrectAnswers, setMinCorrectAnswers] = useState(2);
72951
- const [maxCorrectAnswers, setMaxCorrectAnswers] = useState(3);
72952
- const [isCaseSensitive, setIsCaseSensitive] = useState(false);
72953
- const [numberOfBlanks, setNumberOfBlanks] = useState(2);
72954
- const [numberOfSequenceItems, setNumberOfSequenceItems] = useState(4);
72955
- const [numberOfMatchingPairs, setNumberOfMatchingPairs] = useState(4);
72956
72975
  const [isApiKeyManagerModalOpen, setIsApiKeyManagerModalOpen] = useState(false);
72957
72976
  const [geminiApiKeyExists, setGeminiApiKeyExists] = useState(false);
72958
72977
  const finalQuestionType = questionTypeProp || selectedQuestionType;
72959
72978
  useEffect(() => {
72960
72979
  if (isOpen) {
72961
- setPrompt("");
72980
+ setAdditionalInfo("");
72962
72981
  setError(null);
72963
72982
  setIsLoading(false);
72964
72983
  setSubjectCode("");
72984
+ setCategoryCode("");
72965
72985
  setTopicCode("");
72966
72986
  setGradeBand("");
72967
72987
  setBloomLevelCode("");
72968
72988
  setSelectedQuestionType(questionTypeProp || "multiple_choice");
72989
+ setSelectedLanguage(language3);
72969
72990
  setGeminiApiKeyExists(APIKeyService.hasAPIKey(GEMINI_API_KEY_SERVICE_NAME));
72970
72991
  }
72971
- }, [isOpen, questionTypeProp]);
72992
+ }, [isOpen, questionTypeProp, language3]);
72993
+ const filteredCategories = useMemo(() => {
72994
+ return categories;
72995
+ }, [categories]);
72972
72996
  const filteredTopics = useMemo(() => {
72973
- if (!subjectCode) return [];
72974
- return topics.filter((t2) => t2.subjectCode === subjectCode);
72975
- }, [subjectCode, topics]);
72997
+ if (!subjectCode || !categoryCode) return [];
72998
+ return topics.filter(
72999
+ (t2) => t2.subjectCode === subjectCode
73000
+ /* && t.categoryCode === categoryCode */
73001
+ );
73002
+ }, [subjectCode, categoryCode, topics]);
73003
+ const handleSubjectChange = (newSubjectCode) => {
73004
+ setSubjectCode(newSubjectCode);
73005
+ setCategoryCode("");
73006
+ setTopicCode("");
73007
+ };
73008
+ const handleCategoryChange = (newCategoryCode) => {
73009
+ setCategoryCode(newCategoryCode);
73010
+ setTopicCode("");
73011
+ };
72976
73012
  const handleApiKeyModalClose = () => {
72977
73013
  setIsApiKeyManagerModalOpen(false);
72978
73014
  setGeminiApiKeyExists(APIKeyService.hasAPIKey(GEMINI_API_KEY_SERVICE_NAME));
72979
73015
  };
72980
73016
  const handleSubmit = async () => {
72981
- if (!prompt.trim()) {
72982
- setError("Please provide a prompt for the question.");
73017
+ if (!subjectCode || !categoryCode || !topicCode || !gradeBand || !bloomLevelCode) {
73018
+ setError("Please fill in all required metadata fields: Subject, Category, Topic, Grade Level, and Bloom's Level.");
72983
73019
  return;
72984
73020
  }
72985
73021
  const geminiKey = APIKeyService.getAPIKey(GEMINI_API_KEY_SERVICE_NAME);
@@ -72993,14 +73029,15 @@ var AIQuestionGeneratorModal = ({
72993
73029
  setIsLoading(true);
72994
73030
  try {
72995
73031
  const quizContext = {
72996
- plannedTopic: prompt,
73032
+ plannedTopic: additionalInfo.trim() || topicCode,
72997
73033
  originalSubject: subjectCode,
72998
73034
  originalTopic: topicCode,
73035
+ originalCategory: categoryCode,
72999
73036
  gradeBand,
73000
73037
  plannedBloomLevel: bloomLevelCode
73001
73038
  };
73002
73039
  const baseClientInput = {
73003
- language: language3,
73040
+ language: selectedLanguage,
73004
73041
  difficulty: "Medium",
73005
73042
  quizContext
73006
73043
  };
@@ -73013,33 +73050,32 @@ var AIQuestionGeneratorModal = ({
73013
73050
  generatedResult = await generateMCQQuestion({ ...baseClientInput, numberOfOptions }, geminiKey);
73014
73051
  break;
73015
73052
  case "multiple_response":
73016
- generatedResult = await generateMRQQuestion({ ...baseClientInput, numberOfOptions, minCorrectAnswers, maxCorrectAnswers }, geminiKey);
73053
+ generatedResult = await generateMRQQuestion({ ...baseClientInput, numberOfOptions: 5, minCorrectAnswers: 2, maxCorrectAnswers: 3 }, geminiKey);
73017
73054
  break;
73018
73055
  case "short_answer":
73019
- generatedResult = await generateShortAnswerQuestion({ ...baseClientInput, isCaseSensitive }, geminiKey);
73056
+ generatedResult = await generateShortAnswerQuestion({ ...baseClientInput, isCaseSensitive: false }, geminiKey);
73020
73057
  break;
73021
73058
  case "numeric":
73022
73059
  generatedResult = await generateNumericQuestion({ ...baseClientInput, allowDecimals: true, tolerance: 0 }, geminiKey);
73023
73060
  break;
73024
73061
  case "fill_in_the_blanks":
73025
- generatedResult = await generateFillInTheBlanksQuestion({ ...baseClientInput, numberOfBlanks, isCaseSensitive }, geminiKey);
73062
+ generatedResult = await generateFillInTheBlanksQuestion({ ...baseClientInput, numberOfBlanks: 2, isCaseSensitive: false }, geminiKey);
73026
73063
  break;
73027
73064
  case "sequence":
73028
- generatedResult = await generateSequenceQuestion({ ...baseClientInput, numberOfItems: numberOfSequenceItems }, geminiKey);
73065
+ generatedResult = await generateSequenceQuestion({ ...baseClientInput, numberOfItems: 4 }, geminiKey);
73029
73066
  break;
73030
73067
  case "matching":
73031
- generatedResult = await generateMatchingQuestion({ ...baseClientInput, numberOfPairs: numberOfMatchingPairs, shuffleOptions: true }, geminiKey);
73068
+ generatedResult = await generateMatchingQuestion({ ...baseClientInput, numberOfPairs: 4, shuffleOptions: true }, geminiKey);
73032
73069
  break;
73033
73070
  default:
73034
73071
  throw new Error(`AI generation for '${finalQuestionType}' is not implemented in this flow.`);
73035
73072
  }
73036
- if (generatedResult.error) {
73037
- throw new Error(generatedResult.error);
73038
- }
73073
+ if (generatedResult.error) throw new Error(generatedResult.error);
73039
73074
  if (generatedResult.question) {
73040
73075
  const completeQuestion = generatedResult.question;
73041
73076
  completeQuestion.subject = subjectCode;
73042
73077
  completeQuestion.topic = topicCode;
73078
+ completeQuestion.category = categoryCode;
73043
73079
  completeQuestion.gradeBand = gradeBand;
73044
73080
  completeQuestion.bloomLevel = bloomLevelCode;
73045
73081
  if (completeQuestion.points === void 0) completeQuestion.points = 10;
@@ -73065,47 +73101,13 @@ var AIQuestionGeneratorModal = ({
73065
73101
  const comboboxOptions = {
73066
73102
  subjects: subjects.map((s2) => ({ value: s2.code, label: s2.name })),
73067
73103
  topics: filteredTopics.map((t2) => ({ value: t2.code, label: t2.name })),
73104
+ categories: filteredCategories.map((c2) => ({ value: c2.code, label: c2.name })),
73068
73105
  gradeLevels: gradeLevels.map((g) => ({ value: g.code, label: g.name })),
73069
73106
  bloomLevels: bloomLevels.map((b) => ({ value: b.code, label: b.name }))
73070
73107
  };
73071
- const renderSpecificParams = () => {
73072
- switch (finalQuestionType) {
73073
- case "multiple_choice":
73074
- case "multiple_response":
73075
- return /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-num-options" }, "Number of Options (2-8)"), /* @__PURE__ */ React119__default.createElement(
73076
- Input,
73077
- {
73078
- id: "ai-num-options",
73079
- type: "number",
73080
- value: numberOfOptions,
73081
- onChange: (e2) => setNumberOfOptions(parseInt(e2.target.value, 10)),
73082
- min: 2,
73083
- max: 8
73084
- }
73085
- ), finalQuestionType === "multiple_response" && /* @__PURE__ */ React119__default.createElement(React119__default.Fragment, null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-min-correct" }, "Min Correct Answers"), /* @__PURE__ */ React119__default.createElement(Input, { id: "ai-min-correct", type: "number", value: minCorrectAnswers, onChange: (e2) => setMinCorrectAnswers(parseInt(e2.target.value, 10)), min: 1, max: numberOfOptions }), /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-max-correct" }, "Max Correct Answers"), /* @__PURE__ */ React119__default.createElement(Input, { id: "ai-max-correct", type: "number", value: maxCorrectAnswers, onChange: (e2) => setMaxCorrectAnswers(parseInt(e2.target.value, 10)), min: minCorrectAnswers, max: numberOfOptions })));
73086
- case "short_answer":
73087
- case "fill_in_the_blanks":
73088
- return /* @__PURE__ */ React119__default.createElement("div", { className: "flex items-center space-x-2 pt-4 border-t" }, /* @__PURE__ */ React119__default.createElement("input", { type: "checkbox", id: "ai-case-sensitive", checked: isCaseSensitive, onChange: (e2) => setIsCaseSensitive(e2.target.checked), className: "h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" }), /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-case-sensitive" }, "Case Sensitive Answers"), finalQuestionType === "fill_in_the_blanks" && /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-1 ml-4" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-num-blanks" }, "Number of Blanks (1-5)"), /* @__PURE__ */ React119__default.createElement(Input, { id: "ai-num-blanks", type: "number", value: numberOfBlanks, onChange: (e2) => setNumberOfBlanks(parseInt(e2.target.value, 10)), min: 1, max: 5 })));
73089
- case "sequence":
73090
- return /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-num-seq-items" }, "Number of Items to Sequence (2-10)"), /* @__PURE__ */ React119__default.createElement(Input, { id: "ai-num-seq-items", type: "number", value: numberOfSequenceItems, onChange: (e2) => setNumberOfSequenceItems(parseInt(e2.target.value, 10)), min: 2, max: 10 }));
73091
- case "matching":
73092
- return /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-num-match-pairs" }, "Number of Pairs to Match (2-8)"), /* @__PURE__ */ React119__default.createElement(Input, { id: "ai-num-match-pairs", type: "number", value: numberOfMatchingPairs, onChange: (e2) => setNumberOfMatchingPairs(parseInt(e2.target.value, 10)), min: 2, max: 8 }));
73093
- default:
73094
- return null;
73095
- }
73096
- };
73097
73108
  return /* @__PURE__ */ React119__default.createElement(React119__default.Fragment, null, /* @__PURE__ */ React119__default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => {
73098
73109
  if (!open) onClose();
73099
- } }, /* @__PURE__ */ React119__default.createElement(DialogContent2, { className: "sm:max-w-[600px]" }, /* @__PURE__ */ React119__default.createElement(DialogHeader, null, /* @__PURE__ */ React119__default.createElement(DialogTitle2, { className: "flex items-center font-headline text-2xl" }, /* @__PURE__ */ React119__default.createElement(WandSparkles, { className: "mr-2 h-6 w-6 text-primary" }), " AI Question Generator"), /* @__PURE__ */ React119__default.createElement(DialogDescription2, null, "Provide a prompt and metadata to generate a '", finalQuestionType, "' question.")), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-4 py-4 max-h-[60vh] overflow-y-auto px-2" }, !geminiApiKeyExists && /* @__PURE__ */ React119__default.createElement("div", { className: "p-3 mb-4 border border-amber-500 bg-amber-50 rounded-md text-amber-700" }), !questionTypeProp && /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-q-type-select" }, "Question Type"), /* @__PURE__ */ React119__default.createElement(Select2, { value: selectedQuestionType, onValueChange: (v) => setSelectedQuestionType(v) }, /* @__PURE__ */ React119__default.createElement(SelectTrigger2, { id: "ai-q-type-select" }, /* @__PURE__ */ React119__default.createElement(SelectValue2, null)), /* @__PURE__ */ React119__default.createElement(SelectContent2, null, supportedQuestionTypesForAI.map((type) => /* @__PURE__ */ React119__default.createElement(SelectItem2, { key: type.value, value: type.value }, type.label))))), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-prompt" }, "Prompt / Topic"), /* @__PURE__ */ React119__default.createElement(
73100
- Textarea,
73101
- {
73102
- id: "ai-prompt",
73103
- value: prompt,
73104
- onChange: (e2) => setPrompt(e2.target.value),
73105
- placeholder: "e.g., The process of photosynthesis, The causes of World War II, Basic Algebra Equations",
73106
- className: "min-h-[100px]"
73107
- }
73108
- )), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Subject"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.subjects, value: subjectCode, onChange: setSubjectCode, placeholder: "Select or type a Subject..." })), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Topic"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.topics, value: topicCode, onChange: setTopicCode, placeholder: "Select or type a Topic...", disabled: !subjectCode })), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Grade Level"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.gradeLevels, value: gradeBand, onChange: setGradeBand, placeholder: "Select or type a Grade..." })), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Bloom's Level"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.bloomLevels, value: bloomLevelCode, onChange: setBloomLevelCode, placeholder: "Select a Bloom's Level..." }))), renderSpecificParams(), error && /* @__PURE__ */ React119__default.createElement("p", { className: "text-sm text-destructive flex items-center mt-2" }, /* @__PURE__ */ React119__default.createElement(TriangleAlert, { className: "mr-1 h-4 w-4" }), " ", error)), /* @__PURE__ */ React119__default.createElement(DialogFooter, null, /* @__PURE__ */ React119__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React119__default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React119__default.createElement(Button, { type: "button", onClick: handleSubmit, disabled: isLoading || !prompt.trim() || !geminiApiKeyExists }, isLoading ? /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React119__default.createElement(WandSparkles, { className: "mr-2 h-4 w-4" }), "Generate Question")))), /* @__PURE__ */ React119__default.createElement(APIKeyManagerModal, { isOpen: isApiKeyManagerModalOpen, onClose: handleApiKeyModalClose }));
73110
+ } }, /* @__PURE__ */ React119__default.createElement(DialogContent2, { className: "sm:max-w-[700px]" }, /* @__PURE__ */ React119__default.createElement(DialogHeader, null, /* @__PURE__ */ React119__default.createElement(DialogTitle2, { className: "flex items-center font-headline text-2xl" }, /* @__PURE__ */ React119__default.createElement(WandSparkles, { className: "mr-2 h-6 w-6 text-primary" }), " AI Question Generator"), /* @__PURE__ */ React119__default.createElement(DialogDescription2, null, "Provide metadata and optional info to generate a '", finalQuestionType, "' question.")), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-4 py-4 max-h-[60vh] overflow-y-auto px-2" }, /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-2 gap-4" }, !questionTypeProp && /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Question Type"), /* @__PURE__ */ React119__default.createElement(Select2, { value: selectedQuestionType, onValueChange: (v) => setSelectedQuestionType(v) }, /* @__PURE__ */ React119__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React119__default.createElement(SelectValue2, null)), /* @__PURE__ */ React119__default.createElement(SelectContent2, null, supportedQuestionTypesForAI.map((type) => /* @__PURE__ */ React119__default.createElement(SelectItem2, { key: type.value, value: type.value }, type.label))))), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Language"), /* @__PURE__ */ React119__default.createElement(Select2, { value: selectedLanguage, onValueChange: setSelectedLanguage }, /* @__PURE__ */ React119__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React119__default.createElement(SelectValue2, null)), /* @__PURE__ */ React119__default.createElement(SelectContent2, null, availableLanguages.map((lang) => /* @__PURE__ */ React119__default.createElement(SelectItem2, { key: lang.value, value: lang.value }, lang.label)))))), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-additional-info" }, "Additional Info (Optional)"), /* @__PURE__ */ React119__default.createElement(Textarea, { id: "ai-additional-info", value: additionalInfo, onChange: (e2) => setAdditionalInfo(e2.target.value), placeholder: "Provide extra context, a specific topic, or a detailed prompt for the AI...", className: "min-h-[100px]" })), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Subject *"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.subjects, value: subjectCode, onChange: handleSubjectChange, placeholder: "Select Subject..." })), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Category *"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.categories, value: categoryCode, onChange: handleCategoryChange, placeholder: "Select Category...", disabled: !subjectCode })), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Topic *"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.topics, value: topicCode, onChange: setTopicCode, placeholder: "Select Topic...", disabled: !categoryCode })), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Grade Level *"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.gradeLevels, value: gradeBand, onChange: setGradeBand, placeholder: "Select Grade..." })), /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React119__default.createElement(Label2, null, "Bloom's Level *"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: comboboxOptions.bloomLevels, value: bloomLevelCode, onChange: setBloomLevelCode, placeholder: "Select Bloom's Level..." }))), finalQuestionType === "multiple_choice" && /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-2 pt-4 border-t" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "ai-num-options" }, "Number of Options (2-8)"), /* @__PURE__ */ React119__default.createElement(Input, { id: "ai-num-options", type: "number", value: numberOfOptions, onChange: (e2) => setNumberOfOptions(parseInt(e2.target.value, 10)), min: 2, max: 8 })), error && /* @__PURE__ */ React119__default.createElement("p", { className: "text-sm text-destructive flex items-center mt-2" }, /* @__PURE__ */ React119__default.createElement(TriangleAlert, { className: "mr-1 h-4 w-4" }), " ", error)), /* @__PURE__ */ React119__default.createElement(DialogFooter, null, /* @__PURE__ */ React119__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React119__default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React119__default.createElement(Button, { type: "button", onClick: handleSubmit, disabled: isLoading || !geminiApiKeyExists || !subjectCode || !categoryCode || !topicCode || !gradeBand || !bloomLevelCode }, isLoading ? /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React119__default.createElement(WandSparkles, { className: "mr-2 h-4 w-4" }), "Generate Question")))), /* @__PURE__ */ React119__default.createElement(APIKeyManagerModal, { isOpen: isApiKeyManagerModalOpen, onClose: handleApiKeyModalClose }));
73109
73111
  };
73110
73112
 
73111
73113
  // src/react-ui/components/authoring/AIFullQuizGeneratorModal.tsx