@thanh01.pmt/interactive-quiz-kit 1.0.66 → 1.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react-ui.cjs CHANGED
@@ -9085,7 +9085,7 @@ var translation_default = {
9085
9085
  subject: "Subject",
9086
9086
  category: "Category",
9087
9087
  topic: "Topic",
9088
- loId: "LO ID"
9088
+ code: "LO ID"
9089
9089
  },
9090
9090
  confirmModal: {
9091
9091
  title: "Confirm Data Import",
@@ -9500,7 +9500,7 @@ var translation_default2 = {
9500
9500
  subject: "M\xF4n h\u1ECDc",
9501
9501
  category: "Danh m\u1EE5c",
9502
9502
  topic: "Ch\u1EE7 \u0111\u1EC1",
9503
- loId: "M\xE3 MTH"
9503
+ code: "M\xE3 MTH"
9504
9504
  },
9505
9505
  confirmModal: {
9506
9506
  title: "X\xE1c nh\u1EADn Nh\u1EADp D\u1EEF li\u1EC7u",
@@ -37572,7 +37572,7 @@ var cva = (base3, config3) => (props) => {
37572
37572
 
37573
37573
  // src/react-ui/components/elements/label.tsx
37574
37574
  var labelVariants = cva(
37575
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
37575
+ "text-sm font-Medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
37576
37576
  );
37577
37577
  var Label2 = React169__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React169__namespace.createElement(
37578
37578
  Root3,
@@ -62810,7 +62810,7 @@ var MarkdownRenderer = ({
62810
62810
  },
62811
62811
  h1: ({ node: node2, ...props }) => /* @__PURE__ */ React169__namespace.default.createElement("h1", { ...props, className: "text-3xl font-bold mb-6 mt-8 first:mt-0" }),
62812
62812
  h2: ({ node: node2, ...props }) => /* @__PURE__ */ React169__namespace.default.createElement("h2", { ...props, className: "text-2xl font-semibold mb-4 mt-6" }),
62813
- h3: ({ node: node2, ...props }) => /* @__PURE__ */ React169__namespace.default.createElement("h3", { ...props, className: "text-xl font-medium mb-3 mt-5" }),
62813
+ h3: ({ node: node2, ...props }) => /* @__PURE__ */ React169__namespace.default.createElement("h3", { ...props, className: "text-xl font-Medium mb-3 mt-5" }),
62814
62814
  ul: ({ node: node2, ...props }) => /* @__PURE__ */ React169__namespace.default.createElement("ul", { ...props, className: "my-4 space-y-2 list-disc list-inside" }),
62815
62815
  ol: ({ node: node2, ...props }) => /* @__PURE__ */ React169__namespace.default.createElement("ol", { ...props, className: "my-4 space-y-2 list-decimal list-inside" }),
62816
62816
  p: ({ node: node2, ...props }) => /* @__PURE__ */ React169__namespace.default.createElement("p", { ...props, className: "mb-4 leading-7" }),
@@ -63284,7 +63284,7 @@ var Input = React169__namespace.forwardRef(
63284
63284
  {
63285
63285
  type,
63286
63286
  className: cn(
63287
- "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
63287
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-Medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
63288
63288
  className
63289
63289
  ),
63290
63290
  ref,
@@ -63459,7 +63459,7 @@ init_react_shim();
63459
63459
  // src/react-ui/components/elements/button.tsx
63460
63460
  init_react_shim();
63461
63461
  var buttonVariants = cva(
63462
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
63462
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-Medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
63463
63463
  {
63464
63464
  variants: {
63465
63465
  variant: {
@@ -68412,7 +68412,7 @@ var MatchingQuestionUI = ({
68412
68412
  if (showCorrectAnswer && selectedOptionId) {
68413
68413
  borderColor = isSelectionCorrect ? "border-green-500" : "border-destructive";
68414
68414
  }
68415
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { key: promptItem.id, className: `p-3 border rounded-md ${borderColor} transition-colors bg-background` }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `select-prompt-${promptItem.id}`, className: "font-medium text-base block mb-2 whitespace-normal" }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: promptItem.content })), /* @__PURE__ */ React169__namespace.default.createElement(
68415
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { key: promptItem.id, className: `p-3 border rounded-md ${borderColor} transition-colors bg-background` }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `select-prompt-${promptItem.id}`, className: "font-Medium text-base block mb-2 whitespace-normal" }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: promptItem.content })), /* @__PURE__ */ React169__namespace.default.createElement(
68416
68416
  Select2,
68417
68417
  {
68418
68418
  value: selectedOptionId,
@@ -68467,7 +68467,7 @@ var DragAndDropQuestionUI = ({
68467
68467
  } else {
68468
68468
  itemStyle += " border-muted";
68469
68469
  }
68470
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { key: item.id, className: itemStyle }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `select-draggable-${item.id}`, className: "font-medium text-base mb-2 sm:mb-0 sm:mr-4 flex-1" }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: item.content })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-2 w-full sm:w-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(
68470
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { key: item.id, className: itemStyle }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `select-draggable-${item.id}`, className: "font-Medium text-base mb-2 sm:mb-0 sm:mr-4 flex-1" }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: item.content })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-2 w-full sm:w-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(
68471
68471
  Select2,
68472
68472
  {
68473
68473
  value: selectedDropZoneId,
@@ -95483,7 +95483,7 @@ var TabsTrigger2 = React169__namespace.forwardRef(({ className, ...props }, ref)
95483
95483
  {
95484
95484
  ref,
95485
95485
  className: cn(
95486
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
95486
+ "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-Medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
95487
95487
  className
95488
95488
  ),
95489
95489
  ...props
@@ -96183,7 +96183,7 @@ var AccordionTrigger2 = React169__namespace.forwardRef(({ className, children, .
96183
96183
  {
96184
96184
  ref,
96185
96185
  className: cn(
96186
- "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
96186
+ "flex flex-1 items-center justify-between py-4 font-Medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
96187
96187
  className
96188
96188
  ),
96189
96189
  ...props
@@ -96970,7 +96970,7 @@ var QuizResult = ({
96970
96970
  }
96971
96971
  return String(answer);
96972
96972
  };
96973
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "w-full max-w-3xl mx-auto shadow-xl" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-3xl font-headline text-center" }, t4("practiceFlow.results.title", { quizTitle })), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, { className: "text-center text-lg" }, t4("practiceFlow.results.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-6" }, /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "bg-secondary/50" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-xl flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(BarChart2, { className: "mr-2 h-5 w-5 text-primary" }), t4("practiceFlow.results.overallScore"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "grid grid-cols-1 md:grid-cols-3 gap-4 text-center" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.score, " / ", result.maxScore), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.points"))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.percentage.toFixed(2), "%"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.percentage"))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, result.passed !== void 0 && (result.passed ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col items-center text-green-600" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "h-10 w-10" }), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.passed"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col items-center text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "h-10 w-10" }), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.failed"))))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 text-sm" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement(Clock, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__namespace.default.createElement("span", null, t4("practiceFlow.results.timeSpent")), /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold" }, result.totalTimeSpentSeconds?.toFixed(0) ?? "N/A", " ", t4("practiceFlow.results.timeUnit"))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement(Percent, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__namespace.default.createElement("span", null, t4("practiceFlow.results.avgTimePerQuestion")), /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold" }, result.averageTimePerQuestionSeconds?.toFixed(1) ?? "N/A", " ", t4("practiceFlow.results.timeUnit")))), result.scormStatus && result.scormStatus !== "idle" && result.scormStatus !== "no_api" && /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-lg" }, "SCORM Sync Status")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: `flex items-center ${result.scormStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.scormStatus === "error" && /* @__PURE__ */ React169__namespace.default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold ml-1" }, result.scormStatus)), result.scormError && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.scormError))), result.webhookStatus && result.webhookStatus !== "idle" && /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-lg" }, "Webhook Sync Status")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: `flex items-center ${result.webhookStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.webhookStatus === "error" && /* @__PURE__ */ React169__namespace.default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold ml-1" }, result.webhookStatus)), result.webhookError && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.webhookError))), /* @__PURE__ */ React169__namespace.default.createElement(Accordion2, { type: "single", collapsible: true, className: "w-full" }, /* @__PURE__ */ React169__namespace.default.createElement(AccordionItem2, { value: "question-breakdown" }, /* @__PURE__ */ React169__namespace.default.createElement(AccordionTrigger2, { className: "text-lg font-semibold" }, t4("practiceFlow.results.questionBreakdown")), /* @__PURE__ */ React169__namespace.default.createElement(AccordionContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[300px] pr-4" }, /* @__PURE__ */ React169__namespace.default.createElement("ul", { className: "space-y-4" }, result.questionResults.map((qResult, index3) => /* @__PURE__ */ React169__namespace.default.createElement("li", { key: qResult.questionId, className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold" }, t4("common.questions", { count: index3 + 1 })), qResult.isCorrect ? /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-green-600 font-medium flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.passed")) : /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-destructive font-medium flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.failed"))), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.yourAnswer")), " ", getAnswerDisplay(qResult.userAnswer)), !qResult.isCorrect && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.correctAnswer")), " ", getAnswerDisplay(qResult.correctAnswer)), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.pointsEarned")), " ", qResult.pointsEarned), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.timeSpent")), " ", qResult.timeSpentSeconds?.toFixed(0) ?? "N/A", t4("practiceFlow.results.timeUnit")))))))))), /* @__PURE__ */ React169__namespace.default.createElement(CardFooter, { className: "flex flex-col sm:flex-row justify-between gap-2" }, onExitQuiz && /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline", onClick: onExitQuiz, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(LogOut, { className: "mr-2 h-4 w-4" }), t4("common.exit")), showReviewButton && onGenerateReview && /* @__PURE__ */ React169__namespace.default.createElement(
96973
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "w-full max-w-3xl mx-auto shadow-xl" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-3xl font-headline text-center" }, t4("practiceFlow.results.title", { quizTitle })), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, { className: "text-center text-lg" }, t4("practiceFlow.results.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-6" }, /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "bg-secondary/50" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-xl flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(BarChart2, { className: "mr-2 h-5 w-5 text-primary" }), t4("practiceFlow.results.overallScore"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "grid grid-cols-1 md:grid-cols-3 gap-4 text-center" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.score, " / ", result.maxScore), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.points"))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.percentage.toFixed(2), "%"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.percentage"))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, result.passed !== void 0 && (result.passed ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col items-center text-green-600" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "h-10 w-10" }), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.passed"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col items-center text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "h-10 w-10" }), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.failed"))))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 text-sm" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement(Clock, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__namespace.default.createElement("span", null, t4("practiceFlow.results.timeSpent")), /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold" }, result.totalTimeSpentSeconds?.toFixed(0) ?? "N/A", " ", t4("practiceFlow.results.timeUnit"))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement(Percent, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__namespace.default.createElement("span", null, t4("practiceFlow.results.avgTimePerQuestion")), /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold" }, result.averageTimePerQuestionSeconds?.toFixed(1) ?? "N/A", " ", t4("practiceFlow.results.timeUnit")))), result.scormStatus && result.scormStatus !== "idle" && result.scormStatus !== "no_api" && /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-lg" }, "SCORM Sync Status")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: `flex items-center ${result.scormStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.scormStatus === "error" && /* @__PURE__ */ React169__namespace.default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold ml-1" }, result.scormStatus)), result.scormError && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.scormError))), result.webhookStatus && result.webhookStatus !== "idle" && /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-lg" }, "Webhook Sync Status")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: `flex items-center ${result.webhookStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.webhookStatus === "error" && /* @__PURE__ */ React169__namespace.default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold ml-1" }, result.webhookStatus)), result.webhookError && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.webhookError))), /* @__PURE__ */ React169__namespace.default.createElement(Accordion2, { type: "single", collapsible: true, className: "w-full" }, /* @__PURE__ */ React169__namespace.default.createElement(AccordionItem2, { value: "question-breakdown" }, /* @__PURE__ */ React169__namespace.default.createElement(AccordionTrigger2, { className: "text-lg font-semibold" }, t4("practiceFlow.results.questionBreakdown")), /* @__PURE__ */ React169__namespace.default.createElement(AccordionContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[300px] pr-4" }, /* @__PURE__ */ React169__namespace.default.createElement("ul", { className: "space-y-4" }, result.questionResults.map((qResult, index3) => /* @__PURE__ */ React169__namespace.default.createElement("li", { key: qResult.questionId, className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold" }, t4("common.questions", { count: index3 + 1 })), qResult.isCorrect ? /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-green-600 font-Medium flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.passed")) : /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-destructive font-Medium flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.failed"))), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.yourAnswer")), " ", getAnswerDisplay(qResult.userAnswer)), !qResult.isCorrect && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.correctAnswer")), " ", getAnswerDisplay(qResult.correctAnswer)), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.pointsEarned")), " ", qResult.pointsEarned), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.timeSpent")), " ", qResult.timeSpentSeconds?.toFixed(0) ?? "N/A", t4("practiceFlow.results.timeUnit")))))))))), /* @__PURE__ */ React169__namespace.default.createElement(CardFooter, { className: "flex flex-col sm:flex-row justify-between gap-2" }, onExitQuiz && /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline", onClick: onExitQuiz, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(LogOut, { className: "mr-2 h-4 w-4" }), t4("common.exit")), showReviewButton && onGenerateReview && /* @__PURE__ */ React169__namespace.default.createElement(
96974
96974
  Button,
96975
96975
  {
96976
96976
  onClick: onGenerateReview,
@@ -97285,7 +97285,7 @@ var QuizDataManagement = ({ onQuizLoad, currentQuiz }) => {
97285
97285
  });
97286
97286
  }
97287
97287
  };
97288
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "w-full shadow-lg" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, null, "Quiz Data Management"), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, "Import a quiz from a JSON file or export the current quiz configuration.")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col gap-2 mb-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "quiz-file-input", className: "text-sm font-medium" }, "Import Quiz (JSON)"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React169__namespace.default.createElement(
97288
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "w-full shadow-lg" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, null, "Quiz Data Management"), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, "Import a quiz from a JSON file or export the current quiz configuration.")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col gap-2 mb-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "quiz-file-input", className: "text-sm font-Medium" }, "Import Quiz (JSON)"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React169__namespace.default.createElement(
97289
97289
  Input,
97290
97290
  {
97291
97291
  id: "quiz-file-input",
@@ -97293,7 +97293,7 @@ var QuizDataManagement = ({ onQuizLoad, currentQuiz }) => {
97293
97293
  accept: ".json",
97294
97294
  ref: fileInputRef,
97295
97295
  onChange: handleFileChange,
97296
- className: "w-full h-10 px-3 py-2 border border-input bg-background text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
97296
+ className: "w-full h-10 px-3 py-2 border border-input bg-background text-sm file:border-0 file:bg-transparent file:text-sm file:font-Medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
97297
97297
  }
97298
97298
  ))), error && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-destructive flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleAlert, { className: "mr-1 h-4 w-4" }), " ", error)), /* @__PURE__ */ React169__namespace.default.createElement(CardFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleExportQuiz, disabled: !currentQuiz, variant: "outline" }, /* @__PURE__ */ React169__namespace.default.createElement(Download, { className: "mr-2 h-4 w-4" }), " Export Current Quiz")));
97299
97299
  };
@@ -97728,6 +97728,7 @@ var Close = DialogClose;
97728
97728
 
97729
97729
  // src/react-ui/components/elements/dialog.tsx
97730
97730
  var Dialog2 = Root10;
97731
+ var DialogTrigger2 = Trigger4;
97731
97732
  var DialogPortal2 = Portal3;
97732
97733
  var DialogClose2 = Close;
