@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.mjs CHANGED
@@ -139524,15 +139524,27 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
139524
139524
 
139525
139525
  // src/react-ui/components/metadata/LearningObjectiveManager.tsx
139526
139526
  init_react_shim();
139527
- function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139527
+ function LearningObjectiveManager({
139528
+ initialData,
139529
+ subjects: subjectsProp,
139530
+ isLoading: isLoadingProp,
139531
+ onAdd,
139532
+ onUpdate,
139533
+ onDelete,
139534
+ onBulkAdd
139535
+ }) {
139528
139536
  const [items, setItems] = useState([]);
139529
139537
  const [subjects, setSubjects] = useState([]);
139530
139538
  const [isLoading, setIsLoading] = useState(true);
139531
139539
  const [isDialogOpen, setIsDialogOpen] = useState(false);
139532
139540
  const [isAlertOpen, setIsAlertOpen] = useState(false);
139533
- const [currentItem, setCurrentItem] = useState(null);
139541
+ const [currentItem, setCurrentItem] = useState(
139542
+ null
139543
+ );
139534
139544
  const [formState, setFormState] = useState({});
139535
- const [itemToDelete, setItemToDelete] = useState(null);
139545
+ const [itemToDelete, setItemToDelete] = useState(
139546
+ null
139547
+ );
139536
139548
  const [isPending, startTransition] = useTransition();
139537
139549
  const { toast: toast2 } = useToast();
139538
139550
  const isControlled = initialData !== void 0;
@@ -139543,7 +139555,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139543
139555
  setItems(MetadataService.getLearningObjectives());
139544
139556
  setSubjects(MetadataService.getSubjects());
139545
139557
  } catch (error) {
139546
- toast2({ title: "Error", description: "Failed to refresh data.", variant: "destructive" });
139558
+ toast2({
139559
+ title: "Error",
139560
+ description: "Failed to refresh data.",
139561
+ variant: "destructive"
139562
+ });
139547
139563
  } finally {
139548
139564
  setIsLoading(false);
139549
139565
  }
@@ -139563,7 +139579,9 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139563
139579
  };
139564
139580
  const handleAddItem = () => {
139565
139581
  setCurrentItem(null);
139566
- setFormState({ subjectCode: subjects.length > 0 ? subjects[0].code : "" });
139582
+ setFormState({
139583
+ subjectCode: subjects.length > 0 ? subjects[0].code : ""
139584
+ });
139567
139585
  setIsDialogOpen(true);
139568
139586
  };
139569
139587
  const handleEditItem = (item) => {
@@ -139585,9 +139603,16 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139585
139603
  MetadataService.deleteLearningObjective(itemToDelete.code);
139586
139604
  refreshData();
139587
139605
  }
139588
- toast2({ title: "Success", description: `Learning Objective "${itemToDelete.name}" deleted.` });
139606
+ toast2({
139607
+ title: "Success",
139608
+ description: `Learning Objective "${itemToDelete.name}" deleted.`
139609
+ });
139589
139610
  } catch (error) {
139590
- toast2({ title: "Error", description: error.message, variant: "destructive" });
139611
+ toast2({
139612
+ title: "Error",
139613
+ description: error.message,
139614
+ variant: "destructive"
139615
+ });
139591
139616
  } finally {
139592
139617
  setIsAlertOpen(false);
139593
139618
  setItemToDelete(null);
@@ -139596,7 +139621,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139596
139621
  };
