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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react-ui.mjs CHANGED
@@ -9019,7 +9019,7 @@ var translation_default = {
9019
9019
  subject: "Subject",
9020
9020
  category: "Category",
9021
9021
  topic: "Topic",
9022
- loId: "LO ID"
9022
+ code: "LO ID"
9023
9023
  },
9024
9024
  confirmModal: {
9025
9025
  title: "Confirm Data Import",
@@ -9434,7 +9434,7 @@ var translation_default2 = {
9434
9434
  subject: "M\xF4n h\u1ECDc",
9435
9435
  category: "Danh m\u1EE5c",
9436
9436
  topic: "Ch\u1EE7 \u0111\u1EC1",
9437
- loId: "M\xE3 MTH"
9437
+ code: "M\xE3 MTH"
9438
9438
  },
9439
9439
  confirmModal: {
9440
9440
  title: "X\xE1c nh\u1EADn Nh\u1EADp D\u1EEF li\u1EC7u",
@@ -37506,7 +37506,7 @@ var cva = (base3, config3) => (props) => {
37506
37506
 
37507
37507
  // src/react-ui/components/elements/label.tsx
37508
37508
  var labelVariants = cva(
37509
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
37509
+ "text-sm font-Medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
37510
37510
  );
37511
37511
  var Label2 = React169.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React169.createElement(
37512
37512
  Root3,
@@ -62744,7 +62744,7 @@ var MarkdownRenderer = ({
62744
62744
  },
62745
62745
  h1: ({ node: node2, ...props }) => /* @__PURE__ */ React169__default.createElement("h1", { ...props, className: "text-3xl font-bold mb-6 mt-8 first:mt-0" }),
62746
62746
  h2: ({ node: node2, ...props }) => /* @__PURE__ */ React169__default.createElement("h2", { ...props, className: "text-2xl font-semibold mb-4 mt-6" }),
62747
- h3: ({ node: node2, ...props }) => /* @__PURE__ */ React169__default.createElement("h3", { ...props, className: "text-xl font-medium mb-3 mt-5" }),
62747
+ h3: ({ node: node2, ...props }) => /* @__PURE__ */ React169__default.createElement("h3", { ...props, className: "text-xl font-Medium mb-3 mt-5" }),
62748
62748
  ul: ({ node: node2, ...props }) => /* @__PURE__ */ React169__default.createElement("ul", { ...props, className: "my-4 space-y-2 list-disc list-inside" }),
62749
62749
  ol: ({ node: node2, ...props }) => /* @__PURE__ */ React169__default.createElement("ol", { ...props, className: "my-4 space-y-2 list-decimal list-inside" }),
62750
62750
  p: ({ node: node2, ...props }) => /* @__PURE__ */ React169__default.createElement("p", { ...props, className: "mb-4 leading-7" }),
@@ -63218,7 +63218,7 @@ var Input = React169.forwardRef(
63218
63218
  {
63219
63219
  type,
63220
63220
  className: cn(
63221
- "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",
63221
+ "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",
63222
63222
  className
63223
63223
  ),
63224
63224
  ref,
@@ -63393,7 +63393,7 @@ init_react_shim();
63393
63393
  // src/react-ui/components/elements/button.tsx
63394
63394
  init_react_shim();
63395
63395
  var buttonVariants = cva(
63396
- "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",
63396
+ "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",
63397
63397
  {
63398
63398
  variants: {
63399
63399
  variant: {
@@ -68346,7 +68346,7 @@ var MatchingQuestionUI = ({
68346
68346
  if (showCorrectAnswer && selectedOptionId) {
68347
68347
  borderColor = isSelectionCorrect ? "border-green-500" : "border-destructive";
68348
68348
  }
68349
- return /* @__PURE__ */ React169__default.createElement("div", { key: promptItem.id, className: `p-3 border rounded-md ${borderColor} transition-colors bg-background` }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `select-prompt-${promptItem.id}`, className: "font-medium text-base block mb-2 whitespace-normal" }, /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: promptItem.content })), /* @__PURE__ */ React169__default.createElement(
68349
+ return /* @__PURE__ */ React169__default.createElement("div", { key: promptItem.id, className: `p-3 border rounded-md ${borderColor} transition-colors bg-background` }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `select-prompt-${promptItem.id}`, className: "font-Medium text-base block mb-2 whitespace-normal" }, /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: promptItem.content })), /* @__PURE__ */ React169__default.createElement(
68350
68350
  Select2,
68351
68351
  {
68352
68352
  value: selectedOptionId,
@@ -68401,7 +68401,7 @@ var DragAndDropQuestionUI = ({
68401
68401
  } else {
68402
68402
  itemStyle += " border-muted";
68403
68403
  }
68404
- return /* @__PURE__ */ React169__default.createElement("div", { key: item.id, className: itemStyle }, /* @__PURE__ */ React169__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__default.createElement(MarkdownRenderer, { content: item.content })), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center space-x-2 w-full sm:w-auto" }, /* @__PURE__ */ React169__default.createElement(
68404
+ return /* @__PURE__ */ React169__default.createElement("div", { key: item.id, className: itemStyle }, /* @__PURE__ */ React169__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__default.createElement(MarkdownRenderer, { content: item.content })), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center space-x-2 w-full sm:w-auto" }, /* @__PURE__ */ React169__default.createElement(
68405
68405
  Select2,
68406
68406
  {
68407
68407
  value: selectedDropZoneId,
@@ -95417,7 +95417,7 @@ var TabsTrigger2 = React169.forwardRef(({ className, ...props }, ref) => /* @__P
95417
95417
  {
95418
95418
  ref,
95419
95419
  className: cn(
95420
- "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",
95420
+ "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",
95421
95421
  className
95422
95422
  ),
95423
95423
  ...props
@@ -96117,7 +96117,7 @@ var AccordionTrigger2 = React169.forwardRef(({ className, children, ...props },
96117
96117
  {
96118
96118
  ref,
96119
96119
  className: cn(
96120
- "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
96120
+ "flex flex-1 items-center justify-between py-4 font-Medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
96121
96121
  className
96122
96122
  ),
96123
96123
  ...props
@@ -96904,7 +96904,7 @@ var QuizResult = ({
96904
96904
  }
96905
96905
  return String(answer);
96906
96906
  };
96907
- return /* @__PURE__ */ React169__default.createElement(Card, { className: "w-full max-w-3xl mx-auto shadow-xl" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-3xl font-headline text-center" }, t4("practiceFlow.results.title", { quizTitle })), /* @__PURE__ */ React169__default.createElement(CardDescription, { className: "text-center text-lg" }, t4("practiceFlow.results.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-6" }, /* @__PURE__ */ React169__default.createElement(Card, { className: "bg-secondary/50" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-xl flex items-center" }, /* @__PURE__ */ React169__default.createElement(BarChart2, { className: "mr-2 h-5 w-5 text-primary" }), t4("practiceFlow.results.overallScore"))), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "grid grid-cols-1 md:grid-cols-3 gap-4 text-center" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.score, " / ", result.maxScore), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.points"))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.percentage.toFixed(2), "%"), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.percentage"))), /* @__PURE__ */ React169__default.createElement("div", null, result.passed !== void 0 && (result.passed ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col items-center text-green-600" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "h-10 w-10" }), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.passed"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col items-center text-destructive" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "h-10 w-10" }), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.failed"))))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 text-sm" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__default.createElement(Clock, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__default.createElement("span", null, t4("practiceFlow.results.timeSpent")), /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold" }, result.totalTimeSpentSeconds?.toFixed(0) ?? "N/A", " ", t4("practiceFlow.results.timeUnit"))), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__default.createElement(Percent, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__default.createElement("span", null, t4("practiceFlow.results.avgTimePerQuestion")), /* @__PURE__ */ React169__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__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-lg" }, "SCORM Sync Status")), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement("p", { className: `flex items-center ${result.scormStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.scormStatus === "error" && /* @__PURE__ */ React169__default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold ml-1" }, result.scormStatus)), result.scormError && /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.scormError))), result.webhookStatus && result.webhookStatus !== "idle" && /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-lg" }, "Webhook Sync Status")), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement("p", { className: `flex items-center ${result.webhookStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.webhookStatus === "error" && /* @__PURE__ */ React169__default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold ml-1" }, result.webhookStatus)), result.webhookError && /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.webhookError))), /* @__PURE__ */ React169__default.createElement(Accordion2, { type: "single", collapsible: true, className: "w-full" }, /* @__PURE__ */ React169__default.createElement(AccordionItem2, { value: "question-breakdown" }, /* @__PURE__ */ React169__default.createElement(AccordionTrigger2, { className: "text-lg font-semibold" }, t4("practiceFlow.results.questionBreakdown")), /* @__PURE__ */ React169__default.createElement(AccordionContent2, null, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[300px] pr-4" }, /* @__PURE__ */ React169__default.createElement("ul", { className: "space-y-4" }, result.questionResults.map((qResult, index3) => /* @__PURE__ */ React169__default.createElement("li", { key: qResult.questionId, className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center mb-2" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold" }, t4("common.questions", { count: index3 + 1 })), qResult.isCorrect ? /* @__PURE__ */ React169__default.createElement("span", { className: "text-green-600 font-medium flex items-center" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.passed")) : /* @__PURE__ */ React169__default.createElement("span", { className: "text-destructive font-medium flex items-center" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.failed"))), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.yourAnswer")), " ", getAnswerDisplay(qResult.userAnswer)), !qResult.isCorrect && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.correctAnswer")), " ", getAnswerDisplay(qResult.correctAnswer)), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.pointsEarned")), " ", qResult.pointsEarned), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-medium" }, t4("practiceFlow.results.timeSpent")), " ", qResult.timeSpentSeconds?.toFixed(0) ?? "N/A", t4("practiceFlow.results.timeUnit")))))))))), /* @__PURE__ */ React169__default.createElement(CardFooter, { className: "flex flex-col sm:flex-row justify-between gap-2" }, onExitQuiz && /* @__PURE__ */ React169__default.createElement(Button, { variant: "outline", onClick: onExitQuiz, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__default.createElement(LogOut, { className: "mr-2 h-4 w-4" }), t4("common.exit")), showReviewButton && onGenerateReview && /* @__PURE__ */ React169__default.createElement(
96907
+ return /* @__PURE__ */ React169__default.createElement(Card, { className: "w-full max-w-3xl mx-auto shadow-xl" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-3xl font-headline text-center" }, t4("practiceFlow.results.title", { quizTitle })), /* @__PURE__ */ React169__default.createElement(CardDescription, { className: "text-center text-lg" }, t4("practiceFlow.results.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-6" }, /* @__PURE__ */ React169__default.createElement(Card, { className: "bg-secondary/50" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-xl flex items-center" }, /* @__PURE__ */ React169__default.createElement(BarChart2, { className: "mr-2 h-5 w-5 text-primary" }), t4("practiceFlow.results.overallScore"))), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "grid grid-cols-1 md:grid-cols-3 gap-4 text-center" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.score, " / ", result.maxScore), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.points"))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "text-3xl font-bold text-primary" }, result.percentage.toFixed(2), "%"), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("practiceFlow.results.percentage"))), /* @__PURE__ */ React169__default.createElement("div", null, result.passed !== void 0 && (result.passed ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col items-center text-green-600" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "h-10 w-10" }), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.passed"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col items-center text-destructive" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "h-10 w-10" }), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xl font-semibold mt-1" }, t4("practiceFlow.results.failed"))))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 text-sm" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__default.createElement(Clock, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__default.createElement("span", null, t4("practiceFlow.results.timeSpent")), /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold" }, result.totalTimeSpentSeconds?.toFixed(0) ?? "N/A", " ", t4("practiceFlow.results.timeUnit"))), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center space-x-2 p-3 bg-muted rounded-md" }, /* @__PURE__ */ React169__default.createElement(Percent, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ React169__default.createElement("span", null, t4("practiceFlow.results.avgTimePerQuestion")), /* @__PURE__ */ React169__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__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-lg" }, "SCORM Sync Status")), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement("p", { className: `flex items-center ${result.scormStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.scormStatus === "error" && /* @__PURE__ */ React169__default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold ml-1" }, result.scormStatus)), result.scormError && /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.scormError))), result.webhookStatus && result.webhookStatus !== "idle" && /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-lg" }, "Webhook Sync Status")), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement("p", { className: `flex items-center ${result.webhookStatus === "error" ? "text-destructive" : "text-muted-foreground"}` }, result.webhookStatus === "error" && /* @__PURE__ */ React169__default.createElement(TriangleAlert, { className: "mr-2 h-4 w-4" }), "Status: ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold ml-1" }, result.webhookStatus)), result.webhookError && /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-destructive mt-1" }, "Details: ", result.webhookError))), /* @__PURE__ */ React169__default.createElement(Accordion2, { type: "single", collapsible: true, className: "w-full" }, /* @__PURE__ */ React169__default.createElement(AccordionItem2, { value: "question-breakdown" }, /* @__PURE__ */ React169__default.createElement(AccordionTrigger2, { className: "text-lg font-semibold" }, t4("practiceFlow.results.questionBreakdown")), /* @__PURE__ */ React169__default.createElement(AccordionContent2, null, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[300px] pr-4" }, /* @__PURE__ */ React169__default.createElement("ul", { className: "space-y-4" }, result.questionResults.map((qResult, index3) => /* @__PURE__ */ React169__default.createElement("li", { key: qResult.questionId, className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center mb-2" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold" }, t4("common.questions", { count: index3 + 1 })), qResult.isCorrect ? /* @__PURE__ */ React169__default.createElement("span", { className: "text-green-600 font-Medium flex items-center" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.passed")) : /* @__PURE__ */ React169__default.createElement("span", { className: "text-destructive font-Medium flex items-center" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "mr-1 h-4 w-4" }), " ", t4("practiceFlow.results.failed"))), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.yourAnswer")), " ", getAnswerDisplay(qResult.userAnswer)), !qResult.isCorrect && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.correctAnswer")), " ", getAnswerDisplay(qResult.correctAnswer)), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.pointsEarned")), " ", qResult.pointsEarned), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, /* @__PURE__ */ React169__default.createElement("span", { className: "font-Medium" }, t4("practiceFlow.results.timeSpent")), " ", qResult.timeSpentSeconds?.toFixed(0) ?? "N/A", t4("practiceFlow.results.timeUnit")))))))))), /* @__PURE__ */ React169__default.createElement(CardFooter, { className: "flex flex-col sm:flex-row justify-between gap-2" }, onExitQuiz && /* @__PURE__ */ React169__default.createElement(Button, { variant: "outline", onClick: onExitQuiz, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__default.createElement(LogOut, { className: "mr-2 h-4 w-4" }), t4("common.exit")), showReviewButton && onGenerateReview && /* @__PURE__ */ React169__default.createElement(
96908
96908
  Button,
96909
96909
  {
96910
96910
  onClick: onGenerateReview,
@@ -97219,7 +97219,7 @@ var QuizDataManagement = ({ onQuizLoad, currentQuiz }) => {
97219
97219
  });
97220
97220
  }
97221
97221
  };
97222
- return /* @__PURE__ */ React169__default.createElement(Card, { className: "w-full shadow-lg" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, null, "Quiz Data Management"), /* @__PURE__ */ React169__default.createElement(CardDescription, null, "Import a quiz from a JSON file or export the current quiz configuration.")), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col gap-2 mb-4" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "quiz-file-input", className: "text-sm font-medium" }, "Import Quiz (JSON)"), /* @__PURE__ */ React169__default.createElement("div", { className: "relative" }, /* @__PURE__ */ React169__default.createElement(
97222
+ return /* @__PURE__ */ React169__default.createElement(Card, { className: "w-full shadow-lg" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, null, "Quiz Data Management"), /* @__PURE__ */ React169__default.createElement(CardDescription, null, "Import a quiz from a JSON file or export the current quiz configuration.")), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col gap-2 mb-4" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "quiz-file-input", className: "text-sm font-Medium" }, "Import Quiz (JSON)"), /* @__PURE__ */ React169__default.createElement("div", { className: "relative" }, /* @__PURE__ */ React169__default.createElement(
97223
97223
  Input,
97224
97224
  {
97225
97225
  id: "quiz-file-input",
@@ -97227,7 +97227,7 @@ var QuizDataManagement = ({ onQuizLoad, currentQuiz }) => {
97227
97227
  accept: ".json",
97228
97228
  ref: fileInputRef,
97229
97229
  onChange: handleFileChange,
97230
- 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"
97230
+ 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"
97231
97231
  }
97232
97232
  ))), error && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-destructive flex items-center" }, /* @__PURE__ */ React169__default.createElement(CircleAlert, { className: "mr-1 h-4 w-4" }), " ", error)), /* @__PURE__ */ React169__default.createElement(CardFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleExportQuiz, disabled: !currentQuiz, variant: "outline" }, /* @__PURE__ */ React169__default.createElement(Download, { className: "mr-2 h-4 w-4" }), " Export Current Quiz")));
97233
97233
  };
@@ -97662,6 +97662,7 @@ var Close = DialogClose;
97662
97662
 
97663
97663
  // src/react-ui/components/elements/dialog.tsx
97664
97664
  var Dialog2 = Root10;
97665
+ var DialogTrigger2 = Trigger4;
97665
97666
  var DialogPortal2 = Portal3;
97666
97667
  var DialogClose2 = Close;