97733
97734
  var DialogOverlay2 = React169__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React169__namespace.createElement(
@@ -97926,7 +97927,7 @@ var CommandGroup = React169__namespace.forwardRef(({ className, ...props }, ref)
97926
97927
  {
97927
97928
  ref,
97928
97929
  className: cn(
97929
- "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
97930
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-Medium [&_[cmdk-group-heading]]:text-muted-foreground",
97930
97931
  className
97931
97932
  ),
97932
97933
  ...props
@@ -98327,7 +98328,7 @@ var TrueFalseQuestionForm = ({ question: question2, onFormChange }) => {
98327
98328
  const handleCorrectAnswerChange = (value) => {
98328
98329
  onFormChange({ correctAnswer: value === "true" });
98329
98330
  };
98330
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "True/False Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Correct Answer"), /* @__PURE__ */ React169__namespace.default.createElement(
98331
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "True/False Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Correct Answer"), /* @__PURE__ */ React169__namespace.default.createElement(
98331
98332
  RadioGroup2,
98332
98333
  {
98333
98334
  value: question2.correctAnswer ? "true" : "false",
@@ -98364,7 +98365,7 @@ var MultipleChoiceQuestionForm = ({ question: question2, onFormChange }) => {
98364
98365
  const handleCorrectAnswerChange = (optionId) => {
98365
98366
  onFormChange({ correctAnswerId: optionId });
98366
98367
  };
98367
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Multiple Choice Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Options"), question2.options.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__namespace.default.createElement(
98368
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Multiple Choice Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Options"), question2.options.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__namespace.default.createElement(
98368
98369
  RadioGroup2,
98369
98370
  {
98370
98371
  value: question2.correctAnswerId,
@@ -98426,7 +98427,7 @@ var MultipleResponseQuestionForm = ({ question: question2, onFormChange }) => {
98426
98427
  const newCorrectAnswerIds = question2.correctAnswerIds.filter((id3) => id3 !== optionIdToDelete);
98427
98428
  onFormChange({ options: newOptions, correctAnswerIds: newCorrectAnswerIds });
98428
98429
  };
98429
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Multiple Response Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Options (Select all correct answers)"), question2.options.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 mt-2" }, question2.options.map((option, index3) => (
98430
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Multiple Response Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Options (Select all correct answers)"), question2.options.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 mt-2" }, question2.options.map((option, index3) => (
98430
98431
  // *** CHANGED: Adjusted layout for SimpleMarkdownEditor ***
98431
98432
  /* @__PURE__ */ React169__namespace.default.createElement("div", { key: option.id, className: "flex items-start space-x-2 p-2 border rounded-md bg-background hover:shadow-sm" }, /* @__PURE__ */ React169__namespace.default.createElement(
98432
98433
  Checkbox2,
@@ -98648,7 +98649,7 @@ var ShortAnswerQuestionForm = ({ question: question2, onFormChange }) => {
98648
98649
  const toggleCaseSensitive = (checked) => {
98649
98650
  onFormChange({ isCaseSensitive: checked });
98650
98651
  };
98651
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Short Answer Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Accepted Answers"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Enter all valid plain text answers. The system will check against these."), question2.acceptedAnswers.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No accepted answers defined yet."), question2.acceptedAnswers.map((answer, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: index3, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
98652
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Short Answer Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Accepted Answers"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Enter all valid plain text answers. The system will check against these."), question2.acceptedAnswers.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No accepted answers defined yet."), question2.acceptedAnswers.map((answer, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: index3, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
98652
98653
  Input,
98653
98654
  {
98654
98655
  type: "text",
@@ -98698,7 +98699,7 @@ var NumericQuestionForm = ({ question: question2, onFormChange }) => {
98698
98699
  onFormChange({ tolerance: numValue });
98699
98700
  }
98700
98701
  };
98701
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Numeric Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `num-answer-${question2.id}` }, "Correct Numerical Answer"), /* @__PURE__ */ React169__namespace.default.createElement(
98702
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Numeric Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `num-answer-${question2.id}` }, "Correct Numerical Answer"), /* @__PURE__ */ React169__namespace.default.createElement(
98702
98703
  Input,
98703
98704
  {
98704
98705
  id: `num-answer-${question2.id}`,
@@ -98811,7 +98812,7 @@ var FillInTheBlanksQuestionForm = ({ question: question2, onFormChange }) => {
98811
98812
  const toggleCaseSensitive = (checked) => {
98812
98813
  onFormChange({ isCaseSensitive: checked });
98813
98814
  };
98814
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Fill In The Blanks Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Question Segments"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Construct the question by adding text and blank segments. The prompt in the main editor will be shown above these segments."), question2.segments.map((segment, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: `segment-${index3}`, className: "flex items-start space-x-2 mt-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-grow space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-xs font-medium capitalize text-muted-foreground" }, segment.type, " Segment ", index3 + 1), segment.type === "text" ? (
98815
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Fill In The Blanks Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Question Segments"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Construct the question by adding text and blank segments. The prompt in the main editor will be shown above these segments."), question2.segments.map((segment, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: `segment-${index3}`, className: "flex items-start space-x-2 mt-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-grow space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-xs font-Medium capitalize text-muted-foreground" }, segment.type, " Segment ", index3 + 1), segment.type === "text" ? (
98815
98816
  // *** CHANGED: Replaced Textarea with SimpleMarkdownEditor ***
98816
98817
  /* @__PURE__ */ React169__namespace.default.createElement(
98817
98818
  SimpleMarkdownEditor,
@@ -98884,7 +98885,7 @@ var SequenceQuestionForm = ({ question: question2, onFormChange }) => {
98884
98885
  }
98885
98886
  return htmlString.replace(/<[^>]*>?/gm, "");
98886
98887
  };
98887
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Sequence Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Sequence Items"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Define all items that need to be put in order. Users will arrange these."), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 mt-2" }, question2.items.map((item, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: item.id, className: "flex items-start space-x-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-grow" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "text-xs font-medium text-muted-foreground" }, "Item ", index3 + 1), /* @__PURE__ */ React169__namespace.default.createElement(
98888
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Sequence Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Sequence Items"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Define all items that need to be put in order. Users will arrange these."), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 mt-2" }, question2.items.map((item, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: item.id, className: "flex items-start space-x-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-grow" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "text-xs font-Medium text-muted-foreground" }, "Item ", index3 + 1), /* @__PURE__ */ React169__namespace.default.createElement(
98888
98889
  SimpleMarkdownEditor,
98889
98890
  {
98890
98891
  value: item.content,
@@ -98987,7 +98988,7 @@ var MatchingQuestionForm = ({ question: question2, onFormChange }) => {
98987
98988
  }
98988
98989
  return htmlString.replace(/<[^>]*>?/gm, "");
98989
98990
  };
98990
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Matching Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Prompts (Items to be matched)"), question2.prompts.map((promptItem, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: promptItem.id, className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "text-xs text-muted-foreground" }, "Prompt ", index3 + 1), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeletePrompt(index3), className: "h-7 w-7 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__namespace.default.createElement(
98991
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Matching Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Prompts (Items to be matched)"), question2.prompts.map((promptItem, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: promptItem.id, className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "text-xs text-muted-foreground" }, "Prompt ", index3 + 1), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeletePrompt(index3), className: "h-7 w-7 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__namespace.default.createElement(
98991
98992
  SimpleMarkdownEditor,
98992
98993
  {
98993
98994
  value: promptItem.content,
@@ -99077,7 +99078,7 @@ var DragAndDropQuestionForm = ({ question: question2, onFormChange }) => {
99077
99078
  }
99078
99079
  return htmlString.replace(/<[^>]*>?/gm, "");
99079
99080
  };
99080
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Drag and Drop Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `dnd-bgimage-${question2.id}` }, "Background Image URL (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(
99081
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Drag and Drop Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `dnd-bgimage-${question2.id}` }, "Background Image URL (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(
99081
99082
  Input,
99082
99083
  {
99083
99084
  id: `dnd-bgimage-${question2.id}`,
@@ -99164,7 +99165,7 @@ var HotspotQuestionForm = ({ question: question2, onFormChange }) => {
99164
99165
  }
99165
99166
  onFormChange({ correctHotspotIds: newCorrectIds });
99166
99167
  };
99167
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Hotspot Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `hs-imageurl-${question2.id}` }, "Image URL"), /* @__PURE__ */ React169__namespace.default.createElement(
99168
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Hotspot Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `hs-imageurl-${question2.id}` }, "Image URL"), /* @__PURE__ */ React169__namespace.default.createElement(
99168
99169
  Input,
99169
99170
  {
99170
99171
  id: `hs-imageurl-${question2.id}`,
@@ -99182,7 +99183,7 @@ var HotspotQuestionForm = ({ question: question2, onFormChange }) => {
99182
99183
  onChange: (e3) => onFormChange({ imageAltText: e3.target.value || void 0 }),
99183
99184
  placeholder: "Describe the image"
99184
99185
  }
99185
- )), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Hotspot Areas"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Define clickable areas on the image. Coordinates are relative to the image's top-left corner."), question2.hotspots.map((hotspot, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: hotspot.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-medium" }, "Hotspot ", index3 + 1, " (ID: ", hotspot.id, ")"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteHotspot(index3), className: "h-8 w-8 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `hs-shape-${hotspot.id}`, className: "text-xs" }, "Shape"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: hotspot.shape, onValueChange: (value) => handleHotspotChange(index3, "shape", value) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: `hs-shape-${hotspot.id}` }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "rect" }, "Rectangle"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "circle" }, "Circle")))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `hs-coords-${hotspot.id}`, className: "text-xs" }, hotspot.shape === "rect" ? "Coords (x, y, width, height)" : "Coords (centerX, centerY, radius)"), /* @__PURE__ */ React169__namespace.default.createElement(
99186
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Hotspot Areas"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, "Define clickable areas on the image. Coordinates are relative to the image's top-left corner."), question2.hotspots.map((hotspot, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: hotspot.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-Medium" }, "Hotspot ", index3 + 1, " (ID: ", hotspot.id, ")"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteHotspot(index3), className: "h-8 w-8 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `hs-shape-${hotspot.id}`, className: "text-xs" }, "Shape"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: hotspot.shape, onValueChange: (value) => handleHotspotChange(index3, "shape", value) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: `hs-shape-${hotspot.id}` }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "rect" }, "Rectangle"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "circle" }, "Circle")))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `hs-coords-${hotspot.id}`, className: "text-xs" }, hotspot.shape === "rect" ? "Coords (x, y, width, height)" : "Coords (centerX, centerY, radius)"), /* @__PURE__ */ React169__namespace.default.createElement(
99186
99187
  Input,
99187
99188
  {
99188
99189
  id: `hs-coords-${hotspot.id}`,
@@ -99214,7 +99215,7 @@ var BlocklyProgrammingQuestionForm = ({ question: question2, onFormChange }) =>
99214
99215
  const handleFieldChange = (field, value) => {
99215
99216
  onFormChange({ [field]: value });
99216
99217
  };
99217
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Blockly Programming Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `blockly-toolbox-${question2.id}` }, "Toolbox Definition (XML)"), /* @__PURE__ */ React169__namespace.default.createElement(
99218
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Blockly Programming Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `blockly-toolbox-${question2.id}` }, "Toolbox Definition (XML)"), /* @__PURE__ */ React169__namespace.default.createElement(
99218
99219
  Textarea,
99219
99220
  {
99220
99221
  id: `blockly-toolbox-${question2.id}`,
@@ -99263,7 +99264,7 @@ var ScratchProgrammingQuestionForm = ({ question: question2, onFormChange }) =>
99263
99264
  const handleFieldChange = (field, value) => {
99264
99265
  onFormChange({ [field]: value });
99265
99266
  };
99266
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Scratch Programming Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "scratch-toolbox-" + question2.id }, "Toolbox Definition (XML for Blockly)"), /* @__PURE__ */ React169__namespace.default.createElement(
99267
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Scratch Programming Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "scratch-toolbox-" + question2.id }, "Toolbox Definition (XML for Blockly)"), /* @__PURE__ */ React169__namespace.default.createElement(
99267
99268
  Textarea,
99268
99269
  {
99269
99270
  id: "scratch-toolbox-" + question2.id,
@@ -99340,7 +99341,7 @@ var CodingQuestionForm = ({ question: question2, onFormChange }) => {
99340
99341
  const newTestCases = question2.testCases.filter((_2, i2) => i2 !== index3);
99341
99342
  onFormChange({ testCases: newTestCases });
99342
99343
  };
99343
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-medium text-md" }, "Coding Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `coding-lang-${question2.id}` }, "Programming Language"), /* @__PURE__ */ React169__namespace.default.createElement(
99344
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-Medium text-md" }, "Coding Question Specifics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `coding-lang-${question2.id}` }, "Programming Language"), /* @__PURE__ */ React169__namespace.default.createElement(
99344
99345
  Select2,
99345
99346
  {
99346
99347
  value: question2.codingLanguage,
@@ -99366,7 +99367,7 @@ var CodingQuestionForm = ({ question: question2, onFormChange }) => {
99366
99367
  placeholder: "Enter the complete, correct code solution here.",
99367
99368
  className: "min-h-[200px] font-mono text-xs"
99368
99369
  }
99369
- )), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Test Cases"), question2.testCases.map((tc, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: tc.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-medium" }, "Test Case ", index3 + 1), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteTestCase(index3), className: "h-8 w-8 text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `tc-input-${tc.id}`, className: "text-xs" }, "Input (JSON Array)"), /* @__PURE__ */ React169__namespace.default.createElement(
99370
+ )), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Test Cases"), question2.testCases.map((tc, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: tc.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-Medium" }, "Test Case ", index3 + 1), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteTestCase(index3), className: "h-8 w-8 text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `tc-input-${tc.id}`, className: "text-xs" }, "Input (JSON Array)"), /* @__PURE__ */ React169__namespace.default.createElement(
99370
99371
  Input,
99371
99372
  {
99372
99373
  id: `tc-input-${tc.id}`,
@@ -99534,7 +99535,7 @@ var EditQuestionModal = ({
99534
99535
  if (!isOpen || !editedQuestion) return null;
99535
99536
  return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => {
99536
99537
  if (!open) onClose();
99537
- } }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-[600px] md:max-w-[800px] lg:max-w-[1000px] max-h-[90vh]" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, { className: "font-headline text-2xl" }, questionData?.id && !questionData.id.startsWith("new_") && !questionData.id.startsWith("temp_") ? "Edit Question" : "Add New Question"), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, "Configure the details for this question. Current type:", " ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold" }, editedQuestion.questionType))), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "max-h-[calc(80vh-150px)] p-1 pr-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "prompt", className: "font-semibold" }, "Question Prompt"), /* @__PURE__ */ React169__namespace.default.createElement(SimpleMarkdownEditor, { value: editedQuestion.prompt, onChange: (htmlContent) => handleSpecificFieldChange({ prompt: htmlContent }) })), renderSpecificForm(), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "points" }, "Points"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "points", type: "number", value: editedQuestion.points || 0, onChange: (e3) => handleSpecificFieldChange({ points: parseInt(e3.target.value, 10) || 0 }), min: "0" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "difficulty" }, "Difficulty"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: editedQuestion.difficulty || "medium", onValueChange: (value) => handleSpecificFieldChange({ difficulty: value }) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "easy" }, "Easy"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "medium" }, "Medium"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "hard" }, "Hard"))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "explanation" }, "Explanation (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(SimpleMarkdownEditor, { value: editedQuestion.explanation || "", onChange: (htmlContent) => handleSpecificFieldChange({ explanation: htmlContent }), minHeight: "100px" })), /* @__PURE__ */ React169__namespace.default.createElement("details", { className: "group", open: hasDropdownMetadata }, /* @__PURE__ */ React169__namespace.default.createElement("summary", { className: "cursor-pointer font-semibold text-primary hover:underline" }, "Advanced Metadata (Optional)"), renderMetadataFields()))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, { className: "pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", onClick: handleSaveClick }, /* @__PURE__ */ React169__namespace.default.createElement(Save, { className: "mr-2 h-4 w-4" }), " Save Question"))));
99538
+ } }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-[600px] md:max-w-[800px] lg:max-w-[1000px] max-h-[90vh]" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, { className: "font-headline text-2xl" }, questionData?.id && !questionData.id.startsWith("new_") && !questionData.id.startsWith("temp_") ? "Edit Question" : "Add New Question"), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, "Configure the details for this question. Current type:", " ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-semibold" }, editedQuestion.questionType))), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "max-h-[calc(80vh-150px)] p-1 pr-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6 p-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "prompt", className: "font-semibold" }, "Question Prompt"), /* @__PURE__ */ React169__namespace.default.createElement(SimpleMarkdownEditor, { value: editedQuestion.prompt, onChange: (htmlContent) => handleSpecificFieldChange({ prompt: htmlContent }) })), renderSpecificForm(), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "points" }, "Points"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "points", type: "number", value: editedQuestion.points || 0, onChange: (e3) => handleSpecificFieldChange({ points: parseInt(e3.target.value, 10) || 0 }), min: "0" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "difficulty" }, "Difficulty"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: editedQuestion.difficulty || "Medium", onValueChange: (value) => handleSpecificFieldChange({ difficulty: value }) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "Easy" }, "Easy"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "Medium" }, "Medium"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "Hard" }, "Hard"))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "explanation" }, "Explanation (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(SimpleMarkdownEditor, { value: editedQuestion.explanation || "", onChange: (htmlContent) => handleSpecificFieldChange({ explanation: htmlContent }), minHeight: "100px" })), /* @__PURE__ */ React169__namespace.default.createElement("details", { className: "group", open: hasDropdownMetadata }, /* @__PURE__ */ React169__namespace.default.createElement("summary", { className: "cursor-pointer font-semibold text-primary hover:underline" }, "Advanced Metadata (Optional)"), renderMetadataFields()))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, { className: "pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", onClick: handleSaveClick }, /* @__PURE__ */ React169__namespace.default.createElement(Save, { className: "mr-2 h-4 w-4" }), " Save Question"))));
99538
99539
  };
99539
99540
 
99540
99541
  // src/react-ui/components/authoring/AIQuestionGeneratorModal.tsx
@@ -99684,12 +99685,12 @@ var QuizContextSchema = zod.z.object({
99684
99685
  originalSubject: zod.z.string().optional(),
99685
99686
  originalCategory: zod.z.string().optional(),
99686
99687
  originalTopic: zod.z.string().optional(),
99687
- loDescription: zod.z.string().optional().describe("The full description of the learning objective for deep context."),
99688
+ description: zod.z.string().optional().describe("The full description of the learning objective for deep context."),
99688
99689
  gradeBand: zod.z.string().optional()
99689
99690
  });
99690
99691
  var BaseQuestionGenerationClientInputSchema = zod.z.object({
99691
99692
  language: zod.z.string().optional().default("English"),
99692
- difficulty: zod.z.enum(["easy", "medium", "hard"]),
99693
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]),
99693
99694
  quizContext: QuizContextSchema.optional(),
99694
99695
  imageUrl: zod.z.string().url().optional().describe("Optional URL of an image to be used as context.")
99695
99696
  });
@@ -99698,7 +99699,7 @@ var BaseQuestionZodSchema = zod.z.object({
99698
99699
  prompt: zod.z.string().min(1),
99699
99700
  points: zod.z.number().min(0).optional(),
99700
99701
  explanation: zod.z.string().optional(),
99701
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
99702
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
99702
99703
  topic: zod.z.string().optional(),
99703
99704
  category: zod.z.string().optional(),
99704
99705
  subject: zod.z.string().optional(),
@@ -99794,7 +99795,7 @@ var AITrueFalseOutputFieldsSchema = zod.z.object({
99794
99795
  correctAnswer: zod.z.boolean(),
99795
99796
  explanation: zod.z.string().optional().describe("An explanation of why the statement is true or false, especially important if false."),
99796
99797
  points: zod.z.number().optional().default(10),
99797
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
99798
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
99798
99799
  topic: zod.z.string().optional(),
99799
99800
  verifiedCategory: zod.z.string().optional()
99800
99801
  // Thêm để xác thực
@@ -99815,7 +99816,7 @@ Previous attempts failed. Ensure the JSON is valid and 'correctAnswer' is a bool
99815
99816
  const misconceptionGuidance = quizContext?.targetMisconception ? `**Target Misconception:** The statement you create MUST be FALSE and based on this common mistake: "${quizContext.targetMisconception}"` : "";
99816
99817
  const contextStrings = [
99817
99818
  `**Required Category:** ${category}`,
99818
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
99819
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
99819
99820
  imageContextInstruction,
99820
99821
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
99821
99822
  misconceptionGuidance,
@@ -99826,7 +99827,7 @@ Previous attempts failed. Ensure the JSON is valid and 'correctAnswer' is a bool
99826
99827
  correctAnswer: true,
99827
99828
  explanation: "Optional values in Swift represent the presence or absence of a value. To access the value when it exists, you must unwrap it using methods like 'if let', 'guard let', or the force unwrap operator '!'.",
99828
99829
  points: 10,
99829
- difficulty: "easy",
99830
+ difficulty: "Easy",
99830
99831
  topic: "Swift Optionals",
99831
99832
  verifiedCategory: category
99832
99833
  }, null, 2);
@@ -99962,7 +99963,7 @@ var AIMCQOutputFieldsSchema = zod.z.object({
99962
99963
  correctTempOptionId: zod.z.string().describe("The temporary ID of the correct option from the generated options array."),
99963
99964
  explanation: zod.z.string().optional().describe("A brief explanation of why the answer is correct."),
99964
99965
  points: zod.z.number().optional().default(10),
99965
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
99966
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
99966
99967
  topic: zod.z.string().optional(),
99967
99968
  verifiedCategory: zod.z.string().optional().describe("The category this question actually addresses.")
99968
99969
  });
@@ -99981,7 +99982,7 @@ Previous attempts failed...
99981
99982
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and options must be directly related to the content of this image.` : "";
99982
99983
  const contextStrings = [
99983
99984
  `**Required Category:** ${category}`,
99984
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
99985
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
99985
99986
  imageContextInstruction,
99986
99987
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
99987
99988
  quizContext?.targetMisconception && `**Target Misconception:** Use this to create plausible incorrect answers: "${quizContext.targetMisconception}"`,
@@ -99998,7 +99999,7 @@ Previous attempts failed...
99998
99999
  correctTempOptionId: "C",
99999
100000
  explanation: `The 'guard' statement in ${category} provides an early exit from a scope (like a function) if a condition is false, enhancing code readability by handling required conditions upfront.`,
100000
100001
  points: 10,
100001
- difficulty: "easy",
100002
+ difficulty: "Easy",
100002
100003
  topic: `Control Flow in ${category}`,
100003
100004
  verifiedCategory: category
100004
100005
  }, null, 2);
@@ -100146,7 +100147,7 @@ var AIMRQOutputFieldsSchema = zod.z.object({
100146
100147
  correctTempOptionIds: zod.z.array(zod.z.string()).min(1),
100147
100148
  explanation: zod.z.string().optional(),
100148
100149
  points: zod.z.number().optional().default(10),
100149
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
100150
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
100150
100151
  topic: zod.z.string().optional(),
100151
100152
  verifiedCategory: zod.z.string().optional().describe("The category this question actually addresses.")
100152
100153
  });
@@ -100165,7 +100166,7 @@ Previous attempts failed due to validation errors. Pay close attention to the nu
100165
100166
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and options must be directly related to the content of this image.` : "";
100166
100167
  const contextStrings = [
100167
100168
  `**Required Category:** ${category} (This is the ONLY language to be used)`,
100168
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100169
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100169
100170
  imageContextInstruction,
100170
100171
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100171
100172
  quizContext?.targetMisconception && `**Target Misconception:** Use this to create plausible incorrect answers (distractors). The misconception is: "${quizContext.targetMisconception}"`,
@@ -100183,7 +100184,7 @@ Previous attempts failed due to validation errors. Pay close attention to the nu
100183
100184
  correctTempOptionIds: ["A", "C", "D"],
100184
100185
  explanation: "Object-Oriented, Functional, and Procedural are all major programming paradigms. Assembly is a low-level language, and Middleware is a type of software, not a paradigm.",
100185
100186
  points: 10,
100186
- difficulty: "medium",
100187
+ difficulty: "Medium",
100187
100188
  topic: "Programming Paradigms",
100188
100189
  verifiedCategory: category
100189
100190
  }, null, 2);
@@ -100347,7 +100348,7 @@ var AIShortAnswerOutputFieldsSchema = zod.z.object({
100347
100348
  // isCaseSensitive không cần thiết ở đây, chúng ta sẽ quản lý nó ở phía client
100348
100349
  explanation: zod.z.string().optional(),
100349
100350
  points: zod.z.number().optional().default(10),
100350
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
100351
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
100351
100352
  topic: zod.z.string().optional(),
100352
100353
  verifiedCategory: zod.z.string().optional()
100353
100354
  // Thêm để xác thực
@@ -100367,7 +100368,7 @@ Previous attempts failed. Ensure 'acceptedAnswers' is a non-empty array of strin
100367
100368
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and its short answer must be directly related to the content of this image.` : "";
100368
100369
  const contextStrings = [
100369
100370
  `**Required Category:** ${category}`,
100370
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100371
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100371
100372
  imageContextInstruction,
100372
100373
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100373
100374
  quizContext?.targetMisconception && `**Target Misconception:** The question should require an answer that corrects this specific misconception: "${quizContext.targetMisconception}"`
@@ -100377,7 +100378,7 @@ Previous attempts failed. Ensure 'acceptedAnswers' is a non-empty array of strin
100377
100378
  acceptedAnswers: ["let"],
100378
100379
  explanation: "The 'let' keyword is used to declare constants, which are values that cannot be changed after they are set. 'var' is used for variables.",
100379
100380
  points: 10,
100380
- difficulty: "easy",
100381
+ difficulty: "Easy",
100381
100382
  topic: "Swift Constants",
100382
100383
  verifiedCategory: category
100383
100384
  }, null, 2);
@@ -100510,7 +100511,7 @@ var AINumericOutputFieldsSchema = zod.z.object({
100510
100511
  tolerance: zod.z.number().min(0).optional(),
100511
100512
  explanation: zod.z.string().optional(),
100512
100513
  points: zod.z.number().optional().default(10),
100513
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
100514
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
100514
100515
  topic: zod.z.string().optional(),
100515
100516
  verifiedCategory: zod.z.string().optional()
100516
100517
  // Thêm để xác thực
@@ -100530,7 +100531,7 @@ Previous attempts failed. Ensure the 'answer' is a valid number and fits within
100530
100531
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and its numerical answer must be directly related to the content of this image.` : "";
100531
100532
  const contextStrings = [
100532
100533
  `**Required Category:** ${category}`,
100533
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100534
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100534
100535
  imageContextInstruction,
100535
100536
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100536
100537
  quizContext?.targetMisconception && `**Target Misconception:** The question should clarify this numerical error: "${quizContext.targetMisconception}"`
@@ -100546,7 +100547,7 @@ Previous attempts failed. Ensure the 'answer' is a valid number and fits within
100546
100547
  tolerance: 0,
100547
100548
  explanation: "An Int8 uses 8 bits. One bit is for the sign, leaving 7 bits for the value. The range is from -128 to 127 (2^7 - 1).",
100548
100549
  points: 10,
100549
- difficulty: "medium",
100550
+ difficulty: "Medium",
100550
100551
  topic: "Swift Data Types",
100551
100552
  verifiedCategory: category
100552
100553
  }, null, 2);
@@ -100696,7 +100697,7 @@ var AIFillInTheBlanksOutputFieldsSchema = zod.z.object({
100696
100697
  })).min(1).describe("An array of text and blank segments representing the question."),
100697
100698
  explanation: zod.z.string().optional(),
100698
100699
  points: zod.z.number().optional().default(10),
100699
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
100700
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
100700
100701
  topic: zod.z.string().optional(),
100701
100702
  verifiedCategory: zod.z.string().optional()
100702
100703
  // Thêm để xác thực
@@ -100716,7 +100717,7 @@ Previous attempts failed. Pay strict attention to the JSON schema, especially th
100716
100717
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and blanks must be directly related to the content of this image.` : "";
100717
100718
  const contextStrings = [
100718
100719
  `**Required Category:** ${category}`,
100719
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100720
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100720
100721
  imageContextInstruction,
100721
100722
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100722
100723
  quizContext?.targetMisconception && `**Target Misconception:** Design the blank to test this specific point: "${quizContext.targetMisconception}"`
@@ -100730,7 +100731,7 @@ Previous attempts failed. Pay strict attention to the JSON schema, especially th
100730
100731
  ],
100731
100732
  explanation: "The 'func' keyword is used to declare a function in the Swift programming language.",
100732
100733
  points: 10,
100733
- difficulty: "easy",
100734
+ difficulty: "Easy",
100734
100735
  topic: "Swift Function Declaration",
100735
100736
  verifiedCategory: category
100736
100737
  }, null, 2);
@@ -100884,7 +100885,7 @@ var AISequenceOutputFieldsSchema = zod.z.object({
100884
100885
  itemsInCorrectOrder: zod.z.array(zod.z.string().min(1)).min(2).describe("An array of strings, with each string representing an item to be sequenced. The array itself MUST be in the correct final order."),
100885
100886
  explanation: zod.z.string().optional(),
100886
100887
  points: zod.z.number().optional().default(10),
100887
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
100888
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
100888
100889
  topic: zod.z.string().optional(),
100889
100890
  verifiedCategory: zod.z.string().optional()
100890
100891
  // Thêm để xác thực
@@ -100904,7 +100905,7 @@ Previous attempts failed. Ensure the 'itemsInCorrectOrder' array has exactly the
100904
100905
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The sequence of items must be directly related to the process or content shown in this image.` : "";
100905
100906
  const contextStrings = [
100906
100907
  `**Required Category:** ${category}`,
100907
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100908
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100908
100909
  imageContextInstruction,
100909
100910
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100910
100911
  quizContext?.targetMisconception && `**Target Misconception:** The sequence should clarify this specific process error: "${quizContext.targetMisconception}"`
@@ -100919,7 +100920,7 @@ Previous attempts failed. Ensure the 'itemsInCorrectOrder' array has exactly the
100919
100920
  ],
100920
100921
  explanation: "This is the fundamental sequence for a basic data task in URLSession.",
100921
100922
  points: 10,
100922
- difficulty: "medium",
100923
+ difficulty: "Medium",
100923
100924
  topic: "Swift Networking",
100924
100925
  verifiedCategory: category
100925
100926
  }, null, 2);