139597
139622
  const handleSubmit = () => {
139598
139623
  if (!formState.name?.trim() || !formState.code?.trim()) {
139599
- toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
139624
+ toast2({
139625
+ title: "Validation Error",
139626
+ description: "Code and Name are required.",
139627
+ variant: "destructive"
139628
+ });
139600
139629
  return;
139601
139630
  }
139602
139631
  startTransition(async () => {
@@ -139605,75 +139634,291 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139605
139634
  if (isControlled && onUpdate) {
139606
139635
  await onUpdate({ ...currentItem, ...formState });
139607
139636
  } else {
139608
- MetadataService.updateLearningObjective(currentItem.id, formState);
139637
+ MetadataService.updateLearningObjective(
139638
+ currentItem.id,
139639
+ formState
139640
+ );
139609
139641
  refreshData();
139610
139642
  }
139611
- toast2({ title: "Success", description: "Learning Objective updated." });
139643
+ toast2({
139644
+ title: "Success",
139645
+ description: "Learning Objective updated."
139646
+ });
139612
139647
  } else {
139613
139648
  if (isControlled && onAdd) {
139614
139649
  await onAdd(formState);
139615
139650
  } else {
139616
- MetadataService.addLearningObjective(formState);
139651
+ MetadataService.addLearningObjective(
139652
+ formState
139653
+ );
139617
139654
  refreshData();
139618
139655
  }
139619
- toast2({ title: "Success", description: "Learning Objective added." });
139656
+ toast2({
139657
+ title: "Success",
139658
+ description: "Learning Objective added."
139659
+ });
139620
139660
  }
139621
139661
  setIsDialogOpen(false);
139622
139662
  } catch (error) {
139623
- toast2({ title: "Error", description: error.message, variant: "destructive" });
139663
+ toast2({
139664
+ title: "Error",
139665
+ description: error.message,
139666
+ variant: "destructive"
139667
+ });
139624
139668
  }
139625
139669
  });
139626
139670
  };
139627
139671
  const handleImport = async (records) => {
139628
- console.log(`[LO Manager] handleImport called with ${records.length} raw records.`);
139672
+ console.log(
139673
+ `[LO Manager] handleImport called with ${records.length} raw records.`
139674
+ );
139629
139675
  if (!onBulkAdd) {
139630
139676
  console.error("[LO Manager] onBulkAdd handler is not provided.");
139631
139677
  return;
139632
139678
  }
139633
139679
  const parseStringToArray = (input) => {
139634
139680
  if (Array.isArray(input)) return input;
139635
- if (typeof input === "string") return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139681
+ if (typeof input === "string")
139682
+ return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139636
139683
  return [];
139637
139684
  };
139638
- const validationResult = records.reduce((acc, rec) => {
139639
- if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139640
- acc.valid.push({
139641
- code: rec.code,
139642
- name: rec.name,
139643
- description: rec.description || rec.name,
139644
- subject: rec.subject || "",
139645
- subjectCode: rec.subjectCode,
139646
- category: rec.category || "",
139647
- categoryCode: rec.categoryCode,
139648
- topic: rec.topic || "",
139649
- topicCode: rec.topicCode,
139650
- grade: rec.grade || "",
139651
- gradeCode: rec.gradeCode,
139652
- keywords: parseStringToArray(rec.keywords),
139653
- stemElements: parseStringToArray(rec.stemElements),
139654
- bloomLevelsGuideline: parseStringToArray(rec.bloomLevelsGuideline)
139655
- });
139656
- } else {
139657
- acc.invalidCount++;
139658
- }
139659
- return acc;
139660
- }, { valid: [], invalidCount: 0 });
139661
- console.log(`[LO Manager] Validation complete. ${validationResult.valid.length} valid records found.`);
139685
+ const validationResult = records.reduce(
139686
+ (acc, rec) => {
139687
+ if (typeof rec["LO ID"] === "string" && rec["LO ID"].trim() && typeof rec["LO Description"] === "string" && rec["LO Description"].trim()) {
139688
+ acc.valid.push({
139689
+ code: rec["LO ID"],
139690
+ name: rec["LO ID"],
139691
+ description: rec["LO Description"],
139692
+ subject: rec["Subject"] || "",
139693
+ subjectCode: rec["Subject Code"] || rec["Subject"],
139694
+ category: rec["Category"] || "",
139695
+ categoryCode: rec["Category Code"] || rec["Category"],
139696
+ topic: rec["Topic"] || "",
139697
+ topicCode: rec["Topic Code"] || rec["Topic"],
139698
+ grade: rec["Grade"] || "",
139699
+ gradeCode: rec["Grade Code"] || rec["Grade"],
139700
+ keywords: parseStringToArray(rec["Keywords"]),
139701
+ stemElements: parseStringToArray(
139702
+ rec["STEM Element(s)"]
139703
+ ),
139704
+ bloomLevelsGuideline: parseStringToArray(
139705
+ rec["Bloom\u2019s Level(s) Guideline"]
139706
+ )
139707
+ });
139708
+ } else {
139709
+ acc.invalidCount++;
139710
+ }
139711
+ return acc;
139712
+ },
139713
+ { valid: [], invalidCount: 0 }
139714
+ );
139715
+ console.log(
139716
+ `[LO Manager] Validation complete. ${validationResult.valid.length} valid records found.`
139717
+ );
139662
139718
  if (validationResult.invalidCount > 0) {
139663
139719
  toast2({
139664
139720
  title: "Import Warning",
139665
- description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139721
+ description: `${validationResult.invalidCount} records had invalid or missing 'LO ID' or 'LO Description' fields and were ignored.`,
139666
139722
  variant: "destructive"
139667
139723
  });
139668
139724
  }
