@thanh01.pmt/interactive-quiz-kit 1.0.50 → 1.0.52
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/authoring.cjs +388 -451
- package/dist/authoring.d.cts +1 -1
- package/dist/authoring.d.ts +1 -1
- package/dist/authoring.mjs +388 -451
- package/dist/react-ui.cjs +388 -451
- package/dist/react-ui.d.cts +1 -1
- package/dist/react-ui.d.ts +1 -1
- package/dist/react-ui.mjs +388 -451
- package/dist/{toaster-UW4hDEhn.d.cts → toaster-DjJYlnue.d.cts} +132 -9
- package/dist/{toaster-ehLC4yr7.d.ts → toaster-DrfjPdmG.d.ts} +132 -9
- package/package.json +1 -1
package/dist/authoring.cjs
CHANGED
|
@@ -105649,7 +105649,7 @@ function SubjectManager({
|
|
|
105649
105649
|
|
|
105650
105650
|
// src/react-ui/components/metadata/GradeLevelManager.tsx
|
|
105651
105651
|
init_react_shim();
|
|
105652
|
-
function GradeLevelManager() {
|
|
105652
|
+
function GradeLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
|
|
105653
105653
|
const [items, setItems] = React97.useState([]);
|
|
105654
105654
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
105655
105655
|
const [isDialogOpen, setIsDialogOpen] = React97.useState(false);
|
|
@@ -105660,19 +105660,27 @@ function GradeLevelManager() {
|
|
|
105660
105660
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
105661
105661
|
const [isPending, startTransition] = React97.useTransition();
|
|
105662
105662
|
const { toast: toast2 } = useToast();
|
|
105663
|
-
|
|
105664
|
-
|
|
105665
|
-
|
|
105666
|
-
|
|
105667
|
-
|
|
105668
|
-
|
|
105669
|
-
|
|
105670
|
-
|
|
105671
|
-
|
|
105672
|
-
|
|
105673
|
-
|
|
105663
|
+
const isControlled = initialData !== void 0;
|
|
105664
|
+
const refreshData = () => {
|
|
105665
|
+
if (!isControlled) {
|
|
105666
|
+
setIsLoading(true);
|
|
105667
|
+
try {
|
|
105668
|
+
setItems(MetadataService.getGradeLevels());
|
|
105669
|
+
} catch (error) {
|
|
105670
|
+
toast2({ title: "Error", description: "Failed to refresh grade levels.", variant: "destructive" });
|
|
105671
|
+
} finally {
|
|
105672
|
+
setIsLoading(false);
|
|
105673
|
+
}
|
|
105674
105674
|
}
|
|
105675
105675
|
};
|
|
105676
|
+
React97.useEffect(() => {
|
|
105677
|
+
if (isControlled) {
|
|
105678
|
+
setItems(initialData || []);
|
|
105679
|
+
setIsLoading(isLoadingProp || false);
|
|
105680
|
+
} else {
|
|
105681
|
+
refreshData();
|
|
105682
|
+
}
|
|
105683
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
105676
105684
|
const handleAddItem = () => {
|
|
105677
105685
|
setCurrentItem(null);
|
|
105678
105686
|
setItemName("");
|
|
@@ -105691,13 +105699,17 @@ function GradeLevelManager() {
|
|
|
105691
105699
|
};
|
|
105692
105700
|
const confirmDelete = () => {
|
|
105693
105701
|
if (!itemToDelete) return;
|
|
105694
|
-
startTransition(() => {
|
|
105702
|
+
startTransition(async () => {
|
|
105695
105703
|
try {
|
|
105696
|
-
|
|
105704
|
+
if (isControlled && onDelete) {
|
|
105705
|
+
await onDelete(itemToDelete);
|
|
105706
|
+
} else {
|
|
105707
|
+
MetadataService.deleteGradeLevel(itemToDelete.code);
|
|
105708
|
+
refreshData();
|
|
105709
|
+
}
|
|
105697
105710
|
toast2({ title: "Success", description: `Grade Level "${itemToDelete.name}" deleted.` });
|
|
105698
|
-
fetchItems();
|
|
105699
105711
|
} catch (error) {
|
|
105700
|
-
toast2({ title: "Error", description:
|
|
105712
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
105701
105713
|
} finally {
|
|
105702
105714
|
setIsAlertOpen(false);
|
|
105703
105715
|
setItemToDelete(null);
|
|
@@ -105709,27 +105721,44 @@ function GradeLevelManager() {
|
|
|
105709
105721
|
toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
|
|
105710
105722
|
return;
|
|
105711
105723
|
}
|
|
105712
|
-
startTransition(() => {
|
|
105724
|
+
startTransition(async () => {
|
|
105713
105725
|
try {
|
|
105714
105726
|
if (currentItem) {
|
|
105715
|
-
|
|
105727
|
+
if (isControlled && onUpdate) {
|
|
105728
|
+
await onUpdate({ id: currentItem.id, name: itemName, code: itemCode });
|
|
105729
|
+
} else {
|
|
105730
|
+
MetadataService.updateGradeLevel(currentItem.id, itemName, itemCode);
|
|
105731
|
+
refreshData();
|
|
105732
|
+
}
|
|
105733
|
+
toast2({ title: "Success", description: "Grade Level updated." });
|
|
105716
105734
|
} else {
|
|
105717
|
-
|
|
105735
|
+
if (isControlled && onAdd) {
|
|
105736
|
+
await onAdd({ name: itemName, code: itemCode });
|
|
105737
|
+
} else {
|
|
105738
|
+
MetadataService.addGradeLevel(itemName, itemCode);
|
|
105739
|
+
refreshData();
|
|
105740
|
+
}
|
|
105741
|
+
toast2({ title: "Success", description: "Grade Level added." });
|
|
105718
105742
|
}
|
|
105719
|
-
toast2({ title: "Success", description: `Grade Level saved.` });
|
|
105720
|
-
fetchItems();
|
|
105721
105743
|
setIsDialogOpen(false);
|
|
105722
105744
|
} catch (error) {
|
|
105723
|
-
toast2({ title: "Error", description:
|
|
105745
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
105724
105746
|
}
|
|
105725
105747
|
});
|
|
105726
105748
|
};
|
|
105727
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Award, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Grade Levels"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Grade Level"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No grade levels found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Grade Level" : "Add New Grade Level")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., G9", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Grade 9" }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
105749
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Award, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Grade Levels"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Grade Level"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No grade levels found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Grade Level" : "Add New Grade Level")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., G9", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Grade 9" }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
105728
105750
|
}
|
|
105729
105751
|
|
|
105730
105752
|
// src/react-ui/components/metadata/TopicManager.tsx
|
|
105731
105753
|
init_react_shim();
|
|
105732
|
-
function TopicManager(
|
|
105754
|
+
function TopicManager({
|
|
105755
|
+
initialData,
|
|
105756
|
+
subjects: subjectsProp,
|
|
105757
|
+
isLoading: isLoadingProp,
|
|
105758
|
+
onAdd,
|
|
105759
|
+
onUpdate,
|
|
105760
|
+
onDelete
|
|
105761
|
+
}) {
|
|
105733
105762
|
const [topics, setTopics] = React97.useState([]);
|
|
105734
105763
|
const [subjects, setSubjects] = React97.useState([]);
|
|
105735
105764
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
@@ -105742,36 +105771,34 @@ function TopicManager() {
|
|
|
105742
105771
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
105743
105772
|
const [isPending, startTransition] = React97.useTransition();
|
|
105744
105773
|
const { toast: toast2 } = useToast();
|
|
105745
|
-
const
|
|
105746
|
-
|
|
105747
|
-
|
|
105748
|
-
|
|
105749
|
-
|
|
105750
|
-
|
|
105751
|
-
|
|
105752
|
-
|
|
105753
|
-
|
|
105774
|
+
const isControlled = initialData !== void 0;
|
|
105775
|
+
const refreshData = () => {
|
|
105776
|
+
if (!isControlled) {
|
|
105777
|
+
setIsLoading(true);
|
|
105778
|
+
try {
|
|
105779
|
+
setTopics(MetadataService.getTopics());
|
|
105780
|
+
setSubjects(MetadataService.getSubjects());
|
|
105781
|
+
} catch (error) {
|
|
105782
|
+
toast2({ title: "Error", description: "Failed to refresh topics or subjects.", variant: "destructive" });
|
|
105783
|
+
} finally {
|
|
105784
|
+
setIsLoading(false);
|
|
105754
105785
|
}
|
|
105755
|
-
} catch (error) {
|
|
105756
|
-
toast2({
|
|
105757
|
-
title: "Error",
|
|
105758
|
-
description: "Failed to fetch topics or subjects.",
|
|
105759
|
-
variant: "destructive"
|
|
105760
|
-
});
|
|
105761
|
-
} finally {
|
|
105762
|
-
setIsLoading(false);
|
|
105763
105786
|
}
|
|
105764
105787
|
};
|
|
105765
105788
|
React97.useEffect(() => {
|
|
105766
|
-
|
|
105767
|
-
|
|
105789
|
+
if (isControlled) {
|
|
105790
|
+
setTopics(initialData || []);
|
|
105791
|
+
setSubjects(subjectsProp || []);
|
|
105792
|
+
setIsLoading(isLoadingProp || false);
|
|
105793
|
+
} else {
|
|
105794
|
+
refreshData();
|
|
105795
|
+
}
|
|
105796
|
+
}, [isControlled, initialData, subjectsProp, isLoadingProp]);
|
|
105768
105797
|
const handleAddItem = () => {
|
|
105769
105798
|
setCurrentItem(null);
|
|
105770
105799
|
setItemName("");
|
|
105771
105800
|
setItemCode("");
|
|
105772
|
-
|
|
105773
|
-
setSelectedSubjectCode(subjects[0].code);
|
|
105774
|
-
}
|
|
105801
|
+
setSelectedSubjectCode(subjects.length > 0 ? subjects[0].code : "");
|
|
105775
105802
|
setIsDialogOpen(true);
|
|
105776
105803
|
};
|
|
105777
105804
|
const handleEditItem = (topic) => {
|
|
@@ -105787,20 +105814,17 @@ function TopicManager() {
|
|
|
105787
105814
|
};
|
|
105788
105815
|
const confirmDelete = () => {
|
|
105789
105816
|
if (!itemToDelete) return;
|
|
105790
|
-
startTransition(() => {
|
|
105817
|
+
startTransition(async () => {
|
|
105791
105818
|
try {
|
|
105792
|
-
|
|
105793
|
-
|
|
105794
|
-
|
|
105795
|
-
|
|
105796
|
-
|
|
105797
|
-
|
|
105819
|
+
if (isControlled && onDelete) {
|
|
105820
|
+
await onDelete(itemToDelete);
|
|
105821
|
+
} else {
|
|
105822
|
+
MetadataService.deleteTopic(itemToDelete.code);
|
|
105823
|
+
refreshData();
|
|
105824
|
+
}
|
|
105825
|
+
toast2({ title: "Success", description: `Topic "${itemToDelete.name}" deleted.` });
|
|
105798
105826
|
} catch (error) {
|
|
105799
|
-
toast2({
|
|
105800
|
-
title: "Error",
|
|
105801
|
-
description: "Failed to delete topic.",
|
|
105802
|
-
variant: "destructive"
|
|
105803
|
-
});
|
|
105827
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
105804
105828
|
} finally {
|
|
105805
105829
|
setIsAlertOpen(false);
|
|
105806
105830
|
setItemToDelete(null);
|
|
@@ -105809,144 +105833,43 @@ function TopicManager() {
|
|
|
105809
105833
|
};
|
|
105810
105834
|
const handleSubmit = () => {
|
|
105811
105835
|
if (!itemName.trim() || !itemCode.trim() || !selectedSubjectCode) {
|
|
105812
|
-
toast2({
|
|
105813
|
-
title: "Validation Error",
|
|
105814
|
-
description: "Name, Code, and Subject are required.",
|
|
105815
|
-
variant: "destructive"
|
|
105816
|
-
});
|
|
105836
|
+
toast2({ title: "Validation Error", description: "Name, Code, and Subject are required.", variant: "destructive" });
|
|
105817
105837
|
return;
|
|
105818
105838
|
}
|
|
105819
|
-
startTransition(() => {
|
|
105839
|
+
startTransition(async () => {
|
|
105820
105840
|
try {
|
|
105821
105841
|
if (currentItem) {
|
|
105822
|
-
|
|
105823
|
-
currentItem.id,
|
|
105824
|
-
|
|
105825
|
-
itemCode,
|
|
105826
|
-
|
|
105827
|
-
|
|
105842
|
+
if (isControlled && onUpdate) {
|
|
105843
|
+
await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, subjectCode: selectedSubjectCode });
|
|
105844
|
+
} else {
|
|
105845
|
+
MetadataService.updateTopic(currentItem.id, itemName, itemCode, selectedSubjectCode);
|
|
105846
|
+
refreshData();
|
|
105847
|
+
}
|
|
105848
|
+
toast2({ title: "Success", description: "Topic updated." });
|
|
105828
105849
|
} else {
|
|
105829
|
-
|
|
105830
|
-
itemName,
|
|
105831
|
-
|
|
105832
|
-
selectedSubjectCode
|
|
105833
|
-
|
|
105850
|
+
if (isControlled && onAdd) {
|
|
105851
|
+
await onAdd({ name: itemName, code: itemCode, subjectCode: selectedSubjectCode });
|
|
105852
|
+
} else {
|
|
105853
|
+
MetadataService.addTopic(itemName, itemCode, selectedSubjectCode);
|
|
105854
|
+
refreshData();
|
|
105855
|
+
}
|
|
105856
|
+
toast2({ title: "Success", description: "Topic added." });
|
|
105834
105857
|
}
|
|
105835
|
-
toast2({ title: "Success", description: "Topic saved." });
|
|
105836
|
-
fetchData();
|
|
105837
105858
|
setIsDialogOpen(false);
|
|
105838
105859
|
} catch (error) {
|
|
105839
|
-
toast2({
|
|
105840
|
-
title: "Error",
|
|
105841
|
-
description: "Failed to save topic.",
|
|
105842
|
-
variant: "destructive"
|
|
105843
|
-
});
|
|
105860
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
105844
105861
|
}
|
|
105845
105862
|
});
|
|
105846
105863
|
};
|
|
105847
105864
|
const getSubjectName = (subjectCode) => {
|
|
105848
105865
|
return subjects.find((s2) => s2.code === subjectCode)?.name || "N/A";
|
|
105849
105866
|
};
|
|
105850
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Tag, { className: "mr-2 h-5 w-5 text-primary" }), "Manage Topics"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105851
|
-
Button,
|
|
105852
|
-
{
|
|
105853
|
-
onClick: handleAddItem,
|
|
105854
|
-
size: "sm",
|
|
105855
|
-
disabled: subjects.length === 0
|
|
105856
|
-
},
|
|
105857
|
-
/* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }),
|
|
105858
|
-
" Add Topic"
|
|
105859
|
-
)), subjects.length === 0 && !isLoading && /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-sm text-destructive" }, "Please add subjects before adding topics.")), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : topics.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No topics found. Add one to get started!") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, topics.map((topic) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: topic.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, topic.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, topic.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, getSubjectName(topic.subjectCode), " ", "(", topic.subjectCode, ")"), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105860
|
-
Button,
|
|
105861
|
-
{
|
|
105862
|
-
variant: "ghost",
|
|
105863
|
-
size: "icon",
|
|
105864
|
-
onClick: () => handleEditItem(topic),
|
|
105865
|
-
className: "mr-2"
|
|
105866
|
-
},
|
|
105867
|
-
/* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })
|
|
105868
|
-
), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105869
|
-
Button,
|
|
105870
|
-
{
|
|
105871
|
-
variant: "ghost",
|
|
105872
|
-
size: "icon",
|
|
105873
|
-
onClick: () => handleDeleteItem(topic),
|
|
105874
|
-
className: "text-destructive hover:text-destructive"
|
|
105875
|
-
},
|
|
105876
|
-
/* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })
|
|
105877
|
-
))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Topic" : "Add New Topic")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Topic Code"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105878
|
-
Input,
|
|
105879
|
-
{
|
|
105880
|
-
id: "itemCode",
|
|
105881
|
-
value: itemCode,
|
|
105882
|
-
onChange: (e2) => setItemCode(
|
|
105883
|
-
e2.target.value.toUpperCase()
|
|
105884
|
-
),
|
|
105885
|
-
placeholder: "e.g., ALG-BASICS",
|
|
105886
|
-
disabled: !!currentItem
|
|
105887
|
-
}
|
|
105888
|
-
)), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Topic Name"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105889
|
-
Input,
|
|
105890
|
-
{
|
|
105891
|
-
id: "itemName",
|
|
105892
|
-
value: itemName,
|
|
105893
|
-
onChange: (e2) => setItemName(e2.target.value),
|
|
105894
|
-
placeholder: "e.g., Algebra Basics"
|
|
105895
|
-
}
|
|
105896
|
-
)), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105897
|
-
Select2,
|
|
105898
|
-
{
|
|
105899
|
-
value: selectedSubjectCode,
|
|
105900
|
-
onValueChange: setSelectedSubjectCode,
|
|
105901
|
-
disabled: subjects.length === 0
|
|
105902
|
-
},
|
|
105903
|
-
/* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, { placeholder: "Select a subject" })),
|
|
105904
|
-
/* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, subjects.map((subject) => /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105905
|
-
SelectItem2,
|
|
105906
|
-
{
|
|
105907
|
-
key: subject.code,
|
|
105908
|
-
value: subject.code
|
|
105909
|
-
},
|
|
105910
|
-
subject.name,
|
|
105911
|
-
" (",
|
|
105912
|
-
subject.code,
|
|
105913
|
-
")"
|
|
105914
|
-
)))
|
|
105915
|
-
))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105916
|
-
Button,
|
|
105917
|
-
{
|
|
105918
|
-
type: "button",
|
|
105919
|
-
variant: "outline",
|
|
105920
|
-
onClick: () => setIsDialogOpen(false),
|
|
105921
|
-
disabled: isPending
|
|
105922
|
-
},
|
|
105923
|
-
"Cancel"
|
|
105924
|
-
), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105925
|
-
Button,
|
|
105926
|
-
{
|
|
105927
|
-
type: "submit",
|
|
105928
|
-
onClick: handleSubmit,
|
|
105929
|
-
disabled: isPending || !itemName.trim() || !itemCode.trim() || !selectedSubjectCode
|
|
105930
|
-
},
|
|
105931
|
-
isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
105932
|
-
" ",
|
|
105933
|
-
"Save"
|
|
105934
|
-
)))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete topic "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105935
|
-
AlertDialogAction2,
|
|
105936
|
-
{
|
|
105937
|
-
onClick: confirmDelete,
|
|
105938
|
-
disabled: isPending,
|
|
105939
|
-
className: "bg-destructive hover:bg-destructive/90"
|
|
105940
|
-
},
|
|
105941
|
-
isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
105942
|
-
" ",
|
|
105943
|
-
"Delete"
|
|
105944
|
-
))))));
|
|
105867
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Tag, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Topics"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm", disabled: subjects.length === 0 }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic")), subjects.length === 0 && !isLoading && /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-sm text-destructive" }, "Please add subjects before adding topics.")), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : topics.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No topics found. Add one to get started!") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, topics.map((topic) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: topic.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, topic.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, topic.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, getSubjectName(topic.subjectCode), " (", topic.subjectCode, ")"), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(topic), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(topic), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Topic" : "Add New Topic")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Topic Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., ALG-BASICS", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Topic Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Algebra Basics" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: selectedSubjectCode, onValueChange: setSelectedSubjectCode, disabled: subjects.length === 0 }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, subjects.map((subject) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: subject.code, value: subject.code }, subject.name, " (", subject.code, ")")))))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() || !selectedSubjectCode }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete topic "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
105945
105868
|
}
|
|
105946
105869
|
|
|
105947
105870
|
// src/react-ui/components/metadata/CategoryManager.tsx
|
|
105948
105871
|
init_react_shim();
|
|
105949
|
-
function CategoryManager() {
|
|
105872
|
+
function CategoryManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
|
|
105950
105873
|
const [items, setItems] = React97.useState([]);
|
|
105951
105874
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
105952
105875
|
const [isDialogOpen, setIsDialogOpen] = React97.useState(false);
|
|
@@ -105958,19 +105881,27 @@ function CategoryManager() {
|
|
|
105958
105881
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
105959
105882
|
const [isPending, startTransition] = React97.useTransition();
|
|
105960
105883
|
const { toast: toast2 } = useToast();
|
|
105961
|
-
|
|
105962
|
-
|
|
105963
|
-
|
|
105964
|
-
|
|
105965
|
-
|
|
105966
|
-
|
|
105967
|
-
|
|
105968
|
-
|
|
105969
|
-
|
|
105970
|
-
|
|
105971
|
-
|
|
105884
|
+
const isControlled = initialData !== void 0;
|
|
105885
|
+
const refreshData = () => {
|
|
105886
|
+
if (!isControlled) {
|
|
105887
|
+
setIsLoading(true);
|
|
105888
|
+
try {
|
|
105889
|
+
setItems(MetadataService.getCategories());
|
|
105890
|
+
} catch (error) {
|
|
105891
|
+
toast2({ title: "Error", description: "Failed to refresh categories.", variant: "destructive" });
|
|
105892
|
+
} finally {
|
|
105893
|
+
setIsLoading(false);
|
|
105894
|
+
}
|
|
105972
105895
|
}
|
|
105973
105896
|
};
|
|
105897
|
+
React97.useEffect(() => {
|
|
105898
|
+
if (isControlled) {
|
|
105899
|
+
setItems(initialData || []);
|
|
105900
|
+
setIsLoading(isLoadingProp || false);
|
|
105901
|
+
} else {
|
|
105902
|
+
refreshData();
|
|
105903
|
+
}
|
|
105904
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
105974
105905
|
const handleAddItem = () => {
|
|
105975
105906
|
setCurrentItem(null);
|
|
105976
105907
|
setItemName("");
|
|
@@ -105991,13 +105922,17 @@ function CategoryManager() {
|
|
|
105991
105922
|
};
|
|
105992
105923
|
const confirmDelete = () => {
|
|
105993
105924
|
if (!itemToDelete) return;
|
|
105994
|
-
startTransition(() => {
|
|
105925
|
+
startTransition(async () => {
|
|
105995
105926
|
try {
|
|
105996
|
-
|
|
105927
|
+
if (isControlled && onDelete) {
|
|
105928
|
+
await onDelete(itemToDelete);
|
|
105929
|
+
} else {
|
|
105930
|
+
MetadataService.deleteCategory(itemToDelete.code);
|
|
105931
|
+
refreshData();
|
|
105932
|
+
}
|
|
105997
105933
|
toast2({ title: "Success", description: `Category "${itemToDelete.name}" deleted.` });
|
|
105998
|
-
fetchItems();
|
|
105999
105934
|
} catch (error) {
|
|
106000
|
-
toast2({ title: "Error", description:
|
|
105935
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106001
105936
|
} finally {
|
|
106002
105937
|
setIsAlertOpen(false);
|
|
106003
105938
|
setItemToDelete(null);
|
|
@@ -106009,27 +105944,37 @@ function CategoryManager() {
|
|
|
106009
105944
|
toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
|
|
106010
105945
|
return;
|
|
106011
105946
|
}
|
|
106012
|
-
startTransition(() => {
|
|
105947
|
+
startTransition(async () => {
|
|
106013
105948
|
try {
|
|
106014
105949
|
if (currentItem) {
|
|
106015
|
-
|
|
105950
|
+
if (isControlled && onUpdate) {
|
|
105951
|
+
await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, description: itemDescription });
|
|
105952
|
+
} else {
|
|
105953
|
+
MetadataService.updateCategory(currentItem.id, itemName, itemCode, itemDescription);
|
|
105954
|
+
refreshData();
|
|
105955
|
+
}
|
|
105956
|
+
toast2({ title: "Success", description: "Category updated." });
|
|
106016
105957
|
} else {
|
|
106017
|
-
|
|
105958
|
+
if (isControlled && onAdd) {
|
|
105959
|
+
await onAdd({ name: itemName, code: itemCode, description: itemDescription });
|
|
105960
|
+
} else {
|
|
105961
|
+
MetadataService.addCategory(itemName, itemCode, itemDescription);
|
|
105962
|
+
refreshData();
|
|
105963
|
+
}
|
|
105964
|
+
toast2({ title: "Success", description: "Category added." });
|
|
106018
105965
|
}
|
|
106019
|
-
toast2({ title: "Success", description: "Category saved." });
|
|
106020
|
-
fetchItems();
|
|
106021
105966
|
setIsDialogOpen(false);
|
|
106022
105967
|
} catch (error) {
|
|
106023
|
-
toast2({ title: "Error", description:
|
|
105968
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106024
105969
|
}
|
|
106025
105970
|
});
|
|
106026
105971
|
};
|
|
106027
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Layers, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Categories"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Category"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No categories found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Category" : "Add New Category")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., CORE_CONCEPT", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Core Concept" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value), placeholder: "e.g., Fundamental ideas within a subject." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
105972
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Layers, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Categories"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Category"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No categories found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Category" : "Add New Category")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., CORE_CONCEPT", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Core Concept" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value), placeholder: "e.g., Fundamental ideas within a subject." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
106028
105973
|
}
|
|
106029
105974
|
|
|
106030
105975
|
// src/react-ui/components/metadata/BloomLevelManager.tsx
|
|
106031
105976
|
init_react_shim();
|
|
106032
|
-
function BloomLevelManager() {
|
|
105977
|
+
function BloomLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
|
|
106033
105978
|
const [items, setItems] = React97.useState([]);
|
|
106034
105979
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
106035
105980
|
const [isDialogOpen, setIsDialogOpen] = React97.useState(false);
|
|
@@ -106041,19 +105986,27 @@ function BloomLevelManager() {
|
|
|
106041
105986
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
106042
105987
|
const [isPending, startTransition] = React97.useTransition();
|
|
106043
105988
|
const { toast: toast2 } = useToast();
|
|
106044
|
-
|
|
106045
|
-
|
|
106046
|
-
|
|
106047
|
-
|
|
106048
|
-
|
|
106049
|
-
|
|
106050
|
-
|
|
106051
|
-
|
|
106052
|
-
|
|
106053
|
-
|
|
106054
|
-
|
|
105989
|
+
const isControlled = initialData !== void 0;
|
|
105990
|
+
const refreshData = () => {
|
|
105991
|
+
if (!isControlled) {
|
|
105992
|
+
setIsLoading(true);
|
|
105993
|
+
try {
|
|
105994
|
+
setItems(MetadataService.getBloomLevels());
|
|
105995
|
+
} catch (error) {
|
|
105996
|
+
toast2({ title: "Error", description: "Failed to refresh Bloom's Levels.", variant: "destructive" });
|
|
105997
|
+
} finally {
|
|
105998
|
+
setIsLoading(false);
|
|
105999
|
+
}
|
|
106055
106000
|
}
|
|
106056
106001
|
};
|
|
106002
|
+
React97.useEffect(() => {
|
|
106003
|
+
if (isControlled) {
|
|
106004
|
+
setItems(initialData || []);
|
|
106005
|
+
setIsLoading(isLoadingProp || false);
|
|
106006
|
+
} else {
|
|
106007
|
+
refreshData();
|
|
106008
|
+
}
|
|
106009
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
106057
106010
|
const handleAddItem = () => {
|
|
106058
106011
|
setCurrentItem(null);
|
|
106059
106012
|
setItemCode("");
|
|
@@ -106074,13 +106027,17 @@ function BloomLevelManager() {
|
|
|
106074
106027
|
};
|
|
106075
106028
|
const confirmDelete = () => {
|
|
106076
106029
|
if (!itemToDelete) return;
|
|
106077
|
-
startTransition(() => {
|
|
106030
|
+
startTransition(async () => {
|
|
106078
106031
|
try {
|
|
106079
|
-
|
|
106032
|
+
if (isControlled && onDelete) {
|
|
106033
|
+
await onDelete(itemToDelete);
|
|
106034
|
+
} else {
|
|
106035
|
+
MetadataService.deleteBloomLevel(itemToDelete.code);
|
|
106036
|
+
refreshData();
|
|
106037
|
+
}
|
|
106080
106038
|
toast2({ title: "Success", description: `Bloom's Level "${itemToDelete.name}" deleted.` });
|
|
106081
|
-
fetchItems();
|
|
106082
106039
|
} catch (error) {
|
|
106083
|
-
toast2({ title: "Error", description:
|
|
106040
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106084
106041
|
} finally {
|
|
106085
106042
|
setIsAlertOpen(false);
|
|
106086
106043
|
setItemToDelete(null);
|
|
@@ -106092,27 +106049,37 @@ function BloomLevelManager() {
|
|
|
106092
106049
|
toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
|
|
106093
106050
|
return;
|
|
106094
106051
|
}
|
|
106095
|
-
startTransition(() => {
|
|
106052
|
+
startTransition(async () => {
|
|
106096
106053
|
try {
|
|
106097
106054
|
if (currentItem) {
|
|
106098
|
-
|
|
106055
|
+
if (isControlled && onUpdate) {
|
|
106056
|
+
await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, description: itemDescription });
|
|
106057
|
+
} else {
|
|
106058
|
+
MetadataService.updateBloomLevel(currentItem.id, itemName, itemCode, itemDescription);
|
|
106059
|
+
refreshData();
|
|
106060
|
+
}
|
|
106061
|
+
toast2({ title: "Success", description: "Bloom's Level updated." });
|
|
106099
106062
|
} else {
|
|
106100
|
-
|
|
106063
|
+
if (isControlled && onAdd) {
|
|
106064
|
+
await onAdd({ name: itemName, code: itemCode, description: itemDescription });
|
|
106065
|
+
} else {
|
|
106066
|
+
MetadataService.addBloomLevel(itemName, itemCode, itemDescription);
|
|
106067
|
+
refreshData();
|
|
106068
|
+
}
|
|
106069
|
+
toast2({ title: "Success", description: "Bloom's Level added." });
|
|
106101
106070
|
}
|
|
106102
|
-
toast2({ title: "Success", description: "Bloom's Level saved." });
|
|
106103
|
-
fetchItems();
|
|
106104
106071
|
setIsDialogOpen(false);
|
|
106105
106072
|
} catch (error) {
|
|
106106
|
-
toast2({ title: "Error", description:
|
|
106073
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106107
106074
|
}
|
|
106108
106075
|
});
|
|
106109
106076
|
};
|
|
106110
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Brain, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Bloom's Levels"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Bloom's Level"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Bloom's Levels found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Bloom's Level" : "Add New Bloom's Level")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., REMEMBER", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Remembering" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value), placeholder: "e.g., Recall facts and basic concepts." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
106077
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Brain, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Bloom's Levels"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Bloom's Level"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Bloom's Levels found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Bloom's Level" : "Add New Bloom's Level")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., REMEMBER", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Remembering" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value), placeholder: "e.g., Recall facts and basic concepts." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
106111
106078
|
}
|
|
106112
106079
|
|
|
106113
106080
|
// src/react-ui/components/metadata/QuestionTypeManager.tsx
|
|
106114
106081
|
init_react_shim();
|
|
106115
|
-
function QuestionTypeManager() {
|
|
106082
|
+
function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
|
|
106116
106083
|
const [items, setItems] = React97.useState([]);
|
|
106117
106084
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
106118
106085
|
const [isDialogOpen, setIsDialogOpen] = React97.useState(false);
|
|
@@ -106124,19 +106091,27 @@ function QuestionTypeManager() {
|
|
|
106124
106091
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
106125
106092
|
const [isPending, startTransition] = React97.useTransition();
|
|
106126
106093
|
const { toast: toast2 } = useToast();
|
|
106127
|
-
|
|
106128
|
-
|
|
106129
|
-
|
|
106130
|
-
|
|
106131
|
-
|
|
106132
|
-
|
|
106133
|
-
|
|
106134
|
-
|
|
106135
|
-
|
|
106136
|
-
|
|
106137
|
-
|
|
106094
|
+
const isControlled = initialData !== void 0;
|
|
106095
|
+
const refreshData = () => {
|
|
106096
|
+
if (!isControlled) {
|
|
106097
|
+
setIsLoading(true);
|
|
106098
|
+
try {
|
|
106099
|
+
setItems(MetadataService.getQuestionTypes());
|
|
106100
|
+
} catch (error) {
|
|
106101
|
+
toast2({ title: "Error", description: "Failed to refresh Question Types.", variant: "destructive" });
|
|
106102
|
+
} finally {
|
|
106103
|
+
setIsLoading(false);
|
|
106104
|
+
}
|
|
106138
106105
|
}
|
|
106139
106106
|
};
|
|
106107
|
+
React97.useEffect(() => {
|
|
106108
|
+
if (isControlled) {
|
|
106109
|
+
setItems(initialData || []);
|
|
106110
|
+
setIsLoading(isLoadingProp || false);
|
|
106111
|
+
} else {
|
|
106112
|
+
refreshData();
|
|
106113
|
+
}
|
|
106114
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
106140
106115
|
const handleAddItem = () => {
|
|
106141
106116
|
setCurrentItem(null);
|
|
106142
106117
|
setItemCode("");
|
|
@@ -106157,13 +106132,17 @@ function QuestionTypeManager() {
|
|
|
106157
106132
|
};
|
|
106158
106133
|
const confirmDelete = () => {
|
|
106159
106134
|
if (!itemToDelete) return;
|
|
106160
|
-
startTransition(() => {
|
|
106135
|
+
startTransition(async () => {
|
|
106161
106136
|
try {
|
|
106162
|
-
|
|
106137
|
+
if (isControlled && onDelete) {
|
|
106138
|
+
await onDelete(itemToDelete);
|
|
106139
|
+
} else {
|
|
106140
|
+
MetadataService.deleteQuestionType(itemToDelete.code);
|
|
106141
|
+
refreshData();
|
|
106142
|
+
}
|
|
106163
106143
|
toast2({ title: "Success", description: `Question Type "${itemToDelete.name}" deleted.` });
|
|
106164
|
-
fetchItems();
|
|
106165
106144
|
} catch (error) {
|
|
106166
|
-
toast2({ title: "Error", description:
|
|
106145
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106167
106146
|
} finally {
|
|
106168
106147
|
setIsAlertOpen(false);
|
|
106169
106148
|
setItemToDelete(null);
|
|
@@ -106175,27 +106154,37 @@ function QuestionTypeManager() {
|
|
|
106175
106154
|
toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
|
|
106176
106155
|
return;
|
|
106177
106156
|
}
|
|
106178
|
-
startTransition(() => {
|
|
106157
|
+
startTransition(async () => {
|
|
106179
106158
|
try {
|
|
106180
106159
|
if (currentItem) {
|
|
106181
|
-
|
|
106160
|
+
if (isControlled && onUpdate) {
|
|
106161
|
+
await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, description: itemDescription });
|
|
106162
|
+
} else {
|
|
106163
|
+
MetadataService.updateQuestionType(currentItem.id, itemName, itemCode, itemDescription);
|
|
106164
|
+
refreshData();
|
|
106165
|
+
}
|
|
106166
|
+
toast2({ title: "Success", description: "Question Type updated." });
|
|
106182
106167
|
} else {
|
|
106183
|
-
|
|
106168
|
+
if (isControlled && onAdd) {
|
|
106169
|
+
await onAdd({ name: itemName, code: itemCode, description: itemDescription });
|
|
106170
|
+
} else {
|
|
106171
|
+
MetadataService.addQuestionType(itemName, itemCode, itemDescription);
|
|
106172
|
+
refreshData();
|
|
106173
|
+
}
|
|
106174
|
+
toast2({ title: "Success", description: "Question Type added." });
|
|
106184
106175
|
}
|
|
106185
|
-
toast2({ title: "Success", description: "Question Type saved." });
|
|
106186
|
-
fetchItems();
|
|
106187
106176
|
setIsDialogOpen(false);
|
|
106188
106177
|
} catch (error) {
|
|
106189
|
-
toast2({ title: "Error", description:
|
|
106178
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106190
106179
|
}
|
|
106191
106180
|
});
|
|
106192
106181
|
};
|
|
106193
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(CircleHelp, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Question Types"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Question Type"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Question Types found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Question Type" : "Add New Question Type")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.
|
|
106182
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(CircleHelp, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Question Types"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Question Type"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Question Types found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Question Type" : "Add New Question Type")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toLowerCase().replace(/ /g, "_")), placeholder: "e.g., multiple_choice", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Multiple Choice" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value), placeholder: "e.g., Select one answer from a list of options." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
106194
106183
|
}
|
|
106195
106184
|
|
|
106196
106185
|
// src/react-ui/components/metadata/LearningObjectiveManager.tsx
|
|
106197
106186
|
init_react_shim();
|
|
106198
|
-
function LearningObjectiveManager() {
|
|
106187
|
+
function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
|
|
106199
106188
|
const [items, setItems] = React97.useState([]);
|
|
106200
106189
|
const [subjects, setSubjects] = React97.useState([]);
|
|
106201
106190
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
@@ -106209,34 +106198,35 @@ function LearningObjectiveManager() {
|
|
|
106209
106198
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
106210
106199
|
const [isPending, startTransition] = React97.useTransition();
|
|
106211
106200
|
const { toast: toast2 } = useToast();
|
|
106212
|
-
const
|
|
106213
|
-
|
|
106214
|
-
|
|
106215
|
-
|
|
106216
|
-
|
|
106217
|
-
|
|
106218
|
-
|
|
106219
|
-
|
|
106220
|
-
|
|
106221
|
-
|
|
106222
|
-
|
|
106223
|
-
|
|
106224
|
-
});
|
|
106225
|
-
} finally {
|
|
106226
|
-
setIsLoading(false);
|
|
106201
|
+
const isControlled = initialData !== void 0;
|
|
106202
|
+
const refreshData = () => {
|
|
106203
|
+
if (!isControlled) {
|
|
106204
|
+
setIsLoading(true);
|
|
106205
|
+
try {
|
|
106206
|
+
setItems(MetadataService.getLearningObjectives());
|
|
106207
|
+
setSubjects(MetadataService.getSubjects());
|
|
106208
|
+
} catch (error) {
|
|
106209
|
+
toast2({ title: "Error", description: "Failed to refresh data.", variant: "destructive" });
|
|
106210
|
+
} finally {
|
|
106211
|
+
setIsLoading(false);
|
|
106212
|
+
}
|
|
106227
106213
|
}
|
|
106228
106214
|
};
|
|
106229
106215
|
React97.useEffect(() => {
|
|
106230
|
-
|
|
106231
|
-
|
|
106216
|
+
if (isControlled) {
|
|
106217
|
+
setItems(initialData || []);
|
|
106218
|
+
setSubjects(subjectsProp || []);
|
|
106219
|
+
setIsLoading(isLoadingProp || false);
|
|
106220
|
+
} else {
|
|
106221
|
+
refreshData();
|
|
106222
|
+
}
|
|
106223
|
+
}, [isControlled, initialData, subjectsProp, isLoadingProp]);
|
|
106232
106224
|
const handleAddItem = () => {
|
|
106233
106225
|
setCurrentItem(null);
|
|
106234
106226
|
setItemName("");
|
|
106235
106227
|
setItemCode("");
|
|
106236
106228
|
setItemDescription("");
|
|
106237
|
-
setSelectedSubjectCode(
|
|
106238
|
-
subjects.length > 0 ? subjects[0].code : void 0
|
|
106239
|
-
);
|
|
106229
|
+
setSelectedSubjectCode(subjects.length > 0 ? subjects[0].code : void 0);
|
|
106240
106230
|
setIsDialogOpen(true);
|
|
106241
106231
|
};
|
|
106242
106232
|
const handleEditItem = (item) => {
|
|
@@ -106253,20 +106243,17 @@ function LearningObjectiveManager() {
|
|
|
106253
106243
|
};
|
|
106254
106244
|
const confirmDelete = () => {
|
|
106255
106245
|
if (!itemToDelete) return;
|
|
106256
|
-
startTransition(() => {
|
|
106246
|
+
startTransition(async () => {
|
|
106257
106247
|
try {
|
|
106258
|
-
|
|
106259
|
-
|
|
106260
|
-
|
|
106261
|
-
|
|
106262
|
-
|
|
106263
|
-
|
|
106248
|
+
if (isControlled && onDelete) {
|
|
106249
|
+
await onDelete(itemToDelete);
|
|
106250
|
+
} else {
|
|
106251
|
+
MetadataService.deleteLearningObjective(itemToDelete.code);
|
|
106252
|
+
refreshData();
|
|
106253
|
+
}
|
|
106254
|
+
toast2({ title: "Success", description: `Learning Objective "${itemToDelete.name}" deleted.` });
|
|
106264
106255
|
} catch (error) {
|
|
106265
|
-
toast2({
|
|
106266
|
-
title: "Error",
|
|
106267
|
-
description: "Failed to delete Learning Objective.",
|
|
106268
|
-
variant: "destructive"
|
|
106269
|
-
});
|
|
106256
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106270
106257
|
} finally {
|
|
106271
106258
|
setIsAlertOpen(false);
|
|
106272
106259
|
setItemToDelete(null);
|
|
@@ -106275,43 +106262,31 @@ function LearningObjectiveManager() {
|
|
|
106275
106262
|
};
|
|
106276
106263
|
const handleSubmit = () => {
|
|
106277
106264
|
if (!itemName.trim() || !itemCode.trim()) {
|
|
106278
|
-
toast2({
|
|
106279
|
-
title: "Validation Error",
|
|
106280
|
-
description: "Code and Name are required.",
|
|
106281
|
-
variant: "destructive"
|
|
106282
|
-
});
|
|
106265
|
+
toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
|
|
106283
106266
|
return;
|
|
106284
106267
|
}
|
|
106285
|
-
startTransition(() => {
|
|
106268
|
+
startTransition(async () => {
|
|
106286
106269
|
try {
|
|
106287
106270
|
if (currentItem) {
|
|
106288
|
-
|
|
106289
|
-
currentItem.id,
|
|
106290
|
-
|
|
106291
|
-
itemCode,
|
|
106292
|
-
|
|
106293
|
-
|
|
106294
|
-
);
|
|
106271
|
+
if (isControlled && onUpdate) {
|
|
106272
|
+
await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, subjectCode: selectedSubjectCode, description: itemDescription });
|
|
106273
|
+
} else {
|
|
106274
|
+
MetadataService.updateLearningObjective(currentItem.id, itemName, itemCode, selectedSubjectCode, itemDescription);
|
|
106275
|
+
refreshData();
|
|
106276
|
+
}
|
|
106277
|
+
toast2({ title: "Success", description: "Learning Objective updated." });
|
|
106295
106278
|
} else {
|
|
106296
|
-
|
|
106297
|
-
itemName,
|
|
106298
|
-
|
|
106299
|
-
selectedSubjectCode,
|
|
106300
|
-
|
|
106301
|
-
|
|
106279
|
+
if (isControlled && onAdd) {
|
|
106280
|
+
await onAdd({ name: itemName, code: itemCode, subjectCode: selectedSubjectCode, description: itemDescription });
|
|
106281
|
+
} else {
|
|
106282
|
+
MetadataService.addLearningObjective(itemName, itemCode, selectedSubjectCode, itemDescription);
|
|
106283
|
+
refreshData();
|
|
106284
|
+
}
|
|
106285
|
+
toast2({ title: "Success", description: "Learning Objective added." });
|
|
106302
106286
|
}
|
|
106303
|
-
toast2({
|
|
106304
|
-
title: "Success",
|
|
106305
|
-
description: "Learning Objective saved."
|
|
106306
|
-
});
|
|
106307
|
-
fetchData();
|
|
106308
106287
|
setIsDialogOpen(false);
|
|
106309
106288
|
} catch (error) {
|
|
106310
|
-
toast2({
|
|
106311
|
-
title: "Error",
|
|
106312
|
-
description: "Failed to save Learning Objective.",
|
|
106313
|
-
variant: "destructive"
|
|
106314
|
-
});
|
|
106289
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106315
106290
|
}
|
|
106316
106291
|
});
|
|
106317
106292
|
};
|
|
@@ -106319,100 +106294,12 @@ function LearningObjectiveManager() {
|
|
|
106319
106294
|
if (!subjectCode) return "N/A";
|
|
106320
106295
|
return subjects.find((s2) => s2.code === subjectCode)?.name || "N/A";
|
|
106321
106296
|
};
|
|
106322
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), "
|
|
106323
|
-
Button,
|
|
106324
|
-
{
|
|
106325
|
-
variant: "ghost",
|
|
106326
|
-
size: "icon",
|
|
106327
|
-
onClick: () => handleEditItem(item),
|
|
106328
|
-
className: "mr-2"
|
|
106329
|
-
},
|
|
106330
|
-
/* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })
|
|
106331
|
-
), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106332
|
-
Button,
|
|
106333
|
-
{
|
|
106334
|
-
variant: "ghost",
|
|
106335
|
-
size: "icon",
|
|
106336
|
-
onClick: () => handleDeleteItem(item),
|
|
106337
|
-
className: "text-destructive hover:text-destructive"
|
|
106338
|
-
},
|
|
106339
|
-
/* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })
|
|
106340
|
-
))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106341
|
-
Input,
|
|
106342
|
-
{
|
|
106343
|
-
id: "itemCode",
|
|
106344
|
-
value: itemCode,
|
|
106345
|
-
onChange: (e2) => setItemCode(
|
|
106346
|
-
e2.target.value.toUpperCase()
|
|
106347
|
-
),
|
|
106348
|
-
disabled: !!currentItem
|
|
106349
|
-
}
|
|
106350
|
-
)), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106351
|
-
Input,
|
|
106352
|
-
{
|
|
106353
|
-
id: "itemName",
|
|
106354
|
-
value: itemName,
|
|
106355
|
-
onChange: (e2) => setItemName(e2.target.value)
|
|
106356
|
-
}
|
|
106357
|
-
)), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemSubject" }, "Subject (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106358
|
-
Select2,
|
|
106359
|
-
{
|
|
106360
|
-
value: selectedSubjectCode || "",
|
|
106361
|
-
onValueChange: (value) => setSelectedSubjectCode(
|
|
106362
|
-
value === "_NONE_" ? void 0 : value
|
|
106363
|
-
)
|
|
106364
|
-
},
|
|
106365
|
-
/* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, { id: "itemSubject" }, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, { placeholder: "Select a subject" })),
|
|
106366
|
-
/* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { value: "_NONE_" }, "No Specific Subject"), subjects.map((subject) => /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106367
|
-
SelectItem2,
|
|
106368
|
-
{
|
|
106369
|
-
key: subject.id,
|
|
106370
|
-
value: subject.code
|
|
106371
|
-
},
|
|
106372
|
-
subject.name
|
|
106373
|
-
)))
|
|
106374
|
-
)), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106375
|
-
Textarea,
|
|
106376
|
-
{
|
|
106377
|
-
id: "itemDescription",
|
|
106378
|
-
value: itemDescription,
|
|
106379
|
-
onChange: (e2) => setItemDescription(e2.target.value)
|
|
106380
|
-
}
|
|
106381
|
-
))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106382
|
-
Button,
|
|
106383
|
-
{
|
|
106384
|
-
type: "button",
|
|
106385
|
-
variant: "outline",
|
|
106386
|
-
onClick: () => setIsDialogOpen(false),
|
|
106387
|
-
disabled: isPending
|
|
106388
|
-
},
|
|
106389
|
-
"Cancel"
|
|
106390
|
-
), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106391
|
-
Button,
|
|
106392
|
-
{
|
|
106393
|
-
type: "submit",
|
|
106394
|
-
onClick: handleSubmit,
|
|
106395
|
-
disabled: isPending || !itemName.trim() || !itemCode.trim()
|
|
106396
|
-
},
|
|
106397
|
-
isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
106398
|
-
" ",
|
|
106399
|
-
"Save"
|
|
106400
|
-
)))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
106401
|
-
AlertDialogAction2,
|
|
106402
|
-
{
|
|
106403
|
-
onClick: confirmDelete,
|
|
106404
|
-
disabled: isPending,
|
|
106405
|
-
className: "bg-destructive hover:bg-destructive/90"
|
|
106406
|
-
},
|
|
106407
|
-
isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
106408
|
-
" ",
|
|
106409
|
-
"Delete"
|
|
106410
|
-
))))));
|
|
106297
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, getSubjectName(item.subjectCode)), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value) })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemSubject" }, "Subject (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: selectedSubjectCode || "", onValueChange: (value) => setSelectedSubjectCode(value === "_NONE_" ? void 0 : value) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, { id: "itemSubject" }, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { value: "_NONE_" }, "No Specific Subject"), subjects.map((subject) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: subject.id, value: subject.code }, subject.name))))), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value) }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
106411
106298
|
}
|
|
106412
106299
|
|
|
106413
106300
|
// src/react-ui/components/metadata/ContextManager.tsx
|
|
106414
106301
|
init_react_shim();
|
|
106415
|
-
function ContextManager() {
|
|
106302
|
+
function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
|
|
106416
106303
|
const [items, setItems] = React97.useState([]);
|
|
106417
106304
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
106418
106305
|
const [isDialogOpen, setIsDialogOpen] = React97.useState(false);
|
|
@@ -106424,19 +106311,27 @@ function ContextManager() {
|
|
|
106424
106311
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
106425
106312
|
const [isPending, startTransition] = React97.useTransition();
|
|
106426
106313
|
const { toast: toast2 } = useToast();
|
|
106427
|
-
|
|
106428
|
-
|
|
106429
|
-
|
|
106430
|
-
|
|
106431
|
-
|
|
106432
|
-
|
|
106433
|
-
|
|
106434
|
-
|
|
106435
|
-
|
|
106436
|
-
|
|
106437
|
-
|
|
106314
|
+
const isControlled = initialData !== void 0;
|
|
106315
|
+
const refreshData = () => {
|
|
106316
|
+
if (!isControlled) {
|
|
106317
|
+
setIsLoading(true);
|
|
106318
|
+
try {
|
|
106319
|
+
setItems(MetadataService.getContexts());
|
|
106320
|
+
} catch (error) {
|
|
106321
|
+
toast2({ title: "Error", description: "Failed to refresh Contexts.", variant: "destructive" });
|
|
106322
|
+
} finally {
|
|
106323
|
+
setIsLoading(false);
|
|
106324
|
+
}
|
|
106438
106325
|
}
|
|
106439
106326
|
};
|
|
106327
|
+
React97.useEffect(() => {
|
|
106328
|
+
if (isControlled) {
|
|
106329
|
+
setItems(initialData || []);
|
|
106330
|
+
setIsLoading(isLoadingProp || false);
|
|
106331
|
+
} else {
|
|
106332
|
+
refreshData();
|
|
106333
|
+
}
|
|
106334
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
106440
106335
|
const handleAddItem = () => {
|
|
106441
106336
|
setCurrentItem(null);
|
|
106442
106337
|
setItemName("");
|
|
@@ -106457,13 +106352,17 @@ function ContextManager() {
|
|
|
106457
106352
|
};
|
|
106458
106353
|
const confirmDelete = () => {
|
|
106459
106354
|
if (!itemToDelete) return;
|
|
106460
|
-
startTransition(() => {
|
|
106355
|
+
startTransition(async () => {
|
|
106461
106356
|
try {
|
|
106462
|
-
|
|
106357
|
+
if (isControlled && onDelete) {
|
|
106358
|
+
await onDelete(itemToDelete);
|
|
106359
|
+
} else {
|
|
106360
|
+
MetadataService.deleteContext(itemToDelete.code);
|
|
106361
|
+
refreshData();
|
|
106362
|
+
}
|
|
106463
106363
|
toast2({ title: "Success", description: `Context "${itemToDelete.name}" deleted.` });
|
|
106464
|
-
fetchItems();
|
|
106465
106364
|
} catch (error) {
|
|
106466
|
-
toast2({ title: "Error", description:
|
|
106365
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106467
106366
|
} finally {
|
|
106468
106367
|
setIsAlertOpen(false);
|
|
106469
106368
|
setItemToDelete(null);
|
|
@@ -106475,32 +106374,50 @@ function ContextManager() {
|
|
|
106475
106374
|
toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
|
|
106476
106375
|
return;
|
|
106477
106376
|
}
|
|
106478
|
-
startTransition(() => {
|
|
106377
|
+
startTransition(async () => {
|
|
106479
106378
|
try {
|
|
106480
106379
|
if (currentItem) {
|
|
106481
|
-
|
|
106380
|
+
if (isControlled && onUpdate) {
|
|
106381
|
+
await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, description: itemDescription });
|
|
106382
|
+
} else {
|
|
106383
|
+
MetadataService.updateContext(currentItem.id, itemName, itemCode, itemDescription);
|
|
106384
|
+
refreshData();
|
|
106385
|
+
}
|
|
106386
|
+
toast2({ title: "Success", description: "Context updated." });
|
|
106482
106387
|
} else {
|
|
106483
|
-
|
|
106388
|
+
if (isControlled && onAdd) {
|
|
106389
|
+
await onAdd({ name: itemName, code: itemCode, description: itemDescription });
|
|
106390
|
+
} else {
|
|
106391
|
+
MetadataService.addContext(itemName, itemCode, itemDescription);
|
|
106392
|
+
refreshData();
|
|
106393
|
+
}
|
|
106394
|
+
toast2({ title: "Success", description: "Context added." });
|
|
106484
106395
|
}
|
|
106485
|
-
toast2({ title: "Success", description: "Context saved." });
|
|
106486
|
-
fetchItems();
|
|
106487
106396
|
setIsDialogOpen(false);
|
|
106488
106397
|
} catch (error) {
|
|
106489
|
-
toast2({ title: "Error", description:
|
|
106398
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106490
106399
|
}
|
|
106491
106400
|
});
|
|
106492
106401
|
};
|
|
106493
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(ScanText, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Contexts"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Context"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Contexts found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Context" : "Add New Context")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., HIST_INQ", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Historical Inquiry" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value), placeholder: "e.g., Analyzing primary and secondary sources." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
106402
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(ScanText, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Contexts"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Context"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Contexts found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Context" : "Add New Context")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e2) => setItemCode(e2.target.value.toUpperCase()), placeholder: "e.g., HIST_INQ", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e2) => setItemName(e2.target.value), placeholder: "e.g., Historical Inquiry" })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e2) => setItemDescription(e2.target.value), placeholder: "e.g., Analyzing primary and secondary sources." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
106494
106403
|
}
|
|
106495
106404
|
|
|
106496
106405
|
// src/react-ui/components/metadata/ApproachManager.tsx
|
|
106497
106406
|
init_react_shim();
|
|
106498
106407
|
var knowledgeDimensions = ["Factual", "Conceptual", "Procedural"];
|
|
106499
106408
|
var rawDifficultyLevels = ["E", "E~M", "M", "M~H", "H"];
|
|
106500
|
-
function ApproachManager(
|
|
106409
|
+
function ApproachManager({
|
|
106410
|
+
initialData,
|
|
106411
|
+
bloomLevels: bloomLevelsProp,
|
|
106412
|
+
questionTypes: questionTypesProp,
|
|
106413
|
+
isLoading: isLoadingProp,
|
|
106414
|
+
onAdd,
|
|
106415
|
+
onUpdate,
|
|
106416
|
+
onDelete
|
|
106417
|
+
}) {
|
|
106501
106418
|
const [items, setItems] = React97.useState([]);
|
|
106502
106419
|
const [bloomLevels, setBloomLevels] = React97.useState([]);
|
|
106503
|
-
const [
|
|
106420
|
+
const [questionTypes, setQuestionTypes] = React97.useState([]);
|
|
106504
106421
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
106505
106422
|
const [isDialogOpen, setIsDialogOpen] = React97.useState(false);
|
|
106506
106423
|
const [isAlertOpen, setIsAlertOpen] = React97.useState(false);
|
|
@@ -106509,30 +106426,37 @@ function ApproachManager() {
|
|
|
106509
106426
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
106510
106427
|
const [isPending, startTransition] = React97.useTransition();
|
|
106511
106428
|
const { toast: toast2 } = useToast();
|
|
106512
|
-
const
|
|
106513
|
-
|
|
106514
|
-
|
|
106515
|
-
|
|
106516
|
-
|
|
106517
|
-
|
|
106518
|
-
|
|
106519
|
-
|
|
106520
|
-
|
|
106521
|
-
|
|
106522
|
-
|
|
106523
|
-
|
|
106524
|
-
|
|
106429
|
+
const isControlled = initialData !== void 0;
|
|
106430
|
+
const refreshData = () => {
|
|
106431
|
+
if (!isControlled) {
|
|
106432
|
+
setIsLoading(true);
|
|
106433
|
+
try {
|
|
106434
|
+
setItems(MetadataService.getApproaches());
|
|
106435
|
+
setBloomLevels(MetadataService.getBloomLevels());
|
|
106436
|
+
setQuestionTypes(MetadataService.getQuestionTypes());
|
|
106437
|
+
} catch (error) {
|
|
106438
|
+
toast2({ title: "Error", description: "Failed to refresh metadata for Approaches.", variant: "destructive" });
|
|
106439
|
+
} finally {
|
|
106440
|
+
setIsLoading(false);
|
|
106441
|
+
}
|
|
106525
106442
|
}
|
|
106526
106443
|
};
|
|
106527
106444
|
React97.useEffect(() => {
|
|
106528
|
-
|
|
106529
|
-
|
|
106445
|
+
if (isControlled) {
|
|
106446
|
+
setItems(initialData || []);
|
|
106447
|
+
setBloomLevels(bloomLevelsProp || []);
|
|
106448
|
+
setQuestionTypes(questionTypesProp || []);
|
|
106449
|
+
setIsLoading(isLoadingProp || false);
|
|
106450
|
+
} else {
|
|
106451
|
+
refreshData();
|
|
106452
|
+
}
|
|
106453
|
+
}, [isControlled, initialData, bloomLevelsProp, questionTypesProp, isLoadingProp]);
|
|
106530
106454
|
const resetForm = () => {
|
|
106531
106455
|
setFormState({
|
|
106532
106456
|
knowledgeDimension: "Factual",
|
|
106533
106457
|
rawDifficulty: "E",
|
|
106534
106458
|
bloomLevelCode: bloomLevels.length > 0 ? bloomLevels[0].code : "",
|
|
106535
|
-
iSpringQuizType:
|
|
106459
|
+
iSpringQuizType: questionTypes.length > 0 ? questionTypes[0].code : "multiple_choice"
|
|
106536
106460
|
});
|
|
106537
106461
|
};
|
|
106538
106462
|
const handleAddItem = () => {
|
|
@@ -106562,13 +106486,17 @@ function ApproachManager() {
|
|
|
106562
106486
|
};
|
|
106563
106487
|
const confirmDelete = () => {
|
|
106564
106488
|
if (!itemToDelete) return;
|
|
106565
|
-
startTransition(() => {
|
|
106489
|
+
startTransition(async () => {
|
|
106566
106490
|
try {
|
|
106567
|
-
|
|
106491
|
+
if (isControlled && onDelete) {
|
|
106492
|
+
await onDelete(itemToDelete);
|
|
106493
|
+
} else {
|
|
106494
|
+
MetadataService.deleteApproach(itemToDelete.code);
|
|
106495
|
+
refreshData();
|
|
106496
|
+
}
|
|
106568
106497
|
toast2({ title: "Success", description: `Approach "${itemToDelete.code}" deleted.` });
|
|
106569
|
-
fetchItems();
|
|
106570
106498
|
} catch (error) {
|
|
106571
|
-
toast2({ title: "Error", description:
|
|
106499
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106572
106500
|
} finally {
|
|
106573
106501
|
setIsAlertOpen(false);
|
|
106574
106502
|
setItemToDelete(null);
|
|
@@ -106576,28 +106504,37 @@ function ApproachManager() {
|
|
|
106576
106504
|
});
|
|
106577
106505
|
};
|
|
106578
106506
|
const handleSubmit = () => {
|
|
106579
|
-
const { code: code4, verbEn, verbVi } = formState;
|
|
106580
|
-
if (!code4?.trim() || !verbEn?.trim() || !verbVi?.trim()) {
|
|
106581
|
-
toast2({ title: "Validation Error", description: "
|
|
106507
|
+
const { code: code4, verbEn, verbVi, bloomLevelCode, iSpringQuizType, knowledgeDimension, rawDifficulty } = formState;
|
|
106508
|
+
if (!code4?.trim() || !verbEn?.trim() || !verbVi?.trim() || !bloomLevelCode || !iSpringQuizType || !knowledgeDimension || !rawDifficulty) {
|
|
106509
|
+
toast2({ title: "Validation Error", description: "All fields except examples and context are required.", variant: "destructive" });
|
|
106582
106510
|
return;
|
|
106583
106511
|
}
|
|
106584
|
-
startTransition(() => {
|
|
106512
|
+
startTransition(async () => {
|
|
106585
106513
|
try {
|
|
106586
106514
|
if (currentItem) {
|
|
106587
|
-
|
|
106515
|
+
if (isControlled && onUpdate) {
|
|
106516
|
+
await onUpdate({ ...currentItem, ...formState });
|
|
106517
|
+
} else {
|
|
106518
|
+
MetadataService.updateApproach(currentItem.id, formState);
|
|
106519
|
+
refreshData();
|
|
106520
|
+
}
|
|
106588
106521
|
toast2({ title: "Success", description: "Approach updated." });
|
|
106589
106522
|
} else {
|
|
106590
|
-
|
|
106523
|
+
if (isControlled && onAdd) {
|
|
106524
|
+
await onAdd(formState);
|
|
106525
|
+
} else {
|
|
106526
|
+
MetadataService.addApproach(formState);
|
|
106527
|
+
refreshData();
|
|
106528
|
+
}
|
|
106591
106529
|
toast2({ title: "Success", description: "Approach added." });
|
|
106592
106530
|
}
|
|
106593
|
-
fetchItems();
|
|
106594
106531
|
setIsDialogOpen(false);
|
|
106595
106532
|
} catch (error) {
|
|
106596
|
-
toast2({ title: "Error", description: error.message
|
|
106533
|
+
toast2({ title: "Error", description: error.message, variant: "destructive" });
|
|
106597
106534
|
}
|
|
106598
106535
|
});
|
|
106599
106536
|
};
|
|
106600
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Settings2, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Approaches"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Approach"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Approaches found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Approach ID"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Verb (VI)"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Cognitive Level"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "iSpring Type"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.verbVi), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.bloomLevelCode), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.iSpringQuizType), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Approach" : "Add New Approach")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "code" }, "Approach Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e2) => setFormState((s2) => ({ ...s2, code: e2.target.value.toUpperCase() })), placeholder: "e.g., REM-FAC-IDT-MCQ", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "verbEn" }, "Verb (English)"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "verbEn", value: formState.verbEn || "", onChange: (e2) => setFormState((s2) => ({ ...s2, verbEn: e2.target.value })), placeholder: "e.g., Identify" }))), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "verbVi" }, "Verb (Vietnamese)"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "verbVi", value: formState.verbVi || "", onChange: (e2) => setFormState((s2) => ({ ...s2, verbVi: e2.target.value })), placeholder: "e.g., Nh\u1EADn d\u1EA1ng" })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Cognitive Level"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.bloomLevelCode, onValueChange: (v) => setFormState((s2) => ({ ...s2, bloomLevelCode: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, bloomLevels.map((level) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: level.code, value: level.code }, level.name)))))), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "knowledgeDimension" }, "Knowledge Dimension"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.knowledgeDimension, onValueChange: (v) => setFormState((s2) => ({ ...s2, knowledgeDimension: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, knowledgeDimensions.map((kd) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: kd, value: kd }, kd))))), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "iSpringQuizType" }, "iSpring Quiz Type"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.iSpringQuizType, onValueChange: (v) => setFormState((s2) => ({ ...s2, iSpringQuizType: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, iSpringQuizTypeOptions.map((qt) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: qt.value, value: qt.value }, qt.label))))), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "rawDifficulty" }, "Raw Difficulty"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.rawDifficulty, onValueChange: (v) => setFormState((s2) => ({ ...s2, rawDifficulty: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, rawDifficultyLevels.map((rd) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: rd, value: rd }, rd)))))), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "suggestContext" }, "Suggest Context (comma-separated codes)"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "suggestContext", value: formState.suggestContext || "", onChange: (e2) => setFormState((s2) => ({ ...s2, suggestContext: e2.target.value })), placeholder: "e.g., A, B, D, G, H" })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "exampleEn" }, "Example (English)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "exampleEn", value: formState.exampleEn || "", onChange: (e2) => setFormState((s2) => ({ ...s2, exampleEn: e2.target.value })), placeholder: "English example prompt..." })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "exampleVi" }, "Example (Vietnamese)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "exampleVi", value: formState.exampleVi || "", onChange: (e2) => setFormState((s2) => ({ ...s2, exampleVi: e2.target.value })), placeholder: "Vietnamese example prompt..." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.code?.trim() || !formState.verbEn?.trim() || !formState.verbVi?.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.code, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
106537
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(Settings2, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Approaches"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Approach"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Approaches found.") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Approach ID"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Verb (VI)"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Cognitive Level"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "iSpring Type"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, item.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.verbVi), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.bloomLevelCode), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, item.iSpringQuizType), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Approach" : "Add New Approach")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "code" }, "Approach Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e2) => setFormState((s2) => ({ ...s2, code: e2.target.value.toUpperCase() })), placeholder: "e.g., REM-FAC-IDT-MCQ", disabled: !!currentItem })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "verbEn" }, "Verb (English)"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "verbEn", value: formState.verbEn || "", onChange: (e2) => setFormState((s2) => ({ ...s2, verbEn: e2.target.value })), placeholder: "e.g., Identify" }))), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "verbVi" }, "Verb (Vietnamese)"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "verbVi", value: formState.verbVi || "", onChange: (e2) => setFormState((s2) => ({ ...s2, verbVi: e2.target.value })), placeholder: "e.g., Nh\u1EADn d\u1EA1ng" })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Cognitive Level"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.bloomLevelCode, onValueChange: (v) => setFormState((s2) => ({ ...s2, bloomLevelCode: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, bloomLevels.map((level) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: level.code, value: level.code }, level.name)))))), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "knowledgeDimension" }, "Knowledge Dimension"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.knowledgeDimension, onValueChange: (v) => setFormState((s2) => ({ ...s2, knowledgeDimension: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, knowledgeDimensions.map((kd) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: kd, value: kd }, kd))))), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "iSpringQuizType" }, "iSpring Quiz Type"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.iSpringQuizType, onValueChange: (v) => setFormState((s2) => ({ ...s2, iSpringQuizType: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, questionTypes.map((qt) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name))))), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "rawDifficulty" }, "Raw Difficulty"), /* @__PURE__ */ React97__namespace.default.createElement(Select2, { value: formState.rawDifficulty, onValueChange: (v) => setFormState((s2) => ({ ...s2, rawDifficulty: v })) }, /* @__PURE__ */ React97__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React97__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React97__namespace.default.createElement(SelectContent2, null, rawDifficultyLevels.map((rd) => /* @__PURE__ */ React97__namespace.default.createElement(SelectItem2, { key: rd, value: rd }, rd)))))), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "suggestContext" }, "Suggest Context (comma-separated codes)"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "suggestContext", value: formState.suggestContext || "", onChange: (e2) => setFormState((s2) => ({ ...s2, suggestContext: e2.target.value })), placeholder: "e.g., A, B, D, G, H" })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "exampleEn" }, "Example (English)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "exampleEn", value: formState.exampleEn || "", onChange: (e2) => setFormState((s2) => ({ ...s2, exampleEn: e2.target.value })), placeholder: "English example prompt..." })), /* @__PURE__ */ React97__namespace.default.createElement("div", null, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "exampleVi" }, "Example (Vietnamese)"), /* @__PURE__ */ React97__namespace.default.createElement(Textarea, { id: "exampleVi", value: formState.exampleVi || "", onChange: (e2) => setFormState((s2) => ({ ...s2, exampleVi: e2.target.value })), placeholder: "Vietnamese example prompt..." }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.code, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
106601
106538
|
}
|
|
106602
106539
|
|
|
106603
106540
|
// src/react-ui/components/metadata/MetadataTabs.tsx
|