@@ -101061,7 +101062,7 @@ var AIMatchingOutputFieldsSchema = zod.z.object({
101061
101062
  })).min(2),
101062
101063
  explanation: zod.z.string().optional(),
101063
101064
  points: zod.z.number().optional().default(10),
101064
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
101065
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
101065
101066
  topic: zod.z.string().optional(),
101066
101067
  verifiedCategory: zod.z.string().optional()
101067
101068
  // Thêm để xác thực
@@ -101081,7 +101082,7 @@ Previous attempts failed. Please ensure the 'correctPairs' array has exactly the
101081
101082
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The matching pairs must be directly related to the content of this image.` : "";
101082
101083
  const contextStrings = [
101083
101084
  `**Required Category:** ${category}`,
101084
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
101085
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
101085
101086
  imageContextInstruction,
101086
101087
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
101087
101088
  quizContext?.targetMisconception && `**Target Misconception:** Design a pair that specifically tests this confusion: "${quizContext.targetMisconception}"`
@@ -101095,7 +101096,7 @@ Previous attempts failed. Please ensure the 'correctPairs' array has exactly the
101095
101096
  ],
101096
101097
  explanation: "These are the fundamental characteristics of Swift's main collection types.",
101097
101098
  points: 10,
101098
- difficulty: "easy",
101099
+ difficulty: "Easy",
101099
101100
  topic: "Swift Collection Types",
101100
101101
  verifiedCategory: category
101101
101102
  }, null, 2);
@@ -101311,7 +101312,7 @@ var AIQuestionGeneratorModal = ({
101311
101312
  };
101312
101313
  const baseClientInput = {
101313
101314
  language: language3,
101314
- difficulty: "medium",
101315
+ difficulty: "Medium",
101315
101316
  quizContext
101316
101317
  };
101317
101318
  let generatedResult = {};
@@ -101916,10 +101917,6 @@ init_react_shim();
101916
101917
  // src/services/TopicDataService.ts
101917
101918
  init_react_shim();
101918
101919
  var TopicDataService = class {
101919
- /**
101920
- * Saves an array of LearningObjective objects to Local Storage, overwriting existing data.
101921
- * @param data The array of learning objectives to save.
101922
- */
101923
101920
  static saveData(data) {
101924
101921
  try {
101925
101922
  if (typeof window === "undefined") return;
@@ -101929,24 +101926,15 @@ var TopicDataService = class {
101929
101926
  console.error("Error saving learning objectives to Local Storage:", error);
101930
101927
  }
101931
101928
  }
101932
- /**
101933
- * Merges a new set of learning objectives with the existing data in Local Storage.
101934
- * If an LO ID from newData already exists, it will be updated. Otherwise, it will be added.
101935
- * @param newData The array of new or updated learning objectives.
101936
- */
101937
101929
  static mergeData(newData) {
101938
101930
  const existingData = this.getData();
101939
- const loMap = new Map(existingData.map((lo) => [lo.loId, lo]));
101931
+ const loMap = new Map(existingData.map((lo) => [lo.code, lo]));
101940
101932
  newData.forEach((newLo) => {
101941
- loMap.set(newLo.loId, newLo);
101933
+ loMap.set(newLo.code, newLo);
101942
101934
  });
101943
101935
  const mergedData = Array.from(loMap.values());
101944
101936
  this.saveData(mergedData);
101945
101937
  }
101946
- /**
101947
- * Retrieves the array of LearningObjective objects from Local Storage.
101948
- * @returns An array of learning objectives, or an empty array if none are found or an error occurs.
101949
- */
101950
101938
  static getData() {
101951
101939
  try {
101952
101940
  if (typeof window === "undefined") return [];
@@ -101958,9 +101946,6 @@ var TopicDataService = class {
101958
101946
  return [];
101959
101947
  }
101960
101948
  }
101961
- /**
101962
- * Removes all learning objective data from Local Storage.
101963
- */
101964
101949
  static clearData() {
101965
101950
  try {
101966
101951
  if (typeof window === "undefined") return;
@@ -101969,11 +101954,6 @@ var TopicDataService = class {
101969
101954
  console.error("Error clearing learning objectives from Local Storage:", error);
101970
101955
  }
101971
101956
  }
101972
- /**
101973
- * Parses TSV content into an array of LearningObjective objects.
101974
- * @param tsvContent The raw string content from a .tsv file.
101975
- * @returns An object containing the successfully parsed data and any errors encountered.
101976
- */
101977
101957
  static parseTSV(tsvContent) {
101978
101958
  const lines = tsvContent.split("\n").filter((line) => line.trim() !== "");
101979
101959
  if (lines.length < 2) {
@@ -101995,6 +101975,7 @@ var TopicDataService = class {
101995
101975
  }
101996
101976
  const [
101997
101977
  loId,
101978
+ name3,
101998
101979
  loDescription,
101999
101980
  subject,
102000
101981
  category,
@@ -102004,18 +101985,21 @@ var TopicDataService = class {
102004
101985
  stemElementsStr,
102005
101986
  bloomLevelsStr
102006
101987
  ] = values;
102007
- if (!loId || !subject || !category || !topic) {
102008
- errors2.push(`Line ${index3 + 2}: Missing required fields (LO ID, Subject, Category, or Topic).`);
101988
+ if (!loId || !loDescription || !subject || !category || !topic) {
101989
+ errors2.push(`Line ${index3 + 2}: Missing required fields (LO ID, LO Description, Subject, Category, or Topic).`);
102009
101990
  return;
102010
101991
  }
102011
101992
  const learningObjective = {
102012
- loId,
102013
- loDescription,
101993
+ id: generateUniqueId("lo_"),
101994
+ code: loId,
101995
+ name: name3,
101996
+ description: loDescription,
101997
+ // Can be the same as name or enhanced later
102014
101998
  subject,
102015
101999
  category,
102016
102000
  topic,
102017
- keywords: keywordsStr.split(",").map((k3) => k3.trim()).filter(Boolean),
102018
102001
  grade,
102002
+ keywords: keywordsStr.split(",").map((k3) => k3.trim()).filter(Boolean),
102019
102003
  stemElements: stemElementsStr.split(",").map((s4) => s4.trim()).filter(Boolean),
102020
102004
  bloomLevelsGuideline: bloomLevelsStr.split(",").map((b2) => b2.trim()).filter(Boolean)
102021
102005
  };
@@ -102023,40 +102007,21 @@ var TopicDataService = class {
102023
102007
  });
102024
102008
  return { data, errors: errors2 };
102025
102009
  }
102026
- /**
102027
- * Gets a unique list of all subjects from the stored data.
102028
- * @returns An array of subject strings.
102029
- */
102030
102010
  static getSubjects() {
102031
102011
  const data = this.getData();
102032
102012
  const subjects = data.map((item) => item.subject);
102033
102013
  return [...new Set(subjects)].sort();
102034
102014
  }
102035
- /**
102036
- * Gets a unique list of categories for a given subject.
102037
- * @param subject The subject to filter by.
102038
- * @returns An array of category strings.
102039
- */
102040
102015
  static getCategoriesBySubject(subject) {
102041
102016
  const data = this.getData();
102042
102017
  const categories = data.filter((item) => item.subject === subject).map((item) => item.category);
102043
102018
  return [...new Set(categories)].sort();
102044
102019
  }
102045
- /**
102046
- * Gets a unique list of topics for a given category.
102047
- * @param category The category to filter by.
102048
- * @returns An array of topic strings.
102049
- */
102050
102020
  static getTopicsByCategory(category) {
102051
102021
  const data = this.getData();
102052
102022
  const topics = data.filter((item) => item.category === category).map((item) => item.topic);
102053
102023
  return [...new Set(topics)].sort();
102054
102024
  }
102055
- /**
102056
- * Retrieves all LearningObjective details for a given list of topics.
102057
- * @param topics An array of topic strings to search for.
102058
- * @returns An array of matching LearningObjective objects.
102059
- */
102060
102025
  static getLearningObjectivesByTopics(topics) {
102061
102026
  const data = this.getData();
102062
102027
  const topicSet = new Set(topics);
@@ -102113,7 +102078,7 @@ Previous attempts failed. Pay strict attention to the JSON schema and all rules.
102113
102078
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The coding problem must be directly related to processing or interpreting the content of this image.` : "";
102114
102079
  const contextStrings = [
102115
102080
  `**Subject:** ${subject}`,
102116
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
102081
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
102117
102082
  imageContextInstruction,
102118
102083
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
102119
102084
  quizContext?.targetMisconception && `**Target Misconception:** The problem should test against this common error: "${quizContext.targetMisconception}"`
@@ -102270,9 +102235,9 @@ var calculateCombinedDifficulty = (plannedQ) => {
102270
102235
  break;
102271
102236
  }
102272
102237
  const totalScore = bloomScore + contextScore + questionTypeScore;
102273
- if (totalScore <= 4) return "easy";
102274
- if (totalScore <= 7) return "medium";
102275
- return "hard";
102238
+ if (totalScore <= 4) return "Easy";
102239
+ if (totalScore <= 7) return "Medium";
102240
+ return "Hard";
102276
102241
  };
102277
102242
  async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
102278
102243
  const { quizPlan, language: language3, imageContexts } = clientInput;
@@ -102285,7 +102250,7 @@ async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
102285
102250
  let lastError = null;
102286
102251
  for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
102287
102252
  try {
102288
- const fullLO = plannedQ.originalLoId ? allLearningObjectives.find((lo) => lo.loId === plannedQ.originalLoId) : null;
102253
+ const fullLO = plannedQ.originalLoId ? allLearningObjectives.find((lo) => lo.code === plannedQ.originalLoId) : null;
102289
102254
  const quizContext = {
102290
102255
  plannedTopic: plannedQ.plannedTopic,
102291
102256
  plannedQuestionType: plannedQ.plannedQuestionType,
@@ -102298,7 +102263,7 @@ async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
102298
102263
  originalSubject: plannedQ.originalSubject,
102299
102264
  originalCategory: plannedQ.originalCategory,
102300
102265
  originalTopic: plannedQ.originalTopic,
102301
- loDescription: fullLO?.loDescription || plannedQ.plannedTopic
102266
+ description: fullLO?.description || plannedQ.plannedTopic
102302
102267
  };
102303
102268
  const imageUrl = plannedQ.imageId && imageContexts ? imageContexts.find((ctx) => ctx.id === plannedQ.imageId)?.imageUrl : void 0;
102304
102269
  const baseClientInput = {
@@ -102652,7 +102617,7 @@ var AIFullQuizGeneratorModal = ({
102652
102617
  };
102653
102618
  const renderContent3 = () => {
102654
102619
  if (currentStage === "review") {
102655
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("h3", { className: "text-lg font-medium mb-2 text-primary flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Eye, { className: "mr-2 h-5 w-5" }), " Review & Adjust AI Generated Quiz Plan"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, "The AI has proposed the following plan. You can change question types, reorder, or remove questions before final generation. Note: 'Drag and Drop' type questions in the plan will be created as placeholders and require manual authoring of items/zones/answers."), aiGeneratedPlan && aiGeneratedPlan.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "max-h-[calc(60vh - 120px)] pr-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, aiGeneratedPlan.map((plannedQ, index3) => /* @__PURE__ */ React169__namespace.default.createElement(Card, { key: `planned-${index3}-${plannedQ.plannedTopic.replace(/\s/g, "")}`, className: "p-3" }, /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "p-0 space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold text-sm" }, "Q", index3 + 1, ": ", plannedQ.plannedTopic), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex space-x-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "up"), disabled: index3 === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(ArrowUp, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "down"), disabled: index3 === aiGeneratedPlan.length - 1 }, /* @__PURE__ */ React169__namespace.default.createElement(ArrowDown, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7 text-destructive", onClick: () => handleRemovePlannedQuestion(index3) }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-3 items-end" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `review-qtype-${index3}`, className: "text-xs" }, "Question Type"), /* @__PURE__ */ React169__namespace.default.createElement(
102620
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("h3", { className: "text-lg font-Medium mb-2 text-primary flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Eye, { className: "mr-2 h-5 w-5" }), " Review & Adjust AI Generated Quiz Plan"), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, "The AI has proposed the following plan. You can change question types, reorder, or remove questions before final generation. Note: 'Drag and Drop' type questions in the plan will be created as placeholders and require manual authoring of items/zones/answers."), aiGeneratedPlan && aiGeneratedPlan.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "max-h-[calc(60vh - 120px)] pr-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, aiGeneratedPlan.map((plannedQ, index3) => /* @__PURE__ */ React169__namespace.default.createElement(Card, { key: `planned-${index3}-${plannedQ.plannedTopic.replace(/\s/g, "")}`, className: "p-3" }, /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "p-0 space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold text-sm" }, "Q", index3 + 1, ": ", plannedQ.plannedTopic), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex space-x-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "up"), disabled: index3 === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(ArrowUp, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "down"), disabled: index3 === aiGeneratedPlan.length - 1 }, /* @__PURE__ */ React169__namespace.default.createElement(ArrowDown, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7 text-destructive", onClick: () => handleRemovePlannedQuestion(index3) }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-3 items-end" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `review-qtype-${index3}`, className: "text-xs" }, "Question Type"), /* @__PURE__ */ React169__namespace.default.createElement(
102656
102621
  Select2,
102657
102622
  {
102658
102623
  value: plannedQ.plannedQuestionType,
@@ -102681,7 +102646,7 @@ var AIFullQuizGeneratorModal = ({
102681
102646
  min: "1",
102682
102647
  max: "100"
102683
102648
  }
102684
- )), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-medium px-1" }, "Topic Distribution"), topics.map((topicItem, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: topicItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
102649
+ )), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Topic Distribution"), topics.map((topicItem, index3) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: topicItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
102685
102650
  Input,
102686
102651
  {
102687
102652
  type: "text",
@@ -102701,7 +102666,7 @@ var AIFullQuizGeneratorModal = ({
102701
102666
  min: "0",
102702
102667
  max: "100"
102703
102668
  }
102704
- ), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeTopic(topicItem.id), disabled: topics.length <= 1 }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: addTopic }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic")), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-medium px-1" }, "Bloom Level Distribution"), bloomLevels.map((bloomItem) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: bloomItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "w-32 capitalize flex-shrink-0" }, bloomItem.level), /* @__PURE__ */ React169__namespace.default.createElement(
102669
+ ), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeTopic(topicItem.id), disabled: topics.length <= 1 }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: addTopic }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic")), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Bloom Level Distribution"), bloomLevels.map((bloomItem) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: bloomItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "w-32 capitalize flex-shrink-0" }, bloomItem.level), /* @__PURE__ */ React169__namespace.default.createElement(
102705
102670
  Input,
102706
102671
  {
102707
102672
  type: "number",
@@ -102712,7 +102677,7 @@ var AIFullQuizGeneratorModal = ({
102712
102677
  min: "0",
102713
102678
  max: "100"
102714
102679
  }
102715
- )))), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-medium px-1" }, "Relevant Contexts (Optional, Select Multiple)"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 mt-2 max-h-40 overflow-y-auto" }, contextOptions.filter((opt) => opt.contextId !== "__none__" && opt.contextId !== "__custom__").map((opt) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: opt.contextId, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
102680
+ )))), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Relevant Contexts (Optional, Select Multiple)"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 mt-2 max-h-40 overflow-y-auto" }, contextOptions.filter((opt) => opt.contextId !== "__none__" && opt.contextId !== "__custom__").map((opt) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: opt.contextId, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
102716
102681
  Checkbox2,
102717
102682
  {
102718
102683
  id: `ctx-full-${opt.contextId}`,
@@ -102734,7 +102699,7 @@ var AIFullQuizGeneratorModal = ({
102734
102699
  placeholder: "Enter your specific custom context here...",
102735
102700
  className: "min-h-[60px] mt-2 text-sm"
102736
102701
  }
102737
- )), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-medium px-1" }, "Question Types to Use (Select Multiple)"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 mt-2 max-h-40 overflow-y-auto" }, availableQuestionTypesForFullQuiz.map((qType) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: qType.value, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
102702
+ )), /* @__PURE__ */ React169__namespace.default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Question Types to Use (Select Multiple)"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 mt-2 max-h-40 overflow-y-auto" }, availableQuestionTypesForFullQuiz.map((qType) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: qType.value, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__namespace.default.createElement(
102738
102703
  Checkbox2,
102739
102704
  {
102740
102705
  id: `qtype-full-${qType.value}`,
@@ -103134,7 +103099,7 @@ var AlertTitle = React169__namespace.forwardRef(({ className, ...props }, ref) =
103134
103099
  "h5",
103135
103100
  {
103136
103101
  ref,
103137
- className: cn("mb-1 font-medium leading-none tracking-tight", className),
103102
+ className: cn("mb-1 font-Medium leading-none tracking-tight", className),
103138
103103
  ...props
103139
103104
  }
103140
103105
  ));
@@ -103179,7 +103144,7 @@ var BaseRawQuestionSchema = zod.z.object({
103179
103144
  points: zod.z.number().optional(),
103180
103145
  explanation: zod.z.string().optional(),
103181
103146
  topic: zod.z.string().optional(),
103182
- difficulty: zod.z.enum(["easy", "medium", "hard"]).optional(),
103147
+ difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
103183
103148
  bloomLevel: zod.z.string().optional()
103184
103149
  });
103185
103150
  var RawMCQSchema = BaseRawQuestionSchema.extend({
@@ -103532,7 +103497,7 @@ var QuizEditorService = class {
103532
103497
  questionType: type,
103533
103498
  prompt: "",
103534
103499
  points: 10,
103535
- difficulty: "medium"
103500
+ difficulty: "Medium"
103536
103501
  };
103537
103502
  switch (type) {
103538
103503
  case "true_false":
@@ -103759,7 +103724,7 @@ var SelectedQuestionsPanel = ({
103759
103724
  },
103760
103725
  /* @__PURE__ */ React169__namespace.default.createElement(ArrowDown, { className: "h-3 w-3" })
103761
103726
  )),
103762
- /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "font-medium text-sm leading-5 break-words" }, index3 + 1, ".", " ", q2.prompt.replace(/<[^>]*>?/gm, "").substring(0, 100) || `(${q2.questionType} - Untitled)`), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "text-xs text-muted-foreground mt-1" }, q2.questionType, " \u2022 ", q2.points || 0, " pts")),
103727
+ /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "font-Medium text-sm leading-5 break-words" }, index3 + 1, ".", " ", q2.prompt.replace(/<[^>]*>?/gm, "").substring(0, 100) || `(${q2.questionType} - Untitled)`), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "text-xs text-muted-foreground mt-1" }, q2.questionType, " \u2022 ", q2.points || 0, " pts")),
103763
103728
  /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-1 flex-shrink-0" }, /* @__PURE__ */ React169__namespace.default.createElement(
