@thanh01.pmt/interactive-quiz-kit 1.0.70 → 1.0.72

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/react-ui.cjs CHANGED
@@ -138726,11 +138726,17 @@ function MetadataImportControls({ metadataName, onImport }) {
138726
138726
  const fileInputRef = React169.useRef(null);
138727
138727
  const { toast: toast2 } = useToast();
138728
138728
  const processAndImportRecords = async (records, importSource) => {
138729
+ console.log(`[ImportControls] Processing ${records.length} records from ${importSource} for ${metadataName}.`);
138729
138730
  if (records.length === 0) {
138730
138731
  toast2({ title: "No Data", description: `The selected ${importSource === "file" ? "file" : "JSON string"} contains no data to import.`, variant: "destructive" });
138731
138732
  return;
138732
138733
  }
138733
- await onImport(records);
138734
+ try {
138735
+ await onImport(records);
138736
+ } catch (error) {
138737
+ console.error(`[ImportControls] Error during onImport callback for ${metadataName}:`, error);
138738
+ toast2({ title: "Import Failed", description: `An error occurred while saving the data: ${error instanceof Error ? error.message : String(error)}`, variant: "destructive" });
138739
+ }
138734
138740
  setIsOpen(false);
138735
138741
  setJsonString("");
138736
138742
  };
@@ -138762,8 +138768,10 @@ function MetadataImportControls({ metadataName, onImport }) {
138762
138768
  return record;
138763
138769
  });
138764
138770
  }
138771
+ console.log(`[ImportControls] File parsed successfully. Found ${records.length} records.`);
138765
138772
  await processAndImportRecords(records, "file");
138766
138773
  } catch (err) {
138774
+ console.error("[ImportControls] Error parsing file:", err);
138767
138775
  toast2({ title: "Import Error", description: `Failed to process file: ${err.message}`, variant: "destructive" });
138768
138776
  }
138769
138777
  });
@@ -139582,15 +139590,27 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
139582
139590
 
139583
139591
  // src/react-ui/components/metadata/LearningObjectiveManager.tsx
139584
139592
  init_react_shim();
139585
- function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139593
+ function LearningObjectiveManager({
139594
+ initialData,
139595
+ subjects: subjectsProp,
139596
+ isLoading: isLoadingProp,
139597
+ onAdd,
139598
+ onUpdate,
139599
+ onDelete,
139600
+ onBulkAdd
139601
+ }) {
139586
139602
  const [items, setItems] = React169.useState([]);
139587
139603
  const [subjects, setSubjects] = React169.useState([]);
139588
139604
  const [isLoading, setIsLoading] = React169.useState(true);
139589
139605
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
139590
139606
  const [isAlertOpen, setIsAlertOpen] = React169.useState(false);
139591
- const [currentItem, setCurrentItem] = React169.useState(null);
139607
+ const [currentItem, setCurrentItem] = React169.useState(
139608
+ null
139609
+ );
139592
139610
  const [formState, setFormState] = React169.useState({});
139593
- const [itemToDelete, setItemToDelete] = React169.useState(null);
139611
+ const [itemToDelete, setItemToDelete] = React169.useState(
139612
+ null
139613
+ );
139594
139614
  const [isPending, startTransition] = React169.useTransition();
139595
139615
  const { toast: toast2 } = useToast();
139596
139616
  const isControlled = initialData !== void 0;
@@ -139601,7 +139621,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139601
139621
  setItems(MetadataService.getLearningObjectives());
139602
139622
  setSubjects(MetadataService.getSubjects());
139603
139623
  } catch (error) {
139604
- toast2({ title: "Error", description: "Failed to refresh data.", variant: "destructive" });
139624
+ toast2({
139625
+ title: "Error",
139626
+ description: "Failed to refresh data.",
139627
+ variant: "destructive"
139628
+ });
139605
139629
  } finally {
139606
139630
  setIsLoading(false);
139607
139631
  }
@@ -139621,7 +139645,9 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139621
139645
  };
139622
139646
  const handleAddItem = () => {
139623
139647
  setCurrentItem(null);
139624
- setFormState({ subjectCode: subjects.length > 0 ? subjects[0].code : "" });
139648
+ setFormState({
139649
+ subjectCode: subjects.length > 0 ? subjects[0].code : ""
139650
+ });
139625
139651
  setIsDialogOpen(true);
139626
139652
  };
139627
139653
  const handleEditItem = (item) => {
@@ -139643,9 +139669,16 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139643
139669
  MetadataService.deleteLearningObjective(itemToDelete.code);
139644
139670
  refreshData();
139645
139671
  }