97667
97668
  var DialogOverlay2 = React169.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React169.createElement(
@@ -97860,7 +97861,7 @@ var CommandGroup = React169.forwardRef(({ className, ...props }, ref) => /* @__P
97860
97861
  {
97861
97862
  ref,
97862
97863
  className: cn(
97863
- "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",
97864
+ "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",
97864
97865
  className
97865
97866
  ),
97866
97867
  ...props
@@ -98261,7 +98262,7 @@ var TrueFalseQuestionForm = ({ question: question2, onFormChange }) => {
98261
98262
  const handleCorrectAnswerChange = (value) => {
98262
98263
  onFormChange({ correctAnswer: value === "true" });
98263
98264
  };
98264
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "True/False Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Correct Answer"), /* @__PURE__ */ React169__default.createElement(
98265
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "True/False Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Correct Answer"), /* @__PURE__ */ React169__default.createElement(
98265
98266
  RadioGroup2,
98266
98267
  {
98267
98268
  value: question2.correctAnswer ? "true" : "false",
@@ -98298,7 +98299,7 @@ var MultipleChoiceQuestionForm = ({ question: question2, onFormChange }) => {
98298
98299
  const handleCorrectAnswerChange = (optionId) => {
98299
98300
  onFormChange({ correctAnswerId: optionId });
98300
98301
  };
98301
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Multiple Choice Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Options"), question2.options.length === 0 && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__default.createElement(
98302
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Multiple Choice Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Options"), question2.options.length === 0 && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__default.createElement(
98302
98303
  RadioGroup2,
98303
98304
  {
98304
98305
  value: question2.correctAnswerId,
@@ -98360,7 +98361,7 @@ var MultipleResponseQuestionForm = ({ question: question2, onFormChange }) => {
98360
98361
  const newCorrectAnswerIds = question2.correctAnswerIds.filter((id3) => id3 !== optionIdToDelete);
98361
98362
  onFormChange({ options: newOptions, correctAnswerIds: newCorrectAnswerIds });
98362
98363
  };
98363
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Multiple Response Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Options (Select all correct answers)"), question2.options.length === 0 && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 mt-2" }, question2.options.map((option, index3) => (
98364
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Multiple Response Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Options (Select all correct answers)"), question2.options.length === 0 && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No options added yet."), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 mt-2" }, question2.options.map((option, index3) => (
98364
98365
  // *** CHANGED: Adjusted layout for SimpleMarkdownEditor ***
98365
98366
  /* @__PURE__ */ React169__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__default.createElement(
98366
98367
  Checkbox2,
@@ -98582,7 +98583,7 @@ var ShortAnswerQuestionForm = ({ question: question2, onFormChange }) => {
98582
98583
  const toggleCaseSensitive = (checked) => {
98583
98584
  onFormChange({ isCaseSensitive: checked });
98584
98585
  };
98585
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Short Answer Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Accepted Answers"), /* @__PURE__ */ React169__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__default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No accepted answers defined yet."), question2.acceptedAnswers.map((answer, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: index3, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__default.createElement(
98586
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Short Answer Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Accepted Answers"), /* @__PURE__ */ React169__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__default.createElement("p", { className: "text-sm text-muted-foreground mt-1" }, "No accepted answers defined yet."), question2.acceptedAnswers.map((answer, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: index3, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__default.createElement(
98586
98587
  Input,
98587
98588
  {
98588
98589
  type: "text",
@@ -98632,7 +98633,7 @@ var NumericQuestionForm = ({ question: question2, onFormChange }) => {
98632
98633
  onFormChange({ tolerance: numValue });
98633
98634
  }
98634
98635
  };
98635
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Numeric Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `num-answer-${question2.id}` }, "Correct Numerical Answer"), /* @__PURE__ */ React169__default.createElement(
98636
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Numeric Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `num-answer-${question2.id}` }, "Correct Numerical Answer"), /* @__PURE__ */ React169__default.createElement(
98636
98637
  Input,
98637
98638
  {
98638
98639
  id: `num-answer-${question2.id}`,
@@ -98745,7 +98746,7 @@ var FillInTheBlanksQuestionForm = ({ question: question2, onFormChange }) => {
98745
98746
  const toggleCaseSensitive = (checked) => {
98746
98747
  onFormChange({ isCaseSensitive: checked });
98747
98748
  };
98748
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Fill In The Blanks Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Question Segments"), /* @__PURE__ */ React169__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__default.createElement("div", { key: `segment-${index3}`, className: "flex items-start space-x-2 mt-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex-grow space-y-1" }, /* @__PURE__ */ React169__default.createElement("span", { className: "text-xs font-medium capitalize text-muted-foreground" }, segment.type, " Segment ", index3 + 1), segment.type === "text" ? (
98749
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Fill In The Blanks Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Question Segments"), /* @__PURE__ */ React169__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__default.createElement("div", { key: `segment-${index3}`, className: "flex items-start space-x-2 mt-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex-grow space-y-1" }, /* @__PURE__ */ React169__default.createElement("span", { className: "text-xs font-Medium capitalize text-muted-foreground" }, segment.type, " Segment ", index3 + 1), segment.type === "text" ? (
98749
98750
  // *** CHANGED: Replaced Textarea with SimpleMarkdownEditor ***
98750
98751
  /* @__PURE__ */ React169__default.createElement(
98751
98752
  SimpleMarkdownEditor,
@@ -98818,7 +98819,7 @@ var SequenceQuestionForm = ({ question: question2, onFormChange }) => {
98818
98819
  }
98819
98820
  return htmlString.replace(/<[^>]*>?/gm, "");
98820
98821
  };
98821
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Sequence Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Sequence Items"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "space-y-3 mt-2" }, question2.items.map((item, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: item.id, className: "flex items-start space-x-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex-grow" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "text-xs font-medium text-muted-foreground" }, "Item ", index3 + 1), /* @__PURE__ */ React169__default.createElement(
98822
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Sequence Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Sequence Items"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "space-y-3 mt-2" }, question2.items.map((item, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: item.id, className: "flex items-start space-x-2 p-2 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex-grow" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "text-xs font-Medium text-muted-foreground" }, "Item ", index3 + 1), /* @__PURE__ */ React169__default.createElement(
98822
98823
  SimpleMarkdownEditor,
98823
98824
  {
98824
98825
  value: item.content,
@@ -98921,7 +98922,7 @@ var MatchingQuestionForm = ({ question: question2, onFormChange }) => {
98921
98922
  }
98922
98923
  return htmlString.replace(/<[^>]*>?/gm, "");
98923
98924
  };
98924
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Matching Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Prompts (Items to be matched)"), question2.prompts.map((promptItem, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: promptItem.id, className: "space-y-1" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "text-xs text-muted-foreground" }, "Prompt ", index3 + 1), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeletePrompt(index3), className: "h-7 w-7 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__default.createElement(
98925
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Matching Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Prompts (Items to be matched)"), question2.prompts.map((promptItem, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: promptItem.id, className: "space-y-1" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "text-xs text-muted-foreground" }, "Prompt ", index3 + 1), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeletePrompt(index3), className: "h-7 w-7 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__default.createElement(
98925
98926
  SimpleMarkdownEditor,
98926
98927
  {
98927
98928
  value: promptItem.content,
@@ -99011,7 +99012,7 @@ var DragAndDropQuestionForm = ({ question: question2, onFormChange }) => {
99011
99012
  }
99012
99013
  return htmlString.replace(/<[^>]*>?/gm, "");
99013
99014
  };
99014
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Drag and Drop Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `dnd-bgimage-${question2.id}` }, "Background Image URL (Optional)"), /* @__PURE__ */ React169__default.createElement(
99015
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Drag and Drop Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `dnd-bgimage-${question2.id}` }, "Background Image URL (Optional)"), /* @__PURE__ */ React169__default.createElement(
99015
99016
  Input,
99016
99017
  {
99017
99018
  id: `dnd-bgimage-${question2.id}`,
@@ -99098,7 +99099,7 @@ var HotspotQuestionForm = ({ question: question2, onFormChange }) => {
99098
99099
  }
99099
99100
  onFormChange({ correctHotspotIds: newCorrectIds });
99100
99101
  };
99101
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Hotspot Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `hs-imageurl-${question2.id}` }, "Image URL"), /* @__PURE__ */ React169__default.createElement(
99102
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Hotspot Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `hs-imageurl-${question2.id}` }, "Image URL"), /* @__PURE__ */ React169__default.createElement(
99102
99103
  Input,
99103
99104
  {
99104
99105
  id: `hs-imageurl-${question2.id}`,
@@ -99116,7 +99117,7 @@ var HotspotQuestionForm = ({ question: question2, onFormChange }) => {
99116
99117
  onChange: (e3) => onFormChange({ imageAltText: e3.target.value || void 0 }),
99117
99118
  placeholder: "Describe the image"
99118
99119
  }
99119
- )), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Hotspot Areas"), /* @__PURE__ */ React169__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__default.createElement("div", { key: hotspot.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-medium" }, "Hotspot ", index3 + 1, " (ID: ", hotspot.id, ")"), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteHotspot(index3), className: "h-8 w-8 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `hs-shape-${hotspot.id}`, className: "text-xs" }, "Shape"), /* @__PURE__ */ React169__default.createElement(Select2, { value: hotspot.shape, onValueChange: (value) => handleHotspotChange(index3, "shape", value) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: `hs-shape-${hotspot.id}` }, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "rect" }, "Rectangle"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "circle" }, "Circle")))), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__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__default.createElement(
99120
+ )), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Hotspot Areas"), /* @__PURE__ */ React169__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__default.createElement("div", { key: hotspot.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-Medium" }, "Hotspot ", index3 + 1, " (ID: ", hotspot.id, ")"), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteHotspot(index3), className: "h-8 w-8 text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `hs-shape-${hotspot.id}`, className: "text-xs" }, "Shape"), /* @__PURE__ */ React169__default.createElement(Select2, { value: hotspot.shape, onValueChange: (value) => handleHotspotChange(index3, "shape", value) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: `hs-shape-${hotspot.id}` }, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "rect" }, "Rectangle"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "circle" }, "Circle")))), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__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__default.createElement(
99120
99121
  Input,
99121
99122
  {
99122
99123
  id: `hs-coords-${hotspot.id}`,
@@ -99148,7 +99149,7 @@ var BlocklyProgrammingQuestionForm = ({ question: question2, onFormChange }) =>
99148
99149
  const handleFieldChange = (field, value) => {
99149
99150
  onFormChange({ [field]: value });
99150
99151
  };
99151
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Blockly Programming Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `blockly-toolbox-${question2.id}` }, "Toolbox Definition (XML)"), /* @__PURE__ */ React169__default.createElement(
99152
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Blockly Programming Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `blockly-toolbox-${question2.id}` }, "Toolbox Definition (XML)"), /* @__PURE__ */ React169__default.createElement(
99152
99153
  Textarea,
99153
99154
  {
99154
99155
  id: `blockly-toolbox-${question2.id}`,
@@ -99197,7 +99198,7 @@ var ScratchProgrammingQuestionForm = ({ question: question2, onFormChange }) =>
99197
99198
  const handleFieldChange = (field, value) => {
99198
99199
  onFormChange({ [field]: value });
99199
99200
  };
99200
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Scratch Programming Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "scratch-toolbox-" + question2.id }, "Toolbox Definition (XML for Blockly)"), /* @__PURE__ */ React169__default.createElement(
99201
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Scratch Programming Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "scratch-toolbox-" + question2.id }, "Toolbox Definition (XML for Blockly)"), /* @__PURE__ */ React169__default.createElement(
99201
99202
  Textarea,
99202
99203
  {
99203
99204
  id: "scratch-toolbox-" + question2.id,
@@ -99274,7 +99275,7 @@ var CodingQuestionForm = ({ question: question2, onFormChange }) => {
99274
99275
  const newTestCases = question2.testCases.filter((_2, i2) => i2 !== index3);
99275
99276
  onFormChange({ testCases: newTestCases });
99276
99277
  };
99277
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-medium text-md" }, "Coding Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `coding-lang-${question2.id}` }, "Programming Language"), /* @__PURE__ */ React169__default.createElement(
99278
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4 border rounded-md bg-muted/30" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-Medium text-md" }, "Coding Question Specifics"), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `coding-lang-${question2.id}` }, "Programming Language"), /* @__PURE__ */ React169__default.createElement(
99278
99279
  Select2,
99279
99280
  {
99280
99281
  value: question2.codingLanguage,
@@ -99300,7 +99301,7 @@ var CodingQuestionForm = ({ question: question2, onFormChange }) => {
99300
99301
  placeholder: "Enter the complete, correct code solution here.",
99301
99302
  className: "min-h-[200px] font-mono text-xs"
99302
99303
  }
99303
- )), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Test Cases"), question2.testCases.map((tc, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: tc.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-medium" }, "Test Case ", index3 + 1), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteTestCase(index3), className: "h-8 w-8 text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `tc-input-${tc.id}`, className: "text-xs" }, "Input (JSON Array)"), /* @__PURE__ */ React169__default.createElement(
99304
+ )), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Test Cases"), question2.testCases.map((tc, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: tc.id, className: "p-3 border rounded-md bg-background space-y-2" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-Medium" }, "Test Case ", index3 + 1), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => handleDeleteTestCase(index3), className: "h-8 w-8 text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `tc-input-${tc.id}`, className: "text-xs" }, "Input (JSON Array)"), /* @__PURE__ */ React169__default.createElement(
99304
99305
  Input,
99305
99306
  {
99306
99307
  id: `tc-input-${tc.id}`,
@@ -99468,7 +99469,7 @@ var EditQuestionModal = ({
99468
99469
  if (!isOpen || !editedQuestion) return null;
99469
99470
  return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => {
99470
99471
  if (!open) onClose();
99471
- } }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-[600px] md:max-w-[800px] lg:max-w-[1000px] max-h-[90vh]" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__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__default.createElement(DialogDescription2, null, "Configure the details for this question. Current type:", " ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold" }, editedQuestion.questionType))), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "max-h-[calc(80vh-150px)] p-1 pr-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "prompt", className: "font-semibold" }, "Question Prompt"), /* @__PURE__ */ React169__default.createElement(SimpleMarkdownEditor, { value: editedQuestion.prompt, onChange: (htmlContent) => handleSpecificFieldChange({ prompt: htmlContent }) })), renderSpecificForm(), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "points" }, "Points"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "difficulty" }, "Difficulty"), /* @__PURE__ */ React169__default.createElement(Select2, { value: editedQuestion.difficulty || "medium", onValueChange: (value) => handleSpecificFieldChange({ difficulty: value }) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "easy" }, "Easy"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "medium" }, "Medium"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "hard" }, "Hard"))))), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "explanation" }, "Explanation (Optional)"), /* @__PURE__ */ React169__default.createElement(SimpleMarkdownEditor, { value: editedQuestion.explanation || "", onChange: (htmlContent) => handleSpecificFieldChange({ explanation: htmlContent }), minHeight: "100px" })), /* @__PURE__ */ React169__default.createElement("details", { className: "group", open: hasDropdownMetadata }, /* @__PURE__ */ React169__default.createElement("summary", { className: "cursor-pointer font-semibold text-primary hover:underline" }, "Advanced Metadata (Optional)"), renderMetadataFields()))), /* @__PURE__ */ React169__default.createElement(DialogFooter, { className: "pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", onClick: handleSaveClick }, /* @__PURE__ */ React169__default.createElement(Save, { className: "mr-2 h-4 w-4" }), " Save Question"))));
99472
+ } }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-[600px] md:max-w-[800px] lg:max-w-[1000px] max-h-[90vh]" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__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__default.createElement(DialogDescription2, null, "Configure the details for this question. Current type:", " ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-semibold" }, editedQuestion.questionType))), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "max-h-[calc(80vh-150px)] p-1 pr-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6 p-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "prompt", className: "font-semibold" }, "Question Prompt"), /* @__PURE__ */ React169__default.createElement(SimpleMarkdownEditor, { value: editedQuestion.prompt, onChange: (htmlContent) => handleSpecificFieldChange({ prompt: htmlContent }) })), renderSpecificForm(), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "points" }, "Points"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "difficulty" }, "Difficulty"), /* @__PURE__ */ React169__default.createElement(Select2, { value: editedQuestion.difficulty || "Medium", onValueChange: (value) => handleSpecificFieldChange({ difficulty: value }) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "Easy" }, "Easy"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "Medium" }, "Medium"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "Hard" }, "Hard"))))), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "explanation" }, "Explanation (Optional)"), /* @__PURE__ */ React169__default.createElement(SimpleMarkdownEditor, { value: editedQuestion.explanation || "", onChange: (htmlContent) => handleSpecificFieldChange({ explanation: htmlContent }), minHeight: "100px" })), /* @__PURE__ */ React169__default.createElement("details", { className: "group", open: hasDropdownMetadata }, /* @__PURE__ */ React169__default.createElement("summary", { className: "cursor-pointer font-semibold text-primary hover:underline" }, "Advanced Metadata (Optional)"), renderMetadataFields()))), /* @__PURE__ */ React169__default.createElement(DialogFooter, { className: "pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline" }, "Cancel")), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", onClick: handleSaveClick }, /* @__PURE__ */ React169__default.createElement(Save, { className: "mr-2 h-4 w-4" }), " Save Question"))));
99472
99473
  };
99473
99474
 
99474
99475
  // src/react-ui/components/authoring/AIQuestionGeneratorModal.tsx
@@ -99618,12 +99619,12 @@ var QuizContextSchema = z.object({
99618
99619
  originalSubject: z.string().optional(),
99619
99620
  originalCategory: z.string().optional(),
99620
99621
  originalTopic: z.string().optional(),
99621
- loDescription: z.string().optional().describe("The full description of the learning objective for deep context."),
99622
+ description: z.string().optional().describe("The full description of the learning objective for deep context."),
99622
99623
  gradeBand: z.string().optional()
99623
99624
  });
99624
99625
  var BaseQuestionGenerationClientInputSchema = z.object({
99625
99626
  language: z.string().optional().default("English"),
99626
- difficulty: z.enum(["easy", "medium", "hard"]),
99627
+ difficulty: z.enum(["Easy", "Medium", "Hard"]),
99627
99628
  quizContext: QuizContextSchema.optional(),
99628
99629
  imageUrl: z.string().url().optional().describe("Optional URL of an image to be used as context.")
99629
99630
  });
@@ -99632,7 +99633,7 @@ var BaseQuestionZodSchema = z.object({
99632
99633
  prompt: z.string().min(1),
99633
99634
  points: z.number().min(0).optional(),
99634
99635
  explanation: z.string().optional(),
99635
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
99636
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
99636
99637
  topic: z.string().optional(),
99637
99638
  category: z.string().optional(),
99638
99639
  subject: z.string().optional(),
@@ -99728,7 +99729,7 @@ var AITrueFalseOutputFieldsSchema = z.object({
99728
99729
  correctAnswer: z.boolean(),
99729
99730
  explanation: z.string().optional().describe("An explanation of why the statement is true or false, especially important if false."),
99730
99731
  points: z.number().optional().default(10),
99731
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
99732
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
99732
99733
  topic: z.string().optional(),
99733
99734
  verifiedCategory: z.string().optional()
99734
99735
  // Thêm để xác thực
@@ -99749,7 +99750,7 @@ Previous attempts failed. Ensure the JSON is valid and 'correctAnswer' is a bool
99749
99750
  const misconceptionGuidance = quizContext?.targetMisconception ? `**Target Misconception:** The statement you create MUST be FALSE and based on this common mistake: "${quizContext.targetMisconception}"` : "";
99750
99751
  const contextStrings = [
99751
99752
  `**Required Category:** ${category}`,
99752
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
99753
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
99753
99754
  imageContextInstruction,
99754
99755
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
99755
99756
  misconceptionGuidance,
@@ -99760,7 +99761,7 @@ Previous attempts failed. Ensure the JSON is valid and 'correctAnswer' is a bool
99760
99761
  correctAnswer: true,
99761
99762
  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 '!'.",
99762
99763
  points: 10,
99763
- difficulty: "easy",
99764
+ difficulty: "Easy",
99764
99765
  topic: "Swift Optionals",
99765
99766
  verifiedCategory: category
99766
99767
  }, null, 2);
@@ -99896,7 +99897,7 @@ var AIMCQOutputFieldsSchema = z.object({
99896
99897
  correctTempOptionId: z.string().describe("The temporary ID of the correct option from the generated options array."),
99897
99898
  explanation: z.string().optional().describe("A brief explanation of why the answer is correct."),
99898
99899
  points: z.number().optional().default(10),
99899
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
99900
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
99900
99901
  topic: z.string().optional(),
99901
99902
  verifiedCategory: z.string().optional().describe("The category this question actually addresses.")
99902
99903
  });
@@ -99915,7 +99916,7 @@ Previous attempts failed...
99915
99916
  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.` : "";
99916
99917
  const contextStrings = [
99917
99918
  `**Required Category:** ${category}`,
99918
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
99919
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
99919
99920
  imageContextInstruction,
99920
99921
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
99921
99922
  quizContext?.targetMisconception && `**Target Misconception:** Use this to create plausible incorrect answers: "${quizContext.targetMisconception}"`,
@@ -99932,7 +99933,7 @@ Previous attempts failed...
99932
99933
  correctTempOptionId: "C",
99933
99934
  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.`,
99934
99935
  points: 10,
99935
- difficulty: "easy",
99936
+ difficulty: "Easy",
99936
99937
  topic: `Control Flow in ${category}`,
99937
99938
  verifiedCategory: category
99938
99939
  }, null, 2);
@@ -100080,7 +100081,7 @@ var AIMRQOutputFieldsSchema = z.object({
100080
100081
  correctTempOptionIds: z.array(z.string()).min(1),
100081
100082
  explanation: z.string().optional(),
100082
100083
  points: z.number().optional().default(10),
100083
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
100084
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
100084
100085
  topic: z.string().optional(),
100085
100086
  verifiedCategory: z.string().optional().describe("The category this question actually addresses.")
100086
100087
  });
@@ -100099,7 +100100,7 @@ Previous attempts failed due to validation errors. Pay close attention to the nu
100099
100100
  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.` : "";
100100
100101
  const contextStrings = [
100101
100102
  `**Required Category:** ${category} (This is the ONLY language to be used)`,
100102
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100103
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100103
100104
  imageContextInstruction,
100104
100105
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100105
100106
  quizContext?.targetMisconception && `**Target Misconception:** Use this to create plausible incorrect answers (distractors). The misconception is: "${quizContext.targetMisconception}"`,
@@ -100117,7 +100118,7 @@ Previous attempts failed due to validation errors. Pay close attention to the nu
100117
100118
  correctTempOptionIds: ["A", "C", "D"],
100118
100119
  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.",
100119
100120
  points: 10,
100120
- difficulty: "medium",
100121
+ difficulty: "Medium",
100121
100122
  topic: "Programming Paradigms",
100122
100123
  verifiedCategory: category
100123
100124
  }, null, 2);
@@ -100281,7 +100282,7 @@ var AIShortAnswerOutputFieldsSchema = z.object({
100281
100282
  // isCaseSensitive không cần thiết ở đây, chúng ta sẽ quản lý nó ở phía client
100282
100283
  explanation: z.string().optional(),
100283
100284
  points: z.number().optional().default(10),
100284
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
100285
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
100285
100286
  topic: z.string().optional(),
100286
100287
  verifiedCategory: z.string().optional()
100287
100288
  // Thêm để xác thực
@@ -100301,7 +100302,7 @@ Previous attempts failed. Ensure 'acceptedAnswers' is a non-empty array of strin
100301
100302
  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.` : "";
100302
100303
  const contextStrings = [
100303
100304
  `**Required Category:** ${category}`,
100304
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100305
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100305
100306
  imageContextInstruction,
100306
100307
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100307
100308
  quizContext?.targetMisconception && `**Target Misconception:** The question should require an answer that corrects this specific misconception: "${quizContext.targetMisconception}"`
@@ -100311,7 +100312,7 @@ Previous attempts failed. Ensure 'acceptedAnswers' is a non-empty array of strin
100311
100312
  acceptedAnswers: ["let"],
100312
100313
  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.",
100313
100314
  points: 10,
100314
- difficulty: "easy",
100315
+ difficulty: "Easy",
100315
100316
  topic: "Swift Constants",
100316
100317
  verifiedCategory: category
100317
100318
  }, null, 2);
@@ -100444,7 +100445,7 @@ var AINumericOutputFieldsSchema = z.object({
100444
100445
  tolerance: z.number().min(0).optional(),
100445
100446
  explanation: z.string().optional(),
100446
100447
  points: z.number().optional().default(10),
100447
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
100448
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
100448
100449
  topic: z.string().optional(),
100449
100450
  verifiedCategory: z.string().optional()
100450
100451
  // Thêm để xác thực
@@ -100464,7 +100465,7 @@ Previous attempts failed. Ensure the 'answer' is a valid number and fits within
100464
100465
  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.` : "";
100465
100466
  const contextStrings = [
100466
100467
  `**Required Category:** ${category}`,
100467
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100468
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100468
100469
  imageContextInstruction,
100469
100470
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100470
100471
  quizContext?.targetMisconception && `**Target Misconception:** The question should clarify this numerical error: "${quizContext.targetMisconception}"`
@@ -100480,7 +100481,7 @@ Previous attempts failed. Ensure the 'answer' is a valid number and fits within
100480
100481
  tolerance: 0,
100481
100482
  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).",
100482
100483
  points: 10,
100483
- difficulty: "medium",
100484
+ difficulty: "Medium",
100484
100485
  topic: "Swift Data Types",
100485
100486
  verifiedCategory: category
100486
100487
  }, null, 2);
@@ -100630,7 +100631,7 @@ var AIFillInTheBlanksOutputFieldsSchema = z.object({
100630
100631
  })).min(1).describe("An array of text and blank segments representing the question."),
100631
100632
  explanation: z.string().optional(),
100632
100633
  points: z.number().optional().default(10),
100633
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
100634
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
100634
100635
  topic: z.string().optional(),
100635
100636
  verifiedCategory: z.string().optional()
100636
100637
  // Thêm để xác thực
@@ -100650,7 +100651,7 @@ Previous attempts failed. Pay strict attention to the JSON schema, especially th
100650
100651
  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.` : "";
100651
100652
  const contextStrings = [
100652
100653
  `**Required Category:** ${category}`,
100653
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100654
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100654
100655
  imageContextInstruction,
100655
100656
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100656
100657
  quizContext?.targetMisconception && `**Target Misconception:** Design the blank to test this specific point: "${quizContext.targetMisconception}"`
@@ -100664,7 +100665,7 @@ Previous attempts failed. Pay strict attention to the JSON schema, especially th
100664
100665
  ],
100665
100666
  explanation: "The 'func' keyword is used to declare a function in the Swift programming language.",
100666
100667
  points: 10,
100667
- difficulty: "easy",
100668
+ difficulty: "Easy",
100668
100669
  topic: "Swift Function Declaration",
100669
100670
  verifiedCategory: category
100670
100671
  }, null, 2);