103764
103729
  Button,
103765
103730
  {
@@ -104146,7 +104111,7 @@ var TableFooter = React169__namespace.forwardRef(({ className, ...props }, ref)
104146
104111
  {
104147
104112
  ref,
104148
104113
  className: cn(
104149
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
104114
+ "border-t bg-muted/50 font-Medium [&>tr]:last:border-b-0",
104150
104115
  className
104151
104116
  ),
104152
104117
  ...props
@@ -104170,7 +104135,7 @@ var TableHead = React169__namespace.forwardRef(({ className, ...props }, ref) =>
104170
104135
  {
104171
104136
  ref,
104172
104137
  className: cn(
104173
- "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
104138
+ "h-12 px-4 text-left align-middle font-Medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
104174
104139
  className
104175
104140
  ),
104176
104141
  ...props
@@ -104260,20 +104225,6 @@ var questionTypeManager = new LocalStorageManager("question_types");
104260
104225
  var learningObjectiveManager = new LocalStorageManager("learning_objectives");
104261
104226
  var contextManager = new LocalStorageManager("contexts");
104262
104227
  var approachManager = new LocalStorageManager("approaches");
104263
- function mapRawDifficultyToStandard(rawDifficulty) {
104264
- switch (rawDifficulty) {
104265
- case "E":
104266
- case "E~M":
104267
- return "easy";
104268
- case "M":
104269
- case "M~H":
104270
- return "medium";
104271
- case "H":
104272
- return "hard";
104273
- default:
104274
- return "medium";
104275
- }
104276
- }
104277
104228
  var MetadataService = class {
104278
104229
  };
104279
104230
  // --- Subject Services ---
@@ -104331,15 +104282,10 @@ MetadataService.deleteContext = (code4) => contextManager.delete(code4);
104331
104282
  MetadataService.getApproaches = () => approachManager.getAll().sort((a4, b2) => a4.code.localeCompare(b2.code));
104332
104283
  MetadataService.saveApproaches = (items) => approachManager.saveAll(items);
104333
104284
  MetadataService.addApproach = (approachData) => {
104334
- const difficulty = mapRawDifficultyToStandard(approachData.rawDifficulty);
104335
- return approachManager.add({ ...approachData, difficulty });
104285
+ return approachManager.add(approachData);
104336
104286
  };
104337
104287
  MetadataService.updateApproach = (id3, approachData) => {
104338
- const updates = { ...approachData };
104339
- if (approachData.rawDifficulty) {
104340
- updates.difficulty = mapRawDifficultyToStandard(approachData.rawDifficulty);
104341
- }
104342
- return approachManager.update(id3, updates);
104288
+ return approachManager.update(id3, approachData);
104343
104289
  };
104344
104290
  MetadataService.deleteApproach = (code4) => approachManager.delete(code4);
104345
104291
  // --- LearningObjective Services ---
@@ -104349,8 +104295,12 @@ MetadataService.getLearningObjectives = (subjectCode) => {
104349
104295
  return filtered.sort((a4, b2) => a4.name.localeCompare(b2.name));
104350
104296
  };
104351
104297
  MetadataService.saveLearningObjectives = (items) => learningObjectiveManager.saveAll(items);
104352
- MetadataService.addLearningObjective = (name3, code4, subjectCode, description) => learningObjectiveManager.add({ name: name3, code: code4, subjectCode, description });
104353
- MetadataService.updateLearningObjective = (id3, name3, code4, subjectCode, description) => learningObjectiveManager.update(id3, { name: name3, code: code4, subjectCode, description });
104298
+ MetadataService.addLearningObjective = (item) => {
104299
+ return learningObjectiveManager.add(item);
104300
+ };
104301
+ MetadataService.updateLearningObjective = (id3, updates) => {
104302
+ return learningObjectiveManager.update(id3, updates);
104303
+ };
104354
104304
  MetadataService.deleteLearningObjective = (code4) => learningObjectiveManager.delete(code4);
104355
104305
 
104356
104306
  // node_modules/date-fns/addDays.mjs
@@ -106250,7 +106200,7 @@ function QuestionList({
106250
106200
  if (questions.length === 0) {
106251
106201
  return /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-8" }, "No questions match the current filters. Try adjusting your search or add new questions.");
106252
106202
  }
106253
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[30%]" }, "Question Text"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Type"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Grade"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Bloom's"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Last Modified"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, questions.map((question2) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: question2.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium max-w-xs truncate", title: question2.text }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: question2.questionConfig.prompt })), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, question2.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "secondary" }, getLookupName(question2.questionTypeCode, metadata.questionTypes))), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getLookupName(question2.subjectCode, metadata.subjects)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getLookupName(question2.topicCode, metadata.topics)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getLookupName(question2.gradeLevelCode, metadata.gradeLevels)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "outline" }, getLookupName(question2.bloomLevelCode, metadata.bloomLevels))), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, format(new Date(question2.lastModified), "MMM d, yyyy")), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, onView && /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onView(question2), className: "mr-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Eye, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onEdit(question2), className: "mr-1" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onDelete(question2), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))))))));
106203
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[30%]" }, "Question Text"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Type"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Grade"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Bloom's"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Last Modified"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, questions.map((question2) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: question2.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium max-w-xs truncate", title: question2.text }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: question2.questionConfig.prompt })), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, question2.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "secondary" }, getLookupName(question2.questionTypeCode, metadata.questionTypes))), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getLookupName(question2.subjectCode, metadata.subjects)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getLookupName(question2.topicCode, metadata.topics)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getLookupName(question2.gradeLevelCode, metadata.gradeLevels)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "outline" }, getLookupName(question2.bloomLevelCode, metadata.bloomLevels))), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, format(new Date(question2.lastModified), "MMM d, yyyy")), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, onView && /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onView(question2), className: "mr-1" }, /* @__PURE__ */ React169__namespace.default.createElement(Eye, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onEdit(question2), className: "mr-1" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onDelete(question2), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" }))))))));
106254
106204
  }
106255
106205
 
106256
106206
  // src/react-ui/components/authoring/QuestionFilters.tsx
@@ -106331,7 +106281,7 @@ function QuestionFilters({
106331
106281
  onChange: (e3) => setSearchTerm(e3.target.value),
106332
106282
  className: "lg:col-span-2 xl:col-span-1"
106333
106283
  }
106334
- ), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: subjectCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setSubjectCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Subject" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Subjects"), subjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: topicCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setTopicCode), disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Topic" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Topics"), filteredTopics.map((t4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: gradeLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setGradeLevelCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Grade Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Grade Levels"), gradeLevels.map((gl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: bloomLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setBloomLevelCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Bloom's Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Levels"), bloomLevels.map((bl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: questionTypeCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setQuestionTypeCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Question Type" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Types"), questionTypes.map((qt) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: difficulty || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setDifficulty) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Difficulty" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Difficulties"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "easy" }, "Easy"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "medium" }, "Medium"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "hard" }, "Hard"))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex gap-2 col-span-full sm:col-span-1 xl:col-span-2 xl:col-start-6" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleApplyFilters, className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__namespace.default.createElement(Search, { className: "mr-2 h-4 w-4" }), " Apply"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleClearFilters, variant: "outline", className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "mr-2 h-4 w-4" }), " Clear"))));
106284
+ ), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: subjectCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setSubjectCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Subject" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Subjects"), subjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: topicCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setTopicCode), disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Topic" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Topics"), filteredTopics.map((t4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: gradeLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setGradeLevelCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Grade Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Grade Levels"), gradeLevels.map((gl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: bloomLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setBloomLevelCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Bloom's Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Levels"), bloomLevels.map((bl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: questionTypeCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setQuestionTypeCode) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Question Type" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Types"), questionTypes.map((qt) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: difficulty || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setDifficulty) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Difficulty" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Difficulties"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "Easy" }, "Easy"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "Medium" }, "Medium"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "Hard" }, "Hard"))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex gap-2 col-span-full sm:col-span-1 xl:col-span-2 xl:col-start-6" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleApplyFilters, className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__namespace.default.createElement(Search, { className: "mr-2 h-4 w-4" }), " Apply"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleClearFilters, variant: "outline", className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "mr-2 h-4 w-4" }), " Clear"))));
106335
106285
  }
106336
106286
 
106337
106287
  // src/react-ui/components/authoring/QuestionFormDialog.tsx
@@ -106439,7 +106389,7 @@ function QuestionFormDialog({
106439
106389
  };
106440
106390
  const dialogTitle = questionToEdit ? "Edit Question Metadata" : "Create New Question";
106441
106391
  const dialogDescription = "First, define the metadata for the question. Then, edit the question's content and logic.";
106442
- return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, dialogTitle), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, dialogDescription)), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Question Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "code", value: code4, onChange: (e3) => setCode(e3.target.value.toUpperCase()), placeholder: "Unique code (e.g., MATH-ALG-001)", disabled: !!questionToEdit })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gradeLevelCode" }, "Grade Level"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: gradeLevelCode, onValueChange: setGradeLevelCode }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "gradeLevelCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Grade Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, gradeLevels.map((gl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: subjectCode, onValueChange: setSubjectCode }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Subject" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, subjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topicCode" }, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: topicCode, onValueChange: setTopicCode, disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "topicCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Topic" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, filteredTopics.map((t4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Bloom's Level"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: bloomLevelCode, onValueChange: setBloomLevelCode }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "bloomLevelCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Bloom's Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, bloomLevels.map((bl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Question Content & Logic"), questionConfig ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-3 mt-2 border rounded-md bg-muted/30 flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-medium" }, "Type: ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-normal" }, questionConfig.questionType)), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground truncate max-w-md" }, "Prompt: ", questionConfig.prompt.replace(/<[^>]*>?/gm, "") || "Not set")), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline", onClick: () => handleOpenQuestionEditor() }, /* @__PURE__ */ React169__namespace.default.createElement(SquarePen, { className: "mr-2 h-4 w-4" }), " Edit Content")) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-3 mt-2 border-dashed border-2 rounded-md text-center" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground mb-2" }, "No content has been created yet."), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "default", onClick: () => handleOpenQuestionEditor("multiple_choice") }, /* @__PURE__ */ React169__namespace.default.createElement(BookCopy, { className: "mr-2 h-4 w-4" }), " Create Question Content")))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !questionConfig }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save Question")))), questionConfig && /* @__PURE__ */ React169__namespace.default.createElement(
106392
+ return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, dialogTitle), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, dialogDescription)), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Question Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "code", value: code4, onChange: (e3) => setCode(e3.target.value.toUpperCase()), placeholder: "Unique code (e.g., MATH-ALG-001)", disabled: !!questionToEdit })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gradeLevelCode" }, "Grade Level"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: gradeLevelCode, onValueChange: setGradeLevelCode }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "gradeLevelCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Grade Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, gradeLevels.map((gl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: subjectCode, onValueChange: setSubjectCode }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Subject" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, subjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topicCode" }, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: topicCode, onValueChange: setTopicCode, disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "topicCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Topic" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, filteredTopics.map((t4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Bloom's Level"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: bloomLevelCode, onValueChange: setBloomLevelCode }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "bloomLevelCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select Bloom's Level" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, bloomLevels.map((bl) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { className: "font-semibold" }, "Question Content & Logic"), questionConfig ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-3 mt-2 border rounded-md bg-muted/30 flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-Medium" }, "Type: ", /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "font-normal" }, questionConfig.questionType)), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground truncate max-w-md" }, "Prompt: ", questionConfig.prompt.replace(/<[^>]*>?/gm, "") || "Not set")), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline", onClick: () => handleOpenQuestionEditor() }, /* @__PURE__ */ React169__namespace.default.createElement(SquarePen, { className: "mr-2 h-4 w-4" }), " Edit Content")) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-3 mt-2 border-dashed border-2 rounded-md text-center" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground mb-2" }, "No content has been created yet."), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "default", onClick: () => handleOpenQuestionEditor("multiple_choice") }, /* @__PURE__ */ React169__namespace.default.createElement(BookCopy, { className: "mr-2 h-4 w-4" }), " Create Question Content")))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !questionConfig }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save Question")))), questionConfig && /* @__PURE__ */ React169__namespace.default.createElement(
106443
106393
  EditQuestionModal,
106444
106394
  {
106445
106395
  isOpen: isQuestionEditorOpen,
@@ -110757,10 +110707,10 @@ var RoadmapService = class {
110757
110707
  }
110758
110708
  return null;
110759
110709
  }