139646
- toast2({ title: "Success", description: `Learning Objective "${itemToDelete.name}" deleted.` });
139672
+ toast2({
139673
+ title: "Success",
139674
+ description: `Learning Objective "${itemToDelete.name}" deleted.`
139675
+ });
139647
139676
  } catch (error) {
139648
- toast2({ title: "Error", description: error.message, variant: "destructive" });
139677
+ toast2({
139678
+ title: "Error",
139679
+ description: error.message,
139680
+ variant: "destructive"
139681
+ });
139649
139682
  } finally {
139650
139683
  setIsAlertOpen(false);
139651
139684
  setItemToDelete(null);
@@ -139654,7 +139687,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139654
139687
  };
139655
139688
  const handleSubmit = () => {
139656
139689
  if (!formState.name?.trim() || !formState.code?.trim()) {
139657
- toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
139690
+ toast2({
139691
+ title: "Validation Error",
139692
+ description: "Code and Name are required.",
139693
+ variant: "destructive"
139694
+ });
139658
139695
  return;
139659
139696
  }
139660
139697
  startTransition(async () => {
@@ -139663,28 +139700,291 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139663
139700
  if (isControlled && onUpdate) {
139664
139701
  await onUpdate({ ...currentItem, ...formState });
139665
139702
  } else {
139666
- MetadataService.updateLearningObjective(currentItem.id, formState);
139703
+ MetadataService.updateLearningObjective(
139704
+ currentItem.id,
139705
+ formState
139706
+ );
139667
139707
  refreshData();
139668
139708
  }
139669
- toast2({ title: "Success", description: "Learning Objective updated." });
139709
+ toast2({
139710
+ title: "Success",
139711
+ description: "Learning Objective updated."
139712
+ });
139670
139713
  } else {
139671
139714
  if (isControlled && onAdd) {
139672
139715
  await onAdd(formState);
139673
139716
  } else {
139674
- MetadataService.addLearningObjective(formState);
139717
+ MetadataService.addLearningObjective(
139718
+ formState
139719
+ );
139675
139720
  refreshData();
139676
139721
  }
139677
- toast2({ title: "Success", description: "Learning Objective added." });
139722
+ toast2({
139723
+ title: "Success",
139724
+ description: "Learning Objective added."
139725
+ });
139678
139726
  }
139679
139727
  setIsDialogOpen(false);
139680
139728
  } catch (error) {
139681
- toast2({ title: "Error", description: error.message, variant: "destructive" });
139729
+ toast2({
139730
+ title: "Error",
139731
+ description: error.message,
139732
+ variant: "destructive"
139733
+ });
139682
139734
  }
139683
139735
  });
139684
139736
  };
139685
139737
  const handleImport = async (records) => {
139738
+ console.log(
139739
+ `[LO Manager] handleImport called with ${records.length} raw records.`
139740
+ );
139741
+ if (!onBulkAdd) {
139742
+ console.error("[LO Manager] onBulkAdd handler is not provided.");
139743
+ return;
139744
+ }
139745
+ const parseStringToArray = (input) => {
139746
+ if (Array.isArray(input)) return input;
139747
+ if (typeof input === "string")
139748
+ return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139749
+ return [];
139750
+ };
139751
+ const validationResult = records.reduce(
139752
+ (acc, rec) => {
139753
+ if (typeof rec["LO ID"] === "string" && rec["LO ID"].trim() && typeof rec["LO Description"] === "string" && rec["LO Description"].trim()) {
139754
+ acc.valid.push({
139755
+ code: rec["LO ID"],
139756
+ name: rec["LO ID"],
139757
+ description: rec["LO Description"],
139758
+ subject: rec["Subject"] || "",
139759
+ subjectCode: rec["Subject Code"] || rec["Subject"],
139760
+ category: rec["Category"] || "",
139761
+ categoryCode: rec["Category Code"] || rec["Category"],
139762
+ topic: rec["Topic"] || "",
139763
+ topicCode: rec["Topic Code"] || rec["Topic"],
139764
+ grade: rec["Grade"] || "",
139765
+ gradeCode: rec["Grade Code"] || rec["Grade"],
139766
+ keywords: parseStringToArray(rec["Keywords"]),
139767
+ stemElements: parseStringToArray(
139768
+ rec["STEM Element(s)"]
139769
+ ),
139770
+ bloomLevelsGuideline: parseStringToArray(
139771
+ rec["Bloom\u2019s Level(s) Guideline"]
139772
+ )
139773
+ });
139774
+ } else {
139775
+ acc.invalidCount++;
139776
+ }
139777
+ return acc;
139778
+ },
139779
+ { valid: [], invalidCount: 0 }
139780
+ );
139781
+ console.log(
139782
+ `[LO Manager] Validation complete. ${validationResult.valid.length} valid records found.`
139783
+ );
139784
+ if (validationResult.invalidCount > 0) {
139785
+ toast2({
139786
+ title: "Import Warning",
139787
+ description: `${validationResult.invalidCount} records had invalid or missing 'LO ID' or 'LO Description' fields and were ignored.`,
139788
+ variant: "destructive"
139789
+ });
139790
+ }
139791
+ if (validationResult.valid.length > 0) {
139792
+ console.log(
139793
+ "[LO Manager] Calling onBulkAdd prop with validated data..."
139794
+ );
139795
+ await onBulkAdd(validationResult.valid);
139796
+ } else {
139797
+ console.log("[LO Manager] No valid records to import.");
139798
+ }
139686
139799
  };
