@thanh01.pmt/interactive-quiz-kit 1.0.71 → 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
@@ -139590,15 +139590,27 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
139590
139590
 
139591
139591
  // src/react-ui/components/metadata/LearningObjectiveManager.tsx
139592
139592
  init_react_shim();
139593
- 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
+ }) {
139594
139602
  const [items, setItems] = React169.useState([]);
139595
139603
  const [subjects, setSubjects] = React169.useState([]);
139596
139604
  const [isLoading, setIsLoading] = React169.useState(true);
139597
139605
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
139598
139606
  const [isAlertOpen, setIsAlertOpen] = React169.useState(false);
139599
- const [currentItem, setCurrentItem] = React169.useState(null);
139607
+ const [currentItem, setCurrentItem] = React169.useState(
139608
+ null
139609
+ );
139600
139610
  const [formState, setFormState] = React169.useState({});
139601
- const [itemToDelete, setItemToDelete] = React169.useState(null);
139611
+ const [itemToDelete, setItemToDelete] = React169.useState(
139612
+ null
139613
+ );
139602
139614
  const [isPending, startTransition] = React169.useTransition();
139603
139615
  const { toast: toast2 } = useToast();
139604
139616
  const isControlled = initialData !== void 0;
@@ -139609,7 +139621,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139609
139621
  setItems(MetadataService.getLearningObjectives());
139610
139622
  setSubjects(MetadataService.getSubjects());
139611
139623
  } catch (error) {
139612
- 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
+ });
139613
139629
  } finally {
139614
139630
  setIsLoading(false);
139615
139631
  }
@@ -139629,7 +139645,9 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139629
139645
  };
139630
139646
  const handleAddItem = () => {
139631
139647
  setCurrentItem(null);
139632
- setFormState({ subjectCode: subjects.length > 0 ? subjects[0].code : "" });
139648
+ setFormState({
139649
+ subjectCode: subjects.length > 0 ? subjects[0].code : ""
139650
+ });
139633
139651
  setIsDialogOpen(true);
139634
139652
  };
139635
139653
  const handleEditItem = (item) => {
@@ -139651,9 +139669,16 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139651
139669
  MetadataService.deleteLearningObjective(itemToDelete.code);
139652
139670
  refreshData();
139653
139671
  }
139654
- toast2({ title: "Success", description: `Learning Objective "${itemToDelete.name}" deleted.` });
139672
+ toast2({
139673
+ title: "Success",
139674
+ description: `Learning Objective "${itemToDelete.name}" deleted.`
139675
+ });
139655
139676
  } catch (error) {
139656
- toast2({ title: "Error", description: error.message, variant: "destructive" });
139677
+ toast2({
139678
+ title: "Error",
139679
+ description: error.message,
139680
+ variant: "destructive"
139681
+ });
139657
139682
  } finally {
139658
139683
  setIsAlertOpen(false);
139659
139684
  setItemToDelete(null);
@@ -139662,7 +139687,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139662
139687
  };
139663
139688
  const handleSubmit = () => {
139664
139689
  if (!formState.name?.trim() || !formState.code?.trim()) {
139665
- 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
+ });
139666
139695
  return;
139667
139696
  }
139668
139697
  startTransition(async () => {
@@ -139671,75 +139700,291 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139671
139700
  if (isControlled && onUpdate) {
139672
139701
  await onUpdate({ ...currentItem, ...formState });
139673
139702
  } else {
139674
- MetadataService.updateLearningObjective(currentItem.id, formState);
139703
+ MetadataService.updateLearningObjective(
139704
+ currentItem.id,
139705
+ formState
139706
+ );
139675
139707
  refreshData();
139676
139708
  }
139677
- toast2({ title: "Success", description: "Learning Objective updated." });
139709
+ toast2({
139710
+ title: "Success",
139711
+ description: "Learning Objective updated."
139712
+ });
139678
139713
  } else {
139679
139714
  if (isControlled && onAdd) {
139680
139715
  await onAdd(formState);
139681
139716
  } else {
139682
- MetadataService.addLearningObjective(formState);
139717
+ MetadataService.addLearningObjective(
139718
+ formState
139719
+ );
139683
139720
  refreshData();
139684
139721
  }
139685
- toast2({ title: "Success", description: "Learning Objective added." });
139722
+ toast2({
139723
+ title: "Success",
139724
+ description: "Learning Objective added."
139725
+ });
139686
139726
  }
139687
139727
  setIsDialogOpen(false);
139688
139728
  } catch (error) {
139689
- toast2({ title: "Error", description: error.message, variant: "destructive" });
139729
+ toast2({
139730
+ title: "Error",
139731
+ description: error.message,
139732
+ variant: "destructive"
139733
+ });
139690
139734
  }
139691
139735
  });
139692
139736
  };
139693
139737
  const handleImport = async (records) => {
139694
- console.log(`[LO Manager] handleImport called with ${records.length} raw records.`);
139738
+ console.log(
139739
+ `[LO Manager] handleImport called with ${records.length} raw records.`
139740
+ );
139695
139741
  if (!onBulkAdd) {
139696
139742
  console.error("[LO Manager] onBulkAdd handler is not provided.");
139697
139743
  return;
139698
139744
  }
139699
139745
  const parseStringToArray = (input) => {
139700
139746
  if (Array.isArray(input)) return input;
139701
- if (typeof input === "string") return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139747
+ if (typeof input === "string")
139748
+ return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139702
139749
  return [];
139703
139750
  };
139704
- const validationResult = records.reduce((acc, rec) => {
139705
- if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139706
- acc.valid.push({
139707
- code: rec.code,
139708
- name: rec.name,
139709
- description: rec.description || rec.name,
139710
- subject: rec.subject || "",
139711
- subjectCode: rec.subjectCode,
139712
- category: rec.category || "",
139713
- categoryCode: rec.categoryCode,
139714
- topic: rec.topic || "",
139715
- topicCode: rec.topicCode,
139716
- grade: rec.grade || "",
139717
- gradeCode: rec.gradeCode,
139718
- keywords: parseStringToArray(rec.keywords),
139719
- stemElements: parseStringToArray(rec.stemElements),
139720
- bloomLevelsGuideline: parseStringToArray(rec.bloomLevelsGuideline)
139721
- });
139722
- } else {
139723
- acc.invalidCount++;
139724
- }
139725
- return acc;
139726
- }, { valid: [], invalidCount: 0 });
139727
- console.log(`[LO Manager] Validation complete. ${validationResult.valid.length} valid records found.`);
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
+ );
139728
139784
  if (validationResult.invalidCount > 0) {
139729
139785
  toast2({
139730
139786
  title: "Import Warning",
139731
- description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139787
+ description: `${validationResult.invalidCount} records had invalid or missing 'LO ID' or 'LO Description' fields and were ignored.`,
139732
139788
  variant: "destructive"
139733
139789
  });
139734
139790
  }
139735
139791
  if (validationResult.valid.length > 0) {
139736
- console.log("[LO Manager] Calling onBulkAdd prop with validated data...");
139792
+ console.log(
139793
+ "[LO Manager] Calling onBulkAdd prop with validated data..."
139794
+ );
139737
139795
  await onBulkAdd(validationResult.valid);
139738
139796
  } else {
139739
139797
  console.log("[LO Manager] No valid records to import.");
139740
139798
  }
139741
139799
  };
139742
- 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
+ ))))));
139743
139988
  }
139744
139989
 
139745
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';