110760
- static updateRoadmapItemStatus(loId, isCompleted) {
110710
+ static updateRoadmapItemStatus(code4, isCompleted) {
110761
110711
  const roadmap = this.getRoadmap();
110762
110712
  if (roadmap) {
110763
- const itemIndex = roadmap.items.findIndex((item) => item.loId === loId);
110713
+ const itemIndex = roadmap.items.findIndex((item) => item.code === code4);
110764
110714
  if (itemIndex > -1) {
110765
110715
  roadmap.items[itemIndex].isCompleted = isCompleted;
110766
110716
  this.saveRoadmap(roadmap);
@@ -111341,7 +111291,7 @@ zod.z.object({
111341
111291
  startDate: zod.z.string().describe("The start date for the analysis period in ISO format (YYYY-MM-DD)."),
111342
111292
  endDate: zod.z.string().describe("The end date for the analysis period in ISO format (YYYY-MM-DD)."),
111343
111293
  allAvailableTopics: zod.z.array(zod.z.object({
111344
- loId: zod.z.string(),
111294
+ code: zod.z.string(),
111345
111295
  subject: zod.z.string(),
111346
111296
  category: zod.z.string(),
111347
111297
  topic: zod.z.string()
@@ -111352,7 +111302,7 @@ var RoadmapItemSchema = zod.z.object({
111352
111302
  topicName: zod.z.string(),
111353
111303
  reason: zod.z.string(),
111354
111304
  suggestedDifficulty: zod.z.enum(["Very Easy", "Easy", "Medium", "Hard", "Expert"]),
111355
- loId: zod.z.string(),
111305
+ code: zod.z.string(),
111356
111306
  isCompleted: zod.z.boolean()
111357
111307
  });
111358
111308
  var WeeklyRoadmapSchema = zod.z.object({
@@ -111417,7 +111367,7 @@ All topic names and loIds in your "weeklyRoadmap" output MUST be chosen directly
111417
111367
  - **gamificationRemarks**: Write an encouraging message mentioning their achievements.
111418
111368
  2. **For "weeklyRoadmap":**
111419
111369
  - Create a 5-item roadmap for the upcoming week.
111420
- - Prioritize the "areasForImprovement" you identified. For each, find the corresponding entry in "All Available Topics" and use its "topicName" and "loId".
111370
+ - Prioritize the "areasForImprovement" you identified. For each, find the corresponding entry in "All Available Topics" and use its "topicName" and "code".
111421
111371
  - If more items are needed, select related topics from "All Available Topics".
111422
111372
 
111423
111373
  **IF Practice History IS EMPTY:**
@@ -111428,7 +111378,7 @@ All topic names and loIds in your "weeklyRoadmap" output MUST be chosen directly
111428
111378
  - **gamificationRemarks**: Write a general motivational message about starting to learn.
111429
111379
  2. **For "weeklyRoadmap":**
111430
111380
  - Create a 5-item "starter" roadmap.
111431
- - Select 5 diverse and foundational topics directly from the "All Available Topics" list. Use their exact "topicName" and "loId".
111381
+ - Select 5 diverse and foundational topics directly from the "All Available Topics" list. Use their exact "topicName" and "code".
111432
111382
  - For the "reason", explain that this is a good starting point to explore the subject.
111433
111383
 
111434
111384
  --- END LOGIC FLOW ---
@@ -111456,7 +111406,7 @@ The 'suggestedDifficulty' field MUST ALWAYS be one of these exact English string
111456
111406
  "topicName": "Topic C",
111457
111407
  "reason": "To strengthen your understanding of this key area.",
111458
111408
  "suggestedDifficulty": "Easy",
111459
- "loId": "lo-id-for-topic-c-from-the-list",
111409
+ "code": "lo-id-for-topic-c-from-the-list",
111460
111410
  "isCompleted": false
111461
111411
  }
111462
111412
  ]
@@ -111718,11 +111668,11 @@ init_react_shim();
111718
111668
  // src/ai/flows/assess-and-map-document-types.ts
111719
111669
  init_react_shim();
111720
111670
  var LearningObjectiveContextSchema = zod.z.object({
111721
- loId: zod.z.string(),
111671
+ code: zod.z.string(),
111722
111672
  subject: zod.z.string(),
111723
111673
  category: zod.z.string(),
111724
111674
  topic: zod.z.string(),
111725
- loDescription: zod.z.string()
111675
+ description: zod.z.string()
111726
111676
  });
111727
111677
  zod.z.object({
111728
111678
  language: zod.z.string().default("English"),
@@ -111730,7 +111680,7 @@ zod.z.object({
111730
111680
  learningObjectives: zod.z.array(LearningObjectiveContextSchema).min(1, { message: "At least one learning objective is required for mapping." })
111731
111681
  });
111732
111682
  var MappedLOSchema = zod.z.object({
111733
- loId: zod.z.string().describe("The exact loId from the provided learning objectives list that matches the document content."),
111683
+ code: zod.z.string().describe("The exact code from the provided learning objectives list that matches the document content."),
111734
111684
  confidence: zod.z.number().min(0).max(100).describe("A confidence score (0-100) of how well the document maps to this LO."),
111735
111685
  reasoning: zod.z.string().describe("A brief explanation for why this mapping is relevant.")
111736
111686
  });
@@ -111766,7 +111716,7 @@ You are an expert curriculum analyst. Your task is to analyze a given document a
111766
111716
  1. **Overall Relevance Assessment:** Read the document content and compare it against the entire list of LOs. Assign an overall "relevanceScore" from 0 (completely unrelated) to 100 (perfectly aligned with one or more LOs).
111767
111717
 
111768
111718
  2. **Specific Mapping:** Identify which specific LOs from the list are directly addressed by the document. For each match you find, provide:
111769
- - The exact "loId" of the matched LO.
111719
+ - The exact "code" of the matched LO.
111770
111720
  - A "confidence" score (0-100) for that specific match.
111771
111721
  - A brief "reasoning" in ${language3} explaining why the document content maps to that LO.
111772
111722
 
@@ -111781,7 +111731,7 @@ Return a single, valid JSON object in this EXACT format. Do not include any othe
111781
111731
  "isFreestyleRecommended": false,
111782
111732
  "mappedLOs": [
111783
111733
  {
111784
- "loId": "SWIFT_FUNC_01",
111734
+ "code": "SWIFT_FUNC_01",
111785
111735
  "confidence": 95,
111786
111736
  "reasoning": "The document provides a detailed explanation of function syntax and default parameters, which directly aligns with this learning objective."
111787
111737
  }
@@ -111876,7 +111826,7 @@ Return the response as a single JSON object with a key "generatedQuestions" cont
111876
111826
  "correctTempOptionId": "A",
111877
111827
  "explanation": "The document states that mitochondria are the powerhouses of the cell, responsible for cellular respiration.",
111878
111828
  "points": 10,
111879
- "difficulty": "medium",
111829
+ "difficulty": "Medium",
111880
111830
  "topic": "Cell Biology"
111881
111831
  },
111882
111832
  {
@@ -111885,7 +111835,7 @@ Return the response as a single JSON object with a key "generatedQuestions" cont
111885
111835
  "correctAnswer": false,
111886
111836
  "explanation": "The text specifies that the cell wall is a feature of plant cells, not animal cells.",
111887
111837
  "points": 10,
111888
- "difficulty": "easy",
111838
+ "difficulty": "Easy",
111889
111839
  "topic": "Cell Biology"
111890
111840
  }
111891
111841
  ]
@@ -112718,7 +112668,7 @@ var QuizReview = ({
112718
112668
  };
112719
112669
  return /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "w-full max-w-4xl mx-auto shadow-xl" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-3xl font-headline text-center flex items-center justify-center" }, /* @__PURE__ */ React169__namespace.default.createElement(BookOpen, { className: "mr-3 h-8 w-8 text-primary" }), "AI-Powered Quiz Review"), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, { className: "text-center text-lg" }, "Let's break down your results and reinforce your learning.")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-6" }, /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "bg-muted/30" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-xl flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-yellow-500" }), "Key Concepts Summary")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: reviewContent.overallSummary }))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("h3", { className: "text-xl font-semibold mb-2" }, "Detailed Question Analysis"), /* @__PURE__ */ React169__namespace.default.createElement(Accordion2, { type: "single", collapsible: true, className: "w-full" }, quizResult.questionResults.map((qResult, index3) => {
112720
112670
  const aiReview = getReviewForQuestion(qResult.questionId);
112721
- return /* @__PURE__ */ React169__namespace.default.createElement(AccordionItem2, { value: `item-${index3}`, key: qResult.questionId }, /* @__PURE__ */ React169__namespace.default.createElement(AccordionTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-between w-full pr-2" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-left font-medium" }, "Question ", index3 + 1), qResult.isCorrect ? /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-sm text-green-600 font-medium flex items-center gap-1" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "h-4 w-4" }), " Correct") : /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-sm text-destructive font-medium flex items-center gap-1" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "h-4 w-4" }), " Incorrect"))), /* @__PURE__ */ React169__namespace.default.createElement(AccordionContent2, { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold mb-2" }, "Original Question:"), /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: qResult.prompt })), qResult.questionType === "coding" ? renderCodingResult(qResult) : renderStandardResult(qResult), aiReview && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border-l-4 border-primary bg-primary/10 rounded-r-md" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold text-primary mb-2" }, "AI Tutor Explanation:"), /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: aiReview.explanation }))));
112671
+ return /* @__PURE__ */ React169__namespace.default.createElement(AccordionItem2, { value: `item-${index3}`, key: qResult.questionId }, /* @__PURE__ */ React169__namespace.default.createElement(AccordionTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-between w-full pr-2" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-left font-Medium" }, "Question ", index3 + 1), qResult.isCorrect ? /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-sm text-green-600 font-Medium flex items-center gap-1" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "h-4 w-4" }), " Correct") : /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-sm text-destructive font-Medium flex items-center gap-1" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleX, { className: "h-4 w-4" }), " Incorrect"))), /* @__PURE__ */ React169__namespace.default.createElement(AccordionContent2, { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold mb-2" }, "Original Question:"), /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: qResult.prompt })), qResult.questionType === "coding" ? renderCodingResult(qResult) : renderStandardResult(qResult), aiReview && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border-l-4 border-primary bg-primary/10 rounded-r-md" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold text-primary mb-2" }, "AI Tutor Explanation:"), /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: aiReview.explanation }))));
112722
112672
  }))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("h3", { className: "text-xl font-semibold mb-2" }, "Topics for Further Study"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-wrap gap-2" }, reviewContent.relatedTopics.map((topic, index3) => /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { key: index3, variant: "secondary", className: "text-base px-3 py-1" }, topic))))), /* @__PURE__ */ React169__namespace.default.createElement(CardFooter, { className: "flex flex-col sm:flex-row justify-between gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline", onClick: onBackToResults, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(ArrowLeft, { className: "mr-2 h-4 w-4" }), "Back to Results"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: onExit, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(LogOut, { className: "mr-2 h-4 w-4" }), "Finish & Exit")));
112723
112673
  };
112724
112674
 
@@ -112765,7 +112715,7 @@ var PracticeHistoryTable = ({ history: history2, maxHeight = "400px" }) => {
112765
112715
  if (percentage >= 50) return "secondary";
112766
112716
  return "destructive";
112767
112717
  };
112768
- return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, null, t4("history.title")), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, t4("history.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "w-full border rounded-md", style: { height: maxHeight } }, /* @__PURE__ */ React169__namespace.default.createElement(TooltipProvider2, { delayDuration: 100 }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, { className: "sticky top-0 bg-muted z-10" }, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[120px]" }, t4("history.headers.date")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, t4("history.headers.topic")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[80px]" }, t4("history.headers.score")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[90px]" }, t4("history.headers.percentage")))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, history2.length > 0 ? history2.map((session) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: session.id, onClick: () => handleRowClick(session), className: "cursor-pointer" }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium text-xs text-muted-foreground" }, formatDate(session.timestamp)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col gap-1.5" }, session.topics.map((topicInfo, index3) => /* @__PURE__ */ React169__namespace.default.createElement(Tooltip2, { key: index3 }, /* @__PURE__ */ React169__namespace.default.createElement(TooltipTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold text-sm truncate" }, topicInfo.topic)), /* @__PURE__ */ React169__namespace.default.createElement(TooltipContent2, null, /* @__PURE__ */ React169__namespace.default.createElement("p", null, /* @__PURE__ */ React169__namespace.default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.subject"), ":"), " ", topicInfo.subject), /* @__PURE__ */ React169__namespace.default.createElement("p", null, /* @__PURE__ */ React169__namespace.default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.category"), ":"), " ", topicInfo.category)))))), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right font-mono text-sm" }, session.score !== null ? `${session.score}/${session.maxScore}` : "N/A"), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, session.percentage !== null && /* @__PURE__ */ React169__namespace.default.createElement(
112718
+ return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, null, t4("history.title")), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, t4("history.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "w-full border rounded-md", style: { height: maxHeight } }, /* @__PURE__ */ React169__namespace.default.createElement(TooltipProvider2, { delayDuration: 100 }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, { className: "sticky top-0 bg-muted z-10" }, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[120px]" }, t4("history.headers.date")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, t4("history.headers.topic")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[80px]" }, t4("history.headers.score")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[90px]" }, t4("history.headers.percentage")))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, history2.length > 0 ? history2.map((session) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: session.id, onClick: () => handleRowClick(session), className: "cursor-pointer" }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium text-xs text-muted-foreground" }, formatDate(session.timestamp)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col gap-1.5" }, session.topics.map((topicInfo, index3) => /* @__PURE__ */ React169__namespace.default.createElement(Tooltip2, { key: index3 }, /* @__PURE__ */ React169__namespace.default.createElement(TooltipTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-semibold text-sm truncate" }, topicInfo.topic)), /* @__PURE__ */ React169__namespace.default.createElement(TooltipContent2, null, /* @__PURE__ */ React169__namespace.default.createElement("p", null, /* @__PURE__ */ React169__namespace.default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.subject"), ":"), " ", topicInfo.subject), /* @__PURE__ */ React169__namespace.default.createElement("p", null, /* @__PURE__ */ React169__namespace.default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.category"), ":"), " ", topicInfo.category)))))), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right font-mono text-sm" }, session.score !== null ? `${session.score}/${session.maxScore}` : "N/A"), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, session.percentage !== null && /* @__PURE__ */ React169__namespace.default.createElement(
112769
112719
  Badge2,
112770
112720
  {
112771
112721
  variant: getPercentageBadgeVariant(session.percentage),
@@ -133580,12 +133530,12 @@ var ChartTooltipContent = React169__namespace.forwardRef(
133580
133530
  const itemConfig = getPayloadConfigFromPayload(config3, item, key);
133581
133531
  const value = !labelKey && typeof label === "string" ? config3[label]?.label || label : itemConfig?.label;
133582
133532
  if (labelFormatter) {
133583
- return /* @__PURE__ */ React169__namespace.createElement("div", { className: cn("font-medium", labelClassName) }, labelFormatter(value, payload));
133533
+ return /* @__PURE__ */ React169__namespace.createElement("div", { className: cn("font-Medium", labelClassName) }, labelFormatter(value, payload));
133584
133534
  }
133585
133535
  if (!value) {
133586
133536
  return null;
133587
133537
  }
133588
- return /* @__PURE__ */ React169__namespace.createElement("div", { className: cn("font-medium", labelClassName) }, value);
133538
+ return /* @__PURE__ */ React169__namespace.createElement("div", { className: cn("font-Medium", labelClassName) }, value);
133589
133539
  }, [
133590
133540
  label,
133591
133541
  labelFormatter,
@@ -133648,7 +133598,7 @@ var ChartTooltipContent = React169__namespace.forwardRef(
133648
133598
  )
133649
133599
  },
133650
133600
  /* @__PURE__ */ React169__namespace.createElement("div", { className: "grid gap-1.5" }, nestLabel ? tooltipLabel : null, /* @__PURE__ */ React169__namespace.createElement("span", { className: "text-muted-foreground" }, itemConfig?.label || item.name)),
133651
- item.value && /* @__PURE__ */ React169__namespace.createElement("span", { className: "font-mono font-medium tabular-nums text-foreground" }, item.value.toLocaleString())
133601
+ item.value && /* @__PURE__ */ React169__namespace.createElement("span", { className: "font-mono font-Medium tabular-nums text-foreground" }, item.value.toLocaleString())
133652
133602
  ))
133653
133603
  );
133654
133604
  }))
@@ -134825,7 +134775,7 @@ var ManageTopics = () => {
134825
134775
  return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Card, { className: "w-full max-w-4xl mx-auto shadow-none border-none" }, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, { className: "px-1" }, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex items-center text-2xl font-headline" }, /* @__PURE__ */ React169__namespace.default.createElement(FileText, { className: "mr-3 h-6 w-6 text-primary" }), t4("settingsModal.topics.title")), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, t4("settingsModal.topics.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-6 px-1" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "tsv-importer", className: "text-lg font-semibold" }, t4("settingsModal.topics.importData")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "mt-2 p-4 border border-dashed rounded-lg flex flex-col sm:flex-row items-center gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-grow" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.topics.importHint")), /* @__PURE__ */ React169__namespace.default.createElement("a", { href: "#", className: "text-xs text-primary hover:underline", onClick: (e3) => {
134826
134776
  e3.preventDefault();
134827
134777
  alert("Header format:\nLO ID LO Description Subject Category Topic Keywords Grade STEM Element(s) Bloom\u2019s Level(s) Guideline");
134828
- } }, t4("settingsModal.topics.viewHeaderFormat"))), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "tsv-importer", type: "file", ref: fileInputRef, accept: ".tsv,text/tab-separated-values", onChange: handleFileChange, className: "hidden" }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: () => fileInputRef.current?.click() }, /* @__PURE__ */ React169__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.chooseFile")))), importErrors.length > 0 && /* @__PURE__ */ React169__namespace.default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__namespace.default.createElement(AlertTitle, null, t4("settingsModal.topics.importErrors")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDescription, null, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-24 mt-2" }, /* @__PURE__ */ React169__namespace.default.createElement("ul", { className: "list-disc list-inside text-xs space-y-1" }, importErrors.map((error, index3) => /* @__PURE__ */ React169__namespace.default.createElement("li", { key: index3 }, error)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement("h3", { className: "text-lg font-semibold" }, t4("settingsModal.topics.currentDataTitle")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.topics.showingCount", { shown: filteredLearningObjectives.length, total: learningObjectives.length }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subject-filter" }, t4("settingsModal.topics.filterBySubject")), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: selectedSubjectFilter, onValueChange: setSelectedSubjectFilter, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "subject-filter", className: "w-full sm:w-[280px]" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.topics.filterPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "all" }, t4("settingsModal.topics.allSubjects")), subjects.map((subject) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: subject, value: subject }, subject))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-72" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, { className: "sticky top-0 bg-muted" }, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.subject")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.category")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, t4("settingsModal.topics.tableHeaders.topic")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[100px]" }, t4("settingsModal.topics.tableHeaders.loId")))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { colSpan: 4, className: "text-center" }, t4("common.loading"))) : filteredLearningObjectives.length > 0 ? filteredLearningObjectives.map((lo) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: lo.loId }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, lo.subject), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, lo.category), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, lo.topic), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, lo.loId))) : /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { colSpan: 4, className: "text-center h-24 text-muted-foreground" }, t4("settingsModal.topics.emptyData"))))))))), /* @__PURE__ */ React169__namespace.default.createElement(CardFooter, { className: "px-1" }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "destructive", disabled: learningObjectives.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.clearAllData"))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.clearDataConfirmationTitle")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.clearDataConfirmationMessage", { count: learningObjectives.length }))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleClearData }, t4("settingsModal.topics.confirmDelete"))))))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isConfirmModalOpen, onOpenChange: setIsConfirmModalOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.confirmModal.title")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.confirmModal.description", { count: parsedImportData?.data.length || 0 }))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, { className: "gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { onClick: () => setParsedImportData(null) }, t4("common.cancel")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleConfirmMerge, className: "bg-blue-600 hover:bg-blue-700" }, t4("settingsModal.topics.confirmModal.mergeButton")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleConfirmOverwrite, className: "bg-amber-600 hover:bg-amber-700" }, t4("settingsModal.topics.confirmModal.overwriteButton"))))));
134778
+ } }, t4("settingsModal.topics.viewHeaderFormat"))), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "tsv-importer", type: "file", ref: fileInputRef, accept: ".tsv,text/tab-separated-values", onChange: handleFileChange, className: "hidden" }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: () => fileInputRef.current?.click() }, /* @__PURE__ */ React169__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.chooseFile")))), importErrors.length > 0 && /* @__PURE__ */ React169__namespace.default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__namespace.default.createElement(AlertTitle, null, t4("settingsModal.topics.importErrors")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDescription, null, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-24 mt-2" }, /* @__PURE__ */ React169__namespace.default.createElement("ul", { className: "list-disc list-inside text-xs space-y-1" }, importErrors.map((error, index3) => /* @__PURE__ */ React169__namespace.default.createElement("li", { key: index3 }, error)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between mb-2" }, /* @__PURE__ */ React169__namespace.default.createElement("h3", { className: "text-lg font-semibold" }, t4("settingsModal.topics.currentDataTitle")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.topics.showingCount", { shown: filteredLearningObjectives.length, total: learningObjectives.length }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subject-filter" }, t4("settingsModal.topics.filterBySubject")), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: selectedSubjectFilter, onValueChange: setSelectedSubjectFilter, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "subject-filter", className: "w-full sm:w-[280px]" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.topics.filterPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "all" }, t4("settingsModal.topics.allSubjects")), subjects.map((subject) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: subject, value: subject }, subject))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-72" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, { className: "sticky top-0 bg-muted" }, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.subject")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.category")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, t4("settingsModal.topics.tableHeaders.topic")), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "w-[100px]" }, t4("settingsModal.topics.tableHeaders.code")))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { colSpan: 4, className: "text-center" }, t4("common.loading"))) : filteredLearningObjectives.length > 0 ? filteredLearningObjectives.map((lo) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: lo.code }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, lo.subject), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, lo.category), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, lo.topic), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, lo.code))) : /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { colSpan: 4, className: "text-center h-24 text-muted-foreground" }, t4("settingsModal.topics.emptyData"))))))))), /* @__PURE__ */ React169__namespace.default.createElement(CardFooter, { className: "px-1" }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "destructive", disabled: learningObjectives.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.clearAllData"))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.clearDataConfirmationTitle")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.clearDataConfirmationMessage", { count: learningObjectives.length }))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleClearData }, t4("settingsModal.topics.confirmDelete"))))))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isConfirmModalOpen, onOpenChange: setIsConfirmModalOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.confirmModal.title")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.confirmModal.description", { count: parsedImportData?.data.length || 0 }))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, { className: "gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { onClick: () => setParsedImportData(null) }, t4("common.cancel")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleConfirmMerge, className: "bg-blue-600 hover:bg-blue-700" }, t4("settingsModal.topics.confirmModal.mergeButton")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleConfirmOverwrite, className: "bg-amber-600 hover:bg-amber-700" }, t4("settingsModal.topics.confirmModal.overwriteButton"))))));
134829
134779
  };
134830
134780
 
134831
134781
  // src/react-ui/components/app/ManageImageContexts.tsx
@@ -135232,7 +135182,7 @@ var SettingsModal = ({ isOpen, onClose, defaultTab = "personal" }) => {
135232
135182
  return goal.id;
135233
135183
  }
135234
135184
  };