139669
139725
  if (validationResult.valid.length > 0) {
139670
- console.log("[LO Manager] Calling onBulkAdd prop with validated data...");
139726
+ console.log(
139727
+ "[LO Manager] Calling onBulkAdd prop with validated data..."
139728
+ );
139671
139729
  await onBulkAdd(validationResult.valid);
139672
139730
  } else {
139673
139731
  console.log("[LO Manager] No valid records to import.");
139674
139732
  }
139675
139733
  };
139676
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Learning Objectives", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => handleFormChange("code", e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => handleFormChange("name", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "subject", value: formState.subject || "", onChange: (e3) => handleFormChange("subject", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "category", value: formState.category || "", onChange: (e3) => handleFormChange("category", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "categoryCode", value: formState.categoryCode || "", onChange: (e3) => handleFormChange("categoryCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "topic", value: formState.topic || "", onChange: (e3) => handleFormChange("topic", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "topicCode", value: formState.topicCode || "", onChange: (e3) => handleFormChange("topicCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "grade", value: formState.grade || "", onChange: (e3) => handleFormChange("grade", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "gradeCode", value: formState.gradeCode || "", onChange: (e3) => handleFormChange("gradeCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "keywords", value: formState.keywords?.join(", ") || "", onChange: (e3) => handleFormChange("keywords", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "stemElements", value: formState.stemElements?.join(", ") || "", onChange: (e3) => handleFormChange("stemElements", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "bloomLevelsGuideline", value: formState.bloomLevelsGuideline?.join(", ") || "", onChange: (e3) => handleFormChange("bloomLevelsGuideline", e3.target.value.split(",").map((s4) => s4.trim())) }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.name?.trim() || !formState.code?.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139734
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " ", "Manage Learning Objectives"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(
139735
+ MetadataImportControls,
139736
+ {
139737
+ metadataName: "Learning Objectives",
139738
+ onImport: handleImport
139739
+ }
139740
+ ), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(
139741
+ Button,
139742
+ {
139743
+ variant: "ghost",
139744
+ size: "icon",
139745
+ onClick: () => handleEditItem(item),
139746
+ className: "mr-2"
139747
+ },
139748
+ /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })
139749
+ ), /* @__PURE__ */ React169__default.createElement(
139750
+ Button,
139751
+ {
139752
+ variant: "ghost",
139753
+ size: "icon",
139754
+ onClick: () => handleDeleteItem(item),
139755
+ className: "text-destructive hover:text-destructive"
139756
+ },
139757
+ /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })
139758
+ ))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__default.createElement(
139759
+ Input,
139760
+ {
139761
+ id: "code",
139762
+ value: formState.code || "",
139763
+ onChange: (e3) => handleFormChange(
139764
+ "code",
139765
+ e3.target.value.toUpperCase()
139766
+ ),
139767
+ disabled: !!currentItem
139768
+ }
139769
+ )), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__default.createElement(
139770
+ Input,
139771
+ {
139772
+ id: "name",
139773
+ value: formState.name || "",
139774
+ onChange: (e3) => handleFormChange(
139775
+ "name",
139776
+ e3.target.value
139777
+ )
139778
+ }
139779
+ ))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__default.createElement(
139780
+ Input,
139781
+ {
139782
+ id: "subject",
139783
+ value: formState.subject || "",
139784
+ onChange: (e3) => handleFormChange(
139785
+ "subject",
139786
+ e3.target.value
139787
+ )
139788
+ }
139789
+ )), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__default.createElement(
139790
+ EditableCombobox,
139791
+ {
139792
+ options: subjects.map((s4) => ({
139793
+ value: s4.code,
139794
+ label: s4.name
139795
+ })),
139796
+ value: formState.subjectCode || "",
139797
+ onChange: (val) => handleFormChange("subjectCode", val),
139798
+ placeholder: "Select a subject..."
139799
+ }
139800
+ ))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__default.createElement(
139801
+ Input,
139802
+ {
139803
+ id: "category",
139804
+ value: formState.category || "",
139805
+ onChange: (e3) => handleFormChange(
139806
+ "category",
139807
+ e3.target.value
139808
+ )
139809
+ }
139810
+ )), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__default.createElement(
139811
+ Input,
139812
+ {
139813
+ id: "categoryCode",
139814
+ value: formState.categoryCode || "",
139815
+ onChange: (e3) => handleFormChange(
139816
+ "categoryCode",
139817
+ e3.target.value
139818
+ )
139819
+ }
139820
+ ))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__default.createElement(
139821
+ Input,
139822
+ {
139823
+ id: "topic",
139824
+ value: formState.topic || "",
139825
+ onChange: (e3) => handleFormChange(
139826
+ "topic",
139827
+ e3.target.value
139828
+ )
139829
+ }
139830
+ )), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__default.createElement(
139831
+ Input,
139832
+ {
139833
+ id: "topicCode",
139834
+ value: formState.topicCode || "",
139835
+ onChange: (e3) => handleFormChange(
139836
+ "topicCode",
139837
+ e3.target.value
139838
+ )
139839
+ }
139840
+ ))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__default.createElement(
139841
+ Input,
139842
+ {
139843
+ id: "grade",
139844
+ value: formState.grade || "",
139845
+ onChange: (e3) => handleFormChange(
139846
+ "grade",
139847
+ e3.target.value
139848
+ )
139849
+ }
139850
+ )), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__default.createElement(
139851
+ Input,
139852
+ {
139853
+ id: "gradeCode",
139854
+ value: formState.gradeCode || "",
139855
+ onChange: (e3) => handleFormChange(
139856
+ "gradeCode",
139857
+ e3.target.value
139858
+ )
139859
+ }
139860
+ ))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__default.createElement(
139861
+ Textarea,
139862
+ {
139863
+ id: "keywords",
139864
+ value: formState.keywords?.join(", ") || "",
139865
+ onChange: (e3) => handleFormChange(
139866
+ "keywords",
139867
+ e3.target.value.split(",").map((s4) => s4.trim())
139868
+ )
139869
+ }
139870
+ )), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__default.createElement(
139871
+ Textarea,
139872
+ {
139873
+ id: "stemElements",
139874
+ value: formState.stemElements?.join(", ") || "",
139875
+ onChange: (e3) => handleFormChange(
139876
+ "stemElements",
139877
+ e3.target.value.split(",").map((s4) => s4.trim())
139878
+ )
139879
+ }
139880
+ )), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__default.createElement(
139881
+ Textarea,
139882
+ {
139883
+ id: "bloomLevelsGuideline",
139884
+ value: formState.bloomLevelsGuideline?.join(
139885
+ ", "
139886
+ ) || "",
139887
+ onChange: (e3) => handleFormChange(
139888
+ "bloomLevelsGuideline",
139889
+ e3.target.value.split(",").map((s4) => s4.trim())
139890
+ )
139891
+ }
139892
+ ))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(
139893
+ Button,
139894
+ {
139895
+ type: "button",
139896
+ variant: "outline",
139897
+ onClick: () => setIsDialogOpen(false),
139898
+ disabled: isPending
139899
+ },
139900
+ "Cancel"
139901
+ ), /* @__PURE__ */ React169__default.createElement(
139902
+ Button,
139903
+ {
139904
+ type: "submit",
139905
+ onClick: handleSubmit,
139906
+ disabled: isPending || !formState.name?.trim() || !formState.code?.trim()
139907
+ },
139908
+ isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
139909
+ " ",
139910
+ "Save"
139911
+ )))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(
139912
+ AlertDialogAction2,
139913
+ {
139914
+ onClick: confirmDelete,
139915
+ disabled: isPending,
139916
+ className: "bg-destructive hover:bg-destructive/90"
139917
+ },
139918
+ isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
139919
+ " ",
139920
+ "Delete"
139921
+ ))))));
139677
139922
  }