@@ -100818,7 +100819,7 @@ var AISequenceOutputFieldsSchema = z.object({
100818
100819
  itemsInCorrectOrder: z.array(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."),
100819
100820
  explanation: z.string().optional(),
100820
100821
  points: z.number().optional().default(10),
100821
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
100822
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
100822
100823
  topic: z.string().optional(),
100823
100824
  verifiedCategory: z.string().optional()
100824
100825
  // Thêm để xác thực
@@ -100838,7 +100839,7 @@ Previous attempts failed. Ensure the 'itemsInCorrectOrder' array has exactly the
100838
100839
  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.` : "";
100839
100840
  const contextStrings = [
100840
100841
  `**Required Category:** ${category}`,
100841
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
100842
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
100842
100843
  imageContextInstruction,
100843
100844
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
100844
100845
  quizContext?.targetMisconception && `**Target Misconception:** The sequence should clarify this specific process error: "${quizContext.targetMisconception}"`
@@ -100853,7 +100854,7 @@ Previous attempts failed. Ensure the 'itemsInCorrectOrder' array has exactly the
100853
100854
  ],
100854
100855
  explanation: "This is the fundamental sequence for a basic data task in URLSession.",
100855
100856
  points: 10,
100856
- difficulty: "medium",
100857
+ difficulty: "Medium",
100857
100858
  topic: "Swift Networking",
100858
100859
  verifiedCategory: category
100859
100860
  }, null, 2);
@@ -100995,7 +100996,7 @@ var AIMatchingOutputFieldsSchema = z.object({
100995
100996
  })).min(2),
100996
100997
  explanation: z.string().optional(),
100997
100998
  points: z.number().optional().default(10),
100998
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
100999
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
100999
101000
  topic: z.string().optional(),
101000
101001
  verifiedCategory: z.string().optional()
101001
101002
  // Thêm để xác thực
@@ -101015,7 +101016,7 @@ Previous attempts failed. Please ensure the 'correctPairs' array has exactly the
101015
101016
  const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The matching pairs must be directly related to the content of this image.` : "";
101016
101017
  const contextStrings = [
101017
101018
  `**Required Category:** ${category}`,
101018
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
101019
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
101019
101020
  imageContextInstruction,
101020
101021
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
101021
101022
  quizContext?.targetMisconception && `**Target Misconception:** Design a pair that specifically tests this confusion: "${quizContext.targetMisconception}"`
@@ -101029,7 +101030,7 @@ Previous attempts failed. Please ensure the 'correctPairs' array has exactly the
101029
101030
  ],
101030
101031
  explanation: "These are the fundamental characteristics of Swift's main collection types.",
101031
101032
  points: 10,
101032
- difficulty: "easy",
101033
+ difficulty: "Easy",
101033
101034
  topic: "Swift Collection Types",
101034
101035
  verifiedCategory: category
101035
101036
  }, null, 2);
@@ -101245,7 +101246,7 @@ var AIQuestionGeneratorModal = ({
101245
101246
  };
101246
101247
  const baseClientInput = {
101247
101248
  language: language3,
101248
- difficulty: "medium",
101249
+ difficulty: "Medium",
101249
101250
  quizContext
101250
101251
  };
101251
101252
  let generatedResult = {};
@@ -101850,10 +101851,6 @@ init_react_shim();
101850
101851
  // src/services/TopicDataService.ts
101851
101852
  init_react_shim();
101852
101853
  var TopicDataService = class {
101853
- /**
101854
- * Saves an array of LearningObjective objects to Local Storage, overwriting existing data.
101855
- * @param data The array of learning objectives to save.
101856
- */
101857
101854
  static saveData(data) {
101858
101855
  try {
101859
101856
  if (typeof window === "undefined") return;
@@ -101863,24 +101860,15 @@ var TopicDataService = class {
101863
101860
  console.error("Error saving learning objectives to Local Storage:", error);
101864
101861
  }
101865
101862
  }
101866
- /**
101867
- * Merges a new set of learning objectives with the existing data in Local Storage.
101868
- * If an LO ID from newData already exists, it will be updated. Otherwise, it will be added.
101869
- * @param newData The array of new or updated learning objectives.
101870
- */
101871
101863
  static mergeData(newData) {
101872
101864
  const existingData = this.getData();
101873
- const loMap = new Map(existingData.map((lo) => [lo.loId, lo]));
101865
+ const loMap = new Map(existingData.map((lo) => [lo.code, lo]));
101874
101866
  newData.forEach((newLo) => {
101875
- loMap.set(newLo.loId, newLo);
101867
+ loMap.set(newLo.code, newLo);
101876
101868
  });
101877
101869
  const mergedData = Array.from(loMap.values());
101878
101870
  this.saveData(mergedData);
101879
101871
  }
101880
- /**
101881
- * Retrieves the array of LearningObjective objects from Local Storage.
101882
- * @returns An array of learning objectives, or an empty array if none are found or an error occurs.
101883
- */
101884
101872
  static getData() {
101885
101873
  try {
101886
101874
  if (typeof window === "undefined") return [];
@@ -101892,9 +101880,6 @@ var TopicDataService = class {
101892
101880
  return [];
101893
101881
  }
101894
101882
  }
101895
- /**
101896
- * Removes all learning objective data from Local Storage.
101897
- */
101898
101883
  static clearData() {
101899
101884
  try {
101900
101885
  if (typeof window === "undefined") return;
@@ -101903,11 +101888,6 @@ var TopicDataService = class {
101903
101888
  console.error("Error clearing learning objectives from Local Storage:", error);
101904
101889
  }
101905
101890
  }
101906
- /**
101907
- * Parses TSV content into an array of LearningObjective objects.
101908
- * @param tsvContent The raw string content from a .tsv file.
101909
- * @returns An object containing the successfully parsed data and any errors encountered.
101910
- */
101911
101891
  static parseTSV(tsvContent) {
101912
101892
  const lines = tsvContent.split("\n").filter((line) => line.trim() !== "");
101913
101893
  if (lines.length < 2) {
@@ -101929,6 +101909,7 @@ var TopicDataService = class {
101929
101909
  }
101930
101910
  const [
101931
101911
  loId,
101912
+ name3,
101932
101913
  loDescription,
101933
101914
  subject,
101934
101915
  category,
@@ -101938,18 +101919,21 @@ var TopicDataService = class {
101938
101919
  stemElementsStr,
101939
101920
  bloomLevelsStr
101940
101921
  ] = values;
101941
- if (!loId || !subject || !category || !topic) {
101942
- errors2.push(`Line ${index3 + 2}: Missing required fields (LO ID, Subject, Category, or Topic).`);
101922
+ if (!loId || !loDescription || !subject || !category || !topic) {
101923
+ errors2.push(`Line ${index3 + 2}: Missing required fields (LO ID, LO Description, Subject, Category, or Topic).`);
101943
101924
  return;
101944
101925
  }
101945
101926
  const learningObjective = {
101946
- loId,
101947
- loDescription,
101927
+ id: generateUniqueId("lo_"),
101928
+ code: loId,
101929
+ name: name3,
101930
+ description: loDescription,
101931
+ // Can be the same as name or enhanced later
101948
101932
  subject,
101949
101933
  category,
101950
101934
  topic,
101951
- keywords: keywordsStr.split(",").map((k3) => k3.trim()).filter(Boolean),
101952
101935
  grade,
101936
+ keywords: keywordsStr.split(",").map((k3) => k3.trim()).filter(Boolean),
101953
101937
  stemElements: stemElementsStr.split(",").map((s4) => s4.trim()).filter(Boolean),
101954
101938
  bloomLevelsGuideline: bloomLevelsStr.split(",").map((b2) => b2.trim()).filter(Boolean)
101955
101939
  };
@@ -101957,40 +101941,21 @@ var TopicDataService = class {
101957
101941
  });
101958
101942
  return { data, errors: errors2 };
101959
101943
  }
101960
- /**
101961
- * Gets a unique list of all subjects from the stored data.
101962
- * @returns An array of subject strings.
101963
- */
101964
101944
  static getSubjects() {
101965
101945
  const data = this.getData();
101966
101946
  const subjects = data.map((item) => item.subject);
101967
101947
  return [...new Set(subjects)].sort();
101968
101948
  }
101969
- /**
101970
- * Gets a unique list of categories for a given subject.
101971
- * @param subject The subject to filter by.
101972
- * @returns An array of category strings.
101973
- */
101974
101949
  static getCategoriesBySubject(subject) {
101975
101950
  const data = this.getData();
101976
101951
  const categories = data.filter((item) => item.subject === subject).map((item) => item.category);
101977
101952
  return [...new Set(categories)].sort();
101978
101953
  }
101979
- /**
101980
- * Gets a unique list of topics for a given category.
101981
- * @param category The category to filter by.
101982
- * @returns An array of topic strings.
101983
- */
101984
101954
  static getTopicsByCategory(category) {
101985
101955
  const data = this.getData();
101986
101956
  const topics = data.filter((item) => item.category === category).map((item) => item.topic);
101987
101957
  return [...new Set(topics)].sort();
101988
101958
  }
101989
- /**
101990
- * Retrieves all LearningObjective details for a given list of topics.
101991
- * @param topics An array of topic strings to search for.
101992
- * @returns An array of matching LearningObjective objects.
101993
- */
101994
101959
  static getLearningObjectivesByTopics(topics) {
101995
101960
  const data = this.getData();
101996
101961
  const topicSet = new Set(topics);
@@ -102047,7 +102012,7 @@ Previous attempts failed. Pay strict attention to the JSON schema and all rules.
102047
102012
  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.` : "";
102048
102013
  const contextStrings = [
102049
102014
  `**Subject:** ${subject}`,
102050
- quizContext?.loDescription && `**Learning Objective:** ${quizContext.loDescription}`,
102015
+ quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
102051
102016
  imageContextInstruction,
102052
102017
  quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
102053
102018
  quizContext?.targetMisconception && `**Target Misconception:** The problem should test against this common error: "${quizContext.targetMisconception}"`
@@ -102204,9 +102169,9 @@ var calculateCombinedDifficulty = (plannedQ) => {
102204
102169
  break;
102205
102170
  }
102206
102171
  const totalScore = bloomScore + contextScore + questionTypeScore;
102207
- if (totalScore <= 4) return "easy";
102208
- if (totalScore <= 7) return "medium";
102209
- return "hard";
102172
+ if (totalScore <= 4) return "Easy";
102173
+ if (totalScore <= 7) return "Medium";
102174
+ return "Hard";
102210
102175
  };
102211
102176
  async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
102212
102177
  const { quizPlan, language: language3, imageContexts } = clientInput;
@@ -102219,7 +102184,7 @@ async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
102219
102184
  let lastError = null;
102220
102185
  for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
102221
102186
  try {
102222
- const fullLO = plannedQ.originalLoId ? allLearningObjectives.find((lo) => lo.loId === plannedQ.originalLoId) : null;
102187
+ const fullLO = plannedQ.originalLoId ? allLearningObjectives.find((lo) => lo.code === plannedQ.originalLoId) : null;
102223
102188
  const quizContext = {
102224
102189
  plannedTopic: plannedQ.plannedTopic,
102225
102190
  plannedQuestionType: plannedQ.plannedQuestionType,
@@ -102232,7 +102197,7 @@ async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
102232
102197
  originalSubject: plannedQ.originalSubject,
102233
102198
  originalCategory: plannedQ.originalCategory,
102234
102199
  originalTopic: plannedQ.originalTopic,
102235
- loDescription: fullLO?.loDescription || plannedQ.plannedTopic
102200
+ description: fullLO?.description || plannedQ.plannedTopic
102236
102201
  };
102237
102202
  const imageUrl = plannedQ.imageId && imageContexts ? imageContexts.find((ctx) => ctx.id === plannedQ.imageId)?.imageUrl : void 0;
102238
102203
  const baseClientInput = {
@@ -102586,7 +102551,7 @@ var AIFullQuizGeneratorModal = ({
102586
102551
  };
102587
102552
  const renderContent3 = () => {
102588
102553
  if (currentStage === "review") {
102589
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 py-4" }, /* @__PURE__ */ React169__default.createElement("h3", { className: "text-lg font-medium mb-2 text-primary flex items-center" }, /* @__PURE__ */ React169__default.createElement(Eye, { className: "mr-2 h-5 w-5" }), " Review & Adjust AI Generated Quiz Plan"), /* @__PURE__ */ React169__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__default.createElement(ScrollArea2, { className: "max-h-[calc(60vh - 120px)] pr-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, aiGeneratedPlan.map((plannedQ, index3) => /* @__PURE__ */ React169__default.createElement(Card, { key: `planned-${index3}-${plannedQ.plannedTopic.replace(/\s/g, "")}`, className: "p-3" }, /* @__PURE__ */ React169__default.createElement(CardContent, { className: "p-0 space-y-2" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold text-sm" }, "Q", index3 + 1, ": ", plannedQ.plannedTopic), /* @__PURE__ */ React169__default.createElement("div", { className: "flex space-x-1" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "up"), disabled: index3 === 0 }, /* @__PURE__ */ React169__default.createElement(ArrowUp, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "down"), disabled: index3 === aiGeneratedPlan.length - 1 }, /* @__PURE__ */ React169__default.createElement(ArrowDown, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7 text-destructive", onClick: () => handleRemovePlannedQuestion(index3) }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-3 items-end" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `review-qtype-${index3}`, className: "text-xs" }, "Question Type"), /* @__PURE__ */ React169__default.createElement(
102554
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4 py-4" }, /* @__PURE__ */ React169__default.createElement("h3", { className: "text-lg font-Medium mb-2 text-primary flex items-center" }, /* @__PURE__ */ React169__default.createElement(Eye, { className: "mr-2 h-5 w-5" }), " Review & Adjust AI Generated Quiz Plan"), /* @__PURE__ */ React169__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__default.createElement(ScrollArea2, { className: "max-h-[calc(60vh - 120px)] pr-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, aiGeneratedPlan.map((plannedQ, index3) => /* @__PURE__ */ React169__default.createElement(Card, { key: `planned-${index3}-${plannedQ.plannedTopic.replace(/\s/g, "")}`, className: "p-3" }, /* @__PURE__ */ React169__default.createElement(CardContent, { className: "p-0 space-y-2" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold text-sm" }, "Q", index3 + 1, ": ", plannedQ.plannedTopic), /* @__PURE__ */ React169__default.createElement("div", { className: "flex space-x-1" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "up"), disabled: index3 === 0 }, /* @__PURE__ */ React169__default.createElement(ArrowUp, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleMovePlannedQuestion(index3, "down"), disabled: index3 === aiGeneratedPlan.length - 1 }, /* @__PURE__ */ React169__default.createElement(ArrowDown, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7 text-destructive", onClick: () => handleRemovePlannedQuestion(index3) }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-3 items-end" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `review-qtype-${index3}`, className: "text-xs" }, "Question Type"), /* @__PURE__ */ React169__default.createElement(
102590
102555
  Select2,
102591
102556
  {
102592
102557
  value: plannedQ.plannedQuestionType,
@@ -102615,7 +102580,7 @@ var AIFullQuizGeneratorModal = ({
102615
102580
  min: "1",
102616
102581
  max: "100"
102617
102582
  }
102618
- )), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-medium px-1" }, "Topic Distribution"), topics.map((topicItem, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: topicItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__default.createElement(
102583
+ )), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Topic Distribution"), topics.map((topicItem, index3) => /* @__PURE__ */ React169__default.createElement("div", { key: topicItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__default.createElement(
102619
102584
  Input,
102620
102585
  {
102621
102586
  type: "text",
@@ -102635,7 +102600,7 @@ var AIFullQuizGeneratorModal = ({
102635
102600
  min: "0",
102636
102601
  max: "100"
102637
102602
  }
102638
- ), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeTopic(topicItem.id), disabled: topics.length <= 1 }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: addTopic }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic")), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-medium px-1" }, "Bloom Level Distribution"), bloomLevels.map((bloomItem) => /* @__PURE__ */ React169__default.createElement("div", { key: bloomItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "w-32 capitalize flex-shrink-0" }, bloomItem.level), /* @__PURE__ */ React169__default.createElement(
102603
+ ), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeTopic(topicItem.id), disabled: topics.length <= 1 }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: addTopic }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic")), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Bloom Level Distribution"), bloomLevels.map((bloomItem) => /* @__PURE__ */ React169__default.createElement("div", { key: bloomItem.id, className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "w-32 capitalize flex-shrink-0" }, bloomItem.level), /* @__PURE__ */ React169__default.createElement(
102639
102604
  Input,
102640
102605
  {
102641
102606
  type: "number",
@@ -102646,7 +102611,7 @@ var AIFullQuizGeneratorModal = ({
102646
102611
  min: "0",
102647
102612
  max: "100"
102648
102613
  }
102649
- )))), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-medium px-1" }, "Relevant Contexts (Optional, Select Multiple)"), /* @__PURE__ */ React169__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__default.createElement("div", { key: opt.contextId, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__default.createElement(
102614
+ )))), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Relevant Contexts (Optional, Select Multiple)"), /* @__PURE__ */ React169__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__default.createElement("div", { key: opt.contextId, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__default.createElement(
102650
102615
  Checkbox2,
102651
102616
  {
102652
102617
  id: `ctx-full-${opt.contextId}`,
@@ -102668,7 +102633,7 @@ var AIFullQuizGeneratorModal = ({
102668
102633
  placeholder: "Enter your specific custom context here...",
102669
102634
  className: "min-h-[60px] mt-2 text-sm"
102670
102635
  }
102671
- )), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-medium px-1" }, "Question Types to Use (Select Multiple)"), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-2 mt-2 max-h-40 overflow-y-auto" }, availableQuestionTypesForFullQuiz.map((qType) => /* @__PURE__ */ React169__default.createElement("div", { key: qType.value, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__default.createElement(
102636
+ )), /* @__PURE__ */ React169__default.createElement("fieldset", { className: "border p-3 rounded-md" }, /* @__PURE__ */ React169__default.createElement("legend", { className: "text-sm font-Medium px-1" }, "Question Types to Use (Select Multiple)"), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-2 mt-2 max-h-40 overflow-y-auto" }, availableQuestionTypesForFullQuiz.map((qType) => /* @__PURE__ */ React169__default.createElement("div", { key: qType.value, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__default.createElement(
102672
102637
  Checkbox2,
102673
102638
  {
102674
102639
  id: `qtype-full-${qType.value}`,
@@ -103068,7 +103033,7 @@ var AlertTitle = React169.forwardRef(({ className, ...props }, ref) => /* @__PUR
103068
103033
  "h5",
103069
103034
  {
103070
103035
  ref,
103071
- className: cn("mb-1 font-medium leading-none tracking-tight", className),
103036
+ className: cn("mb-1 font-Medium leading-none tracking-tight", className),
103072
103037
  ...props
103073
103038
  }
103074
103039
  ));
@@ -103113,7 +103078,7 @@ var BaseRawQuestionSchema = z.object({
103113
103078
  points: z.number().optional(),
103114
103079
  explanation: z.string().optional(),
103115
103080
  topic: z.string().optional(),
103116
- difficulty: z.enum(["easy", "medium", "hard"]).optional(),
103081
+ difficulty: z.enum(["Easy", "Medium", "Hard"]).optional(),
103117
103082
  bloomLevel: z.string().optional()
103118
103083
  });
103119
103084
  var RawMCQSchema = BaseRawQuestionSchema.extend({
@@ -103466,7 +103431,7 @@ var QuizEditorService = class {
103466
103431
  questionType: type,
103467
103432
  prompt: "",
103468
103433
  points: 10,
103469
- difficulty: "medium"
103434
+ difficulty: "Medium"
103470
103435
  };
103471
103436
  switch (type) {
103472
103437
  case "true_false":
@@ -103693,7 +103658,7 @@ var SelectedQuestionsPanel = ({
103693
103658
  },
103694
103659
  /* @__PURE__ */ React169__default.createElement(ArrowDown, { className: "h-3 w-3" })
103695
103660
  )),
103696
- /* @__PURE__ */ React169__default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React169__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__default.createElement("div", { className: "text-xs text-muted-foreground mt-1" }, q2.questionType, " \u2022 ", q2.points || 0, " pts")),
103661
+ /* @__PURE__ */ React169__default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React169__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__default.createElement("div", { className: "text-xs text-muted-foreground mt-1" }, q2.questionType, " \u2022 ", q2.points || 0, " pts")),
103697
103662
  /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-1 flex-shrink-0" }, /* @__PURE__ */ React169__default.createElement(
103698
103663
  Button,
103699
103664
  {
@@ -104080,7 +104045,7 @@ var TableFooter = React169.forwardRef(({ className, ...props }, ref) => /* @__PU
104080
104045
  {
104081
104046
  ref,
104082
104047
  className: cn(
104083
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
104048
+ "border-t bg-muted/50 font-Medium [&>tr]:last:border-b-0",
104084
104049
  className
104085
104050
  ),
104086
104051
  ...props
@@ -104104,7 +104069,7 @@ var TableHead = React169.forwardRef(({ className, ...props }, ref) => /* @__PURE
104104
104069
  {
104105
104070
  ref,
104106
104071
  className: cn(
104107
- "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
104072
+ "h-12 px-4 text-left align-middle font-Medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
104108
104073
  className
104109
104074
  ),
104110
104075
  ...props
@@ -104194,20 +104159,6 @@ var questionTypeManager = new LocalStorageManager("question_types");
104194
104159
  var learningObjectiveManager = new LocalStorageManager("learning_objectives");
104195
104160
  var contextManager = new LocalStorageManager("contexts");
104196
104161
  var approachManager = new LocalStorageManager("approaches");
104197
- function mapRawDifficultyToStandard(rawDifficulty) {
104198
- switch (rawDifficulty) {
104199
- case "E":
104200
- case "E~M":
104201
- return "easy";
104202
- case "M":
104203
- case "M~H":
104204
- return "medium";
104205
- case "H":
104206
- return "hard";
104207
- default:
104208
- return "medium";
104209
- }
104210
- }
104211
104162
  var MetadataService = class {
104212
104163
  };
104213
104164
  // --- Subject Services ---
@@ -104265,15 +104216,10 @@ MetadataService.deleteContext = (code4) => contextManager.delete(code4);
104265
104216
  MetadataService.getApproaches = () => approachManager.getAll().sort((a4, b2) => a4.code.localeCompare(b2.code));
104266
104217
  MetadataService.saveApproaches = (items) => approachManager.saveAll(items);
104267
104218
  MetadataService.addApproach = (approachData) => {
104268
- const difficulty = mapRawDifficultyToStandard(approachData.rawDifficulty);
104269
- return approachManager.add({ ...approachData, difficulty });
104219
+ return approachManager.add(approachData);
104270
104220
  };
104271
104221
  MetadataService.updateApproach = (id3, approachData) => {
104272
- const updates = { ...approachData };
104273
- if (approachData.rawDifficulty) {
104274
- updates.difficulty = mapRawDifficultyToStandard(approachData.rawDifficulty);
104275
- }
104276
- return approachManager.update(id3, updates);
104222
+ return approachManager.update(id3, approachData);
104277
104223
  };
104278
104224
  MetadataService.deleteApproach = (code4) => approachManager.delete(code4);
104279
104225
  // --- LearningObjective Services ---
@@ -104283,8 +104229,12 @@ MetadataService.getLearningObjectives = (subjectCode) => {
104283
104229
  return filtered.sort((a4, b2) => a4.name.localeCompare(b2.name));
104284
104230
  };
104285
104231
  MetadataService.saveLearningObjectives = (items) => learningObjectiveManager.saveAll(items);
104286
- MetadataService.addLearningObjective = (name3, code4, subjectCode, description) => learningObjectiveManager.add({ name: name3, code: code4, subjectCode, description });
104287
- MetadataService.updateLearningObjective = (id3, name3, code4, subjectCode, description) => learningObjectiveManager.update(id3, { name: name3, code: code4, subjectCode, description });
104232
+ MetadataService.addLearningObjective = (item) => {
104233
+ return learningObjectiveManager.add(item);
104234
+ };
104235
+ MetadataService.updateLearningObjective = (id3, updates) => {
104236
+ return learningObjectiveManager.update(id3, updates);
104237
+ };
104288
104238
  MetadataService.deleteLearningObjective = (code4) => learningObjectiveManager.delete(code4);
104289
104239
 
104290
104240
  // node_modules/date-fns/addDays.mjs
@@ -106184,7 +106134,7 @@ function QuestionList({
106184
106134
  if (questions.length === 0) {
106185
106135
  return /* @__PURE__ */ React169__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.");
106186
106136
  }
106187
- return /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[30%]" }, "Question Text"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Type"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Grade"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Bloom's"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Last Modified"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, questions.map((question2) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: question2.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium max-w-xs truncate", title: question2.text }, /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: question2.questionConfig.prompt })), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, question2.code), /* @__PURE__ */ React169__default.createElement(TableCell, null, /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "secondary" }, getLookupName(question2.questionTypeCode, metadata.questionTypes))), /* @__PURE__ */ React169__default.createElement(TableCell, null, getLookupName(question2.subjectCode, metadata.subjects)), /* @__PURE__ */ React169__default.createElement(TableCell, null, getLookupName(question2.topicCode, metadata.topics)), /* @__PURE__ */ React169__default.createElement(TableCell, null, getLookupName(question2.gradeLevelCode, metadata.gradeLevels)), /* @__PURE__ */ React169__default.createElement(TableCell, null, /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "outline" }, getLookupName(question2.bloomLevelCode, metadata.bloomLevels))), /* @__PURE__ */ React169__default.createElement(TableCell, null, format(new Date(question2.lastModified), "MMM d, yyyy")), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, onView && /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onView(question2), className: "mr-1" }, /* @__PURE__ */ React169__default.createElement(Eye, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onEdit(question2), className: "mr-1" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onDelete(question2), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))))))));
106137
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[30%]" }, "Question Text"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Type"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Grade"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Bloom's"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Last Modified"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, questions.map((question2) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: question2.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium max-w-xs truncate", title: question2.text }, /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: question2.questionConfig.prompt })), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, question2.code), /* @__PURE__ */ React169__default.createElement(TableCell, null, /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "secondary" }, getLookupName(question2.questionTypeCode, metadata.questionTypes))), /* @__PURE__ */ React169__default.createElement(TableCell, null, getLookupName(question2.subjectCode, metadata.subjects)), /* @__PURE__ */ React169__default.createElement(TableCell, null, getLookupName(question2.topicCode, metadata.topics)), /* @__PURE__ */ React169__default.createElement(TableCell, null, getLookupName(question2.gradeLevelCode, metadata.gradeLevels)), /* @__PURE__ */ React169__default.createElement(TableCell, null, /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "outline" }, getLookupName(question2.bloomLevelCode, metadata.bloomLevels))), /* @__PURE__ */ React169__default.createElement(TableCell, null, format(new Date(question2.lastModified), "MMM d, yyyy")), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, onView && /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onView(question2), className: "mr-1" }, /* @__PURE__ */ React169__default.createElement(Eye, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onEdit(question2), className: "mr-1" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => onDelete(question2), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" }))))))));
106188
106138
  }
106189
106139
 
106190
106140
  // src/react-ui/components/authoring/QuestionFilters.tsx
@@ -106265,7 +106215,7 @@ function QuestionFilters({
106265
106215
  onChange: (e3) => setSearchTerm(e3.target.value),
106266
106216
  className: "lg:col-span-2 xl:col-span-1"
106267
106217
  }
106268
- ), /* @__PURE__ */ React169__default.createElement(Select2, { value: subjectCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setSubjectCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Subjects"), subjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: topicCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setTopicCode), disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Topic" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Topics"), filteredTopics.map((t4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: gradeLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setGradeLevelCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Grade Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Grade Levels"), gradeLevels.map((gl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: bloomLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setBloomLevelCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Bloom's Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Levels"), bloomLevels.map((bl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: questionTypeCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setQuestionTypeCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Question Type" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Types"), questionTypes.map((qt) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: difficulty || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setDifficulty) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Difficulty" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Difficulties"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "easy" }, "Easy"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "medium" }, "Medium"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "hard" }, "Hard"))), /* @__PURE__ */ React169__default.createElement("div", { className: "flex gap-2 col-span-full sm:col-span-1 xl:col-span-2 xl:col-start-6" }, /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleApplyFilters, className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__default.createElement(Search, { className: "mr-2 h-4 w-4" }), " Apply"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleClearFilters, variant: "outline", className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "mr-2 h-4 w-4" }), " Clear"))));
106218
+ ), /* @__PURE__ */ React169__default.createElement(Select2, { value: subjectCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setSubjectCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Subjects"), subjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: topicCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setTopicCode), disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Topic" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Topics"), filteredTopics.map((t4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: gradeLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setGradeLevelCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Grade Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Grade Levels"), gradeLevels.map((gl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: bloomLevelCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setBloomLevelCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Bloom's Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Levels"), bloomLevels.map((bl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: questionTypeCode || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setQuestionTypeCode) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Question Type" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Types"), questionTypes.map((qt) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: difficulty || ALL_ITEMS_VALUE, onValueChange: createSelectHandler(setDifficulty) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Difficulty" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: ALL_ITEMS_VALUE }, "All Difficulties"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "Easy" }, "Easy"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "Medium" }, "Medium"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "Hard" }, "Hard"))), /* @__PURE__ */ React169__default.createElement("div", { className: "flex gap-2 col-span-full sm:col-span-1 xl:col-span-2 xl:col-start-6" }, /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleApplyFilters, className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__default.createElement(Search, { className: "mr-2 h-4 w-4" }), " Apply"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleClearFilters, variant: "outline", className: "w-full sm:w-auto flex-grow" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "mr-2 h-4 w-4" }), " Clear"))));
106269
106219
  }
106270
106220
 
106271
106221
  // src/react-ui/components/authoring/QuestionFormDialog.tsx
@@ -106373,7 +106323,7 @@ function QuestionFormDialog({
106373
106323
  };
106374
106324
  const dialogTitle = questionToEdit ? "Edit Question Metadata" : "Create New Question";
106375
106325
  const dialogDescription = "First, define the metadata for the question. Then, edit the question's content and logic.";
106376
- return /* @__PURE__ */ React169__default.createElement(React169__default.Fragment, null, /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, dialogTitle), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, dialogDescription)), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Question Code"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gradeLevelCode" }, "Grade Level"), /* @__PURE__ */ React169__default.createElement(Select2, { value: gradeLevelCode, onValueChange: setGradeLevelCode }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "gradeLevelCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Grade Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, gradeLevels.map((gl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__default.createElement(Select2, { value: subjectCode, onValueChange: setSubjectCode }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, subjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic"), /* @__PURE__ */ React169__default.createElement(Select2, { value: topicCode, onValueChange: setTopicCode, disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "topicCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Topic" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, filteredTopics.map((t4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Bloom's Level"), /* @__PURE__ */ React169__default.createElement(Select2, { value: bloomLevelCode, onValueChange: setBloomLevelCode }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "bloomLevelCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Bloom's Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, bloomLevels.map((bl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name))))), /* @__PURE__ */ React169__default.createElement("div", { className: "pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Question Content & Logic"), questionConfig ? /* @__PURE__ */ React169__default.createElement("div", { className: "p-3 mt-2 border rounded-md bg-muted/30 flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "font-medium" }, "Type: ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-normal" }, questionConfig.questionType)), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground truncate max-w-md" }, "Prompt: ", questionConfig.prompt.replace(/<[^>]*>?/gm, "") || "Not set")), /* @__PURE__ */ React169__default.createElement(Button, { variant: "outline", onClick: () => handleOpenQuestionEditor() }, /* @__PURE__ */ React169__default.createElement(SquarePen, { className: "mr-2 h-4 w-4" }), " Edit Content")) : /* @__PURE__ */ React169__default.createElement("div", { className: "p-3 mt-2 border-dashed border-2 rounded-md text-center" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground mb-2" }, "No content has been created yet."), /* @__PURE__ */ React169__default.createElement(Button, { variant: "default", onClick: () => handleOpenQuestionEditor("multiple_choice") }, /* @__PURE__ */ React169__default.createElement(BookCopy, { className: "mr-2 h-4 w-4" }), " Create Question Content")))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !questionConfig }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save Question")))), questionConfig && /* @__PURE__ */ React169__default.createElement(
106326
+ return /* @__PURE__ */ React169__default.createElement(React169__default.Fragment, null, /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, dialogTitle), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, dialogDescription)), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Question Code"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gradeLevelCode" }, "Grade Level"), /* @__PURE__ */ React169__default.createElement(Select2, { value: gradeLevelCode, onValueChange: setGradeLevelCode }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "gradeLevelCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Grade Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, gradeLevels.map((gl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: gl.code, value: gl.code }, gl.name)))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__default.createElement(Select2, { value: subjectCode, onValueChange: setSubjectCode }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, subjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4.code, value: s4.code }, s4.name))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic"), /* @__PURE__ */ React169__default.createElement(Select2, { value: topicCode, onValueChange: setTopicCode, disabled: !subjectCode || filteredTopics.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "topicCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Topic" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, filteredTopics.map((t4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: t4.code, value: t4.code }, t4.name)))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Bloom's Level"), /* @__PURE__ */ React169__default.createElement(Select2, { value: bloomLevelCode, onValueChange: setBloomLevelCode }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "bloomLevelCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select Bloom's Level" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, bloomLevels.map((bl) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: bl.code, value: bl.code }, bl.name))))), /* @__PURE__ */ React169__default.createElement("div", { className: "pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement(Label2, { className: "font-semibold" }, "Question Content & Logic"), questionConfig ? /* @__PURE__ */ React169__default.createElement("div", { className: "p-3 mt-2 border rounded-md bg-muted/30 flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "font-Medium" }, "Type: ", /* @__PURE__ */ React169__default.createElement("span", { className: "font-normal" }, questionConfig.questionType)), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground truncate max-w-md" }, "Prompt: ", questionConfig.prompt.replace(/<[^>]*>?/gm, "") || "Not set")), /* @__PURE__ */ React169__default.createElement(Button, { variant: "outline", onClick: () => handleOpenQuestionEditor() }, /* @__PURE__ */ React169__default.createElement(SquarePen, { className: "mr-2 h-4 w-4" }), " Edit Content")) : /* @__PURE__ */ React169__default.createElement("div", { className: "p-3 mt-2 border-dashed border-2 rounded-md text-center" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground mb-2" }, "No content has been created yet."), /* @__PURE__ */ React169__default.createElement(Button, { variant: "default", onClick: () => handleOpenQuestionEditor("multiple_choice") }, /* @__PURE__ */ React169__default.createElement(BookCopy, { className: "mr-2 h-4 w-4" }), " Create Question Content")))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !questionConfig }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save Question")))), questionConfig && /* @__PURE__ */ React169__default.createElement(
106377
106327
  EditQuestionModal,
106378
106328
  {
106379
106329
  isOpen: isQuestionEditorOpen,
@@ -110691,10 +110641,10 @@ var RoadmapService = class {
110691
110641
  }
110692
110642
  return null;
110693
110643
  }
110694
- static updateRoadmapItemStatus(loId, isCompleted) {
110644
+ static updateRoadmapItemStatus(code4, isCompleted) {
110695
110645
  const roadmap = this.getRoadmap();
110696
110646
  if (roadmap) {
110697
- const itemIndex = roadmap.items.findIndex((item) => item.loId === loId);
110647
+ const itemIndex = roadmap.items.findIndex((item) => item.code === code4);
110698
110648
  if (itemIndex > -1) {
110699
110649
  roadmap.items[itemIndex].isCompleted = isCompleted;
110700
110650
  this.saveRoadmap(roadmap);
@@ -111275,7 +111225,7 @@ z.object({
111275
111225
  startDate: z.string().describe("The start date for the analysis period in ISO format (YYYY-MM-DD)."),
111276
111226
  endDate: z.string().describe("The end date for the analysis period in ISO format (YYYY-MM-DD)."),
111277
111227
  allAvailableTopics: z.array(z.object({
111278
- loId: z.string(),
111228
+ code: z.string(),
111279
111229
  subject: z.string(),
111280
111230
  category: z.string(),
111281
111231
  topic: z.string()
@@ -111286,7 +111236,7 @@ var RoadmapItemSchema = z.object({
111286
111236
  topicName: z.string(),
111287
111237
  reason: z.string(),
111288
111238
  suggestedDifficulty: z.enum(["Very Easy", "Easy", "Medium", "Hard", "Expert"]),
111289
- loId: z.string(),
111239
+ code: z.string(),
111290
111240
  isCompleted: z.boolean()
111291
111241
  });
111292
111242
  var WeeklyRoadmapSchema = z.object({
@@ -111351,7 +111301,7 @@ All topic names and loIds in your "weeklyRoadmap" output MUST be chosen directly
111351
111301
  - **gamificationRemarks**: Write an encouraging message mentioning their achievements.
111352
111302
  2. **For "weeklyRoadmap":**
111353
111303
  - Create a 5-item roadmap for the upcoming week.
111354
- - Prioritize the "areasForImprovement" you identified. For each, find the corresponding entry in "All Available Topics" and use its "topicName" and "loId".
111304
+ - Prioritize the "areasForImprovement" you identified. For each, find the corresponding entry in "All Available Topics" and use its "topicName" and "code".
111355
111305
  - If more items are needed, select related topics from "All Available Topics".
111356
111306
 
111357
111307
  **IF Practice History IS EMPTY:**
@@ -111362,7 +111312,7 @@ All topic names and loIds in your "weeklyRoadmap" output MUST be chosen directly
111362
111312
  - **gamificationRemarks**: Write a general motivational message about starting to learn.
111363
111313
  2. **For "weeklyRoadmap":**
111364
111314
  - Create a 5-item "starter" roadmap.
111365
- - Select 5 diverse and foundational topics directly from the "All Available Topics" list. Use their exact "topicName" and "loId".
111315
+ - Select 5 diverse and foundational topics directly from the "All Available Topics" list. Use their exact "topicName" and "code".
111366
111316
  - For the "reason", explain that this is a good starting point to explore the subject.
111367
111317
 
111368
111318
  --- END LOGIC FLOW ---
@@ -111390,7 +111340,7 @@ The 'suggestedDifficulty' field MUST ALWAYS be one of these exact English string
111390
111340
  "topicName": "Topic C",
111391
111341
  "reason": "To strengthen your understanding of this key area.",
111392
111342
  "suggestedDifficulty": "Easy",
111393
- "loId": "lo-id-for-topic-c-from-the-list",
111343
+ "code": "lo-id-for-topic-c-from-the-list",
111394
111344
  "isCompleted": false
111395
111345
  }
111396
111346
  ]
@@ -111652,11 +111602,11 @@ init_react_shim();
111652
111602
  // src/ai/flows/assess-and-map-document-types.ts
111653
111603
  init_react_shim();
111654
111604
  var LearningObjectiveContextSchema = z.object({
111655
- loId: z.string(),
111605
+ code: z.string(),
111656
111606
  subject: z.string(),
111657
111607
  category: z.string(),
111658
111608
  topic: z.string(),
111659
- loDescription: z.string()
111609
+ description: z.string()
111660
111610
  });
111661
111611
  z.object({
111662
111612
  language: z.string().default("English"),
@@ -111664,7 +111614,7 @@ z.object({
111664
111614
  learningObjectives: z.array(LearningObjectiveContextSchema).min(1, { message: "At least one learning objective is required for mapping." })
111665
111615
  });
111666
111616
  var MappedLOSchema = z.object({
111667
- loId: z.string().describe("The exact loId from the provided learning objectives list that matches the document content."),
111617
+ code: z.string().describe("The exact code from the provided learning objectives list that matches the document content."),
111668
111618
  confidence: z.number().min(0).max(100).describe("A confidence score (0-100) of how well the document maps to this LO."),
111669
111619
  reasoning: z.string().describe("A brief explanation for why this mapping is relevant.")
111670
111620
  });
@@ -111700,7 +111650,7 @@ You are an expert curriculum analyst. Your task is to analyze a given document a
111700
111650
  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).
111701
111651
 
111702
111652
  2. **Specific Mapping:** Identify which specific LOs from the list are directly addressed by the document. For each match you find, provide:
111703
- - The exact "loId" of the matched LO.
111653
+ - The exact "code" of the matched LO.
111704
111654
  - A "confidence" score (0-100) for that specific match.
111705
111655
  - A brief "reasoning" in ${language3} explaining why the document content maps to that LO.
111706
111656
 
@@ -111715,7 +111665,7 @@ Return a single, valid JSON object in this EXACT format. Do not include any othe
111715
111665
  "isFreestyleRecommended": false,
111716
111666
  "mappedLOs": [
111717
111667
  {
111718
- "loId": "SWIFT_FUNC_01",
111668
+ "code": "SWIFT_FUNC_01",
111719
111669
  "confidence": 95,
111720
111670
  "reasoning": "The document provides a detailed explanation of function syntax and default parameters, which directly aligns with this learning objective."
111721
111671
  }
@@ -111810,7 +111760,7 @@ Return the response as a single JSON object with a key "generatedQuestions" cont
111810
111760
  "correctTempOptionId": "A",
111811
111761
  "explanation": "The document states that mitochondria are the powerhouses of the cell, responsible for cellular respiration.",
111812
111762
  "points": 10,
111813
- "difficulty": "medium",
111763
+ "difficulty": "Medium",
111814
111764
  "topic": "Cell Biology"
111815
111765
  },
111816
111766
  {
@@ -111819,7 +111769,7 @@ Return the response as a single JSON object with a key "generatedQuestions" cont
111819
111769
  "correctAnswer": false,
111820
111770
  "explanation": "The text specifies that the cell wall is a feature of plant cells, not animal cells.",
111821
111771
  "points": 10,
111822
- "difficulty": "easy",
111772
+ "difficulty": "Easy",
111823
111773
  "topic": "Cell Biology"
111824
111774
  }
111825
111775
  ]
@@ -112652,7 +112602,7 @@ var QuizReview = ({
112652
112602
  };
112653
112603
  return /* @__PURE__ */ React169__default.createElement(Card, { className: "w-full max-w-4xl mx-auto shadow-xl" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-3xl font-headline text-center flex items-center justify-center" }, /* @__PURE__ */ React169__default.createElement(BookOpen, { className: "mr-3 h-8 w-8 text-primary" }), "AI-Powered Quiz Review"), /* @__PURE__ */ React169__default.createElement(CardDescription, { className: "text-center text-lg" }, "Let's break down your results and reinforce your learning.")), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-6" }, /* @__PURE__ */ React169__default.createElement(Card, { className: "bg-muted/30" }, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-xl flex items-center" }, /* @__PURE__ */ React169__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-yellow-500" }), "Key Concepts Summary")), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: reviewContent.overallSummary }))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("h3", { className: "text-xl font-semibold mb-2" }, "Detailed Question Analysis"), /* @__PURE__ */ React169__default.createElement(Accordion2, { type: "single", collapsible: true, className: "w-full" }, quizResult.questionResults.map((qResult, index3) => {
112654
112604
  const aiReview = getReviewForQuestion(qResult.questionId);
112655
- return /* @__PURE__ */ React169__default.createElement(AccordionItem2, { value: `item-${index3}`, key: qResult.questionId }, /* @__PURE__ */ React169__default.createElement(AccordionTrigger2, null, /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-between w-full pr-2" }, /* @__PURE__ */ React169__default.createElement("span", { className: "text-left font-medium" }, "Question ", index3 + 1), qResult.isCorrect ? /* @__PURE__ */ React169__default.createElement("span", { className: "text-sm text-green-600 font-medium flex items-center gap-1" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "h-4 w-4" }), " Correct") : /* @__PURE__ */ React169__default.createElement("span", { className: "text-sm text-destructive font-medium flex items-center gap-1" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "h-4 w-4" }), " Incorrect"))), /* @__PURE__ */ React169__default.createElement(AccordionContent2, { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold mb-2" }, "Original Question:"), /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: qResult.prompt })), qResult.questionType === "coding" ? renderCodingResult(qResult) : renderStandardResult(qResult), aiReview && /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border-l-4 border-primary bg-primary/10 rounded-r-md" }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold text-primary mb-2" }, "AI Tutor Explanation:"), /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: aiReview.explanation }))));
112605
+ return /* @__PURE__ */ React169__default.createElement(AccordionItem2, { value: `item-${index3}`, key: qResult.questionId }, /* @__PURE__ */ React169__default.createElement(AccordionTrigger2, null, /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-between w-full pr-2" }, /* @__PURE__ */ React169__default.createElement("span", { className: "text-left font-Medium" }, "Question ", index3 + 1), qResult.isCorrect ? /* @__PURE__ */ React169__default.createElement("span", { className: "text-sm text-green-600 font-Medium flex items-center gap-1" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "h-4 w-4" }), " Correct") : /* @__PURE__ */ React169__default.createElement("span", { className: "text-sm text-destructive font-Medium flex items-center gap-1" }, /* @__PURE__ */ React169__default.createElement(CircleX, { className: "h-4 w-4" }), " Incorrect"))), /* @__PURE__ */ React169__default.createElement(AccordionContent2, { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-md bg-background" }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold mb-2" }, "Original Question:"), /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: qResult.prompt })), qResult.questionType === "coding" ? renderCodingResult(qResult) : renderStandardResult(qResult), aiReview && /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border-l-4 border-primary bg-primary/10 rounded-r-md" }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold text-primary mb-2" }, "AI Tutor Explanation:"), /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: aiReview.explanation }))));
112656
112606
  }))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("h3", { className: "text-xl font-semibold mb-2" }, "Topics for Further Study"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-wrap gap-2" }, reviewContent.relatedTopics.map((topic, index3) => /* @__PURE__ */ React169__default.createElement(Badge2, { key: index3, variant: "secondary", className: "text-base px-3 py-1" }, topic))))), /* @__PURE__ */ React169__default.createElement(CardFooter, { className: "flex flex-col sm:flex-row justify-between gap-2" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "outline", onClick: onBackToResults, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__default.createElement(ArrowLeft, { className: "mr-2 h-4 w-4" }), "Back to Results"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: onExit, className: "w-full sm:w-auto" }, /* @__PURE__ */ React169__default.createElement(LogOut, { className: "mr-2 h-4 w-4" }), "Finish & Exit")));
112657
112607
  };
112658
112608
 
@@ -112699,7 +112649,7 @@ var PracticeHistoryTable = ({ history: history2, maxHeight = "400px" }) => {
112699
112649
  if (percentage >= 50) return "secondary";
112700
112650
  return "destructive";
112701
112651
  };
112702
- return /* @__PURE__ */ React169__default.createElement(React169__default.Fragment, null, /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, null, t4("history.title")), /* @__PURE__ */ React169__default.createElement(CardDescription, null, t4("history.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "w-full border rounded-md", style: { height: maxHeight } }, /* @__PURE__ */ React169__default.createElement(TooltipProvider2, { delayDuration: 100 }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, { className: "sticky top-0 bg-muted z-10" }, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[120px]" }, t4("history.headers.date")), /* @__PURE__ */ React169__default.createElement(TableHead, null, t4("history.headers.topic")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[80px]" }, t4("history.headers.score")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[90px]" }, t4("history.headers.percentage")))), /* @__PURE__ */ React169__default.createElement(TableBody, null, history2.length > 0 ? history2.map((session) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: session.id, onClick: () => handleRowClick(session), className: "cursor-pointer" }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium text-xs text-muted-foreground" }, formatDate(session.timestamp)), /* @__PURE__ */ React169__default.createElement(TableCell, null, /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col gap-1.5" }, session.topics.map((topicInfo, index3) => /* @__PURE__ */ React169__default.createElement(Tooltip2, { key: index3 }, /* @__PURE__ */ React169__default.createElement(TooltipTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold text-sm truncate" }, topicInfo.topic)), /* @__PURE__ */ React169__default.createElement(TooltipContent2, null, /* @__PURE__ */ React169__default.createElement("p", null, /* @__PURE__ */ React169__default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.subject"), ":"), " ", topicInfo.subject), /* @__PURE__ */ React169__default.createElement("p", null, /* @__PURE__ */ React169__default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.category"), ":"), " ", topicInfo.category)))))), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right font-mono text-sm" }, session.score !== null ? `${session.score}/${session.maxScore}` : "N/A"), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, session.percentage !== null && /* @__PURE__ */ React169__default.createElement(
112652
+ return /* @__PURE__ */ React169__default.createElement(React169__default.Fragment, null, /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, null, t4("history.title")), /* @__PURE__ */ React169__default.createElement(CardDescription, null, t4("history.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "w-full border rounded-md", style: { height: maxHeight } }, /* @__PURE__ */ React169__default.createElement(TooltipProvider2, { delayDuration: 100 }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, { className: "sticky top-0 bg-muted z-10" }, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[120px]" }, t4("history.headers.date")), /* @__PURE__ */ React169__default.createElement(TableHead, null, t4("history.headers.topic")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[80px]" }, t4("history.headers.score")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[90px]" }, t4("history.headers.percentage")))), /* @__PURE__ */ React169__default.createElement(TableBody, null, history2.length > 0 ? history2.map((session) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: session.id, onClick: () => handleRowClick(session), className: "cursor-pointer" }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium text-xs text-muted-foreground" }, formatDate(session.timestamp)), /* @__PURE__ */ React169__default.createElement(TableCell, null, /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col gap-1.5" }, session.topics.map((topicInfo, index3) => /* @__PURE__ */ React169__default.createElement(Tooltip2, { key: index3 }, /* @__PURE__ */ React169__default.createElement(TooltipTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement("p", { className: "font-semibold text-sm truncate" }, topicInfo.topic)), /* @__PURE__ */ React169__default.createElement(TooltipContent2, null, /* @__PURE__ */ React169__default.createElement("p", null, /* @__PURE__ */ React169__default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.subject"), ":"), " ", topicInfo.subject), /* @__PURE__ */ React169__default.createElement("p", null, /* @__PURE__ */ React169__default.createElement("strong", null, t4("settingsModal.topics.tableHeaders.category"), ":"), " ", topicInfo.category)))))), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right font-mono text-sm" }, session.score !== null ? `${session.score}/${session.maxScore}` : "N/A"), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, session.percentage !== null && /* @__PURE__ */ React169__default.createElement(
112703
112653
  Badge2,
112704
112654
  {
112705
112655
  variant: getPercentageBadgeVariant(session.percentage),
@@ -133514,12 +133464,12 @@ var ChartTooltipContent = React169.forwardRef(
133514
133464
  const itemConfig = getPayloadConfigFromPayload(config3, item, key);
133515
133465
  const value = !labelKey && typeof label === "string" ? config3[label]?.label || label : itemConfig?.label;
133516
133466
  if (labelFormatter) {
133517
- return /* @__PURE__ */ React169.createElement("div", { className: cn("font-medium", labelClassName) }, labelFormatter(value, payload));
133467
+ return /* @__PURE__ */ React169.createElement("div", { className: cn("font-Medium", labelClassName) }, labelFormatter(value, payload));
133518
133468
  }
133519
133469
  if (!value) {
133520
133470
  return null;
133521
133471
  }
133522
- return /* @__PURE__ */ React169.createElement("div", { className: cn("font-medium", labelClassName) }, value);
133472
+ return /* @__PURE__ */ React169.createElement("div", { className: cn("font-Medium", labelClassName) }, value);
133523
133473
  }, [
133524
133474
  label,
133525
133475
  labelFormatter,
@@ -133582,7 +133532,7 @@ var ChartTooltipContent = React169.forwardRef(
133582
133532
  )
133583
133533
  },
133584
133534
  /* @__PURE__ */ React169.createElement("div", { className: "grid gap-1.5" }, nestLabel ? tooltipLabel : null, /* @__PURE__ */ React169.createElement("span", { className: "text-muted-foreground" }, itemConfig?.label || item.name)),
133585
- item.value && /* @__PURE__ */ React169.createElement("span", { className: "font-mono font-medium tabular-nums text-foreground" }, item.value.toLocaleString())
133535
+ item.value && /* @__PURE__ */ React169.createElement("span", { className: "font-mono font-Medium tabular-nums text-foreground" }, item.value.toLocaleString())
133586
133536
  ))
133587
133537
  );
133588
133538
  }))
@@ -134759,7 +134709,7 @@ var ManageTopics = () => {
134759
134709
  return /* @__PURE__ */ React169__default.createElement(React169__default.Fragment, null, /* @__PURE__ */ React169__default.createElement(Card, { className: "w-full max-w-4xl mx-auto shadow-none border-none" }, /* @__PURE__ */ React169__default.createElement(CardHeader, { className: "px-1" }, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex items-center text-2xl font-headline" }, /* @__PURE__ */ React169__default.createElement(FileText, { className: "mr-3 h-6 w-6 text-primary" }), t4("settingsModal.topics.title")), /* @__PURE__ */ React169__default.createElement(CardDescription, null, t4("settingsModal.topics.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-6 px-1" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "tsv-importer", className: "text-lg font-semibold" }, t4("settingsModal.topics.importData")), /* @__PURE__ */ React169__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__default.createElement("div", { className: "flex-grow" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.topics.importHint")), /* @__PURE__ */ React169__default.createElement("a", { href: "#", className: "text-xs text-primary hover:underline", onClick: (e3) => {
134760
134710
  e3.preventDefault();
134761
134711
  alert("Header format:\nLO ID LO Description Subject Category Topic Keywords Grade STEM Element(s) Bloom\u2019s Level(s) Guideline");
134762
- } }, t4("settingsModal.topics.viewHeaderFormat"))), /* @__PURE__ */ React169__default.createElement(Input, { id: "tsv-importer", type: "file", ref: fileInputRef, accept: ".tsv,text/tab-separated-values", onChange: handleFileChange, className: "hidden" }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: () => fileInputRef.current?.click() }, /* @__PURE__ */ React169__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.chooseFile")))), importErrors.length > 0 && /* @__PURE__ */ React169__default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__default.createElement(AlertTitle, null, t4("settingsModal.topics.importErrors")), /* @__PURE__ */ React169__default.createElement(AlertDescription, null, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-24 mt-2" }, /* @__PURE__ */ React169__default.createElement("ul", { className: "list-disc list-inside text-xs space-y-1" }, importErrors.map((error, index3) => /* @__PURE__ */ React169__default.createElement("li", { key: index3 }, error)))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between mb-2" }, /* @__PURE__ */ React169__default.createElement("h3", { className: "text-lg font-semibold" }, t4("settingsModal.topics.currentDataTitle")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.topics.showingCount", { shown: filteredLearningObjectives.length, total: learningObjectives.length }))), /* @__PURE__ */ React169__default.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subject-filter" }, t4("settingsModal.topics.filterBySubject")), /* @__PURE__ */ React169__default.createElement(Select2, { value: selectedSubjectFilter, onValueChange: setSelectedSubjectFilter, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "subject-filter", className: "w-full sm:w-[280px]" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.topics.filterPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "all" }, t4("settingsModal.topics.allSubjects")), subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: subject, value: subject }, subject))))), /* @__PURE__ */ React169__default.createElement("div", { className: "border rounded-lg" }, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-72" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, { className: "sticky top-0 bg-muted" }, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.subject")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.category")), /* @__PURE__ */ React169__default.createElement(TableHead, null, t4("settingsModal.topics.tableHeaders.topic")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[100px]" }, t4("settingsModal.topics.tableHeaders.loId")))), /* @__PURE__ */ React169__default.createElement(TableBody, null, isLoading ? /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableCell, { colSpan: 4, className: "text-center" }, t4("common.loading"))) : filteredLearningObjectives.length > 0 ? filteredLearningObjectives.map((lo) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: lo.loId }, /* @__PURE__ */ React169__default.createElement(TableCell, null, lo.subject), /* @__PURE__ */ React169__default.createElement(TableCell, null, lo.category), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, lo.topic), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, lo.loId))) : /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableCell, { colSpan: 4, className: "text-center h-24 text-muted-foreground" }, t4("settingsModal.topics.emptyData"))))))))), /* @__PURE__ */ React169__default.createElement(CardFooter, { className: "px-1" }, /* @__PURE__ */ React169__default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "destructive", disabled: learningObjectives.length === 0 }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.clearAllData"))), /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.clearDataConfirmationTitle")), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.clearDataConfirmationMessage", { count: learningObjectives.length }))), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleClearData }, t4("settingsModal.topics.confirmDelete"))))))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isConfirmModalOpen, onOpenChange: setIsConfirmModalOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.confirmModal.title")), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.confirmModal.description", { count: parsedImportData?.data.length || 0 }))), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, { className: "gap-2" }, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { onClick: () => setParsedImportData(null) }, t4("common.cancel")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleConfirmMerge, className: "bg-blue-600 hover:bg-blue-700" }, t4("settingsModal.topics.confirmModal.mergeButton")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleConfirmOverwrite, className: "bg-amber-600 hover:bg-amber-700" }, t4("settingsModal.topics.confirmModal.overwriteButton"))))));
134712
+ } }, t4("settingsModal.topics.viewHeaderFormat"))), /* @__PURE__ */ React169__default.createElement(Input, { id: "tsv-importer", type: "file", ref: fileInputRef, accept: ".tsv,text/tab-separated-values", onChange: handleFileChange, className: "hidden" }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: () => fileInputRef.current?.click() }, /* @__PURE__ */ React169__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.chooseFile")))), importErrors.length > 0 && /* @__PURE__ */ React169__default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__default.createElement(AlertTitle, null, t4("settingsModal.topics.importErrors")), /* @__PURE__ */ React169__default.createElement(AlertDescription, null, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-24 mt-2" }, /* @__PURE__ */ React169__default.createElement("ul", { className: "list-disc list-inside text-xs space-y-1" }, importErrors.map((error, index3) => /* @__PURE__ */ React169__default.createElement("li", { key: index3 }, error)))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between mb-2" }, /* @__PURE__ */ React169__default.createElement("h3", { className: "text-lg font-semibold" }, t4("settingsModal.topics.currentDataTitle")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.topics.showingCount", { shown: filteredLearningObjectives.length, total: learningObjectives.length }))), /* @__PURE__ */ React169__default.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subject-filter" }, t4("settingsModal.topics.filterBySubject")), /* @__PURE__ */ React169__default.createElement(Select2, { value: selectedSubjectFilter, onValueChange: setSelectedSubjectFilter, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "subject-filter", className: "w-full sm:w-[280px]" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.topics.filterPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "all" }, t4("settingsModal.topics.allSubjects")), subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: subject, value: subject }, subject))))), /* @__PURE__ */ React169__default.createElement("div", { className: "border rounded-lg" }, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-72" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, { className: "sticky top-0 bg-muted" }, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.subject")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[150px]" }, t4("settingsModal.topics.tableHeaders.category")), /* @__PURE__ */ React169__default.createElement(TableHead, null, t4("settingsModal.topics.tableHeaders.topic")), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "w-[100px]" }, t4("settingsModal.topics.tableHeaders.code")))), /* @__PURE__ */ React169__default.createElement(TableBody, null, isLoading ? /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableCell, { colSpan: 4, className: "text-center" }, t4("common.loading"))) : filteredLearningObjectives.length > 0 ? filteredLearningObjectives.map((lo) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: lo.code }, /* @__PURE__ */ React169__default.createElement(TableCell, null, lo.subject), /* @__PURE__ */ React169__default.createElement(TableCell, null, lo.category), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, lo.topic), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, lo.code))) : /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableCell, { colSpan: 4, className: "text-center h-24 text-muted-foreground" }, t4("settingsModal.topics.emptyData"))))))))), /* @__PURE__ */ React169__default.createElement(CardFooter, { className: "px-1" }, /* @__PURE__ */ React169__default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "destructive", disabled: learningObjectives.length === 0 }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "mr-2 h-4 w-4" }), t4("settingsModal.topics.clearAllData"))), /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.clearDataConfirmationTitle")), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.clearDataConfirmationMessage", { count: learningObjectives.length }))), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleClearData }, t4("settingsModal.topics.confirmDelete"))))))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isConfirmModalOpen, onOpenChange: setIsConfirmModalOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, t4("settingsModal.topics.confirmModal.title")), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, t4("settingsModal.topics.confirmModal.description", { count: parsedImportData?.data.length || 0 }))), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, { className: "gap-2" }, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { onClick: () => setParsedImportData(null) }, t4("common.cancel")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleConfirmMerge, className: "bg-blue-600 hover:bg-blue-700" }, t4("settingsModal.topics.confirmModal.mergeButton")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleConfirmOverwrite, className: "bg-amber-600 hover:bg-amber-700" }, t4("settingsModal.topics.confirmModal.overwriteButton"))))));
134763
134713
  };
134764
134714
 
134765
134715
  // src/react-ui/components/app/ManageImageContexts.tsx
@@ -135166,7 +135116,7 @@ var SettingsModal = ({ isOpen, onClose, defaultTab = "personal" }) => {
135166
135116
  return goal.id;
135167
135117
  }
135168
135118
  };
135169
- return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl lg:max-w-3xl max-h-[85vh] flex flex-col" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, { className: "shrink-0" }, /* @__PURE__ */ React169__default.createElement(DialogTitle2, { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Settings, { className: "mr-2 h-5 w-5 text-primary" }), t4("settingsModal.title")), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, t4("settingsModal.description"))), /* @__PURE__ */ React169__default.createElement(Tabs2, { value: activeTab, onValueChange: (value) => setActiveTab(value), className: "pt-2 flex-1 flex flex-col min-h-0" }, /* @__PURE__ */ React169__default.createElement(TabsList2, { className: "grid w-full grid-cols-5 shrink-0" }, /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "personal" }, /* @__PURE__ */ React169__default.createElement(User, { className: "mr-1 h-4 w-4" }), t4("settingsModal.personalTab")), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "topics" }, /* @__PURE__ */ React169__default.createElement(ListTodo, { className: "mr-1 h-4 w-4" }), t4("settingsModal.topicsTab")), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "imageContexts" }, /* @__PURE__ */ React169__default.createElement(ImagePlus, { className: "mr-1 h-4 w-4" }), "Images"), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "layout" }, /* @__PURE__ */ React169__default.createElement(LayoutDashboard, { className: "mr-1 h-4 w-4" }), t4("settingsModal.layoutTab")), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "apiKeys" }, /* @__PURE__ */ React169__default.createElement(KeyRound, { className: "mr-1 h-4 w-4" }), t4("settingsModal.apiKeysTab"))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "personal", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-full pr-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-3" }, t4("settingsModal.personal.basicInfo")), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "full-name" }, t4("settingsModal.personal.fullName")), /* @__PURE__ */ React169__default.createElement(Input, { id: "full-name", value: fullName, onChange: (e3) => setFullName(e3.target.value), placeholder: t4("settingsModal.personal.fullNamePlaceholder") })), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "weekly-goal" }, t4("settingsModal.personal.weeklyGoal")), /* @__PURE__ */ React169__default.createElement(Input, { id: "weekly-goal", type: "number", value: weeklyGoal, onChange: (e3) => setWeeklyGoal(parseInt(e3.target.value, 10) || 0), min: "1" })), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "language-select", className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Languages, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.languageSelectLabel")), /* @__PURE__ */ React169__default.createElement(Select2, { value: language3, onValueChange: changeLanguage2 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "language-select" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select a language..." })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "en" }, "English"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "vi" }, "Ti\u1EBFng Vi\u1EC7t")))))), /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-3 flex items-center" }, /* @__PURE__ */ React169__default.createElement(Target, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.advancedGoals")), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2 mb-4" }, advancedGoals.map((goal) => /* @__PURE__ */ React169__default.createElement("div", { key: goal.id, className: "flex items-center justify-between p-2 bg-muted/50 rounded-md" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm flex-1" }, renderGoalDescription(goal)), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleDeleteGoal(goal.id) }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), advancedGoals.length === 0 && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.personal.noGoals"))), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement("h5", { className: "font-medium" }, t4("settingsModal.personal.addNewGoal")), /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalType, onValueChange: (v) => setNewGoalType(v) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.goalTypePlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "average_score_subject" }, t4("settingsModal.personal.goalType.avgScoreSubject")), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "mastery_topic" }, t4("settingsModal.personal.goalType.masteryTopic")))), newGoalType === "average_score_subject" && /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") })), newGoalType === "mastery_topic" && /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalTopic, onValueChange: setNewGoalTopic, disabled: !newGoalSubject }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.topicPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, topicsForSelectedSubject.map((t5) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: t5, value: t5 }, t5)))), /* @__PURE__ */ React169__default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") }), /* @__PURE__ */ React169__default.createElement(Input, { type: "number", value: newGoalConsecutive, onChange: (e3) => setNewGoalConsecutive(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.consecutiveSessionsPlaceholder") })), newGoalType && /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", onClick: handleAddNewGoal }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.addGoalButton"))))))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "topics", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__default.createElement(ManageTopics, null)), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "imageContexts", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__default.createElement(ManageImageContexts, null)), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "layout", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold" }, t4("settingsModal.layout.title")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground mt-1 mb-3" }, t4("settingsModal.layout.description")), /* @__PURE__ */ React169__default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(RefreshCw, { className: "mr-2 h-4 w-4" }), t4("settingsModal.layout.resetButton"))), /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, t4("settingsModal.layout.resetConfirmationTitle")), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, t4("settingsModal.layout.resetConfirmationMessage"))), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleResetLayout }, t4("settingsModal.layout.confirmReset"))))))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "apiKeys", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gemini-api-key" }, t4("settingsModal.apiKeys.geminiKey")), /* @__PURE__ */ React169__default.createElement(Input, { id: "gemini-api-key", type: "password", value: geminiApiKey, onChange: (e3) => setGeminiApiKey(e3.target.value), placeholder: t4("settingsModal.apiKeys.geminiKeyPlaceholder") }), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, t4("settingsModal.apiKeys.storageHint"))))), /* @__PURE__ */ React169__default.createElement(DialogFooter, { className: "gap-2 sm:justify-end pt-4 shrink-0" }, /* @__PURE__ */ React169__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline" }, t4("common.close"))), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", onClick: handleSave }, /* @__PURE__ */ React169__default.createElement(Save, { className: "mr-2 h-4 w-4" }), t4("settingsModal.saveChanges")))));
135119
+ return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-xl md:max-w-2xl lg:max-w-3xl max-h-[85vh] flex flex-col" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, { className: "shrink-0" }, /* @__PURE__ */ React169__default.createElement(DialogTitle2, { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Settings, { className: "mr-2 h-5 w-5 text-primary" }), t4("settingsModal.title")), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, t4("settingsModal.description"))), /* @__PURE__ */ React169__default.createElement(Tabs2, { value: activeTab, onValueChange: (value) => setActiveTab(value), className: "pt-2 flex-1 flex flex-col min-h-0" }, /* @__PURE__ */ React169__default.createElement(TabsList2, { className: "grid w-full grid-cols-5 shrink-0" }, /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "personal" }, /* @__PURE__ */ React169__default.createElement(User, { className: "mr-1 h-4 w-4" }), t4("settingsModal.personalTab")), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "topics" }, /* @__PURE__ */ React169__default.createElement(ListTodo, { className: "mr-1 h-4 w-4" }), t4("settingsModal.topicsTab")), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "imageContexts" }, /* @__PURE__ */ React169__default.createElement(ImagePlus, { className: "mr-1 h-4 w-4" }), "Images"), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "layout" }, /* @__PURE__ */ React169__default.createElement(LayoutDashboard, { className: "mr-1 h-4 w-4" }), t4("settingsModal.layoutTab")), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "apiKeys" }, /* @__PURE__ */ React169__default.createElement(KeyRound, { className: "mr-1 h-4 w-4" }), t4("settingsModal.apiKeysTab"))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "personal", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-full pr-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-3" }, t4("settingsModal.personal.basicInfo")), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "full-name" }, t4("settingsModal.personal.fullName")), /* @__PURE__ */ React169__default.createElement(Input, { id: "full-name", value: fullName, onChange: (e3) => setFullName(e3.target.value), placeholder: t4("settingsModal.personal.fullNamePlaceholder") })), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "weekly-goal" }, t4("settingsModal.personal.weeklyGoal")), /* @__PURE__ */ React169__default.createElement(Input, { id: "weekly-goal", type: "number", value: weeklyGoal, onChange: (e3) => setWeeklyGoal(parseInt(e3.target.value, 10) || 0), min: "1" })), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "language-select", className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Languages, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.languageSelectLabel")), /* @__PURE__ */ React169__default.createElement(Select2, { value: language3, onValueChange: changeLanguage2 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "language-select" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select a language..." })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "en" }, "English"), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "vi" }, "Ti\u1EBFng Vi\u1EC7t")))))), /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-3 flex items-center" }, /* @__PURE__ */ React169__default.createElement(Target, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.advancedGoals")), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2 mb-4" }, advancedGoals.map((goal) => /* @__PURE__ */ React169__default.createElement("div", { key: goal.id, className: "flex items-center justify-between p-2 bg-muted/50 rounded-md" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm flex-1" }, renderGoalDescription(goal)), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", onClick: () => handleDeleteGoal(goal.id) }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4 text-destructive" })))), advancedGoals.length === 0 && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, t4("settingsModal.personal.noGoals"))), /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3 pt-4 border-t" }, /* @__PURE__ */ React169__default.createElement("h5", { className: "font-Medium" }, t4("settingsModal.personal.addNewGoal")), /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalType, onValueChange: (v) => setNewGoalType(v) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.goalTypePlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "average_score_subject" }, t4("settingsModal.personal.goalType.avgScoreSubject")), /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "mastery_topic" }, t4("settingsModal.personal.goalType.masteryTopic")))), newGoalType === "average_score_subject" && /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") })), newGoalType === "mastery_topic" && /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-2 gap-2 animate-in fade-in" }, /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalSubject, onValueChange: setNewGoalSubject }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.subjectPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, allSubjects.map((s4) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: s4, value: s4 }, s4)))), /* @__PURE__ */ React169__default.createElement(Select2, { value: newGoalTopic, onValueChange: setNewGoalTopic, disabled: !newGoalSubject }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: t4("settingsModal.personal.topicPlaceholder") })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, topicsForSelectedSubject.map((t5) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: t5, value: t5 }, t5)))), /* @__PURE__ */ React169__default.createElement(Input, { type: "number", value: newGoalTargetValue, onChange: (e3) => setNewGoalTargetValue(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.targetScorePlaceholder") }), /* @__PURE__ */ React169__default.createElement(Input, { type: "number", value: newGoalConsecutive, onChange: (e3) => setNewGoalConsecutive(parseInt(e3.target.value)), placeholder: t4("settingsModal.personal.consecutiveSessionsPlaceholder") })), newGoalType && /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", onClick: handleAddNewGoal }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), t4("settingsModal.personal.addGoalButton"))))))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "topics", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__default.createElement(ManageTopics, null)), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "imageContexts", className: "flex-1 overflow-auto mt-4" }, /* @__PURE__ */ React169__default.createElement(ManageImageContexts, null)), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "layout", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 border rounded-lg" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold" }, t4("settingsModal.layout.title")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground mt-1 mb-3" }, t4("settingsModal.layout.description")), /* @__PURE__ */ React169__default.createElement(AlertDialog2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(RefreshCw, { className: "mr-2 h-4 w-4" }), t4("settingsModal.layout.resetButton"))), /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, t4("settingsModal.layout.resetConfirmationTitle")), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, t4("settingsModal.layout.resetConfirmationMessage"))), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, null, t4("common.cancel")), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: handleResetLayout }, t4("settingsModal.layout.confirmReset"))))))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "apiKeys", className: "space-y-4 pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gemini-api-key" }, t4("settingsModal.apiKeys.geminiKey")), /* @__PURE__ */ React169__default.createElement(Input, { id: "gemini-api-key", type: "password", value: geminiApiKey, onChange: (e3) => setGeminiApiKey(e3.target.value), placeholder: t4("settingsModal.apiKeys.geminiKeyPlaceholder") }), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, t4("settingsModal.apiKeys.storageHint"))))), /* @__PURE__ */ React169__default.createElement(DialogFooter, { className: "gap-2 sm:justify-end pt-4 shrink-0" }, /* @__PURE__ */ React169__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline" }, t4("common.close"))), /* @__PURE__ */ React169__default.createElement(Button, { type: "button", onClick: handleSave }, /* @__PURE__ */ React169__default.createElement(Save, { className: "mr-2 h-4 w-4" }), t4("settingsModal.saveChanges")))));
135170
135120
  };
135171
135121
 
135172
135122
  // src/react-ui/components/dashboard/Cheatsheet.tsx
@@ -135265,7 +135215,7 @@ var Cheatsheet = () => {
135265
135215
  }
135266
135216
  return null;
135267
135217
  };
135268
- return /* @__PURE__ */ React169__default.createElement(React169__default.Fragment, null, /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), t4("knowledgeCards.title")), /* @__PURE__ */ React169__default.createElement(CardDescription, null, t4("knowledgeCards.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement(Input, { type: "search", placeholder: t4("knowledgeCards.searchPlaceholder"), value: searchQuery, onChange: (e3) => setSearchQuery2(e3.target.value), disabled: allCards.length === 0 }), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, allCards.length > 0 ? filteredCards.length > 0 ? /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, filteredCards.map((card) => /* @__PURE__ */ React169__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__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.noMatch"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.empty")))), renderActionArea())), /* @__PURE__ */ React169__default.createElement(
135218
+ return /* @__PURE__ */ React169__default.createElement(React169__default.Fragment, null, /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), t4("knowledgeCards.title")), /* @__PURE__ */ React169__default.createElement(CardDescription, null, t4("knowledgeCards.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React169__default.createElement(Input, { type: "search", placeholder: t4("knowledgeCards.searchPlaceholder"), value: searchQuery, onChange: (e3) => setSearchQuery2(e3.target.value), disabled: allCards.length === 0 }), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, allCards.length > 0 ? filteredCards.length > 0 ? /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, filteredCards.map((card) => /* @__PURE__ */ React169__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__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.noMatch"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("knowledgeCards.empty")))), renderActionArea())), /* @__PURE__ */ React169__default.createElement(
135269
135219
  CardViewerDialog,
135270
135220
  {
135271
135221
  isOpen: isDialogOpen,
@@ -135292,9 +135242,9 @@ var StatCard = ({
135292
135242
  isLoading = false
135293
135243
  }) => {
135294
135244
  if (isLoading) {
135295
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-sm font-medium" }, title), /* @__PURE__ */ React169__default.createElement(Skeleton, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement(Skeleton, { className: "h-8 w-3/4 mb-2" }), /* @__PURE__ */ React169__default.createElement(Skeleton, { className: "h-4 w-1/2" })));
135245
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-sm font-Medium" }, title), /* @__PURE__ */ React169__default.createElement(Skeleton, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement(Skeleton, { className: "h-8 w-3/4 mb-2" }), /* @__PURE__ */ React169__default.createElement(Skeleton, { className: "h-4 w-1/2" })));
135296
135246
  }
135297
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-sm font-medium" }, title), /* @__PURE__ */ React169__default.createElement("div", { className: "text-muted-foreground" }, icon)), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement("div", { className: "text-2xl font-bold" }, value, unit2 && /* @__PURE__ */ React169__default.createElement("span", { className: "text-xl font-medium text-muted-foreground ml-1" }, unit2)), context && /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, context)));
135247
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2" }, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "text-sm font-Medium" }, title), /* @__PURE__ */ React169__default.createElement("div", { className: "text-muted-foreground" }, icon)), /* @__PURE__ */ React169__default.createElement(CardContent, null, /* @__PURE__ */ React169__default.createElement("div", { className: "text-2xl font-bold" }, value, unit2 && /* @__PURE__ */ React169__default.createElement("span", { className: "text-xl font-Medium text-muted-foreground ml-1" }, unit2)), context && /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs text-muted-foreground" }, context)));
135298
135248
  };
135299
135249
 
135300
135250
  // src/react-ui/components/dashboard/PerformanceSnapshot.tsx
@@ -135393,7 +135343,7 @@ var RoadmapChecklist = () => {
135393
135343
  }, []);
135394
135344
  const handleStartPractice = useCallback((item) => {
135395
135345
  const practiceConfig = {
135396
- loIds: [item.loId],
135346
+ loIds: [item.code],
135397
135347
  difficulty: item.suggestedDifficulty,
135398
135348
  language: "Vietnamese"
135399
135349
  };
@@ -135403,7 +135353,7 @@ var RoadmapChecklist = () => {
135403
135353
  return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(CalendarCheck, { className: "mr-2 h-5 w-5 text-primary" }), t4("roadmap.title")), /* @__PURE__ */ React169__default.createElement(CardDescription, null, t4("roadmap.description"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, !roadmap || !roadmap.items || roadmap.items.length === 0 ? /* @__PURE__ */ React169__default.createElement("div", { className: "text-center text-muted-foreground py-8" }, /* @__PURE__ */ React169__default.createElement("p", null, t4("roadmap.emptyState")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, t4("roadmap.emptyStateSuggestion"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, roadmap.items.map((item, index3) => /* @__PURE__ */ React169__default.createElement(
135404
135354
  "div",
135405
135355
  {
135406
- key: `${item.loId}-${index3}`,
135356
+ key: `${item.code}-${index3}`,
135407
135357
  className: "flex items-center justify-between p-3 border rounded-md bg-background hover:bg-muted/50 transition-colors"
135408
135358
  },
135409
135359
  /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React169__default.createElement(
@@ -136946,7 +136896,7 @@ function Calendar2({
136946
136896
  months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
136947
136897
  month: "space-y-4",
136948
136898
  caption: "flex justify-center pt-1 relative items-center",
136949
- caption_label: "text-sm font-medium",
136899
+ caption_label: "text-sm font-Medium",
136950
136900
  nav: "space-x-1 flex items-center",
136951
136901
  nav_button: cn(
136952
136902
  buttonVariants({ variant: "outline" }),
@@ -137068,7 +137018,7 @@ var AnalysisDialog = ({ isOpen, onClose }) => {
137068
137018
  }
137069
137019
  try {
137070
137020
  const allAvailableTopics = TopicDataService.getData().map((lo) => ({
137071
- loId: lo.loId,
137021
+ code: lo.code,
137072
137022
  subject: lo.subject,
137073
137023
  category: lo.category,
137074
137024
  topic: lo.topic
@@ -137521,7 +137471,7 @@ var GeneratedQuizzesCard = () => {
137521
137471
  onChange: (e3) => setSearchQuery2(e3.target.value),
137522
137472
  disabled: uniqueQuizzes.length === 0
137523
137473
  }
137524
- ), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm font-medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.noMatch"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.empty"))))));
137474
+ ), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm font-Medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.noMatch"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.generated.empty"))))));
137525
137475
  };
137526
137476
 
137527
137477
  // src/react-ui/components/app/UploadResourceModal.tsx
@@ -137601,11 +137551,12 @@ var UploadResourceModal = ({ isOpen, onClose }) => {
137601
137551
  language: i18n.language === "vi" ? "Vietnamese" : "English",
137602
137552
  documentContent: textContent,
137603
137553
  learningObjectives: learningObjectives.map((lo) => ({
137604
- loId: lo.loId,
137554
+ name: lo.name,
137555
+ code: lo.code,
137605
137556
  subject: lo.subject,
137606
137557
  category: lo.category,
137607
137558
  topic: lo.topic,
137608
- loDescription: lo.loDescription
137559
+ description: lo.description || ""
137609
137560
  }))
137610
137561
  }, apiKey);
137611
137562
  setAnalysisResult(result);
@@ -137638,12 +137589,12 @@ var UploadResourceModal = ({ isOpen, onClose }) => {
137638
137589
  generatedQuestions = result.generatedQuestions;
137639
137590
  } else {
137640
137591
  const plan = analysisResult.mappedLOs.map((lo) => {
137641
- const sourceLO = TopicDataService.getData().find((orig) => orig.loId === lo.loId);
137592
+ const sourceLO = TopicDataService.getData().find((orig) => orig.code === lo.code);
137642
137593
  return {
137643
137594
  plannedTopic: lo.reasoning,
137644
137595
  plannedQuestionType: "multiple_choice",
137645
137596
  plannedBloomLevel: "understanding",
137646
- originalLoId: lo.loId,
137597
+ originalLoId: lo.code,
137647
137598
  originalTopic: sourceLO?.topic,
137648
137599
  originalCategory: sourceLO?.category,
137649
137600
  originalSubject: sourceLO?.subject
@@ -137688,7 +137639,7 @@ var UploadResourceModal = ({ isOpen, onClose }) => {
137688
137639
  return /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col items-center justify-center h-48" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-12 w-12 animate-spin text-primary" }), /* @__PURE__ */ React169__default.createElement("p", { className: "mt-4 text-muted-foreground font-semibold" }, stage === "analyzing" && t4("dialogs.uploadResource.analyzing"), stage === "generating" && t4("dialogs.uploadResource.generating")));
137689
137640
  case "result":
137690
137641
  if (!analysisResult) return null;
137691
- return /* @__PURE__ */ React169__default.createElement("div", { className: "py-4 space-y-4" }, /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardContent, { className: "p-4" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-2" }, "AI Analysis Complete"), analysisResult.isFreestyleRecommended ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-start gap-3 text-amber-700" }, /* @__PURE__ */ React169__default.createElement(BrainCircuit, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "font-medium" }, t4("dialogs.uploadResource.freestyleRecommended")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.freestyleDescription")))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-start gap-3 text-green-700" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "font-medium" }, t4("dialogs.uploadResource.curriculumMatch")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.curriculumDescription")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs mt-2 font-semibold" }, t4("dialogs.uploadResource.mappedTopics")), /* @__PURE__ */ React169__default.createElement("ul", { className: "list-disc list-inside text-xs" }, analysisResult.mappedLOs.map((lo) => /* @__PURE__ */ React169__default.createElement("li", { key: lo.loId }, TopicDataService.getData().find((orig) => orig.loId === lo.loId)?.topic || lo.loId))))))), error && /* @__PURE__ */ React169__default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__default.createElement(AlertTitle, null, t4("common.error")), /* @__PURE__ */ React169__default.createElement(AlertDescription, null, error)));
137642
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "py-4 space-y-4" }, /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardContent, { className: "p-4" }, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-2" }, "AI Analysis Complete"), analysisResult.isFreestyleRecommended ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-start gap-3 text-amber-700" }, /* @__PURE__ */ React169__default.createElement(BrainCircuit, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "font-Medium" }, t4("dialogs.uploadResource.freestyleRecommended")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.freestyleDescription")))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-start gap-3 text-green-700" }, /* @__PURE__ */ React169__default.createElement(CircleCheckBig, { className: "h-5 w-5 mt-1 flex-shrink-0" }), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("p", { className: "font-Medium" }, t4("dialogs.uploadResource.curriculumMatch")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm" }, t4("dialogs.uploadResource.curriculumDescription")), /* @__PURE__ */ React169__default.createElement("p", { className: "text-xs mt-2 font-semibold" }, t4("dialogs.uploadResource.mappedTopics")), /* @__PURE__ */ React169__default.createElement("ul", { className: "list-disc list-inside text-xs" }, analysisResult.mappedLOs.map((lo) => /* @__PURE__ */ React169__default.createElement("li", { key: lo.code }, TopicDataService.getData().find((orig) => orig.code === lo.code)?.topic || lo.code))))))), error && /* @__PURE__ */ React169__default.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(CircleAlert, { className: "h-4 w-4" }), /* @__PURE__ */ React169__default.createElement(AlertTitle, null, t4("common.error")), /* @__PURE__ */ React169__default.createElement(AlertDescription, null, error)));
137692
137643
  }
137693
137644
  };
137694
137645
  return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-lg" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(FileText, { className: "mr-2 h-5 w-5" }), t4("dialogs.uploadResource.title")), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, t4("dialogs.uploadResource.description"))), renderContent3(), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "outline" }, t4("common.cancel"))), stage === "result" && /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleGenerateQuiz }, /* @__PURE__ */ React169__default.createElement(Sparkles, { className: "mr-2 h-4 w-4" }), t4("dialogs.uploadResource.generateButton")))));
@@ -137809,7 +137760,7 @@ var FreestyleQuizzesCard = () => {
137809
137760
  onChange: (e3) => setSearchQuery2(e3.target.value),
137810
137761
  disabled: uniqueQuizzes.length === 0
137811
137762
  }
137812
- ), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm font-medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.noMatch"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.empty"))))));
137763
+ ), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "h-[180px] w-full rounded-md border p-2" }, uniqueQuizzes.length > 0 ? filteredQuizzes.length > 0 ? /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-1" }, filteredQuizzes.map((quiz) => /* @__PURE__ */ React169__default.createElement("div", { key: quiz.id, className: "flex items-center justify-between p-2 rounded-md hover:bg-accent" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm font-Medium truncate pr-2", title: quiz.title }, quiz.title), /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", variant: "ghost", onClick: () => handleRetake(quiz) }, /* @__PURE__ */ React169__default.createElement(CirclePlay, { className: "mr-2 h-4 w-4" }), t4("common.retake"))))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.noMatch"))) : /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center justify-center h-full" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-muted-foreground" }, t4("quizLists.freestyle.empty"))))));
137813
137764
  };
137814
137765
 
137815
137766
  // src/react-ui/components/common/ClientTranslation.tsx
@@ -137959,7 +137910,7 @@ var PersonalPracticeDashboard = ({ settingsPath, initialHistory, initialStats, i
137959
137910
  }
137960
137911
  try {
137961
137912
  const allAvailableTopics = TopicDataService.getData().map((lo) => ({
137962
- loId: lo.loId,
137913
+ code: lo.code,
137963
137914
  subject: lo.subject,
137964
137915
  category: lo.category,
137965
137916
  topic: lo.topic
@@ -138453,7 +138404,7 @@ var PracticeModeController = () => {
138453
138404
  try {
138454
138405
  const config3 = JSON.parse(suggestedConfigString);
138455
138406
  const allLOs = TopicDataService.getData();
138456
- const suggestedLOs = allLOs.filter((lo) => config3.loIds?.includes(lo.loId));
138407
+ const suggestedLOs = allLOs.filter((lo) => config3.loIds?.includes(lo.code));
138457
138408
  if (suggestedLOs.length > 0) {
138458
138409
  setInitialSuggestedLOs(suggestedLOs);
138459
138410
  setInitialSuggestedDifficulty(config3.difficulty || "Medium");
@@ -138496,9 +138447,10 @@ var PracticeModeController = () => {
138496
138447
  totalQuestions,
138497
138448
  numCodingQuestions,
138498
138449
  topics: selectedLOs.map((lo) => ({
138499
- topic: lo.loDescription,
138450
+ topic: lo.name || lo.code,
138451
+ // FIX: Provide fallback for name
138500
138452
  ratio: 100 / selectedLOs.length,
138501
- originalLoId: lo.loId,
138453
+ originalLoId: lo.code,
138502
138454
  originalSubject: lo.subject,
138503
138455
  originalCategory: lo.category,
138504
138456
  originalTopic: lo.topic
@@ -138690,7 +138642,7 @@ var SuggestionDialog = ({
138690
138642
  if (!suggestion) {
138691
138643
  return /* @__PURE__ */ React169__default.createElement("div", { className: "flex flex-col items-center justify-center h-64 gap-4" }, /* @__PURE__ */ React169__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."));
138692
138644
  }
138693
- return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 bg-muted/50 rounded-lg" }, /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: suggestion.suggestionText })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-3" }, "K\u1EBF ho\u1EA1ch Luy\u1EC7n t\u1EADp \u0111\u01B0\u1EE3c G\u1EE3i \xFD:"), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "max-h-[200px] pr-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, suggestion.suggestedTopics.map((topic) => /* @__PURE__ */ React169__default.createElement("div", { key: topic.loId, className: "flex items-center justify-between p-3 border rounded-md" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex-1 mr-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2 mb-1" }, topic.reason === "review" ? /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(RefreshCw, { className: "h-3 w-3 mr-1.5" }), "\xD4n t\u1EADp") : /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "secondary" }, /* @__PURE__ */ React169__default.createElement(Search, { className: "h-3 w-3 mr-1.5" }), "Kh\xE1m ph\xE1")), /* @__PURE__ */ React169__default.createElement("p", { className: "font-medium" }, topic.topicName)), /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", onClick: () => onStartSuggestedPractice(topic) }, /* @__PURE__ */ React169__default.createElement(CirclePlay, { className: "h-4 w-4 mr-2" }), "B\u1EAFt \u0111\u1EA7u")))))));
138645
+ return /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React169__default.createElement("div", { className: "p-4 bg-muted/50 rounded-lg" }, /* @__PURE__ */ React169__default.createElement(MarkdownRenderer, { content: suggestion.suggestionText })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement("h4", { className: "font-semibold mb-3" }, "K\u1EBF ho\u1EA1ch Luy\u1EC7n t\u1EADp \u0111\u01B0\u1EE3c G\u1EE3i \xFD:"), /* @__PURE__ */ React169__default.createElement(ScrollArea2, { className: "max-h-[200px] pr-3" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, suggestion.suggestedTopics.map((topic) => /* @__PURE__ */ React169__default.createElement("div", { key: topic.code, className: "flex items-center justify-between p-3 border rounded-md" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex-1 mr-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2 mb-1" }, topic.reason === "review" ? /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "destructive" }, /* @__PURE__ */ React169__default.createElement(RefreshCw, { className: "h-3 w-3 mr-1.5" }), "\xD4n t\u1EADp") : /* @__PURE__ */ React169__default.createElement(Badge2, { variant: "secondary" }, /* @__PURE__ */ React169__default.createElement(Search, { className: "h-3 w-3 mr-1.5" }), "Kh\xE1m ph\xE1")), /* @__PURE__ */ React169__default.createElement("p", { className: "font-Medium" }, topic.topicName)), /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", onClick: () => onStartSuggestedPractice(topic) }, /* @__PURE__ */ React169__default.createElement(CirclePlay, { className: "h-4 w-4 mr-2" }), "B\u1EAFt \u0111\u1EA7u")))))));
138694
138646
  };
138695
138647
  return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: (open) => !open && onClose() }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-lg md:max-w-xl" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, { className: "flex items-center text-2xl" }, /* @__PURE__ */ React169__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__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__default.createElement("div", { className: "py-4" }, renderContent3()), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(DialogClose2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline" }, "\u0110\xF3ng")))));
138696
138648
  };
@@ -138700,12 +138652,96 @@ init_react_shim();
138700
138652
 
138701
138653
  // src/react-ui/components/metadata/SubjectManager.tsx
138702
138654
  init_react_shim();
138655
+
138656
+ // src/react-ui/components/metadata/MetadataImportControls.tsx
138657
+ init_react_shim();
138658
+ function MetadataImportControls({ metadataName, onImport }) {
138659
+ const [isOpen, setIsOpen] = useState(false);
138660
+ const [jsonString, setJsonString] = useState("");
138661
+ const [isImporting, startImportTransition] = useTransition();
138662
+ const fileInputRef = useRef(null);
138663
+ const { toast: toast2 } = useToast();
138664
+ const processAndImportRecords = async (records, importSource) => {
138665
+ if (records.length === 0) {
138666
+ toast2({ title: "No Data", description: `The selected ${importSource === "file" ? "file" : "JSON string"} contains no data to import.`, variant: "destructive" });
138667
+ return;
138668
+ }
138669
+ await onImport(records);
138670
+ setIsOpen(false);
138671
+ setJsonString("");
138672
+ };
138673
+ const handleFileSelected = (event) => {
138674
+ const file = event.target.files?.[0];
138675
+ if (!file) return;
138676
+ if (file.type !== "application/json" && !file.name.endsWith(".csv")) {
138677
+ toast2({ title: "Invalid File Type", description: "Please select a JSON or CSV file.", variant: "destructive" });
138678
+ if (event.target) event.target.value = "";
138679
+ return;
138680
+ }
138681
+ startImportTransition(async () => {
138682
+ try {
138683
+ const fileContent = await file.text();
138684
+ let records = [];
138685
+ if (file.type === "application/json") {
138686
+ records = JSON.parse(fileContent);
138687
+ if (!Array.isArray(records)) throw new Error("JSON file must contain an array of objects.");
138688
+ } else if (file.name.endsWith(".csv")) {
138689
+ const lines = fileContent.split(/\r\n|\n/).filter((line) => line.trim() !== "");
138690
+ if (lines.length < 2) throw new Error("CSV must have a header and at least one data row.");
138691
+ const headers = lines[0].split(",").map((h3) => h3.trim());
138692
+ records = lines.slice(1).map((line) => {
138693
+ const values = line.split(",").map((v) => v.trim());
138694
+ const record = {};
138695
+ headers.forEach((header, index3) => {
138696
+ record[header] = values[index3];
138697
+ });
138698
+ return record;
138699
+ });
138700
+ }
138701
+ await processAndImportRecords(records, "file");
138702
+ } catch (err) {
138703
+ toast2({ title: "Import Error", description: `Failed to process file: ${err.message}`, variant: "destructive" });
138704
+ }
138705
+ });
138706
+ if (event.target) event.target.value = "";
138707
+ };
138708
+ const handleJsonStringImport = () => {
138709
+ if (!jsonString.trim()) {
138710
+ toast2({ title: "Missing Data", description: "JSON string cannot be empty.", variant: "destructive" });
138711
+ return;
138712
+ }
138713
+ startImportTransition(async () => {
138714
+ try {
138715
+ const records = JSON.parse(jsonString);
138716
+ if (!Array.isArray(records)) throw new Error("JSON string must represent an array of objects.");
138717
+ await processAndImportRecords(records, "text");
138718
+ } catch (err) {
138719
+ toast2({ title: "Import Error", description: `Failed to process JSON string: ${err.message}`, variant: "destructive" });
138720
+ }
138721
+ });
138722
+ };
138723
+ return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React169__default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React169__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React169__default.createElement(DialogContent2, null, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React169__default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React169__default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React169__default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React169__default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__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__default.createElement(Button, { variant: "outline", onClick: () => fileInputRef.current?.click(), disabled: isImporting }, isImporting ? /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), isImporting ? "Importing..." : "Select File"), /* @__PURE__ */ React169__default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileSelected, accept: ".json,.csv", className: "hidden" }))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "text", className: "pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "jsonInput" }, "JSON Data (Array of Objects)"), /* @__PURE__ */ React169__default.createElement(
138724
+ Textarea,
138725
+ {
138726
+ id: "jsonInput",
138727
+ value: jsonString,
138728
+ onChange: (e3) => setJsonString(e3.target.value),
138729
+ placeholder: '[{"code": "SUB1", "name": "Subject 1"}, ...]',
138730
+ rows: 8,
138731
+ className: "font-mono text-xs",
138732
+ disabled: isImporting
138733
+ }
138734
+ ), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleJsonStringImport, disabled: isImporting || !jsonString.trim() }, isImporting ? /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), "Import from Text"))))));
138735
+ }
138736
+
138737
+ // src/react-ui/components/metadata/SubjectManager.tsx
138703
138738
  function SubjectManager({
138704
138739
  initialData,
138705
138740
  isLoading: isLoadingProp,
138706
138741
  onAdd,
138707
138742
  onUpdate,
138708
- onDelete
138743
+ onDelete,
138744
+ onBulkAdd
138709
138745
  }) {
138710
138746
  const [subjects, setSubjects] = useState([]);
138711
138747
  const [isLoading, setIsLoading] = useState(true);
@@ -138803,12 +138839,37 @@ function SubjectManager({
138803
138839
  }
138804
138840
  });
138805
138841
  };
138806
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e3) => setSubjectName(e3.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
138842
+ const handleImport = async (records) => {
138843
+ if (!onBulkAdd) return;
138844
+ const validatedRecords = records.map((rec) => {
138845
+ if (typeof rec.code === "string" && typeof rec.name === "string") {
138846
+ return { code: rec.code, name: rec.name };
138847
+ }
138848
+ return null;
138849
+ }).filter((rec) => rec !== null);
138850
+ if (validatedRecords.length !== records.length) {
138851
+ toast2({
138852
+ title: "Import Warning",
138853
+ description: "Some records had invalid or missing 'code' or 'name' fields and were ignored.",
138854
+ variant: "destructive"
138855
+ });
138856
+ }
138857
+ if (validatedRecords.length > 0) {
138858
+ await onBulkAdd(validatedRecords);
138859
+ }
138860
+ };
138861
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(
138862
+ MetadataImportControls,
138863
+ {
138864
+ metadataName: "Subjects",
138865
+ onImport: handleImport
138866
+ }
138867
+ ), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, subject.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e3) => setSubjectName(e3.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
138807
138868
  }
138808
138869
 
138809
138870
  // src/react-ui/components/metadata/GradeLevelManager.tsx
138810
138871
  init_react_shim();
138811
- function GradeLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
138872
+ function GradeLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
138812
138873
  const [items, setItems] = useState([]);
138813
138874
  const [isLoading, setIsLoading] = useState(true);
138814
138875
  const [isDialogOpen, setIsDialogOpen] = useState(false);
@@ -138905,7 +138966,26 @@ function GradeLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpd
138905
138966
  }
138906
138967
  });
138907
138968
  };
138908
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Award, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Grade Levels"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Grade Level"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No grade levels found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Grade Level" : "Add New Grade Level")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., G9", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Grade 9" }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
138969
+ const handleImport = async (records) => {
138970
+ if (!onBulkAdd) return;
138971
+ const validatedRecords = records.map((rec) => {
138972
+ if (typeof rec.code === "string" && typeof rec.name === "string") {
138973
+ return { code: rec.code, name: rec.name };
138974
+ }
138975
+ return null;
138976
+ }).filter((rec) => rec !== null);
138977
+ if (validatedRecords.length !== records.length) {
138978
+ toast2({
138979
+ title: "Import Warning",
138980
+ description: "Some records had invalid or missing 'code' or 'name' fields and were ignored.",
138981
+ variant: "destructive"
138982
+ });
138983
+ }
138984
+ if (validatedRecords.length > 0) {
138985
+ await onBulkAdd(validatedRecords);
138986
+ }
138987
+ };
138988
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Award, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Grade Levels"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Grade Levels", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Grade Level")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No grade levels found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Grade Level" : "Add New Grade Level")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., G9", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Grade 9" }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
138909
138989
  }
138910
138990
 
138911
138991
  // src/react-ui/components/metadata/TopicManager.tsx
@@ -138916,7 +138996,8 @@ function TopicManager({
138916
138996
  isLoading: isLoadingProp,
138917
138997
  onAdd,
138918
138998
  onUpdate,
138919
- onDelete
138999
+ onDelete,
139000
+ onBulkAdd
138920
139001
  }) {
138921
139002
  const [topics, setTopics] = useState([]);
138922
139003
  const [subjects, setSubjects] = useState([]);
@@ -139020,15 +139101,34 @@ function TopicManager({
139020
139101
  }
139021
139102
  });
139022
139103
  };
139104
+ const handleImport = async (records) => {
139105
+ if (!onBulkAdd) return;
139106
+ const validatedRecords = records.map((rec) => {
139107
+ if (typeof rec.code === "string" && typeof rec.name === "string" && typeof rec.subjectCode === "string") {
139108
+ return { code: rec.code, name: rec.name, subjectCode: rec.subjectCode };
139109
+ }
139110
+ return null;
139111
+ }).filter((rec) => rec !== null);
139112
+ if (validatedRecords.length !== records.length) {
139113
+ toast2({
139114
+ title: "Import Warning",
139115
+ description: "Some records had invalid or missing 'code', 'name', or 'subjectCode' fields and were ignored.",
139116
+ variant: "destructive"
139117
+ });
139118
+ }
139119
+ if (validatedRecords.length > 0) {
139120
+ await onBulkAdd(validatedRecords);
139121
+ }
139122
+ };
139023
139123
  const getSubjectName = (subjectCode) => {
139024
139124
  return subjects.find((s4) => s4.code === subjectCode)?.name || "N/A";
139025
139125
  };
139026
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Tag, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Topics"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm", disabled: subjects.length === 0 }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic")), subjects.length === 0 && !isLoading && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-destructive" }, "Please add subjects before adding topics.")), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : topics.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No topics found. Add one to get started!") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, topics.map((topic) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: topic.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, topic.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, topic.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, getSubjectName(topic.subjectCode), " (", topic.subjectCode, ")"), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(topic), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(topic), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Topic" : "Add New Topic")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Topic Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., ALG-BASICS", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Topic Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Algebra Basics" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__default.createElement(Select2, { value: selectedSubjectCode, onValueChange: setSelectedSubjectCode, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: subject.code, value: subject.code }, subject.name, " (", subject.code, ")")))))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() || !selectedSubjectCode }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete topic "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139126
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Tag, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Topics"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Topics", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm", disabled: subjects.length === 0 }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Topic"))), subjects.length === 0 && !isLoading && /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-destructive" }, "Please add subjects before adding topics.")), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : topics.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No topics found. Add one to get started!") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, topics.map((topic) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: topic.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, topic.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, topic.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, getSubjectName(topic.subjectCode), " (", topic.subjectCode, ")"), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(topic), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(topic), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Topic" : "Add New Topic")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Topic Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., ALG-BASICS", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Topic Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Algebra Basics" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject"), /* @__PURE__ */ React169__default.createElement(Select2, { value: selectedSubjectCode, onValueChange: setSelectedSubjectCode, disabled: subjects.length === 0 }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "subjectCode" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: subject.code, value: subject.code }, subject.name, " (", subject.code, ")")))))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() || !selectedSubjectCode }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete topic "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139027
139127
  }
139028
139128
 
139029
139129
  // src/react-ui/components/metadata/CategoryManager.tsx
139030
139130
  init_react_shim();
139031
- function CategoryManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139131
+ function CategoryManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139032
139132
  const [items, setItems] = useState([]);
139033
139133
  const [isLoading, setIsLoading] = useState(true);
139034
139134
  const [isDialogOpen, setIsDialogOpen] = useState(false);
@@ -139128,12 +139228,37 @@ function CategoryManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdat
139128
139228
  }
139129
139229
  });
139130
139230
  };
139131
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Layers, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Categories"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Category"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No categories found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Category" : "Add New Category")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., CORE_CONCEPT", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Core Concept" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Fundamental ideas within a subject." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139231
+ const handleImport = async (records) => {
139232
+ if (!onBulkAdd) return;
139233
+ const validationResult = records.reduce((acc, rec) => {
139234
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139235
+ acc.valid.push({
139236
+ code: rec.code,
139237
+ name: rec.name,
139238
+ description: typeof rec.description === "string" ? rec.description : void 0
139239
+ });
139240
+ } else {
139241
+ acc.invalidCount++;
139242
+ }
139243
+ return acc;
139244
+ }, { valid: [], invalidCount: 0 });
139245
+ if (validationResult.invalidCount > 0) {
139246
+ toast2({
139247
+ title: "Import Warning",
139248
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139249
+ variant: "destructive"
139250
+ });
139251
+ }
139252
+ if (validationResult.valid.length > 0) {
139253
+ await onBulkAdd(validationResult.valid);
139254
+ }
139255
+ };
139256
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Layers, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Categories"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Categories", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Category")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No categories found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Category" : "Add New Category")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., CORE_CONCEPT", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Core Concept" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Fundamental ideas within a subject." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139132
139257
  }
139133
139258
 
139134
139259
  // src/react-ui/components/metadata/BloomLevelManager.tsx
139135
139260
  init_react_shim();
139136
- function BloomLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139261
+ function BloomLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139137
139262
  const [items, setItems] = useState([]);
139138
139263
  const [isLoading, setIsLoading] = useState(true);
139139
139264
  const [isDialogOpen, setIsDialogOpen] = useState(false);
@@ -139233,12 +139358,37 @@ function BloomLevelManager({ initialData, isLoading: isLoadingProp, onAdd, onUpd
139233
139358
  }
139234
139359
  });
139235
139360
  };
139236
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Brain, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Bloom's Levels"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Bloom's Level"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Bloom's Levels found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Bloom's Level" : "Add New Bloom's Level")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., REMEMBER", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Remembering" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Recall facts and basic concepts." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139361
+ const handleImport = async (records) => {
139362
+ if (!onBulkAdd) return;
139363
+ const validationResult = records.reduce((acc, rec) => {
139364
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139365
+ acc.valid.push({
139366
+ code: rec.code,
139367
+ name: rec.name,
139368
+ description: typeof rec.description === "string" ? rec.description : void 0
139369
+ });
139370
+ } else {
139371
+ acc.invalidCount++;
139372
+ }
139373
+ return acc;
139374
+ }, { valid: [], invalidCount: 0 });
139375
+ if (validationResult.invalidCount > 0) {
139376
+ toast2({
139377
+ title: "Import Warning",
139378
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139379
+ variant: "destructive"
139380
+ });
139381
+ }
139382
+ if (validationResult.valid.length > 0) {
139383
+ await onBulkAdd(validationResult.valid);
139384
+ }
139385
+ };
139386
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Brain, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Bloom's Levels"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Bloom's Levels", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Bloom's Level")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Bloom's Levels found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Bloom's Level" : "Add New Bloom's Level")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., REMEMBER", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Remembering" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Recall facts and basic concepts." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139237
139387
  }
139238
139388
 
139239
139389
  // src/react-ui/components/metadata/QuestionTypeManager.tsx
139240
139390
  init_react_shim();
139241
- function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139391
+ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139242
139392
  const [items, setItems] = useState([]);
139243
139393
  const [isLoading, setIsLoading] = useState(true);
139244
139394
  const [isDialogOpen, setIsDialogOpen] = useState(false);
@@ -139308,6 +139458,31 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
139308
139458
  }
139309
139459
  });
139310
139460
  };
139461
+ const handleImport = async (records) => {
139462
+ if (!onBulkAdd) return;
139463
+ const validationResult = records.reduce((acc, rec) => {
139464
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139465
+ acc.valid.push({
139466
+ code: rec.code,
139467
+ name: rec.name,
139468
+ description: typeof rec.description === "string" ? rec.description : void 0
139469
+ });
139470
+ } else {
139471
+ acc.invalidCount++;
139472
+ }
139473
+ return acc;
139474
+ }, { valid: [], invalidCount: 0 });
139475
+ if (validationResult.invalidCount > 0) {
139476
+ toast2({
139477
+ title: "Import Warning",
139478
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139479
+ variant: "destructive"
139480
+ });
139481
+ }
139482
+ if (validationResult.valid.length > 0) {
139483
+ await onBulkAdd(validationResult.valid);
139484
+ }
139485
+ };
139311
139486
  const handleSubmit = () => {
139312
139487
  if (!itemName.trim() || !itemCode.trim()) {
139313
139488
  toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
@@ -139338,22 +139513,19 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
139338
139513
  }
139339
139514
  });
139340
139515
  };
139341
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(CircleHelp, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Question Types"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Question Type"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Question Types found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Question Type" : "Add New Question Type")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Multiple Choice" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__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__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139516
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(CircleHelp, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Question Types"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Question Types", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Question Type")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Question Types found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Question Type" : "Add New Question Type")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Multiple Choice" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__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__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139342
139517
  }
139343
139518
 
139344
139519
  // src/react-ui/components/metadata/LearningObjectiveManager.tsx
139345
139520
  init_react_shim();
139346
- function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139521
+ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139347
139522
  const [items, setItems] = useState([]);
139348
139523
  const [subjects, setSubjects] = useState([]);
139349
139524
  const [isLoading, setIsLoading] = useState(true);
139350
139525
  const [isDialogOpen, setIsDialogOpen] = useState(false);
139351
139526
  const [isAlertOpen, setIsAlertOpen] = useState(false);
139352
139527
  const [currentItem, setCurrentItem] = useState(null);
139353
- const [itemName, setItemName] = useState("");
139354
- const [itemCode, setItemCode] = useState("");
139355
- const [itemDescription, setItemDescription] = useState("");
139356
- const [selectedSubjectCode, setSelectedSubjectCode] = useState(void 0);
139528
+ const [formState, setFormState] = useState({});
139357
139529
  const [itemToDelete, setItemToDelete] = useState(null);
139358
139530
  const [isPending, startTransition] = useTransition();
139359
139531
  const { toast: toast2 } = useToast();
@@ -139380,20 +139552,17 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139380
139552
  refreshData();
139381
139553
  }
139382
139554
  }, [isControlled, initialData, subjectsProp, isLoadingProp]);
139555
+ const handleFormChange = (field, value) => {
139556
+ setFormState((prev) => ({ ...prev, [field]: value }));
139557
+ };
139383
139558
  const handleAddItem = () => {
139384
139559
  setCurrentItem(null);
139385
- setItemName("");
139386
- setItemCode("");
139387
- setItemDescription("");
139388
- setSelectedSubjectCode(subjects.length > 0 ? subjects[0].code : void 0);
139560
+ setFormState({ subjectCode: subjects.length > 0 ? subjects[0].code : "" });
139389
139561
  setIsDialogOpen(true);
139390
139562
  };
139391
139563
  const handleEditItem = (item) => {
139392
139564
  setCurrentItem(item);
139393
- setItemName(item.name);
139394
- setItemCode(item.code);
139395
- setItemDescription(item.description || "");
139396
- setSelectedSubjectCode(item.subjectCode);
139565
+ setFormState(item);
139397
139566
  setIsDialogOpen(true);
139398
139567
  };
139399
139568
  const handleDeleteItem = (item) => {
@@ -139420,7 +139589,7 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139420
139589
  });
139421
139590
  };
139422
139591
  const handleSubmit = () => {
139423
- if (!itemName.trim() || !itemCode.trim()) {
139592
+ if (!formState.name?.trim() || !formState.code?.trim()) {
139424
139593
  toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
139425
139594
  return;
139426
139595
  }
@@ -139428,17 +139597,17 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139428
139597
  try {
139429
139598
  if (currentItem) {
139430
139599
  if (isControlled && onUpdate) {
139431
- await onUpdate({ id: currentItem.id, name: itemName, code: itemCode, subjectCode: selectedSubjectCode, description: itemDescription });
139600
+ await onUpdate({ ...currentItem, ...formState });
139432
139601
  } else {
139433
- MetadataService.updateLearningObjective(currentItem.id, itemName, itemCode, selectedSubjectCode, itemDescription);
139602
+ MetadataService.updateLearningObjective(currentItem.id, formState);
139434
139603
  refreshData();
139435
139604
  }
139436
139605
  toast2({ title: "Success", description: "Learning Objective updated." });
139437
139606
  } else {
139438
139607
  if (isControlled && onAdd) {
139439
- await onAdd({ name: itemName, code: itemCode, subjectCode: selectedSubjectCode, description: itemDescription });
139608
+ await onAdd(formState);
139440
139609
  } else {
139441
- MetadataService.addLearningObjective(itemName, itemCode, selectedSubjectCode, itemDescription);
139610
+ MetadataService.addLearningObjective(formState);
139442
139611
  refreshData();
139443
139612
  }
139444
139613
  toast2({ title: "Success", description: "Learning Objective added." });
@@ -139449,16 +139618,51 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
139449
139618
  }
139450
139619
  });
139451
139620
  };
139452
- const getSubjectName = (subjectCode) => {
139453
- if (!subjectCode) return "N/A";
139454
- return subjects.find((s4) => s4.code === subjectCode)?.name || "N/A";
139621
+ const handleImport = async (records) => {
139622
+ if (!onBulkAdd) return;
139623
+ const parseStringToArray = (input) => {
139624
+ if (Array.isArray(input)) return input;
139625
+ if (typeof input === "string") return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139626
+ return [];
139627
+ };
139628
+ const validatedRecords = records.reduce((acc, rec) => {
139629
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139630
+ acc.push({
139631
+ code: rec.code,
139632
+ name: rec.name,
139633
+ description: rec.description,
139634
+ subject: rec.subject,
139635
+ subjectCode: rec.subjectCode,
139636
+ category: rec.category,
139637
+ categoryCode: rec.categoryCode,
139638
+ topic: rec.topic,
139639
+ topicCode: rec.topicCode,
139640
+ grade: rec.grade,
139641
+ gradeCode: rec.gradeCode,
139642
+ keywords: parseStringToArray(rec.keywords),
139643
+ stemElements: parseStringToArray(rec.stemElements),
139644
+ bloomLevelsGuideline: parseStringToArray(rec.bloomLevelsGuideline)
139645
+ });
139646
+ }
139647
+ return acc;
139648
+ }, []);
139649
+ if (validatedRecords.length !== records.length) {
139650
+ toast2({
139651
+ title: "Import Warning",
139652
+ description: `${records.length - validatedRecords.length} records had invalid or missing required fields ('code', 'name') and were ignored.`,
139653
+ variant: "destructive"
139654
+ });
139655
+ }
139656
+ if (validatedRecords.length > 0) {
139657
+ await onBulkAdd(validatedRecords);
139658
+ }
139455
139659
  };
139456
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, getSubjectName(item.subjectCode)), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemSubject" }, "Subject (Optional)"), /* @__PURE__ */ React169__default.createElement(Select2, { value: selectedSubjectCode || "", onValueChange: (value) => setSelectedSubjectCode(value === "_NONE_" ? void 0 : value) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, { id: "itemSubject" }, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, /* @__PURE__ */ React169__default.createElement(SelectItem2, { value: "_NONE_" }, "No Specific Subject"), subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: subject.id, value: subject.code }, subject.name))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value) }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemName.trim() || !itemCode.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139660
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Learning Objectives", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => handleFormChange("code", e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => handleFormChange("name", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.subjectCode || "", onValueChange: (value) => handleFormChange("subjectCode", value) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, { placeholder: "Select a subject" })), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, subjects.map((subject) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: subject.id, value: subject.code }, subject.name))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "topicCode", value: formState.topicCode || "", onChange: (e3) => handleFormChange("topicCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "categoryCode", value: formState.categoryCode || "", onChange: (e3) => handleFormChange("categoryCode", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "gradeCode", value: formState.gradeCode || "", onChange: (e3) => handleFormChange("gradeCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "keywords", value: formState.keywords?.join(", ") || "", onChange: (e3) => handleFormChange("keywords", e3.target.value.split(",").map((s4) => s4.trim())) }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.name?.trim() || !formState.code?.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139457
139661
  }
139458
139662
 
139459
139663
  // src/react-ui/components/metadata/ContextManager.tsx
139460
139664
  init_react_shim();
139461
- function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }) {
139665
+ function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }) {
139462
139666
  const [items, setItems] = useState([]);
139463
139667
  const [isLoading, setIsLoading] = useState(true);
139464
139668
  const [isDialogOpen, setIsDialogOpen] = useState(false);
@@ -139528,6 +139732,31 @@ function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate
139528
139732
  }
139529
139733
  });
139530
139734
  };
139735
+ const handleImport = async (records) => {
139736
+ if (!onBulkAdd) return;
139737
+ const validationResult = records.reduce((acc, rec) => {
139738
+ if (typeof rec.code === "string" && rec.code.trim() && typeof rec.name === "string" && rec.name.trim()) {
139739
+ acc.valid.push({
139740
+ code: rec.code,
139741
+ name: rec.name,
139742
+ description: typeof rec.description === "string" ? rec.description : void 0
139743
+ });
139744
+ } else {
139745
+ acc.invalidCount++;
139746
+ }
139747
+ return acc;
139748
+ }, { valid: [], invalidCount: 0 });
139749
+ if (validationResult.invalidCount > 0) {
139750
+ toast2({
139751
+ title: "Import Warning",
139752
+ description: `${validationResult.invalidCount} records had invalid or missing 'code' or 'name' fields and were ignored.`,
139753
+ variant: "destructive"
139754
+ });
139755
+ }
139756
+ if (validationResult.valid.length > 0) {
139757
+ await onBulkAdd(validationResult.valid);
139758
+ }
139759
+ };
139531
139760
  const handleSubmit = () => {
139532
139761
  if (!itemName.trim() || !itemCode.trim()) {
139533
139762
  toast2({ title: "Validation Error", description: "Code and Name are required.", variant: "destructive" });
@@ -139558,13 +139787,13 @@ function ContextManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate
139558
139787
  }
139559
139788
  });
139560
139789
  };
139561
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(ScanText, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Contexts"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Context"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Contexts found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Context" : "Add New Context")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., HIST_INQ", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Historical Inquiry" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Analyzing primary and secondary sources." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139790
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(ScanText, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Contexts"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Categories", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Context")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Contexts found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Description"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.description), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Context" : "Add New Context")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemCode" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemCode", value: itemCode, onChange: (e3) => setItemCode(e3.target.value.toUpperCase()), placeholder: "e.g., HIST_INQ", disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemName" }, "Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "itemName", value: itemName, onChange: (e3) => setItemName(e3.target.value), placeholder: "e.g., Historical Inquiry" })), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "itemDescription" }, "Description (Optional)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "itemDescription", value: itemDescription, onChange: (e3) => setItemDescription(e3.target.value), placeholder: "e.g., Analyzing primary and secondary sources." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !itemCode.trim() || !itemName.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139562
139791
  }
139563
139792
 
139564
139793
  // src/react-ui/components/metadata/ApproachManager.tsx
139565
139794
  init_react_shim();
139566
139795
  var knowledgeDimensions = ["Factual", "Conceptual", "Procedural"];
139567
- var rawDifficultyLevels = ["E", "E~M", "M", "M~H", "H"];
139796
+ var standardDifficulties = ["Easy", "Medium", "Hard"];
139568
139797
  function ApproachManager({
139569
139798
  initialData,
139570
139799
  bloomLevels: bloomLevelsProp,
@@ -139572,7 +139801,8 @@ function ApproachManager({
139572
139801
  isLoading: isLoadingProp,
139573
139802
  onAdd,
139574
139803
  onUpdate,
139575
- onDelete
139804
+ onDelete,
139805
+ onBulkAdd
139576
139806
  }) {
139577
139807
  const [items, setItems] = useState([]);
139578
139808
  const [bloomLevels, setBloomLevels] = useState([]);
@@ -139613,7 +139843,7 @@ function ApproachManager({
139613
139843
  const resetForm = () => {
139614
139844
  setFormState({
139615
139845
  knowledgeDimension: "Factual",
139616
- rawDifficulty: "E",
139846
+ difficulty: ["Medium"],
139617
139847
  bloomLevelCode: bloomLevels.length > 0 ? bloomLevels[0].code : "",
139618
139848
  iSpringQuizType: questionTypes.length > 0 ? questionTypes[0].code : "multiple_choice"
139619
139849
  });
@@ -139625,18 +139855,7 @@ function ApproachManager({
139625
139855
  };
139626
139856
  const handleEditItem = (item) => {
139627
139857
  setCurrentItem(item);
139628
- setFormState({
139629
- code: item.code,
139630
- verbEn: item.verbEn,
139631
- verbVi: item.verbVi,
139632
- bloomLevelCode: item.bloomLevelCode,
139633
- knowledgeDimension: item.knowledgeDimension,
139634
- iSpringQuizType: item.iSpringQuizType,
139635
- rawDifficulty: item.rawDifficulty,
139636
- suggestContext: item.suggestContext,
139637
- exampleEn: item.exampleEn,
139638
- exampleVi: item.exampleVi
139639
- });
139858
+ setFormState(item);
139640
139859
  setIsDialogOpen(true);
139641
139860
  };
139642
139861
  const handleDeleteItem = (item) => {
@@ -139663,9 +139882,9 @@ function ApproachManager({
139663
139882
  });
139664
139883
  };
139665
139884
  const handleSubmit = () => {
139666
- const { code: code4, verbEn, verbVi, bloomLevelCode, iSpringQuizType, knowledgeDimension, rawDifficulty } = formState;
139667
- if (!code4?.trim() || !verbEn?.trim() || !verbVi?.trim() || !bloomLevelCode || !iSpringQuizType || !knowledgeDimension || !rawDifficulty) {
139668
- toast2({ title: "Validation Error", description: "All fields except examples and context are required.", variant: "destructive" });
139885
+ const { code: code4, name: name3, verbEn, verbVi, bloomLevelCode, iSpringQuizType, knowledgeDimension, difficulty } = formState;
139886
+ if (!code4?.trim() || !name3?.trim() || !verbEn?.trim() || !verbVi?.trim() || !bloomLevelCode || !iSpringQuizType || !knowledgeDimension || !difficulty || difficulty.length === 0) {
139887
+ toast2({ title: "Validation Error", description: "All fields except examples and context are required, and at least one difficulty must be selected.", variant: "destructive" });
139669
139888
  return;
139670
139889
  }
139671
139890
  startTransition(async () => {
@@ -139693,7 +139912,47 @@ function ApproachManager({
139693
139912
  }
139694
139913
  });
139695
139914
  };
139696
- return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Settings2, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Approaches"), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Approach"))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Approaches found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Approach ID"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Verb (VI)"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Cognitive Level"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "iSpring Type"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.verbVi), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.bloomLevelCode), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.iSpringQuizType), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Approach" : "Add New Approach")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Approach Code"), /* @__PURE__ */ React169__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__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "verbEn" }, "Verb (English)"), /* @__PURE__ */ React169__default.createElement(Input, { id: "verbEn", value: formState.verbEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, verbEn: e3.target.value })), placeholder: "e.g., Identify" }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "verbVi" }, "Verb (Vietnamese)"), /* @__PURE__ */ React169__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__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Cognitive Level"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.bloomLevelCode, onValueChange: (v) => setFormState((s4) => ({ ...s4, bloomLevelCode: v })) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, bloomLevels.map((level) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: level.code, value: level.code }, level.name)))))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "knowledgeDimension" }, "Knowledge Dimension"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.knowledgeDimension, onValueChange: (v) => setFormState((s4) => ({ ...s4, knowledgeDimension: v })) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, knowledgeDimensions.map((kd) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: kd, value: kd }, kd))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "iSpringQuizType" }, "iSpring Quiz Type"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.iSpringQuizType, onValueChange: (v) => setFormState((s4) => ({ ...s4, iSpringQuizType: v })) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, questionTypes.map((qt) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "rawDifficulty" }, "Raw Difficulty"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.rawDifficulty, onValueChange: (v) => setFormState((s4) => ({ ...s4, rawDifficulty: v })) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, rawDifficultyLevels.map((rd) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: rd, value: rd }, rd)))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "suggestContext" }, "Suggest Context (comma-separated codes)"), /* @__PURE__ */ React169__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__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "exampleEn" }, "Example (English)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "exampleEn", value: formState.exampleEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleEn: e3.target.value })), placeholder: "English example prompt..." })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "exampleVi" }, "Example (Vietnamese)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "exampleVi", value: formState.exampleVi || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleVi: e3.target.value })), placeholder: "Vietnamese example prompt..." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.code, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139915
+ const handleImport = async (records) => {
139916
+ if (!onBulkAdd) return;
139917
+ const parseStringToArray = (input) => {
139918
+ if (Array.isArray(input)) return input;
139919
+ if (typeof input === "string") return input.split(",").map((s4) => s4.trim()).filter(Boolean);
139920
+ return [];
139921
+ };
139922
+ const validatedRecords = records.reduce((acc, rec) => {
139923
+ if (rec.code && rec.name && rec.verbEn && rec.verbVi && rec.knowledgeDimension && rec.iSpringQuizType && rec.difficulty && rec.bloomLevelCode) {
139924
+ acc.push({
139925
+ code: rec.code,
139926
+ name: rec.name,
139927
+ verbEn: rec.verbEn,
139928
+ verbVi: rec.verbVi,
139929
+ knowledgeDimension: rec.knowledgeDimension,
139930
+ iSpringQuizType: rec.iSpringQuizType,
139931
+ difficulty: parseStringToArray(rec.difficulty),
139932
+ bloomLevelCode: rec.bloomLevelCode,
139933
+ suggestContext: rec.suggestContext,
139934
+ exampleEn: rec.exampleEn,
139935
+ exampleVi: rec.exampleVi
139936
+ });
139937
+ }
139938
+ return acc;
139939
+ }, []);
139940
+ if (validatedRecords.length !== records.length) {
139941
+ toast2({
139942
+ title: "Import Warning",
139943
+ description: `${records.length - validatedRecords.length} records had missing required fields and were ignored.`,
139944
+ variant: "destructive"
139945
+ });
139946
+ }
139947
+ if (validatedRecords.length > 0) {
139948
+ await onBulkAdd(validatedRecords);
139949
+ }
139950
+ };
139951
+ return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Settings2, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Approaches"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Approaches", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Approach")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Approaches found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Approach ID"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Verb (VI)"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Cognitive Level"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-Medium" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.verbVi), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.bloomLevelCode), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Approach" : "Add New Approach")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Approach Code"), /* @__PURE__ */ React169__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__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "name" }, "Name / Description"), /* @__PURE__ */ React169__default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => setFormState((s4) => ({ ...s4, name: e3.target.value })), placeholder: "e.g., Identify a Fact" }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "verbEn" }, "Verb (English)"), /* @__PURE__ */ React169__default.createElement(Input, { id: "verbEn", value: formState.verbEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, verbEn: e3.target.value })), placeholder: "e.g., Identify" })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "verbVi" }, "Verb (Vietnamese)"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelCode" }, "Cognitive Level"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.bloomLevelCode, onValueChange: (v) => setFormState((s4) => ({ ...s4, bloomLevelCode: v })) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, bloomLevels.map((level) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: level.code, value: level.code }, level.name))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "knowledgeDimension" }, "Knowledge Dimension"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.knowledgeDimension, onValueChange: (v) => setFormState((s4) => ({ ...s4, knowledgeDimension: v })) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, knowledgeDimensions.map((kd) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: kd, value: kd }, kd))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "iSpringQuizType" }, "iSpring Quiz Type"), /* @__PURE__ */ React169__default.createElement(Select2, { value: formState.iSpringQuizType, onValueChange: (v) => setFormState((s4) => ({ ...s4, iSpringQuizType: v })) }, /* @__PURE__ */ React169__default.createElement(SelectTrigger2, null, /* @__PURE__ */ React169__default.createElement(SelectValue2, null)), /* @__PURE__ */ React169__default.createElement(SelectContent2, null, questionTypes.map((qt) => /* @__PURE__ */ React169__default.createElement(SelectItem2, { key: qt.code, value: qt.code }, qt.name)))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, null, "Difficulty"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center space-x-4 pt-2" }, standardDifficulties.map((diff2) => /* @__PURE__ */ React169__default.createElement("div", { key: diff2, className: "flex items-center space-x-2" }, /* @__PURE__ */ React169__default.createElement(Checkbox2, { id: `diff-${diff2}`, checked: (formState.difficulty || []).includes(diff2), onCheckedChange: (checked) => {
139952
+ const current = formState.difficulty || [];
139953
+ const newDiff = checked ? [...current, diff2] : current.filter((d) => d !== diff2);
139954
+ setFormState((s4) => ({ ...s4, difficulty: newDiff }));
139955
+ } }), /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: `diff-${diff2}` }, diff2))))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "suggestContext" }, "Suggest Context (comma-separated codes)"), /* @__PURE__ */ React169__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__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "exampleEn" }, "Example (English)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "exampleEn", value: formState.exampleEn || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleEn: e3.target.value })), placeholder: "English example prompt..." })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "exampleVi" }, "Example (Vietnamese)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "exampleVi", value: formState.exampleVi || "", onChange: (e3) => setFormState((s4) => ({ ...s4, exampleVi: e3.target.value })), placeholder: "Vietnamese example prompt..." }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.code, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
139697
139956
  }
139698
139957
 
139699
139958
  // src/react-ui/components/metadata/MetadataTabs.tsx
@@ -140369,7 +140628,7 @@ var ToastAction2 = React169.forwardRef(({ className, ...props }, ref) => /* @__P
140369
140628
  {
140370
140629
  ref,
140371
140630
  className: cn(
140372
- "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",
140631
+ "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",
140373
140632
  className
140374
140633
  ),
140375
140634
  ...props
@@ -141964,4 +142223,4 @@ react-tooltip/dist/react-tooltip.min.mjs:
141964
142223
  *)
141965
142224
  */
141966
142225
 
141967
- export { AIFullQuizGeneratorModal, AIQuestionGeneratorModal, APIKeyManagerModal, Accordion2 as Accordion, AccordionContent2 as AccordionContent, AccordionItem2 as AccordionItem, AccordionTrigger2 as AccordionTrigger, Achievements, ActivityCalendar, Alert, AlertDescription, AlertTitle, ApiKeySettings, ApproachManager, Badge2 as Badge, BloomLevelManager, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryManager, Cheatsheet, Checkbox2 as Checkbox, ContextManager, Dialog2 as Dialog, DialogContent2 as DialogContent, DialogDescription2 as DialogDescription, DialogFooter, DialogHeader, DialogTitle2 as DialogTitle, EditQuestionModal, FreestyleQuizzesCard, GeneratedQuizzesCard, GradeLevelManager, ImportQuestionsModal, Input, Label2 as Label, LanguageProvider, LearningObjectiveManager, ManageTopics, MetadataTabs, PerformanceCharts, PersonalPracticeDashboard, PracticeHistoryTable, PracticeModeController, Progress2 as Progress, QuestionFilters, QuestionFormDialog, QuestionList, QuestionPreviewModal, QuestionRenderer, QuestionTypeManager, QuizAuthoringTool, QuizDataManagement, QuizPlayer, QuizResult, QuizReview, QuizSettingsForm, RadioGroup2 as RadioGroup, RadioGroupItem2 as RadioGroupItem, SCORMExportModal, ScrollArea2 as ScrollArea, Select2 as Select, SelectContent2 as SelectContent, SelectItem2 as SelectItem, SelectTrigger2 as SelectTrigger, SelectValue2 as SelectValue, SelectedQuestionsPanel, SettingsModal, Skeleton, SubjectManager, SuggestionDialog, Tabs2 as Tabs, TabsContent2 as TabsContent, TabsList2 as TabsList, TabsTrigger2 as TabsTrigger, Toaster, Tooltip2 as Tooltip, TooltipContent2 as TooltipContent, TooltipProvider2 as TooltipProvider, TooltipTrigger2 as TooltipTrigger, TopicManager, UploadResourceModal, toast, useToast };
142226
+ export { AIFullQuizGeneratorModal, AIQuestionGeneratorModal, APIKeyManagerModal, Accordion2 as Accordion, AccordionContent2 as AccordionContent, AccordionItem2 as AccordionItem, AccordionTrigger2 as AccordionTrigger, Achievements, ActivityCalendar, Alert, AlertDescription, AlertTitle, ApiKeySettings, ApproachManager, Badge2 as Badge, BloomLevelManager, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryManager, Cheatsheet, Checkbox2 as Checkbox, ContextManager, Dialog2 as Dialog, DialogContent2 as DialogContent, DialogDescription2 as DialogDescription, DialogFooter, DialogHeader, DialogTitle2 as DialogTitle, EditQuestionModal, FreestyleQuizzesCard, GeneratedQuizzesCard, GradeLevelManager, ImportQuestionsModal, Input, Label2 as Label, LanguageProvider, LearningObjectiveManager, ManageTopics, MetadataImportControls, MetadataTabs, PerformanceCharts, PersonalPracticeDashboard, PracticeHistoryTable, PracticeModeController, Progress2 as Progress, QuestionFilters, QuestionFormDialog, QuestionList, QuestionPreviewModal, QuestionRenderer, QuestionTypeManager, QuizAuthoringTool, QuizDataManagement, QuizPlayer, QuizResult, QuizReview, QuizSettingsForm, RadioGroup2 as RadioGroup, RadioGroupItem2 as RadioGroupItem, SCORMExportModal, ScrollArea2 as ScrollArea, Select2 as Select, SelectContent2 as SelectContent, SelectItem2 as SelectItem, SelectTrigger2 as SelectTrigger, SelectValue2 as SelectValue, SelectedQuestionsPanel, SettingsModal, Skeleton, SubjectManager, SuggestionDialog, Tabs2 as Tabs, TabsContent2 as TabsContent, TabsList2 as TabsList, TabsTrigger2 as TabsTrigger, Toaster, Tooltip2 as Tooltip, TooltipContent2 as TooltipContent, TooltipProvider2 as TooltipProvider, TooltipTrigger2 as TooltipTrigger, TopicManager, UploadResourceModal, toast, useToast };