135235
- return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl lg:max-w-3xl max-h-[85vh] flex flex-col" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, { className: "shrink-0" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Settings, { className: "mr-2 h-5 w-5 text-primary" }), t4("settingsModal.title")), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, t4("settingsModal.description"))), /* @__PURE__ */ React169__namespace.default.createElement(Tabs2, { value: activeTab, onValueChange: (value) => setActiveTab(value), className: "pt-2 flex-1 flex flex-col min-h-0" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsList2, { className: "grid w-full grid-cols-5 shrink-0" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "personal" }, /* @__PURE__ */ React169__namespace.default.createElement(User, { className: "mr-1 h-4 w-4" }), t4("settingsModal.personalTab")), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "topics" }, /* @__PURE__ */ React169__namespace.default.createElement(ListTodo, { className: "mr-1 h-4 w-4" }), t4("settingsModal.topicsTab")), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "imageContexts" }, /* @__PURE__ */ React169__namespace.default.createElement(ImagePlus, { className: "mr-1 h-4 w-4" }), "Images"), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "layout" }, /* @__PURE__ */ React169__namespace.default.createElement(LayoutDashboard, { className: "mr-1 h-4 w-4" }), t4("settingsModal.layoutTab")), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "apiKeys" }, /* @__PURE__ */ React169__namespace.default.createElement(KeyRound, { className: "mr-1 h-4 w-4" }), t4("settingsModal.apiKeysTab"))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "personal", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-full pr-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-3" }, t4("settingsModal.personal.basicInfo")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "full-name" }, t4("settingsModal.personal.fullName")), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "full-name", value: fullName, onChange: (e3) => setFullName(e3.target.value), placeholder: t4("settingsModal.personal.fullNamePlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "weekly-goal" }, t4("settingsModal.personal.weeklyGoal")), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "weekly-goal", type: "number", value: weeklyGoal, onChange: (e3) => setWeeklyGoal(parseInt(e3.target.value, 10) || 0), min: "1" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "language-select", className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Languages, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.languageSelectLabel")), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: language3, onValueChange: changeLanguage2 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "language-select" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select a language..." })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "en" }, "English"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "vi" }, "Ti\u1EBFng Vi\u1EC7t")))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-3 flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Target, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.advancedGoals")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2 mb-4" }, advancedGoals.map((goal) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: goal.id, className: "flex items-center justify-between p-2 bg-muted/50 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm flex-1" }, renderGoalDescription(goal)), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleDeleteGoal(goal.id) }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), advancedGoals.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.personal.noGoals"))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement("h5", { className: "font-medium" }, t4("settingsModal.personal.addNewGoal")), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalType, onValueChange: (v) => setNewGoalType(v) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.goalTypePlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "average_score_subject" }, t4("settingsModal.personal.goalType.avgScoreSubject")), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "mastery_topic" }, t4("settingsModal.personal.goalType.masteryTopic")))), newGoalType === "average_score_subject" && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") })), newGoalType === "mastery_topic" && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalTopic, onValueChange: setNewGoalTopic, disabled: !newGoalSubject }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.topicPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, topicsForSelectedSubject.map((t5) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: t5, value: t5 }, t5)))), /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") }), /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "number", value: newGoalConsecutive, onChange: (e3) => setNewGoalConsecutive(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.consecutiveSessionsPlaceholder") })), newGoalType && /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", onClick: handleAddNewGoal }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.addGoalButton"))))))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "topics", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__namespace.default.createElement(ManageTopics, null)), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "imageContexts", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__namespace.default.createElement(ManageImageContexts, null)), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "layout", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold" }, t4("settingsModal.layout.title")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1 mb-3" }, t4("settingsModal.layout.description")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(RefreshCw, { className: "mr-2 h-4 w-4" }), t4("settingsModal.layout.resetButton"))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, t4("settingsModal.layout.resetConfirmationTitle")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, t4("settingsModal.layout.resetConfirmationMessage"))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleResetLayout }, t4("settingsModal.layout.confirmReset"))))))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "apiKeys", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gemini-api-key" }, t4("settingsModal.apiKeys.geminiKey")), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "gemini-api-key", type: "password", value: geminiApiKey, onChange: (e3) => setGeminiApiKey(e3.target.value), placeholder: t4("settingsModal.apiKeys.geminiKeyPlaceholder") }), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, t4("settingsModal.apiKeys.storageHint"))))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, { className: "gap-2 sm:justify-end pt-4 shrink-0" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline" }, t4("common.close"))), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", onClick: handleSave }, /* @__PURE__ */ React169__namespace.default.createElement(Save, { className: "mr-2 h-4 w-4" }), t4("settingsModal.saveChanges")))));
135185
+ return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl lg:max-w-3xl max-h-[85vh] flex flex-col" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, { className: "shrink-0" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Settings, { className: "mr-2 h-5 w-5 text-primary" }), t4("settingsModal.title")), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, t4("settingsModal.description"))), /* @__PURE__ */ React169__namespace.default.createElement(Tabs2, { value: activeTab, onValueChange: (value) => setActiveTab(value), className: "pt-2 flex-1 flex flex-col min-h-0" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsList2, { className: "grid w-full grid-cols-5 shrink-0" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "personal" }, /* @__PURE__ */ React169__namespace.default.createElement(User, { className: "mr-1 h-4 w-4" }), t4("settingsModal.personalTab")), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "topics" }, /* @__PURE__ */ React169__namespace.default.createElement(ListTodo, { className: "mr-1 h-4 w-4" }), t4("settingsModal.topicsTab")), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "imageContexts" }, /* @__PURE__ */ React169__namespace.default.createElement(ImagePlus, { className: "mr-1 h-4 w-4" }), "Images"), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "layout" }, /* @__PURE__ */ React169__namespace.default.createElement(LayoutDashboard, { className: "mr-1 h-4 w-4" }), t4("settingsModal.layoutTab")), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "apiKeys" }, /* @__PURE__ */ React169__namespace.default.createElement(KeyRound, { className: "mr-1 h-4 w-4" }), t4("settingsModal.apiKeysTab"))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "personal", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-full pr-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-3" }, t4("settingsModal.personal.basicInfo")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "full-name" }, t4("settingsModal.personal.fullName")), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "full-name", value: fullName, onChange: (e3) => setFullName(e3.target.value), placeholder: t4("settingsModal.personal.fullNamePlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "weekly-goal" }, t4("settingsModal.personal.weeklyGoal")), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "weekly-goal", type: "number", value: weeklyGoal, onChange: (e3) => setWeeklyGoal(parseInt(e3.target.value, 10) || 0), min: "1" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "language-select", className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Languages, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.languageSelectLabel")), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: language3, onValueChange: changeLanguage2 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "language-select" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select a language..." })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "en" }, "English"), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "vi" }, "Ti\u1EBFng Vi\u1EC7t")))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-3 flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Target, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.advancedGoals")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2 mb-4" }, advancedGoals.map((goal) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: goal.id, className: "flex items-center justify-between p-2 bg-muted/50 rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm flex-1" }, renderGoalDescription(goal)), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleDeleteGoal(goal.id) }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), advancedGoals.length === 0 && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.personal.noGoals"))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__namespace.default.createElement("h5", { className: "font-Medium" }, t4("settingsModal.personal.addNewGoal")), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalType, onValueChange: (v) => setNewGoalType(v) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.goalTypePlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "average_score_subject" }, t4("settingsModal.personal.goalType.avgScoreSubject")), /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "mastery_topic" }, t4("settingsModal.personal.goalType.masteryTopic")))), newGoalType === "average_score_subject" && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") })), newGoalType === "mastery_topic" && /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: newGoalTopic, onValueChange: setNewGoalTopic, disabled: !newGoalSubject }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.topicPlaceholder") })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, topicsForSelectedSubject.map((t5) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: t5, value: t5 }, t5)))), /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") }), /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "number", value: newGoalConsecutive, onChange: (e3) => setNewGoalConsecutive(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.consecutiveSessionsPlaceholder") })), newGoalType && /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", onClick: handleAddNewGoal }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.addGoalButton"))))))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "topics", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__namespace.default.createElement(ManageTopics, null)), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "imageContexts", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__namespace.default.createElement(ManageImageContexts, null)), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "layout", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold" }, t4("settingsModal.layout.title")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mt-1 mb-3" }, t4("settingsModal.layout.description")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(RefreshCw, { className: "mr-2 h-4 w-4" }), t4("settingsModal.layout.resetButton"))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, t4("settingsModal.layout.resetConfirmationTitle")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, t4("settingsModal.layout.resetConfirmationMessage"))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: handleResetLayout }, t4("settingsModal.layout.confirmReset"))))))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "apiKeys", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gemini-api-key" }, t4("settingsModal.apiKeys.geminiKey")), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "gemini-api-key", type: "password", value: geminiApiKey, onChange: (e3) => setGeminiApiKey(e3.target.value), placeholder: t4("settingsModal.apiKeys.geminiKeyPlaceholder") }), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, t4("settingsModal.apiKeys.storageHint"))))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, { className: "gap-2 sm:justify-end pt-4 shrink-0" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline" }, t4("common.close"))), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", onClick: handleSave }, /* @__PURE__ */ React169__namespace.default.createElement(Save, { className: "mr-2 h-4 w-4" }), t4("settingsModal.saveChanges")))));
135236
135186
  };
135237
135187
 
135238
135188
  // src/react-ui/components/dashboard/Cheatsheet.tsx
@@ -135331,7 +135281,7 @@ var Cheatsheet = () => {
135331
135281
  }
135332
135282
  return null;
135333
135283
  };
135334
- return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), t4("knowledgeCards.title")), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, t4("knowledgeCards.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "search", placeholder: t4("knowledgeCards.searchPlaceholder"), value: searchQuery, onChange: (e3) => setSearchQuery2(e3.target.value), disabled: allCards.length === 0 }), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, allCards.length > 0 ? filteredCards.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, filteredCards.map((card) => /* @__PURE__ */ React169__namespace.default.createElement("button", { key: card.id, onClick: () => handleCardClick(card.id), className: "w-full text-left p-2 rounded-md hover:bg-accent text-sm font-medium" }, card.concept))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.noMatch"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.empty")))), renderActionArea())), /* @__PURE__ */ React169__namespace.default.createElement(
135284
+ return /* @__PURE__ */ React169__namespace.default.createElement(React169__namespace.default.Fragment, null, /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), t4("knowledgeCards.title")), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, t4("knowledgeCards.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Input, { type: "search", placeholder: t4("knowledgeCards.searchPlaceholder"), value: searchQuery, onChange: (e3) => setSearchQuery2(e3.target.value), disabled: allCards.length === 0 }), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, allCards.length > 0 ? filteredCards.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, filteredCards.map((card) => /* @__PURE__ */ React169__namespace.default.createElement("button", { key: card.id, onClick: () => handleCardClick(card.id), className: "w-full text-left p-2 rounded-md hover:bg-accent text-sm font-Medium" }, card.concept))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.noMatch"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.empty")))), renderActionArea())), /* @__PURE__ */ React169__namespace.default.createElement(
135335
135285
  CardViewerDialog,
135336
135286
  {
135337
135287
  isOpen: isDialogOpen,
@@ -135358,9 +135308,9 @@ var StatCard = ({
135358
135308
  isLoading = false
135359
135309
  }) => {
135360
135310
  if (isLoading) {
135361
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-sm font-medium" }, title), /* @__PURE__ */ React169__namespace.default.createElement(Skeleton, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement(Skeleton, { className: "h-8 w-3/4 mb-2" }), /* @__PURE__ */ React169__namespace.default.createElement(Skeleton, { className: "h-4 w-1/2" })));
135311
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-sm font-Medium" }, title), /* @__PURE__ */ React169__namespace.default.createElement(Skeleton, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement(Skeleton, { className: "h-8 w-3/4 mb-2" }), /* @__PURE__ */ React169__namespace.default.createElement(Skeleton, { className: "h-4 w-1/2" })));
135362
135312
  }
135363
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-sm font-medium" }, title), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "text-muted-foreground" }, icon)), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "text-2xl font-bold" }, value, unit2 && /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-xl font-medium text-muted-foreground ml-1" }, unit2)), context && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, context)));
135313
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "text-sm font-Medium" }, title), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "text-muted-foreground" }, icon)), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "text-2xl font-bold" }, value, unit2 && /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "text-xl font-Medium text-muted-foreground ml-1" }, unit2)), context && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, context)));
135364
135314
  };
135365
135315
 
135366
135316
  // src/react-ui/components/dashboard/PerformanceSnapshot.tsx
@@ -135459,7 +135409,7 @@ var RoadmapChecklist = () => {
135459
135409
  }, []);
135460
135410
  const handleStartPractice = React169.useCallback((item) => {
135461
135411
  const practiceConfig = {
135462
- loIds: [item.loId],
135412
+ loIds: [item.code],
135463
135413
  difficulty: item.suggestedDifficulty,
135464
135414
  language: "Vietnamese"
135465
135415
  };
@@ -135469,7 +135419,7 @@ var RoadmapChecklist = () => {
135469
135419
  return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CalendarCheck, { className: "mr-2 h-5 w-5 text-primary" }), t4("roadmap.title")), /* @__PURE__ */ React169__namespace.default.createElement(CardDescription, null, t4("roadmap.description"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, !roadmap || !roadmap.items || roadmap.items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "text-center text-muted-foreground py-8" }, /* @__PURE__ */ React169__namespace.default.createElement("p", null, t4("roadmap.emptyState")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, t4("roadmap.emptyStateSuggestion"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, roadmap.items.map((item, index3) => /* @__PURE__ */ React169__namespace.default.createElement(
135470
135420
  "div",
135471
135421
  {
135472
- key: `${item.loId}-${index3}`,
135422
+ key: `${item.code}-${index3}`,
135473
135423
  className: "flex items-center justify-between p-3 border rounded-md bg-background hover:bg-muted/50 transition-colors"
135474
135424
  },
135475
135425
  /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React169__namespace.default.createElement(
@@ -137012,7 +136962,7 @@ function Calendar2({
137012
136962
  months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
137013
136963
  month: "space-y-4",
137014
136964
  caption: "flex justify-center pt-1 relative items-center",
137015
- caption_label: "text-sm font-medium",
136965
+ caption_label: "text-sm font-Medium",
137016
136966
  nav: "space-x-1 flex items-center",
137017
136967
  nav_button: cn(
137018
136968
  buttonVariants({ variant: "outline" }),
@@ -137134,7 +137084,7 @@ var AnalysisDialog = ({ isOpen, onClose }) => {
137134
137084
  }
137135
137085
  try {
137136
137086
  const allAvailableTopics = TopicDataService.getData().map((lo) => ({
137137
- loId: lo.loId,
137087
+ code: lo.code,
137138
137088
  subject: lo.subject,
137139
137089
  category: lo.category,
137140
137090
  topic: lo.topic
@@ -137587,7 +137537,7 @@ var GeneratedQuizzesCard = () => {
137587
137537
  onChange: (e3) => setSearchQuery2(e3.target.value),
137588
137538
  disabled: uniqueQuizzes.length === 0
137589
137539
  }
137590
- ), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm font-medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.noMatch"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.empty"))))));
137540
+ ), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm font-Medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.noMatch"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.empty"))))));
137591
137541
  };
137592
137542
 
137593
137543
  // src/react-ui/components/app/UploadResourceModal.tsx
@@ -137667,11 +137617,12 @@ var UploadResourceModal = ({ isOpen, onClose }) => {
137667
137617
  language: i18n.language === "vi" ? "Vietnamese" : "English",
137668
137618
  documentContent: textContent,
137669
137619
  learningObjectives: learningObjectives.map((lo) => ({
137670
- loId: lo.loId,
137620
+ name: lo.name,
137621
+ code: lo.code,
137671
137622
  subject: lo.subject,
137672
137623
  category: lo.category,
137673
137624
  topic: lo.topic,
137674
- loDescription: lo.loDescription
137625
+ description: lo.description || ""
137675
137626
  }))
137676
137627
  }, apiKey);
137677
137628
  setAnalysisResult(result);
@@ -137704,12 +137655,12 @@ var UploadResourceModal = ({ isOpen, onClose }) => {
137704
137655
  generatedQuestions = result.generatedQuestions;
137705
137656
  } else {
137706
137657
  const plan = analysisResult.mappedLOs.map((lo) => {
137707
- const sourceLO = TopicDataService.getData().find((orig) => orig.loId === lo.loId);
137658
+ const sourceLO = TopicDataService.getData().find((orig) => orig.code === lo.code);
137708
137659
  return {
137709
137660
  plannedTopic: lo.reasoning,
137710
137661
  plannedQuestionType: "multiple_choice",
137711
137662
  plannedBloomLevel: "understanding",
137712
- originalLoId: lo.loId,
137663
+ originalLoId: lo.code,
137713
137664
  originalTopic: sourceLO?.topic,
137714
137665
  originalCategory: sourceLO?.category,
137715
137666
  originalSubject: sourceLO?.subject
@@ -137754,7 +137705,7 @@ var UploadResourceModal = ({ isOpen, onClose }) => {
137754
137705
  return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col items-center justify-center h-48" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-12 w-12 animate-spin text-primary" }), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "mt-4 text-muted-foreground font-semibold" }, stage === "analyzing" && t4("dialogs.uploadResource.analyzing"), stage === "generating" && t4("dialogs.uploadResource.generating")));
137755
137706
  case "result":
137756
137707
  if (!analysisResult) return null;
137757
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "py-4 space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "p-4" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-2" }, "AI Analysis Complete"), analysisResult.isFreestyleRecommended ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-start gap-3 text-amber-700" }, /* @__PURE__ */ React169__namespace.default.createElement(BrainCircuit, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-medium" }, t4("dialogs.uploadResource.freestyleRecommended")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.freestyleDescription")))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-start gap-3 text-green-700" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-medium" }, t4("dialogs.uploadResource.curriculumMatch")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.curriculumDescription")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs mt-2 font-semibold" }, t4("dialogs.uploadResource.mappedTopics")), /* @__PURE__ */ React169__namespace.default.createElement("ul", { className: "list-disc list-inside text-xs" }, analysisResult.mappedLOs.map((lo) => /* @__PURE__ */ React169__namespace.default.createElement("li", { key: lo.loId }, TopicDataService.getData().find((orig) => orig.loId === lo.loId)?.topic || lo.loId))))))), error && /* @__PURE__ */ React169__namespace.default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__namespace.default.createElement(AlertTitle, null, t4("common.error")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDescription, null, error)));
137708
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "py-4 space-y-4" }, /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardContent, { className: "p-4" }, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-2" }, "AI Analysis Complete"), analysisResult.isFreestyleRecommended ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-start gap-3 text-amber-700" }, /* @__PURE__ */ React169__namespace.default.createElement(BrainCircuit, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-Medium" }, t4("dialogs.uploadResource.freestyleRecommended")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.freestyleDescription")))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-start gap-3 text-green-700" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleCheckBig, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-Medium" }, t4("dialogs.uploadResource.curriculumMatch")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.curriculumDescription")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-xs mt-2 font-semibold" }, t4("dialogs.uploadResource.mappedTopics")), /* @__PURE__ */ React169__namespace.default.createElement("ul", { className: "list-disc list-inside text-xs" }, analysisResult.mappedLOs.map((lo) => /* @__PURE__ */ React169__namespace.default.createElement("li", { key: lo.code }, TopicDataService.getData().find((orig) => orig.code === lo.code)?.topic || lo.code))))))), error && /* @__PURE__ */ React169__namespace.default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__namespace.default.createElement(AlertTitle, null, t4("common.error")), /* @__PURE__ */ React169__namespace.default.createElement(AlertDescription, null, error)));
137758
137709
  }
137759
137710
  };
137760
137711
  return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-lg" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(FileText, { className: "mr-2 h-5 w-5" }), t4("dialogs.uploadResource.title")), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, t4("dialogs.uploadResource.description"))), renderContent3(), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline" }, t4("common.cancel"))), stage === "result" && /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleGenerateQuiz }, /* @__PURE__ */ React169__namespace.default.createElement(Sparkles, { className: "mr-2 h-4 w-4" }), t4("dialogs.uploadResource.generateButton")))));
@@ -137875,7 +137826,7 @@ var FreestyleQuizzesCard = () => {
137875
137826
  onChange: (e3) => setSearchQuery2(e3.target.value),
137876
137827
  disabled: uniqueQuizzes.length === 0
137877
137828
  }
137878
- ), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm font-medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.noMatch"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.empty"))))));
137829
+ ), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm font-Medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.noMatch"))) : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.empty"))))));
137879
137830
  };
137880
137831
 
137881
137832
  // src/react-ui/components/common/ClientTranslation.tsx