139678
139923
 
139679
139924
  // src/react-ui/components/metadata/ContextManager.tsx
@@ -265,12 +265,12 @@ interface LearningObjectiveManagerProps {
265
265
  initialData?: LearningObjective[];
266
266
  subjects?: Subject[];
267
267
  isLoading?: boolean;
268
- onAdd?: (item: Omit<LearningObjective, 'id'>) => Promise<void>;
268
+ onAdd?: (item: Omit<LearningObjective, "id">) => Promise<void>;
269
269
  onUpdate?: (item: LearningObjective) => Promise<void>;
270
270
  onDelete?: (item: LearningObjective) => Promise<void>;
271
- onBulkAdd?: (items: Omit<LearningObjective, 'id'>[]) => Promise<void>;
271
+ onBulkAdd?: (items: Omit<LearningObjective, "id">[]) => Promise<void>;
272
272
  }
273
- declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }: LearningObjectiveManagerProps): React__default.JSX.Element;
273
+ declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd, }: LearningObjectiveManagerProps): React__default.JSX.Element;
274
274
 
275
275
  interface ContextManagerProps {
276
276
  initialData?: Context[];
@@ -265,12 +265,12 @@ interface LearningObjectiveManagerProps {
265
265
  initialData?: LearningObjective[];
266
266
  subjects?: Subject[];
267
267
  isLoading?: boolean;
268
- onAdd?: (item: Omit<LearningObjective, 'id'>) => Promise<void>;
268
+ onAdd?: (item: Omit<LearningObjective, "id">) => Promise<void>;
269
269
  onUpdate?: (item: LearningObjective) => Promise<void>;
270
270
  onDelete?: (item: LearningObjective) => Promise<void>;
271
- onBulkAdd?: (items: Omit<LearningObjective, 'id'>[]) => Promise<void>;
271
+ onBulkAdd?: (items: Omit<LearningObjective, "id">[]) => Promise<void>;
272
272
  }
273
- declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }: LearningObjectiveManagerProps): React__default.JSX.Element;
273
+ declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd, }: LearningObjectiveManagerProps): React__default.JSX.Element;
274
274
 
275
275
  interface ContextManagerProps {
276
276
  initialData?: Context[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thanh01.pmt/interactive-quiz-kit",
3
- "version": "1.0.71",
3
+ "version": "1.0.72",
4
4
  "description": "A comprehensive library for creating, managing, and playing interactive quizzes, with AI generation and SCORM support.",
5
5
  "keywords": [
6
6
  "react",