139687
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Learning Objectives", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => handleFormChange("code", e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => handleFormChange("name", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "subject", value: formState.subject || "", onChange: (e3) => handleFormChange("subject", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: subjects.map((s4) => ({ value: s4.code, label: s4.name })), value: formState.subjectCode || "", onChange: (val) => handleFormChange("subjectCode", val), placeholder: "Select a subject..." }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "category", value: formState.category || "", onChange: (e3) => handleFormChange("category", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "categoryCode", value: formState.categoryCode || "", onChange: (e3) => handleFormChange("categoryCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "topic", value: formState.topic || "", onChange: (e3) => handleFormChange("topic", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "topicCode", value: formState.topicCode || "", onChange: (e3) => handleFormChange("topicCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "grade", value: formState.grade || "", onChange: (e3) => handleFormChange("grade", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "gradeCode", value: formState.gradeCode || "", onChange: (e3) => handleFormChange("gradeCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "keywords", value: formState.keywords?.join(", ") || "", onChange: (e3) => handleFormChange("keywords", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "stemElements", value: formState.stemElements?.join(", ") || "", onChange: (e3) => handleFormChange("stemElements", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "bloomLevelsGuideline", value: formState.bloomLevelsGuideline?.join(", ") || "", onChange: (e3) => handleFormChange("bloomLevelsGuideline", e3.target.value.split(",").map((s4) => s4.trim())) }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.name?.trim() || !formState.code?.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139800
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " ", "Manage Learning Objectives"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(
139801
+ MetadataImportControls,
139802
+ {
139803
+ metadataName: "Learning Objectives",
139804
+ onImport: handleImport
139805
+ }
139806
+ ), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(
139807
+ Button,
139808
+ {
139809
+ variant: "ghost",
139810
+ size: "icon",
139811
+ onClick: () => handleEditItem(item),
139812
+ className: "mr-2"
139813
+ },
139814
+ /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })
139815
+ ), /* @__PURE__ */ React169__namespace.default.createElement(
139816
+ Button,
139817
+ {
139818
+ variant: "ghost",
139819
+ size: "icon",
139820
+ onClick: () => handleDeleteItem(item),
139821
+ className: "text-destructive hover:text-destructive"
139822
+ },
139823
+ /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })
139824
+ ))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(
139825
+ Input,
139826
+ {
139827
+ id: "code",
139828
+ value: formState.code || "",
139829
+ onChange: (e3) => handleFormChange(
139830
+ "code",
139831
+ e3.target.value.toUpperCase()
139832
+ ),
139833
+ disabled: !!currentItem
139834
+ }
139835
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__namespace.default.createElement(
139836
+ Input,
139837
+ {
139838
+ id: "name",
139839
+ value: formState.name || "",
139840
+ onChange: (e3) => handleFormChange(
139841
+ "name",
139842
+ e3.target.value
139843
+ )
139844
+ }
139845
+ ))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__namespace.default.createElement(
139846
+ Input,
139847
+ {
139848
+ id: "subject",
139849
+ value: formState.subject || "",
139850
+ onChange: (e3) => handleFormChange(
139851
+ "subject",
139852
+ e3.target.value
139853
+ )
139854
+ }
139855
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__namespace.default.createElement(
139856
+ EditableCombobox,
139857
+ {
139858
+ options: subjects.map((s4) => ({
139859
+ value: s4.code,
139860
+ label: s4.name
139861
+ })),
139862
+ value: formState.subjectCode || "",
139863
+ onChange: (val) => handleFormChange("subjectCode", val),
139864
+ placeholder: "Select a subject..."
139865
+ }
139866
+ ))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__namespace.default.createElement(
139867
+ Input,
139868
+ {
139869
+ id: "category",
139870
+ value: formState.category || "",
139871
+ onChange: (e3) => handleFormChange(
139872
+ "category",
139873
+ e3.target.value
139874
+ )
139875
+ }
139876
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__namespace.default.createElement(
139877
+ Input,
139878
+ {
139879
+ id: "categoryCode",
139880
+ value: formState.categoryCode || "",
139881
+ onChange: (e3) => handleFormChange(
139882
+ "categoryCode",
139883
+ e3.target.value
139884
+ )
139885
+ }
139886
+ ))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__namespace.default.createElement(
139887
+ Input,
139888
+ {
139889
+ id: "topic",
139890
+ value: formState.topic || "",
139891
+ onChange: (e3) => handleFormChange(
139892
+ "topic",
139893
+ e3.target.value
139894
+ )
139895
+ }
139896
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__namespace.default.createElement(
139897
+ Input,
139898
+ {
139899
+ id: "topicCode",
139900
+ value: formState.topicCode || "",
139901
+ onChange: (e3) => handleFormChange(
139902
+ "topicCode",
139903
+ e3.target.value
139904
+ )
139905
+ }
139906
+ ))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__namespace.default.createElement(
139907
+ Input,
139908
+ {
139909
+ id: "grade",
139910
+ value: formState.grade || "",
139911
+ onChange: (e3) => handleFormChange(
139912
+ "grade",
139913
+ e3.target.value
139914
+ )
139915
+ }
139916
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__namespace.default.createElement(
139917
+ Input,
139918
+ {
139919
+ id: "gradeCode",
139920
+ value: formState.gradeCode || "",
139921
+ onChange: (e3) => handleFormChange(
139922
+ "gradeCode",
139923
+ e3.target.value
139924
+ )
139925
+ }
139926
+ ))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(
139927
+ Textarea,
139928
+ {
139929
+ id: "keywords",
139930
+ value: formState.keywords?.join(", ") || "",
139931
+ onChange: (e3) => handleFormChange(
139932
+ "keywords",
139933
+ e3.target.value.split(",").map((s4) => s4.trim())
139934
+ )
139935
+ }
139936
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(
139937
+ Textarea,
139938
+ {
139939
+ id: "stemElements",
139940
+ value: formState.stemElements?.join(", ") || "",
139941
+ onChange: (e3) => handleFormChange(
139942
+ "stemElements",
139943
+ e3.target.value.split(",").map((s4) => s4.trim())
139944
+ )
139945
+ }
139946
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(
139947
+ Textarea,
139948
+ {
139949
+ id: "bloomLevelsGuideline",
139950
+ value: formState.bloomLevelsGuideline?.join(
139951
+ ", "
139952
+ ) || "",
139953
+ onChange: (e3) => handleFormChange(
139954
+ "bloomLevelsGuideline",
139955
+ e3.target.value.split(",").map((s4) => s4.trim())
139956
+ )
139957
+ }
139958
+ ))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(
139959
+ Button,
139960
+ {
139961
+ type: "button",
139962
+ variant: "outline",
139963
+ onClick: () => setIsDialogOpen(false),
139964
+ disabled: isPending
139965
+ },
139966
+ "Cancel"
139967
+ ), /* @__PURE__ */ React169__namespace.default.createElement(
139968
+ Button,
139969
+ {
139970
+ type: "submit",
139971
+ onClick: handleSubmit,
139972
+ disabled: isPending || !formState.name?.trim() || !formState.code?.trim()
139973
+ },
139974
+ isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
139975
+ " ",
139976
+ "Save"
139977
+ )))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(
139978
+ AlertDialogAction2,
139979
+ {
139980
+ onClick: confirmDelete,
139981
+ disabled: isPending,
139982
+ className: "bg-destructive hover:bg-destructive/90"
139983
+ },
139984
+ isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
139985
+ " ",
139986
+ "Delete"
139987
+ ))))));
139688
139988
  }
139689
139989
 
139690
139990
  // src/react-ui/components/metadata/ContextManager.tsx
@@ -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-BWaJj0l-.cjs';
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-6AR8w2TO.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';
@@ -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-BVaUJA6E.js';
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-DAXYZdrz.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';