@@ -138025,7 +137976,7 @@ var PersonalPracticeDashboard = ({ settingsPath, initialHistory, initialStats, i
138025
137976
  }
138026
137977
  try {
138027
137978
  const allAvailableTopics = TopicDataService.getData().map((lo) => ({
138028
- loId: lo.loId,
137979
+ code: lo.code,
138029
137980
  subject: lo.subject,
138030
137981
  category: lo.category,
138031
137982
  topic: lo.topic
@@ -138519,7 +138470,7 @@ var PracticeModeController = () => {
138519
138470
  try {
138520
138471
  const config3 = JSON.parse(suggestedConfigString);
138521
138472
  const allLOs = TopicDataService.getData();
138522
- const suggestedLOs = allLOs.filter((lo) => config3.loIds?.includes(lo.loId));
138473
+ const suggestedLOs = allLOs.filter((lo) => config3.loIds?.includes(lo.code));
138523
138474
  if (suggestedLOs.length > 0) {
138524
138475
  setInitialSuggestedLOs(suggestedLOs);
138525
138476
  setInitialSuggestedDifficulty(config3.difficulty || "Medium");
@@ -138562,9 +138513,10 @@ var PracticeModeController = () => {
138562
138513
  totalQuestions,
138563
138514
  numCodingQuestions,
138564
138515
  topics: selectedLOs.map((lo) => ({
138565
- topic: lo.loDescription,
138516
+ topic: lo.name || lo.code,
138517
+ // FIX: Provide fallback for name
138566
138518
  ratio: 100 / selectedLOs.length,
138567
- originalLoId: lo.loId,
138519
+ originalLoId: lo.code,
138568
138520
  originalSubject: lo.subject,
138569
138521
  originalCategory: lo.category,
138570
138522
  originalTopic: lo.topic
@@ -138756,7 +138708,7 @@ var SuggestionDialog = ({
138756
138708
  if (!suggestion) {
138757
138709
  return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex flex-col items-center justify-center h-64 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-muted-foreground text-center" }, "Kh\xF4ng th\u1EC3 t\u1EA1o g\u1EE3i \xFD v\xE0o l\xFAc n\xE0y. Vui l\xF2ng th\u1EED l\u1EA1i."));
138758
138710
  }
138759
- return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 bg-muted/50 rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: suggestion.suggestionText })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-3" }, "K\u1EBF ho\u1EA1ch Luy\u1EC7n t\u1EADp \u0111\u01B0\u1EE3c G\u1EE3i \xFD:"), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "max-h-[200px] pr-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, suggestion.suggestedTopics.map((topic) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: topic.loId, className: "flex items-center justify-between p-3 border rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-1 mr-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, topic.reason === "review" ? /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(RefreshCw, { className: "h-3 w-3 mr-1.5" }), "\xD4n t\u1EADp") : /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "secondary" }, /* @__PURE__ */ React169__namespace.default.createElement(Search, { className: "h-3 w-3 mr-1.5" }), "Kh\xE1m ph\xE1")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-medium" }, topic.topicName)), /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", onClick: () => onStartSuggestedPractice(topic) }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlay, { className: "h-4 w-4 mr-2" }), "B\u1EAFt \u0111\u1EA7u")))))));
138711
+ return /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "p-4 bg-muted/50 rounded-lg" }, /* @__PURE__ */ React169__namespace.default.createElement(MarkdownRenderer, { content: suggestion.suggestionText })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement("h4", { className: "font-semibold mb-3" }, "K\u1EBF ho\u1EA1ch Luy\u1EC7n t\u1EADp \u0111\u01B0\u1EE3c G\u1EE3i \xFD:"), /* @__PURE__ */ React169__namespace.default.createElement(ScrollArea2, { className: "max-h-[200px] pr-3" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, suggestion.suggestedTopics.map((topic) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: topic.code, className: "flex items-center justify-between p-3 border rounded-md" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex-1 mr-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, topic.reason === "review" ? /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(RefreshCw, { className: "h-3 w-3 mr-1.5" }), "\xD4n t\u1EADp") : /* @__PURE__ */ React169__namespace.default.createElement(Badge2, { variant: "secondary" }, /* @__PURE__ */ React169__namespace.default.createElement(Search, { className: "h-3 w-3 mr-1.5" }), "Kh\xE1m ph\xE1")), /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "font-Medium" }, topic.topicName)), /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", onClick: () => onStartSuggestedPractice(topic) }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlay, { className: "h-4 w-4 mr-2" }), "B\u1EAFt \u0111\u1EA7u")))))));
138760
138712
  };
138761
138713
  return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-lg md:max-w-xl" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, { className: "flex items-center text-2xl" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "h-6 w-6 mr-2 text-yellow-500" }), "G\u1EE3i \xFD Luy\u1EC7n t\u1EADp t\u1EEB AI"), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, "D\u1EF1a tr\xEAn k\u1EBFt qu\u1EA3 g\u1EA7n \u0111\xE2y, \u0111\xE2y l\xE0 nh\u1EEFng g\xEC gia s\u01B0 AI \u0111\u1EC1 xu\u1EA5t cho b\u1EA1n.")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "py-4" }, renderContent3()), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline" }, "\u0110\xF3ng")))));
138762
138714
  };
@@ -138766,12 +138718,96 @@ init_react_shim();
138766
138718
 
138767
138719
  // src/react-ui/components/metadata/SubjectManager.tsx
138768
138720
  init_react_shim();
138721
+
138722
+ // src/react-ui/components/metadata/MetadataImportControls.tsx
138723
+ init_react_shim();
138724
+ function MetadataImportControls({ metadataName, onImport }) {
138725
+ const [isOpen, setIsOpen] = React169.useState(false);
138726
+ const [jsonString, setJsonString] = React169.useState("");
138727
+ const [isImporting, startImportTransition] = React169.useTransition();
138728
+ const fileInputRef = React169.useRef(null);
138729
+ const { toast: toast2 } = useToast();
138730
+ const processAndImportRecords = async (records, importSource) => {
138731
+ if (records.length === 0) {
138732
+ toast2({ title: "No Data", description: `The selected ${importSource === "file" ? "file" : "JSON string"} contains no data to import.`, variant: "destructive" });
138733
+ return;
138734
+ }
138735
+ await onImport(records);
138736
+ setIsOpen(false);
138737
+ setJsonString("");
138738
+ };
138739
+ const handleFileSelected = (event) => {
138740
+ const file = event.target.files?.[0];
138741
+ if (!file) return;
138742
+ if (file.type !== "application/json" && !file.name.endsWith(".csv")) {
138743
+ toast2({ title: "Invalid File Type", description: "Please select a JSON or CSV file.", variant: "destructive" });
138744
+ if (event.target) event.target.value = "";
138745
+ return;
138746
+ }
138747
+ startImportTransition(async () => {
138748
+ try {
138749
+ const fileContent = await file.text();
138750
+ let records = [];
138751
+ if (file.type === "application/json") {
138752
+ records = JSON.parse(fileContent);
138753
+ if (!Array.isArray(records)) throw new Error("JSON file must contain an array of objects.");
138754
+ } else if (file.name.endsWith(".csv")) {
138755
+ const lines = fileContent.split(/\r\n|\n/).filter((line) => line.trim() !== "");
138756
+ if (lines.length < 2) throw new Error("CSV must have a header and at least one data row.");
138757
+ const headers = lines[0].split(",").map((h3) => h3.trim());
138758
+ records = lines.slice(1).map((line) => {
138759
+ const values = line.split(",").map((v) => v.trim());
138760
+ const record = {};
138761
+ headers.forEach((header, index3) => {
138762
+ record[header] = values[index3];
138763
+ });
138764
+ return record;
138765
+ });
138766
+ }
138767
+ await processAndImportRecords(records, "file");
138768
+ } catch (err) {
138769
+ toast2({ title: "Import Error", description: `Failed to process file: ${err.message}`, variant: "destructive" });
138770
+ }
138771
+ });
138772
+ if (event.target) event.target.value = "";
138773
+ };
138774
+ const handleJsonStringImport = () => {
138775
+ if (!jsonString.trim()) {
138776
+ toast2({ title: "Missing Data", description: "JSON string cannot be empty.", variant: "destructive" });
138777
+ return;
138778
+ }
138779
+ startImportTransition(async () => {
138780
+ try {
138781
+ const records = JSON.parse(jsonString);
138782
+ if (!Array.isArray(records)) throw new Error("JSON string must represent an array of objects.");
138783
+ await processAndImportRecords(records, "text");
138784
+ } catch (err) {
138785
+ toast2({ title: "Import Error", description: `Failed to process JSON string: ${err.message}`, variant: "destructive" });
138786
+ }
138787
+ });
138788
+ };
138789
+ return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React169__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React169__namespace.default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React169__namespace.default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React169__namespace.default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or CSV file. Ensure column names in the file match the table schema (e.g., 'code', 'name', 'subject_code')."), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline", onClick: () => fileInputRef.current?.click(), disabled: isImporting }, isImporting ? /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), isImporting ? "Importing..." : "Select File"), /* @__PURE__ */ React169__namespace.default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileSelected, accept: ".json,.csv", className: "hidden" }))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "text", className: "pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "jsonInput" }, "JSON Data (Array of Objects)"), /* @__PURE__ */ React169__namespace.default.createElement(
138790
+ Textarea,
138791
+ {
138792
+ id: "jsonInput",
138793
+ value: jsonString,
138794
+ onChange: (e3) => setJsonString(e3.target.value),
138795
+ placeholder: '[{"code": "SUB1", "name": "Subject 1"}, ...]',
138796
+ rows: 8,
138797
+ className: "font-mono text-xs",
138798
+ disabled: isImporting
138799
+ }
138800
+ ), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleJsonStringImport, disabled: isImporting || !jsonString.trim() }, isImporting ? /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__namespace.default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), "Import from Text"))))));
138801
+ }
138802
+
138803
+ // src/react-ui/components/metadata/SubjectManager.tsx
138769
138804
  function SubjectManager({
138770
138805
  initialData,
138771
138806
  isLoading: isLoadingProp,
138772
138807
  onAdd,
138773
138808
  onUpdate,
138774
- onDelete
138809
+ onDelete,
138810
+ onBulkAdd
138775
138811
  }) {
138776
138812
  const [subjects, setSubjects] = React169.useState([]);
138777
138813
  const [isLoading, setIsLoading] = React169.useState(true);
@@ -138869,12 +138905,37 @@ function SubjectManager({
138869
138905
  }
138870
138906
  });
138871
138907
  };
138872
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e3) => setSubjectName(e3.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
138908
+ const handleImport = async (records) => {
138909
+ if (!onBulkAdd) return;
138910
+ const validatedRecords = records.map((rec) => {
138911
+ if (typeof rec.code === "string" && typeof rec.name === "string") {
138912
+ return { code: rec.code, name: rec.name };
138913
+ }
138914
+ return null;
138915
+ }).filter((rec) => rec !== null);
138916
+ if (validatedRecords.length !== records.length) {
138917
+ toast2({
138918
+ title: "Import Warning",
138919
+ description: "Some records had invalid or missing 'code' or 'name' fields and were ignored.",
138920
+ variant: "destructive"
138921
+ });
138922
+ }
138923
+ if (validatedRecords.length > 0) {
138924
+ await onBulkAdd(validatedRecords);
138925
+ }
138926
+ };
138927
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(
138928
+ MetadataImportControls,
138929
+ {
138930
+ metadataName: "Subjects",
138931
+ onImport: handleImport
138932
+ }
138933
+ ), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, subject.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e3) => setSubjectName(e3.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
138873
138934
  }
138874
138935
 
138875
138936
  // src/react-ui/components/metadata/GradeLevelManager.tsx
138876
138937
  init_react_shim();
138877
- function GradeLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
138938
+ function GradeLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
138878
138939
  const [items, setItems] = React169.useState([]);
138879
138940
  const [isLoading, setIsLoading] = React169.useState(true);
138880
138941
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
@@ -138971,7 +139032,26 @@ function GradeLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpd
138971
139032
  }
138972
139033
  });
138973
139034
  };
138974
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Award, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Grade Levels"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Grade Level"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No grade levels found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Grade Level" : "Add New Grade Level")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., G9", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Grade 9" }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139035
+ const handleImport = async (records) => {
139036
+ if (!onBulkAdd) return;
139037
+ const validatedRecords = records.map((rec) => {
139038
+ if (typeof rec.code === "string" && typeof rec.name === "string") {
139039
+ return { code: rec.code, name: rec.name };
139040
+ }
139041
+ return null;
139042
+ }).filter((rec) => rec !== null);
139043
+ if (validatedRecords.length !== records.length) {
139044
+ toast2({
139045
+ title: "Import Warning",
139046
+ description: "Some records had invalid or missing 'code' or 'name' fields and were ignored.",
139047
+ variant: "destructive"
139048
+ });
139049
+ }
139050
+ if (validatedRecords.length > 0) {
139051
+ await onBulkAdd(validatedRecords);
139052
+ }
139053
+ };
139054
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Award, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Grade Levels"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Grade Levels", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Grade Level")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No grade levels found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Grade Level" : "Add New Grade Level")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., G9", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Grade 9" }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
138975
139055
  }
138976
139056
 
138977
139057
  // src/react-ui/components/metadata/TopicManager.tsx
@@ -138982,7 +139062,8 @@ function TopicManager({
138982
139062
  isLoading: isLoadingProp,
138983
139063
  onAdd,
138984
139064
  onUpdate,
138985
- onDelete
139065
+ onDelete,
139066
+ onBulkAdd
138986
139067
  }) {
138987
139068
  const [topics, setTopics] = React169.useState([]);
138988
139069
  const [subjects, setSubjects] = React169.useState([]);
@@ -139086,15 +139167,34 @@ function TopicManager({
139086
139167
  }
139087
139168
  });
139088
139169
  };
139170
+ const handleImport = async (records) => {
139171
+ if (!onBulkAdd) return;
139172
+ const validatedRecords = records.map((rec) => {
139173
+ if (typeof rec.code === "string" && typeof rec.name === "string" && typeof rec.subjectCode === "string") {
139174
+ return { code: rec.code, name: rec.name, subjectCode: rec.subjectCode };
139175
+ }
139176
+ return null;
139177
+ }).filter((rec) => rec !== null);
139178
+ if (validatedRecords.length !== records.length) {
139179
+ toast2({
139180
+ title: "Import Warning",
139181
+ description: "Some records had invalid or missing 'code', 'name', or 'subjectCode' fields and were ignored.",
139182
+ variant: "destructive"
139183
+ });
139184
+ }
139185
+ if (validatedRecords.length > 0) {
139186
+ await onBulkAdd(validatedRecords);
139187
+ }
139188
+ };
139089
139189
  const getSubjectName = (subjectCode) => {
139090
139190
  return subjects.find((s4) => s4.code === subjectCode)?.name || "N/A";
139091
139191
  };
139092
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Tag, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Topics"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm", disabled: subjects.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic")), subjects.length === 0 && !isLoading && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-destructive" }, "Please add subjects before adding topics.")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : topics.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No topics found. Add one to get started!") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, topics.map((topic) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: topic.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, topic.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, topic.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getSubjectName(topic.subjectCode), " (", topic.subjectCode, ")"), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(topic), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(topic), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Topic" : "Add New Topic")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Topic Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., ALG-BASICS", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Topic Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Algebra Basics" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: selectedSubjectCode, onValueChange: setSelectedSubjectCode, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, subjects.map((subject) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: subject.code, value: subject.code }, subject.name, " (", subject.code, ")")))))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() || !selectedSubjectCode }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete topic "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139192
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Tag, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Topics"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Topics", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm", disabled: subjects.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic"))), subjects.length === 0 && !isLoading && /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-destructive" }, "Please add subjects before adding topics.")), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : topics.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No topics found. Add one to get started!") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, topics.map((topic) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: topic.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, topic.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, topic.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getSubjectName(topic.subjectCode), " (", topic.subjectCode, ")"), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(topic), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(topic), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Topic" : "Add New Topic")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Topic Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., ALG-BASICS", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Topic Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Algebra Basics" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: selectedSubjectCode, onValueChange: setSelectedSubjectCode, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, subjects.map((subject) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: subject.code, value: subject.code }, subject.name, " (", subject.code, ")")))))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() || !selectedSubjectCode }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete topic "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139093
139193
  }
139094
139194
 
139095
139195
  // src/react-ui/components/metadata/CategoryManager.tsx
139096
139196
  init_react_shim();
139097
- function CategoryManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139197
+ function CategoryManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139098
139198
  const [items, setItems] = React169.useState([]);
139099
139199
  const [isLoading, setIsLoading] = React169.useState(true);
139100
139200
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
@@ -139194,12 +139294,37 @@ function CategoryManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdat
139194
139294
  }
139195
139295
  });
139196
139296
  };
139197
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Layers, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Categories"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Category"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No categories found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Category" : "Add New Category")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., CORE_CONCEPT", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Core Concept" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Fundamental ideas within a subject." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139297
+ const handleImport = async (records) => {
139298
+ if (!onBulkAdd) return;
139299
+ const validationResult = records.reduce((acc, rec) => {
139300
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139301
+ acc.valid.push({
139302
+ code: rec.code,
139303
+ name: rec.name,
139304
+ description: typeof rec.description === "string" ? rec.description : void 0
139305
+ });
139306
+ } else {
139307
+ acc.invalidCount++;
139308
+ }
139309
+ return acc;
139310
+ }, { valid: [], invalidCount: 0 });
139311
+ if (validationResult.invalidCount > 0) {
139312
+ toast2({
139313
+ title: "Import Warning",
139314
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139315
+ variant: "destructive"
139316
+ });
139317
+ }
139318
+ if (validationResult.valid.length > 0) {
139319
+ await onBulkAdd(validationResult.valid);
139320
+ }
139321
+ };
139322
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Layers, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Categories"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Categories", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Category")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No categories found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Category" : "Add New Category")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., CORE_CONCEPT", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Core Concept" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Fundamental ideas within a subject." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139198
139323
  }
139199
139324
 
139200
139325
  // src/react-ui/components/metadata/BloomLevelManager.tsx
139201
139326
  init_react_shim();
139202
- function BloomLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139327
+ function BloomLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139203
139328
  const [items, setItems] = React169.useState([]);
139204
139329
  const [isLoading, setIsLoading] = React169.useState(true);
139205
139330
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
@@ -139299,12 +139424,37 @@ function BloomLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpd
139299
139424
  }
139300
139425
  });
139301
139426
  };
139302
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Brain, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Bloom's Levels"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Bloom's Level"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Bloom's Levels found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Bloom's Level" : "Add New Bloom's Level")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., REMEMBER", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Remembering" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Recall facts and basic concepts." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139427
+ const handleImport = async (records) => {
139428
+ if (!onBulkAdd) return;
139429
+ const validationResult = records.reduce((acc, rec) => {
139430
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139431
+ acc.valid.push({
139432
+ code: rec.code,
139433
+ name: rec.name,
139434
+ description: typeof rec.description === "string" ? rec.description : void 0
139435
+ });
139436
+ } else {
139437
+ acc.invalidCount++;
139438
+ }
139439
+ return acc;
139440
+ }, { valid: [], invalidCount: 0 });
139441
+ if (validationResult.invalidCount > 0) {
139442
+ toast2({
139443
+ title: "Import Warning",
139444
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139445
+ variant: "destructive"
139446
+ });
139447
+ }
139448
+ if (validationResult.valid.length > 0) {
139449
+ await onBulkAdd(validationResult.valid);
139450
+ }
139451
+ };
139452
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Brain, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Bloom's Levels"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Bloom's Levels", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Bloom's Level")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Bloom's Levels found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Bloom's Level" : "Add New Bloom's Level")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., REMEMBER", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Remembering" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Recall facts and basic concepts." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139303
139453
  }
139304
139454
 
139305
139455
  // src/react-ui/components/metadata/QuestionTypeManager.tsx
139306
139456
  init_react_shim();
139307
- function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139457
+ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139308
139458
  const [items, setItems] = React169.useState([]);
139309
139459
  const [isLoading, setIsLoading] = React169.useState(true);
139310
139460
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
@@ -139374,6 +139524,31 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
139374
139524
  }
139375
139525
  });
139376
139526
  };
139527
+ const handleImport = async (records) => {
139528
+ if (!onBulkAdd) return;
139529
+ const validationResult = records.reduce((acc, rec) => {
139530
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139531
+ acc.valid.push({
139532
+ code: rec.code,
139533
+ name: rec.name,
139534
+ description: typeof rec.description === "string" ? rec.description : void 0
139535
+ });
139536
+ } else {
139537
+ acc.invalidCount++;
139538
+ }
139539
+ return acc;
139540
+ }, { valid: [], invalidCount: 0 });
139541
+ if (validationResult.invalidCount > 0) {
139542
+ toast2({
139543
+ title: "Import Warning",
139544
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139545
+ variant: "destructive"
139546
+ });
139547
+ }
139548
+ if (validationResult.valid.length > 0) {
139549
+ await onBulkAdd(validationResult.valid);
139550
+ }
139551
+ };
139377
139552
  const handleSubmit = () => {
139378
139553
  if (!itemName.trim() || !itemCode.trim()) {
139379
139554
  toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
@@ -139404,22 +139579,19 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
139404
139579
  }
139405
139580
  });
139406
139581
  };
139407
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleHelp, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Question Types"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Question Type"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Question Types found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Question Type" : "Add New Question Type")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toLowerCase().replace(/ /g, "_")), placeholder: "e.g., multiple_choice", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Multiple Choice" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Select one answer from a list of options." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139582
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(CircleHelp, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Question Types"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Question Types", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Question Type")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Question Types found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Question Type" : "Add New Question Type")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toLowerCase().replace(/ /g, "_")), placeholder: "e.g., multiple_choice", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Multiple Choice" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Select one answer from a list of options." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139408
139583
  }
139409
139584
 
139410
139585
  // src/react-ui/components/metadata/LearningObjectiveManager.tsx
139411
139586
  init_react_shim();
139412
- function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139587
+ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139413
139588
  const [items, setItems] = React169.useState([]);
139414
139589
  const [subjects, setSubjects] = React169.useState([]);
139415
139590
  const [isLoading, setIsLoading] = React169.useState(true);
139416
139591
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
139417
139592
  const [isAlertOpen, setIsAlertOpen] = React169.useState(false);
139418
139593
  const [currentItem, setCurrentItem] = React169.useState(null);
139419
- const [itemName, setItemName] = React169.useState("");
139420
- const [itemCode, setItemCode] = React169.useState("");
139421
- const [itemDescription, setItemDescription] = React169.useState("");
139422
- const [selectedSubjectCode, setSelectedSubjectCode] = React169.useState(void 0);
139594
+ const [formState, setFormState] = React169.useState({});
139423
139595
  const [itemToDelete, setItemToDelete] = React169.useState(null);
139424
139596
  const [isPending, startTransition] = React169.useTransition();
139425
139597
  const { toast: toast2 } = useToast();
@@ -139446,20 +139618,17 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139446
139618
  refreshData();
139447
139619
  }
139448
139620
  }, [isControlled, initialData, subjectsProp, isLoadingProp]);
139621
+ const handleFormChange = (field, value) => {
139622
+ setFormState((prev) => ({ ...prev, [field]: value }));
139623
+ };
139449
139624
  const handleAddItem = () => {
139450
139625
  setCurrentItem(null);
139451
- setItemName("");
139452
- setItemCode("");
139453
- setItemDescription("");
139454
- setSelectedSubjectCode(subjects.length > 0 ? subjects[0].code : void 0);
139626
+ setFormState({ subjectCode: subjects.length > 0 ? subjects[0].code : "" });
139455
139627
  setIsDialogOpen(true);
139456
139628
  };
139457
139629
  const handleEditItem = (item) => {
139458
139630
  setCurrentItem(item);
139459
- setItemName(item.name);
139460
- setItemCode(item.code);
139461
- setItemDescription(item.description || "");
139462
- setSelectedSubjectCode(item.subjectCode);
139631
+ setFormState(item);
139463
139632
  setIsDialogOpen(true);
139464
139633
  };
139465
139634
  const handleDeleteItem = (item) => {
@@ -139486,7 +139655,7 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139486
139655
  });
139487
139656
  };
139488
139657
  const handleSubmit = () => {
139489
- if (!itemName.trim() || !itemCode.trim()) {
139658
+ if (!formState.name?.trim() || !formState.code?.trim()) {
139490
139659
  toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
139491
139660
  return;
139492
139661
  }
@@ -139494,17 +139663,17 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139494
139663
  try {
139495
139664
  if (currentItem) {
139496
139665
  if (isControlled && onUpdate) {
139497
- await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, subjectCode: selectedSubjectCode, description: itemDescription });
139666
+ await onUpdate({ ...currentItem, ...formState });
139498
139667
  } else {
139499
- MetadataService.updateLearningObjective(currentItem.id, itemName, itemCode, selectedSubjectCode, itemDescription);
139668
+ MetadataService.updateLearningObjective(currentItem.id, formState);
139500
139669
  refreshData();
139501
139670
  }
139502
139671
  toast2({ title: "Success", description: "Learning Objective updated." });
139503
139672
  } else {
139504
139673
  if (isControlled && onAdd) {
139505
- await onAdd({ name: itemName, code: itemCode, subjectCode: selectedSubjectCode, description: itemDescription });
139674
+ await onAdd(formState);
139506
139675
  } else {
139507
- MetadataService.addLearningObjective(itemName, itemCode, selectedSubjectCode, itemDescription);
139676
+ MetadataService.addLearningObjective(formState);
139508
139677
  refreshData();
139509
139678
  }
139510
139679
  toast2({ title: "Success", description: "Learning Objective added." });
@@ -139515,16 +139684,14 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139515
139684
  }
139516
139685
  });
139517
139686
  };
139518
- const getSubjectName = (subjectCode) => {
139519
- if (!subjectCode) return "N/A";
139520
- return subjects.find((s4) => s4.code === subjectCode)?.name || "N/A";
139687
+ const handleImport = async (records) => {
139521
139688
  };
139522
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, getSubjectName(item.subjectCode)), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemSubject" }, "Subject (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: selectedSubjectCode || "", onValueChange: (value) => setSelectedSubjectCode(value === "_NONE_" ? void 0 : value) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, { id: "itemSubject" }, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { value: "_NONE_" }, "No Specific Subject"), subjects.map((subject) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: subject.id, value: subject.code }, subject.name))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139689
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Learning Objectives", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => handleFormChange("code", e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => handleFormChange("name", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "subject", value: formState.subject || "", onChange: (e3) => handleFormChange("subject", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: subjects.map((s4) => ({ value: s4.code, label: s4.name })), value: formState.subjectCode || "", onChange: (val) => handleFormChange("subjectCode", val), placeholder: "Select a subject..." }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "category", value: formState.category || "", onChange: (e3) => handleFormChange("category", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "categoryCode", value: formState.categoryCode || "", onChange: (e3) => handleFormChange("categoryCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "topic", value: formState.topic || "", onChange: (e3) => handleFormChange("topic", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "topicCode", value: formState.topicCode || "", onChange: (e3) => handleFormChange("topicCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "grade", value: formState.grade || "", onChange: (e3) => handleFormChange("grade", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "gradeCode", value: formState.gradeCode || "", onChange: (e3) => handleFormChange("gradeCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "keywords", value: formState.keywords?.join(", ") || "", onChange: (e3) => handleFormChange("keywords", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "stemElements", value: formState.stemElements?.join(", ") || "", onChange: (e3) => handleFormChange("stemElements", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "bloomLevelsGuideline", value: formState.bloomLevelsGuideline?.join(", ") || "", onChange: (e3) => handleFormChange("bloomLevelsGuideline", e3.target.value.split(",").map((s4) => s4.trim())) }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.name?.trim() || !formState.code?.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139523
139690
  }
139524
139691
 
139525
139692
  // src/react-ui/components/metadata/ContextManager.tsx
139526
139693
  init_react_shim();
139527
- function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139694
+ function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139528
139695
  const [items, setItems] = React169.useState([]);
139529
139696
  const [isLoading, setIsLoading] = React169.useState(true);
139530
139697
  const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
@@ -139594,6 +139761,31 @@ function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate
139594
139761
  }
139595
139762
  });
139596
139763
  };
139764
+ const handleImport = async (records) => {
139765
+ if (!onBulkAdd) return;
139766
+ const validationResult = records.reduce((acc, rec) => {
139767
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139768
+ acc.valid.push({
139769
+ code: rec.code,
139770
+ name: rec.name,
139771
+ description: typeof rec.description === "string" ? rec.description : void 0
139772
+ });
139773
+ } else {
139774
+ acc.invalidCount++;
139775
+ }
139776
+ return acc;
139777
+ }, { valid: [], invalidCount: 0 });
139778
+ if (validationResult.invalidCount > 0) {
139779
+ toast2({
139780
+ title: "Import Warning",
139781
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139782
+ variant: "destructive"
139783
+ });
139784
+ }
139785
+ if (validationResult.valid.length > 0) {
139786
+ await onBulkAdd(validationResult.valid);
139787
+ }
139788
+ };
139597
139789
  const handleSubmit = () => {
139598
139790
  if (!itemName.trim() || !itemCode.trim()) {
139599
139791
  toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
@@ -139624,13 +139816,13 @@ function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate
139624
139816
  }
139625
139817
  });
139626
139818
  };
139627
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(ScanText, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Contexts"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Context"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Contexts found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Context" : "Add New Context")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., HIST_INQ", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Historical Inquiry" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Analyzing primary and secondary sources." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139819
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(ScanText, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Contexts"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Categories", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Context")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Contexts found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Context" : "Add New Context")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., HIST_INQ", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Historical Inquiry" })), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Analyzing primary and secondary sources." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139628
139820
  }
139629
139821
 
139630
139822
  // src/react-ui/components/metadata/ApproachManager.tsx
139631
139823
  init_react_shim();
139632
139824
  var knowledgeDimensions = ["Factual", "Conceptual", "Procedural"];
139633
- var rawDifficultyLevels = ["E", "E~M", "M", "M~H", "H"];
139825
+ var standardDifficulties = ["Easy", "Medium", "Hard"];
139634
139826
  function ApproachManager({
139635
139827
  initialData,
139636
139828
  bloomLevels: bloomLevelsProp,
@@ -139638,7 +139830,8 @@ function ApproachManager({
139638
139830
  isLoading: isLoadingProp,
139639
139831
  onAdd,
139640
139832
  onUpdate,
139641
- onDelete
139833
+ onDelete,
139834
+ onBulkAdd
139642
139835
  }) {
139643
139836
  const [items, setItems] = React169.useState([]);
139644
139837
  const [bloomLevels, setBloomLevels] = React169.useState([]);
@@ -139679,7 +139872,7 @@ function ApproachManager({
139679
139872
  const resetForm = () => {
139680
139873
  setFormState({
139681
139874
  knowledgeDimension: "Factual",
139682
- rawDifficulty: "E",
139875
+ difficulty: ["Medium"],
139683
139876
  bloomLevelCode: bloomLevels.length > 0 ? bloomLevels[0].code : "",
139684
139877
  iSpringQuizType: questionTypes.length > 0 ? questionTypes[0].code : "multiple_choice"
139685
139878
  });
@@ -139691,18 +139884,7 @@ function ApproachManager({
139691
139884
  };
139692
139885
  const handleEditItem = (item) => {
139693
139886
  setCurrentItem(item);
139694
- setFormState({
139695
- code: item.code,
139696
- verbEn: item.verbEn,
139697
- verbVi: item.verbVi,
139698
- bloomLevelCode: item.bloomLevelCode,
139699
- knowledgeDimension: item.knowledgeDimension,
139700
- iSpringQuizType: item.iSpringQuizType,
139701
- rawDifficulty: item.rawDifficulty,
139702
- suggestContext: item.suggestContext,
139703
- exampleEn: item.exampleEn,
139704
- exampleVi: item.exampleVi
139705
- });
139887
+ setFormState(item);
139706
139888
  setIsDialogOpen(true);
139707
139889
  };
139708
139890
  const handleDeleteItem = (item) => {
@@ -139729,9 +139911,9 @@ function ApproachManager({
139729
139911
  });
139730
139912
  };
139731
139913
  const handleSubmit = () => {
139732
- const { code: code4, verbEn, verbVi, bloomLevelCode, iSpringQuizType, knowledgeDimension, rawDifficulty } = formState;
139733
- if (!code4?.trim() || !verbEn?.trim() || !verbVi?.trim() || !bloomLevelCode || !iSpringQuizType || !knowledgeDimension || !rawDifficulty) {
139734
- toast2({ title: "Validation Error", description: "All fields except examples and context are required.", variant: "destructive" });
139914
+ const { code: code4, name: name3, verbEn, verbVi, bloomLevelCode, iSpringQuizType, knowledgeDimension, difficulty } = formState;
139915
+ if (!code4?.trim() || !name3?.trim() || !verbEn?.trim() || !verbVi?.trim() || !bloomLevelCode || !iSpringQuizType || !knowledgeDimension || !difficulty || difficulty.length === 0) {
139916
+ toast2({ title: "Validation Error", description: "All fields except examples and context are required, and at least one difficulty must be selected.", variant: "destructive" });
139735
139917
  return;
139736
139918
  }
139737
139919
  startTransition(async () => {
@@ -139759,7 +139941,47 @@ function ApproachManager({
139759
139941
  }
139760
139942
  });
139761
139943
  };
139762
- return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Settings2, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Approaches"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Approach"))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Approaches found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Approach ID"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Verb (VI)"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Cognitive Level"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "iSpring Type"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.verbVi), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.bloomLevelCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.iSpringQuizType), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Approach" : "Add New Approach")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Approach Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => setFormState((s4) => ({ ...s4, code: e3.target.value.toUpperCase() })), placeholder: "e.g., REM-FAC-IDT-MCQ", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "verbEn" }, "Verb (English)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "verbEn", value: formState.verbEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, verbEn: e3.target.value })), placeholder: "e.g., Identify" }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "verbVi" }, "Verb (Vietnamese)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "verbVi", value: formState.verbVi || "", onChange: (e3) => setFormState((s4) => ({ ...s4, verbVi: e3.target.value })), placeholder: "e.g., Nh\u1EADn d\u1EA1ng" })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Cognitive Level"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: formState.bloomLevelCode, onValueChange: (v) => setFormState((s4) => ({ ...s4, bloomLevelCode: v })) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, bloomLevels.map((level) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: level.code, value: level.code }, level.name)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "knowledgeDimension" }, "Knowledge Dimension"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: formState.knowledgeDimension, onValueChange: (v) => setFormState((s4) => ({ ...s4, knowledgeDimension: v })) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, knowledgeDimensions.map((kd) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: kd, value: kd }, kd))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "iSpringQuizType" }, "iSpring Quiz Type"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: formState.iSpringQuizType, onValueChange: (v) => setFormState((s4) => ({ ...s4, iSpringQuizType: v })) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, questionTypes.map((qt) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "rawDifficulty" }, "Raw Difficulty"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: formState.rawDifficulty, onValueChange: (v) => setFormState((s4) => ({ ...s4, rawDifficulty: v })) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, rawDifficultyLevels.map((rd) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: rd, value: rd }, rd)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "suggestContext" }, "Suggest Context (comma-separated codes)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "suggestContext", value: formState.suggestContext || "", onChange: (e3) => setFormState((s4) => ({ ...s4, suggestContext: e3.target.value })), placeholder: "e.g., A, B, D, G, H" })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "exampleEn" }, "Example (English)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "exampleEn", value: formState.exampleEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleEn: e3.target.value })), placeholder: "English example prompt..." })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "exampleVi" }, "Example (Vietnamese)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "exampleVi", value: formState.exampleVi || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleVi: e3.target.value })), placeholder: "Vietnamese example prompt..." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.code, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139944
+ const handleImport = async (records) => {
139945
+ if (!onBulkAdd) return;
139946
+ const parseStringToArray = (input) => {
139947
+ if (Array.isArray(input)) return input;
139948
+ if (typeof input === "string") return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139949
+ return [];
139950
+ };
139951
+ const validatedRecords = records.reduce((acc, rec) => {
139952
+ if (rec.code && rec.name && rec.verbEn && rec.verbVi && rec.knowledgeDimension && rec.iSpringQuizType && rec.difficulty && rec.bloomLevelCode) {
139953
+ acc.push({
139954
+ code: rec.code,
139955
+ name: rec.name,
139956
+ verbEn: rec.verbEn,
139957
+ verbVi: rec.verbVi,
139958
+ knowledgeDimension: rec.knowledgeDimension,
139959
+ iSpringQuizType: rec.iSpringQuizType,
139960
+ difficulty: parseStringToArray(rec.difficulty),
139961
+ bloomLevelCode: rec.bloomLevelCode,
139962
+ suggestContext: rec.suggestContext,
139963
+ exampleEn: rec.exampleEn,
139964
+ exampleVi: rec.exampleVi
139965
+ });
139966
+ }
139967
+ return acc;
139968
+ }, []);
139969
+ if (validatedRecords.length !== records.length) {
139970
+ toast2({
139971
+ title: "Import Warning",
139972
+ description: `${records.length - validatedRecords.length} records had missing required fields and were ignored.`,
139973
+ variant: "destructive"
139974
+ });
139975
+ }
139976
+ if (validatedRecords.length > 0) {
139977
+ await onBulkAdd(validatedRecords);
139978
+ }
139979
+ };
139980
+ return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Settings2, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Approaches"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Approaches", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Approach")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Approaches found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Approach ID"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Verb (VI)"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Cognitive Level"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-Medium" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.verbVi), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.bloomLevelCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Approach" : "Add New Approach")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Approach Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => setFormState((s4) => ({ ...s4, code: e3.target.value.toUpperCase() })), placeholder: "e.g., REM-FAC-IDT-MCQ", disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "name" }, "Name / Description"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => setFormState((s4) => ({ ...s4, name: e3.target.value })), placeholder: "e.g., Identify a Fact" }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "verbEn" }, "Verb (English)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "verbEn", value: formState.verbEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, verbEn: e3.target.value })), placeholder: "e.g., Identify" })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "verbVi" }, "Verb (Vietnamese)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "verbVi", value: formState.verbVi || "", onChange: (e3) => setFormState((s4) => ({ ...s4, verbVi: e3.target.value })), placeholder: "e.g., Nh\u1EADn d\u1EA1ng" }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Cognitive Level"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: formState.bloomLevelCode, onValueChange: (v) => setFormState((s4) => ({ ...s4, bloomLevelCode: v })) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, bloomLevels.map((level) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: level.code, value: level.code }, level.name))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "knowledgeDimension" }, "Knowledge Dimension"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: formState.knowledgeDimension, onValueChange: (v) => setFormState((s4) => ({ ...s4, knowledgeDimension: v })) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, knowledgeDimensions.map((kd) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: kd, value: kd }, kd))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "iSpringQuizType" }, "iSpring Quiz Type"), /* @__PURE__ */ React169__namespace.default.createElement(Select2, { value: formState.iSpringQuizType, onValueChange: (v) => setFormState((s4) => ({ ...s4, iSpringQuizType: v })) }, /* @__PURE__ */ React169__namespace.default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__namespace.default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__namespace.default.createElement(SelectContent2, null, questionTypes.map((qt) => /* @__PURE__ */ React169__namespace.default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name)))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, null, "Difficulty"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center space-x-4 pt-2" }, standardDifficulties.map((diff2) => /* @__PURE__ */ React169__namespace.default.createElement("div", { key: diff2, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__namespace.default.createElement(Checkbox2, { id: `diff-${diff2}`, checked: (formState.difficulty || []).includes(diff2), onCheckedChange: (checked) => {
139981
+ const current = formState.difficulty || [];
139982
+ const newDiff = checked ? [...current, diff2] : current.filter((d) => d !== diff2);
139983
+ setFormState((s4) => ({ ...s4, difficulty: newDiff }));
139984
+ } }), /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: `diff-${diff2}` }, diff2))))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "suggestContext" }, "Suggest Context (comma-separated codes)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "suggestContext", value: formState.suggestContext || "", onChange: (e3) => setFormState((s4) => ({ ...s4, suggestContext: e3.target.value })), placeholder: "e.g., A, B, D, G, H" })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "exampleEn" }, "Example (English)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "exampleEn", value: formState.exampleEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleEn: e3.target.value })), placeholder: "English example prompt..." })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "exampleVi" }, "Example (Vietnamese)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "exampleVi", value: formState.exampleVi || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleVi: e3.target.value })), placeholder: "Vietnamese example prompt..." }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.code, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139763
139985
  }
139764
139986
 
139765
139987
  // src/react-ui/components/metadata/MetadataTabs.tsx
@@ -140435,7 +140657,7 @@ var ToastAction2 = React169__namespace.forwardRef(({ className, ...props }, ref)
140435
140657
  {
140436
140658
  ref,
140437
140659
  className: cn(
140438
- "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
140660
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-Medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
140439
140661
  className
140440
140662
  ),
140441
140663
  ...props
@@ -142073,6 +142295,7 @@ exports.Label = Label2;
142073
142295
  exports.LanguageProvider = LanguageProvider;
142074
142296
  exports.LearningObjectiveManager = LearningObjectiveManager;
142075
142297
  exports.ManageTopics = ManageTopics;
142298
+ exports.MetadataImportControls = MetadataImportControls;
142076
142299
  exports.MetadataTabs = MetadataTabs;
142077
142300
  exports.PerformanceCharts = PerformanceCharts;
142078
142301
  exports.PersonalPracticeDashboard = PersonalPracticeDashboard;