@thanh01.pmt/interactive-quiz-kit 1.0.49 → 1.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring.cjs +47 -38
- package/dist/authoring.d.cts +1 -1
- package/dist/authoring.d.ts +1 -1
- package/dist/authoring.mjs +47 -38
- package/dist/react-ui.cjs +47 -38
- package/dist/react-ui.d.cts +1 -1
- package/dist/react-ui.d.ts +1 -1
- package/dist/react-ui.mjs +47 -38
- package/dist/{toaster-DfLqsPwa.d.cts → toaster-UW4hDEhn.d.cts} +26 -2
- package/dist/{toaster-Z0Qz6kch.d.ts → toaster-ehLC4yr7.d.ts} +26 -2
- package/package.json +1 -1
package/dist/authoring.cjs
CHANGED
|
@@ -105541,7 +105541,13 @@ init_react_shim();
|
|
|
105541
105541
|
|
|
105542
105542
|
// src/react-ui/components/metadata/SubjectManager.tsx
|
|
105543
105543
|
init_react_shim();
|
|
105544
|
-
function SubjectManager(
|
|
105544
|
+
function SubjectManager({
|
|
105545
|
+
initialData,
|
|
105546
|
+
isLoading: isLoadingProp,
|
|
105547
|
+
onAdd,
|
|
105548
|
+
onUpdate,
|
|
105549
|
+
onDelete
|
|
105550
|
+
}) {
|
|
105545
105551
|
const [subjects, setSubjects] = React97.useState([]);
|
|
105546
105552
|
const [isLoading, setIsLoading] = React97.useState(true);
|
|
105547
105553
|
const [isDialogOpen, setIsDialogOpen] = React97.useState(false);
|
|
@@ -105552,20 +105558,27 @@ function SubjectManager() {
|
|
|
105552
105558
|
const [itemToDelete, setItemToDelete] = React97.useState(null);
|
|
105553
105559
|
const [isPending, startTransition] = React97.useTransition();
|
|
105554
105560
|
const { toast: toast2 } = useToast();
|
|
105555
|
-
|
|
105556
|
-
setIsLoading(true);
|
|
105557
|
-
try {
|
|
105558
|
-
const data = MetadataService.getSubjects();
|
|
105559
|
-
setSubjects(data);
|
|
105560
|
-
} catch (error) {
|
|
105561
|
-
toast2({ title: "Error", description: "Failed to fetch subjects from local storage.", variant: "destructive" });
|
|
105562
|
-
} finally {
|
|
105563
|
-
setIsLoading(false);
|
|
105564
|
-
}
|
|
105565
|
-
}, []);
|
|
105561
|
+
const isControlled = initialData !== void 0;
|
|
105566
105562
|
const refreshData = () => {
|
|
105567
|
-
|
|
105563
|
+
if (!isControlled) {
|
|
105564
|
+
setIsLoading(true);
|
|
105565
|
+
try {
|
|
105566
|
+
setSubjects(MetadataService.getSubjects());
|
|
105567
|
+
} catch (error) {
|
|
105568
|
+
toast2({ title: "Error", description: "Failed to refresh subjects.", variant: "destructive" });
|
|
105569
|
+
} finally {
|
|
105570
|
+
setIsLoading(false);
|
|
105571
|
+
}
|
|
105572
|
+
}
|
|
105568
105573
|
};
|
|
105574
|
+
React97.useEffect(() => {
|
|
105575
|
+
if (isControlled) {
|
|
105576
|
+
setSubjects(initialData || []);
|
|
105577
|
+
setIsLoading(isLoadingProp || false);
|
|
105578
|
+
} else {
|
|
105579
|
+
refreshData();
|
|
105580
|
+
}
|
|
105581
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
105569
105582
|
const handleAddItem = () => {
|
|
105570
105583
|
setCurrentSubject(null);
|
|
105571
105584
|
setSubjectName("");
|
|
@@ -105584,11 +105597,15 @@ function SubjectManager() {
|
|
|
105584
105597
|
};
|
|
105585
105598
|
const confirmDelete = () => {
|
|
105586
105599
|
if (!itemToDelete) return;
|
|
105587
|
-
startTransition(() => {
|
|
105600
|
+
startTransition(async () => {
|
|
105588
105601
|
try {
|
|
105589
|
-
|
|
105602
|
+
if (isControlled && onDelete) {
|
|
105603
|
+
await onDelete(itemToDelete);
|
|
105604
|
+
} else {
|
|
105605
|
+
MetadataService.deleteSubject(itemToDelete.code);
|
|
105606
|
+
refreshData();
|
|
105607
|
+
}
|
|
105590
105608
|
toast2({ title: "Success", description: `Subject "${itemToDelete.name}" deleted.` });
|
|
105591
|
-
refreshData();
|
|
105592
105609
|
} catch (error) {
|
|
105593
105610
|
toast2({ title: "Error", description: error.message || "Failed to delete subject.", variant: "destructive" });
|
|
105594
105611
|
} finally {
|
|
@@ -105602,40 +105619,32 @@ function SubjectManager() {
|
|
|
105602
105619
|
toast2({ title: "Validation Error", description: "Please enter Subject Name and Subject Code.", variant: "destructive" });
|
|
105603
105620
|
return;
|
|
105604
105621
|
}
|
|
105605
|
-
startTransition(() => {
|
|
105622
|
+
startTransition(async () => {
|
|
105606
105623
|
try {
|
|
105607
105624
|
if (currentSubject) {
|
|
105608
|
-
|
|
105625
|
+
if (isControlled && onUpdate) {
|
|
105626
|
+
await onUpdate({ id: currentSubject.id, name: subjectName, code: subjectCode });
|
|
105627
|
+
} else {
|
|
105628
|
+
MetadataService.updateSubject(currentSubject.id, subjectName, subjectCode);
|
|
105629
|
+
refreshData();
|
|
105630
|
+
}
|
|
105609
105631
|
toast2({ title: "Success", description: "Subject updated." });
|
|
105610
105632
|
} else {
|
|
105611
|
-
|
|
105633
|
+
if (isControlled && onAdd) {
|
|
105634
|
+
await onAdd({ name: subjectName, code: subjectCode });
|
|
105635
|
+
} else {
|
|
105636
|
+
MetadataService.addSubject(subjectName, subjectCode);
|
|
105637
|
+
refreshData();
|
|
105638
|
+
}
|
|
105612
105639
|
toast2({ title: "Success", description: "Subject added." });
|
|
105613
105640
|
}
|
|
105614
|
-
refreshData();
|
|
105615
105641
|
setIsDialogOpen(false);
|
|
105616
105642
|
} catch (error) {
|
|
105617
105643
|
toast2({ title: "Error", description: error.message || "Failed to save subject.", variant: "destructive" });
|
|
105618
105644
|
}
|
|
105619
105645
|
});
|
|
105620
105646
|
};
|
|
105621
|
-
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React97__namespace.default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105622
|
-
Input,
|
|
105623
|
-
{
|
|
105624
|
-
id: "subjectCode",
|
|
105625
|
-
value: subjectCode,
|
|
105626
|
-
onChange: (e2) => setSubjectCode(e2.target.value.toUpperCase()),
|
|
105627
|
-
placeholder: "e.g., MATH",
|
|
105628
|
-
disabled: !!currentSubject
|
|
105629
|
-
}
|
|
105630
|
-
)), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React97__namespace.default.createElement(
|
|
105631
|
-
Input,
|
|
105632
|
-
{
|
|
105633
|
-
id: "subjectName",
|
|
105634
|
-
value: subjectName,
|
|
105635
|
-
onChange: (e2) => setSubjectName(e2.target.value),
|
|
105636
|
-
placeholder: "e.g., Mathematics"
|
|
105637
|
-
}
|
|
105638
|
-
))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '" (Code: ', itemToDelete?.code, "). Ensure no topics, questions, or learning objectives reference this subject.")), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
105647
|
+
return /* @__PURE__ */ React97__namespace.default.createElement(Card, null, /* @__PURE__ */ React97__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React97__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React97__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__namespace.default.createElement(Table2, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React97__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__namespace.default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React97__namespace.default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React97__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React97__namespace.default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e2) => setSubjectCode(e2.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React97__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__namespace.default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React97__namespace.default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e2) => setSubjectName(e2.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React97__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
105639
105648
|
}
|
|
105640
105649
|
|
|
105641
105650
|
// src/react-ui/components/metadata/GradeLevelManager.tsx
|
package/dist/authoring.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ export { B as BaseQuestion, e as BlocklyProgrammingQuestion, C as CodingQuestion
|
|
|
2
2
|
export { APIKeyService, AchievementService, Approach, ApproachTableRawDifficulty, BloomLevelName, BloomLevelType, Category, CodeNamedEntity, Context, GEMINI_API_KEY_SERVICE_NAME, GradeLevel, KnowledgeCardService, KnowledgeDimension, LearningObjective, LearningObjectiveMetadata, MetadataService, PracticeHistoryService, QuestionBankService, QuestionImportService, QuestionInBank, QuestionTypeType, QuizEditorService, QuizEngine, QuizEngineCallbacks, QuizEngineConstructorOptions, QuoteService, SCORMService, StandardDifficulty, Subject, Topic, UserConfigService, cn, emptyQuiz, exportQuizAsSCORMZip, generateLauncherHTML, generateSCORMManifest, generateUniqueId, sampleQuiz } from './index.cjs';
|
|
3
3
|
export { i as Achievement, j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, n as PracticeSession, p as PracticeSessionSummary, o as PracticeStats, m as PracticeSuggestion, l as PracticeSuggestionTopic, q as PracticeTopicSummary, g as QuestionReview, Q as QuizResultType, h as QuizReviewContent, R as RoadmapItem, T as TestCaseResult, U as UserAnswerType, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-DqFRlFU3.cjs';
|
|
4
4
|
export { AssessAndMapDocumentClientInput, AssessAndMapDocumentOutput, BloomLevelStringsForAI, GenerateCodingQuestionClientInput, GenerateCodingQuestionOutput, GenerateFillInTheBlanksQuestionClientInput, GenerateFillInTheBlanksQuestionOutput, GenerateLearningAnalysisClientInput, GenerateLearningAnalysisOutput, GenerateMCQQuestionClientInput, GenerateMCQQuestionOutput, GenerateMRQQuestionClientInput, GenerateMRQQuestionOutput, GenerateMatchingQuestionClientInput, GenerateMatchingQuestionOutput, GenerateMotivationalQuoteClientInput, GenerateMotivationalQuoteOutput, GenerateNumericQuestionClientInput, GenerateNumericQuestionOutput, GeneratePracticeSuggestionClientInput, GeneratePracticeSuggestionOutput, GenerateQuestionsFromQuizPlanClientInput, GenerateQuestionsFromQuizPlanOutput, GenerateQuizFromTextClientInput, GenerateQuizFromTextOutput, GenerateQuizPlanClientInput, GenerateQuizPlanOutput, GenerateQuizReviewClientInput, GenerateQuizReviewOutput, GenerateSequenceQuestionClientInput, GenerateSequenceQuestionOutput, GenerateShortAnswerQuestionClientInput, GenerateShortAnswerQuestionOutput, GenerateSingleKnowledgeCardClientInput, GenerateSingleKnowledgeCardOutput, GenerateTrueFalseQuestionClientInput, GenerateTrueFalseQuestionOutput, PlanKnowledgeCardsClientInput, PlanKnowledgeCardsOutput, PlannedQuestion, assessAndMapDocument, generateCodingQuestion, generateFillInTheBlanksQuestion, generateLearningAnalysis, generateMCQQuestion, generateMRQQuestion, generateMatchingQuestion, generateMotivationalQuote, generateNumericQuestion, generatePracticeSuggestion, generateQuestionsFromQuizPlan, generateQuizFromText, generateQuizPlan, generateQuizReview, generateSequenceQuestion, generateShortAnswerQuestion, generateSingleKnowledgeCard, generateTrueFalseQuestion, planKnowledgeCards } from './ai.cjs';
|
|
5
|
-
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
5
|
+
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-UW4hDEhn.cjs';
|
|
6
6
|
import 'clsx';
|
|
7
7
|
import 'zod';
|
|
8
8
|
import 'react';
|
package/dist/authoring.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { B as BaseQuestion, e as BlocklyProgrammingQuestion, C as CodingQuestion
|
|
|
2
2
|
export { APIKeyService, AchievementService, Approach, ApproachTableRawDifficulty, BloomLevelName, BloomLevelType, Category, CodeNamedEntity, Context, GEMINI_API_KEY_SERVICE_NAME, GradeLevel, KnowledgeCardService, KnowledgeDimension, LearningObjective, LearningObjectiveMetadata, MetadataService, PracticeHistoryService, QuestionBankService, QuestionImportService, QuestionInBank, QuestionTypeType, QuizEditorService, QuizEngine, QuizEngineCallbacks, QuizEngineConstructorOptions, QuoteService, SCORMService, StandardDifficulty, Subject, Topic, UserConfigService, cn, emptyQuiz, exportQuizAsSCORMZip, generateLauncherHTML, generateSCORMManifest, generateUniqueId, sampleQuiz } from './index.js';
|
|
3
3
|
export { i as Achievement, j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, n as PracticeSession, p as PracticeSessionSummary, o as PracticeStats, m as PracticeSuggestion, l as PracticeSuggestionTopic, q as PracticeTopicSummary, g as QuestionReview, Q as QuizResultType, h as QuizReviewContent, R as RoadmapItem, T as TestCaseResult, U as UserAnswerType, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-DqVlSO3r.js';
|
|
4
4
|
export { AssessAndMapDocumentClientInput, AssessAndMapDocumentOutput, BloomLevelStringsForAI, GenerateCodingQuestionClientInput, GenerateCodingQuestionOutput, GenerateFillInTheBlanksQuestionClientInput, GenerateFillInTheBlanksQuestionOutput, GenerateLearningAnalysisClientInput, GenerateLearningAnalysisOutput, GenerateMCQQuestionClientInput, GenerateMCQQuestionOutput, GenerateMRQQuestionClientInput, GenerateMRQQuestionOutput, GenerateMatchingQuestionClientInput, GenerateMatchingQuestionOutput, GenerateMotivationalQuoteClientInput, GenerateMotivationalQuoteOutput, GenerateNumericQuestionClientInput, GenerateNumericQuestionOutput, GeneratePracticeSuggestionClientInput, GeneratePracticeSuggestionOutput, GenerateQuestionsFromQuizPlanClientInput, GenerateQuestionsFromQuizPlanOutput, GenerateQuizFromTextClientInput, GenerateQuizFromTextOutput, GenerateQuizPlanClientInput, GenerateQuizPlanOutput, GenerateQuizReviewClientInput, GenerateQuizReviewOutput, GenerateSequenceQuestionClientInput, GenerateSequenceQuestionOutput, GenerateShortAnswerQuestionClientInput, GenerateShortAnswerQuestionOutput, GenerateSingleKnowledgeCardClientInput, GenerateSingleKnowledgeCardOutput, GenerateTrueFalseQuestionClientInput, GenerateTrueFalseQuestionOutput, PlanKnowledgeCardsClientInput, PlanKnowledgeCardsOutput, PlannedQuestion, assessAndMapDocument, generateCodingQuestion, generateFillInTheBlanksQuestion, generateLearningAnalysis, generateMCQQuestion, generateMRQQuestion, generateMatchingQuestion, generateMotivationalQuote, generateNumericQuestion, generatePracticeSuggestion, generateQuestionsFromQuizPlan, generateQuizFromText, generateQuizPlan, generateQuizReview, generateSequenceQuestion, generateShortAnswerQuestion, generateSingleKnowledgeCard, generateTrueFalseQuestion, planKnowledgeCards } from './ai.js';
|
|
5
|
-
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
5
|
+
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-ehLC4yr7.js';
|
|
6
6
|
import 'clsx';
|
|
7
7
|
import 'zod';
|
|
8
8
|
import 'react';
|
package/dist/authoring.mjs
CHANGED
|
@@ -105515,7 +105515,13 @@ init_react_shim();
|
|
|
105515
105515
|
|
|
105516
105516
|
// src/react-ui/components/metadata/SubjectManager.tsx
|
|
105517
105517
|
init_react_shim();
|
|
105518
|
-
function SubjectManager(
|
|
105518
|
+
function SubjectManager({
|
|
105519
|
+
initialData,
|
|
105520
|
+
isLoading: isLoadingProp,
|
|
105521
|
+
onAdd,
|
|
105522
|
+
onUpdate,
|
|
105523
|
+
onDelete
|
|
105524
|
+
}) {
|
|
105519
105525
|
const [subjects, setSubjects] = useState([]);
|
|
105520
105526
|
const [isLoading, setIsLoading] = useState(true);
|
|
105521
105527
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
@@ -105526,20 +105532,27 @@ function SubjectManager() {
|
|
|
105526
105532
|
const [itemToDelete, setItemToDelete] = useState(null);
|
|
105527
105533
|
const [isPending, startTransition] = useTransition();
|
|
105528
105534
|
const { toast: toast2 } = useToast();
|
|
105529
|
-
|
|
105530
|
-
setIsLoading(true);
|
|
105531
|
-
try {
|
|
105532
|
-
const data = MetadataService.getSubjects();
|
|
105533
|
-
setSubjects(data);
|
|
105534
|
-
} catch (error) {
|
|
105535
|
-
toast2({ title: "Error", description: "Failed to fetch subjects from local storage.", variant: "destructive" });
|
|
105536
|
-
} finally {
|
|
105537
|
-
setIsLoading(false);
|
|
105538
|
-
}
|
|
105539
|
-
}, []);
|
|
105535
|
+
const isControlled = initialData !== void 0;
|
|
105540
105536
|
const refreshData = () => {
|
|
105541
|
-
|
|
105537
|
+
if (!isControlled) {
|
|
105538
|
+
setIsLoading(true);
|
|
105539
|
+
try {
|
|
105540
|
+
setSubjects(MetadataService.getSubjects());
|
|
105541
|
+
} catch (error) {
|
|
105542
|
+
toast2({ title: "Error", description: "Failed to refresh subjects.", variant: "destructive" });
|
|
105543
|
+
} finally {
|
|
105544
|
+
setIsLoading(false);
|
|
105545
|
+
}
|
|
105546
|
+
}
|
|
105542
105547
|
};
|
|
105548
|
+
useEffect(() => {
|
|
105549
|
+
if (isControlled) {
|
|
105550
|
+
setSubjects(initialData || []);
|
|
105551
|
+
setIsLoading(isLoadingProp || false);
|
|
105552
|
+
} else {
|
|
105553
|
+
refreshData();
|
|
105554
|
+
}
|
|
105555
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
105543
105556
|
const handleAddItem = () => {
|
|
105544
105557
|
setCurrentSubject(null);
|
|
105545
105558
|
setSubjectName("");
|
|
@@ -105558,11 +105571,15 @@ function SubjectManager() {
|
|
|
105558
105571
|
};
|
|
105559
105572
|
const confirmDelete = () => {
|
|
105560
105573
|
if (!itemToDelete) return;
|
|
105561
|
-
startTransition(() => {
|
|
105574
|
+
startTransition(async () => {
|
|
105562
105575
|
try {
|
|
105563
|
-
|
|
105576
|
+
if (isControlled && onDelete) {
|
|
105577
|
+
await onDelete(itemToDelete);
|
|
105578
|
+
} else {
|
|
105579
|
+
MetadataService.deleteSubject(itemToDelete.code);
|
|
105580
|
+
refreshData();
|
|
105581
|
+
}
|
|
105564
105582
|
toast2({ title: "Success", description: `Subject "${itemToDelete.name}" deleted.` });
|
|
105565
|
-
refreshData();
|
|
105566
105583
|
} catch (error) {
|
|
105567
105584
|
toast2({ title: "Error", description: error.message || "Failed to delete subject.", variant: "destructive" });
|
|
105568
105585
|
} finally {
|
|
@@ -105576,40 +105593,32 @@ function SubjectManager() {
|
|
|
105576
105593
|
toast2({ title: "Validation Error", description: "Please enter Subject Name and Subject Code.", variant: "destructive" });
|
|
105577
105594
|
return;
|
|
105578
105595
|
}
|
|
105579
|
-
startTransition(() => {
|
|
105596
|
+
startTransition(async () => {
|
|
105580
105597
|
try {
|
|
105581
105598
|
if (currentSubject) {
|
|
105582
|
-
|
|
105599
|
+
if (isControlled && onUpdate) {
|
|
105600
|
+
await onUpdate({ id: currentSubject.id, name: subjectName, code: subjectCode });
|
|
105601
|
+
} else {
|
|
105602
|
+
MetadataService.updateSubject(currentSubject.id, subjectName, subjectCode);
|
|
105603
|
+
refreshData();
|
|
105604
|
+
}
|
|
105583
105605
|
toast2({ title: "Success", description: "Subject updated." });
|
|
105584
105606
|
} else {
|
|
105585
|
-
|
|
105607
|
+
if (isControlled && onAdd) {
|
|
105608
|
+
await onAdd({ name: subjectName, code: subjectCode });
|
|
105609
|
+
} else {
|
|
105610
|
+
MetadataService.addSubject(subjectName, subjectCode);
|
|
105611
|
+
refreshData();
|
|
105612
|
+
}
|
|
105586
105613
|
toast2({ title: "Success", description: "Subject added." });
|
|
105587
105614
|
}
|
|
105588
|
-
refreshData();
|
|
105589
105615
|
setIsDialogOpen(false);
|
|
105590
105616
|
} catch (error) {
|
|
105591
105617
|
toast2({ title: "Error", description: error.message || "Failed to save subject.", variant: "destructive" });
|
|
105592
105618
|
}
|
|
105593
105619
|
});
|
|
105594
105620
|
};
|
|
105595
|
-
return /* @__PURE__ */ React97__default.createElement(Card, null, /* @__PURE__ */ React97__default.createElement(CardHeader, null, /* @__PURE__ */ React97__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React97__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React97__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React97__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React97__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__default.createElement(Table2, null, /* @__PURE__ */ React97__default.createElement(TableHeader, null, /* @__PURE__ */ React97__default.createElement(TableRow, null, /* @__PURE__ */ React97__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React97__default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React97__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React97__default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React97__default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React97__default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React97__default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React97__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__default.createElement(DialogHeader, null, /* @__PURE__ */ React97__default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React97__default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React97__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React97__default.createElement(
|
|
105596
|
-
Input,
|
|
105597
|
-
{
|
|
105598
|
-
id: "subjectCode",
|
|
105599
|
-
value: subjectCode,
|
|
105600
|
-
onChange: (e2) => setSubjectCode(e2.target.value.toUpperCase()),
|
|
105601
|
-
placeholder: "e.g., MATH",
|
|
105602
|
-
disabled: !!currentSubject
|
|
105603
|
-
}
|
|
105604
|
-
)), /* @__PURE__ */ React97__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React97__default.createElement(
|
|
105605
|
-
Input,
|
|
105606
|
-
{
|
|
105607
|
-
id: "subjectName",
|
|
105608
|
-
value: subjectName,
|
|
105609
|
-
onChange: (e2) => setSubjectName(e2.target.value),
|
|
105610
|
-
placeholder: "e.g., Mathematics"
|
|
105611
|
-
}
|
|
105612
|
-
))), /* @__PURE__ */ React97__default.createElement(DialogFooter, null, /* @__PURE__ */ React97__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React97__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React97__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '" (Code: ', itemToDelete?.code, "). Ensure no topics, questions, or learning objectives reference this subject.")), /* @__PURE__ */ React97__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
105621
|
+
return /* @__PURE__ */ React97__default.createElement(Card, null, /* @__PURE__ */ React97__default.createElement(CardHeader, null, /* @__PURE__ */ React97__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React97__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React97__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React97__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React97__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React97__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React97__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React97__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React97__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React97__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React97__default.createElement(Table2, null, /* @__PURE__ */ React97__default.createElement(TableHeader, null, /* @__PURE__ */ React97__default.createElement(TableRow, null, /* @__PURE__ */ React97__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React97__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React97__default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React97__default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React97__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React97__default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React97__default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React97__default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React97__default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React97__default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React97__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React97__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React97__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React97__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React97__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React97__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React97__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React97__default.createElement(DialogHeader, null, /* @__PURE__ */ React97__default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React97__default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React97__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React97__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React97__default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e2) => setSubjectCode(e2.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React97__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React97__default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React97__default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e2) => setSubjectName(e2.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React97__default.createElement(DialogFooter, null, /* @__PURE__ */ React97__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React97__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React97__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React97__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React97__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React97__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React97__default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React97__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React97__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React97__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React97__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
105613
105622
|
}
|
|
105614
105623
|
|
|
105615
105624
|
// src/react-ui/components/metadata/GradeLevelManager.tsx
|
package/dist/react-ui.cjs
CHANGED
|
@@ -168139,7 +168139,13 @@ init_react_shim();
|
|
|
168139
168139
|
|
|
168140
168140
|
// src/react-ui/components/metadata/SubjectManager.tsx
|
|
168141
168141
|
init_react_shim();
|
|
168142
|
-
function SubjectManager(
|
|
168142
|
+
function SubjectManager({
|
|
168143
|
+
initialData,
|
|
168144
|
+
isLoading: isLoadingProp,
|
|
168145
|
+
onAdd,
|
|
168146
|
+
onUpdate,
|
|
168147
|
+
onDelete
|
|
168148
|
+
}) {
|
|
168143
168149
|
const [subjects, setSubjects] = React163.useState([]);
|
|
168144
168150
|
const [isLoading, setIsLoading] = React163.useState(true);
|
|
168145
168151
|
const [isDialogOpen, setIsDialogOpen] = React163.useState(false);
|
|
@@ -168150,20 +168156,27 @@ function SubjectManager() {
|
|
|
168150
168156
|
const [itemToDelete, setItemToDelete] = React163.useState(null);
|
|
168151
168157
|
const [isPending, startTransition] = React163.useTransition();
|
|
168152
168158
|
const { toast: toast2 } = useToast();
|
|
168153
|
-
|
|
168154
|
-
setIsLoading(true);
|
|
168155
|
-
try {
|
|
168156
|
-
const data = MetadataService.getSubjects();
|
|
168157
|
-
setSubjects(data);
|
|
168158
|
-
} catch (error) {
|
|
168159
|
-
toast2({ title: "Error", description: "Failed to fetch subjects from local storage.", variant: "destructive" });
|
|
168160
|
-
} finally {
|
|
168161
|
-
setIsLoading(false);
|
|
168162
|
-
}
|
|
168163
|
-
}, []);
|
|
168159
|
+
const isControlled = initialData !== void 0;
|
|
168164
168160
|
const refreshData = () => {
|
|
168165
|
-
|
|
168161
|
+
if (!isControlled) {
|
|
168162
|
+
setIsLoading(true);
|
|
168163
|
+
try {
|
|
168164
|
+
setSubjects(MetadataService.getSubjects());
|
|
168165
|
+
} catch (error) {
|
|
168166
|
+
toast2({ title: "Error", description: "Failed to refresh subjects.", variant: "destructive" });
|
|
168167
|
+
} finally {
|
|
168168
|
+
setIsLoading(false);
|
|
168169
|
+
}
|
|
168170
|
+
}
|
|
168166
168171
|
};
|
|
168172
|
+
React163.useEffect(() => {
|
|
168173
|
+
if (isControlled) {
|
|
168174
|
+
setSubjects(initialData || []);
|
|
168175
|
+
setIsLoading(isLoadingProp || false);
|
|
168176
|
+
} else {
|
|
168177
|
+
refreshData();
|
|
168178
|
+
}
|
|
168179
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
168167
168180
|
const handleAddItem = () => {
|
|
168168
168181
|
setCurrentSubject(null);
|
|
168169
168182
|
setSubjectName("");
|
|
@@ -168182,11 +168195,15 @@ function SubjectManager() {
|
|
|
168182
168195
|
};
|
|
168183
168196
|
const confirmDelete = () => {
|
|
168184
168197
|
if (!itemToDelete) return;
|
|
168185
|
-
startTransition(() => {
|
|
168198
|
+
startTransition(async () => {
|
|
168186
168199
|
try {
|
|
168187
|
-
|
|
168200
|
+
if (isControlled && onDelete) {
|
|
168201
|
+
await onDelete(itemToDelete);
|
|
168202
|
+
} else {
|
|
168203
|
+
MetadataService.deleteSubject(itemToDelete.code);
|
|
168204
|
+
refreshData();
|
|
168205
|
+
}
|
|
168188
168206
|
toast2({ title: "Success", description: `Subject "${itemToDelete.name}" deleted.` });
|
|
168189
|
-
refreshData();
|
|
168190
168207
|
} catch (error) {
|
|
168191
168208
|
toast2({ title: "Error", description: error.message || "Failed to delete subject.", variant: "destructive" });
|
|
168192
168209
|
} finally {
|
|
@@ -168200,40 +168217,32 @@ function SubjectManager() {
|
|
|
168200
168217
|
toast2({ title: "Validation Error", description: "Please enter Subject Name and Subject Code.", variant: "destructive" });
|
|
168201
168218
|
return;
|
|
168202
168219
|
}
|
|
168203
|
-
startTransition(() => {
|
|
168220
|
+
startTransition(async () => {
|
|
168204
168221
|
try {
|
|
168205
168222
|
if (currentSubject) {
|
|
168206
|
-
|
|
168223
|
+
if (isControlled && onUpdate) {
|
|
168224
|
+
await onUpdate({ id: currentSubject.id, name: subjectName, code: subjectCode });
|
|
168225
|
+
} else {
|
|
168226
|
+
MetadataService.updateSubject(currentSubject.id, subjectName, subjectCode);
|
|
168227
|
+
refreshData();
|
|
168228
|
+
}
|
|
168207
168229
|
toast2({ title: "Success", description: "Subject updated." });
|
|
168208
168230
|
} else {
|
|
168209
|
-
|
|
168231
|
+
if (isControlled && onAdd) {
|
|
168232
|
+
await onAdd({ name: subjectName, code: subjectCode });
|
|
168233
|
+
} else {
|
|
168234
|
+
MetadataService.addSubject(subjectName, subjectCode);
|
|
168235
|
+
refreshData();
|
|
168236
|
+
}
|
|
168210
168237
|
toast2({ title: "Success", description: "Subject added." });
|
|
168211
168238
|
}
|
|
168212
|
-
refreshData();
|
|
168213
168239
|
setIsDialogOpen(false);
|
|
168214
168240
|
} catch (error) {
|
|
168215
168241
|
toast2({ title: "Error", description: error.message || "Failed to save subject.", variant: "destructive" });
|
|
168216
168242
|
}
|
|
168217
168243
|
});
|
|
168218
168244
|
};
|
|
168219
|
-
return /* @__PURE__ */ React163__namespace.default.createElement(Card, null, /* @__PURE__ */ React163__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React163__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React163__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React163__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React163__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React163__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React163__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React163__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React163__namespace.default.createElement(Table3, null, /* @__PURE__ */ React163__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React163__namespace.default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React163__namespace.default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React163__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React163__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React163__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React163__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React163__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React163__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React163__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React163__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React163__namespace.default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React163__namespace.default.createElement(
|
|
168220
|
-
Input,
|
|
168221
|
-
{
|
|
168222
|
-
id: "subjectCode",
|
|
168223
|
-
value: subjectCode,
|
|
168224
|
-
onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()),
|
|
168225
|
-
placeholder: "e.g., MATH",
|
|
168226
|
-
disabled: !!currentSubject
|
|
168227
|
-
}
|
|
168228
|
-
)), /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__namespace.default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React163__namespace.default.createElement(
|
|
168229
|
-
Input,
|
|
168230
|
-
{
|
|
168231
|
-
id: "subjectName",
|
|
168232
|
-
value: subjectName,
|
|
168233
|
-
onChange: (e3) => setSubjectName(e3.target.value),
|
|
168234
|
-
placeholder: "e.g., Mathematics"
|
|
168235
|
-
}
|
|
168236
|
-
))), /* @__PURE__ */ React163__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React163__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React163__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '" (Code: ', itemToDelete?.code, "). Ensure no topics, questions, or learning objectives reference this subject.")), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React163__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
168245
|
+
return /* @__PURE__ */ React163__namespace.default.createElement(Card, null, /* @__PURE__ */ React163__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React163__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React163__namespace.default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React163__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React163__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React163__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React163__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React163__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React163__namespace.default.createElement(Table3, null, /* @__PURE__ */ React163__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React163__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React163__namespace.default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React163__namespace.default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React163__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React163__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React163__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React163__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React163__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React163__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React163__namespace.default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React163__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React163__namespace.default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React163__namespace.default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React163__namespace.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__namespace.default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React163__namespace.default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e3) => setSubjectName(e3.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React163__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React163__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React163__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React163__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
168237
168246
|
}
|
|
168238
168247
|
|
|
168239
168248
|
// src/react-ui/components/metadata/GradeLevelManager.tsx
|
package/dist/react-ui.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { Q as QuizResultType, U as UserAnswerType, n as PracticeSession, o as Pr
|
|
|
5
5
|
export { j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, q as PracticeTopicSummary, g as QuestionReview, R as RoadmapItem, T as TestCaseResult, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-DqFRlFU3.cjs';
|
|
6
6
|
import * as React$1 from 'react';
|
|
7
7
|
import React__default, { ReactNode } from 'react';
|
|
8
|
-
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
8
|
+
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-UW4hDEhn.cjs';
|
|
9
9
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
10
10
|
import { VariantProps } from 'class-variance-authority';
|
|
11
11
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
package/dist/react-ui.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Q as QuizResultType, U as UserAnswerType, n as PracticeSession, o as Pr
|
|
|
5
5
|
export { j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, q as PracticeTopicSummary, g as QuestionReview, R as RoadmapItem, T as TestCaseResult, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-DqVlSO3r.js';
|
|
6
6
|
import * as React$1 from 'react';
|
|
7
7
|
import React__default, { ReactNode } from 'react';
|
|
8
|
-
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
8
|
+
export { a as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, b as APIKeyManagerModal, c as ApiKeySettings, j as ApproachManager, B as BloomLevelManager, C as CategoryManager, i as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, M as MetadataTabs, e as QuestionFilters, f as QuestionFormDialog, d as QuestionList, h as QuestionTypeManager, Q as QuizAuthoringTool, S as SCORMExportModal, g as SubjectManager, k as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-ehLC4yr7.js';
|
|
9
9
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
10
10
|
import { VariantProps } from 'class-variance-authority';
|
|
11
11
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
package/dist/react-ui.mjs
CHANGED
|
@@ -168112,7 +168112,13 @@ init_react_shim();
|
|
|
168112
168112
|
|
|
168113
168113
|
// src/react-ui/components/metadata/SubjectManager.tsx
|
|
168114
168114
|
init_react_shim();
|
|
168115
|
-
function SubjectManager(
|
|
168115
|
+
function SubjectManager({
|
|
168116
|
+
initialData,
|
|
168117
|
+
isLoading: isLoadingProp,
|
|
168118
|
+
onAdd,
|
|
168119
|
+
onUpdate,
|
|
168120
|
+
onDelete
|
|
168121
|
+
}) {
|
|
168116
168122
|
const [subjects, setSubjects] = useState([]);
|
|
168117
168123
|
const [isLoading, setIsLoading] = useState(true);
|
|
168118
168124
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
@@ -168123,20 +168129,27 @@ function SubjectManager() {
|
|
|
168123
168129
|
const [itemToDelete, setItemToDelete] = useState(null);
|
|
168124
168130
|
const [isPending, startTransition] = useTransition();
|
|
168125
168131
|
const { toast: toast2 } = useToast();
|
|
168126
|
-
|
|
168127
|
-
setIsLoading(true);
|
|
168128
|
-
try {
|
|
168129
|
-
const data = MetadataService.getSubjects();
|
|
168130
|
-
setSubjects(data);
|
|
168131
|
-
} catch (error) {
|
|
168132
|
-
toast2({ title: "Error", description: "Failed to fetch subjects from local storage.", variant: "destructive" });
|
|
168133
|
-
} finally {
|
|
168134
|
-
setIsLoading(false);
|
|
168135
|
-
}
|
|
168136
|
-
}, []);
|
|
168132
|
+
const isControlled = initialData !== void 0;
|
|
168137
168133
|
const refreshData = () => {
|
|
168138
|
-
|
|
168134
|
+
if (!isControlled) {
|
|
168135
|
+
setIsLoading(true);
|
|
168136
|
+
try {
|
|
168137
|
+
setSubjects(MetadataService.getSubjects());
|
|
168138
|
+
} catch (error) {
|
|
168139
|
+
toast2({ title: "Error", description: "Failed to refresh subjects.", variant: "destructive" });
|
|
168140
|
+
} finally {
|
|
168141
|
+
setIsLoading(false);
|
|
168142
|
+
}
|
|
168143
|
+
}
|
|
168139
168144
|
};
|
|
168145
|
+
useEffect(() => {
|
|
168146
|
+
if (isControlled) {
|
|
168147
|
+
setSubjects(initialData || []);
|
|
168148
|
+
setIsLoading(isLoadingProp || false);
|
|
168149
|
+
} else {
|
|
168150
|
+
refreshData();
|
|
168151
|
+
}
|
|
168152
|
+
}, [isControlled, initialData, isLoadingProp]);
|
|
168140
168153
|
const handleAddItem = () => {
|
|
168141
168154
|
setCurrentSubject(null);
|
|
168142
168155
|
setSubjectName("");
|
|
@@ -168155,11 +168168,15 @@ function SubjectManager() {
|
|
|
168155
168168
|
};
|
|
168156
168169
|
const confirmDelete = () => {
|
|
168157
168170
|
if (!itemToDelete) return;
|
|
168158
|
-
startTransition(() => {
|
|
168171
|
+
startTransition(async () => {
|
|
168159
168172
|
try {
|
|
168160
|
-
|
|
168173
|
+
if (isControlled && onDelete) {
|
|
168174
|
+
await onDelete(itemToDelete);
|
|
168175
|
+
} else {
|
|
168176
|
+
MetadataService.deleteSubject(itemToDelete.code);
|
|
168177
|
+
refreshData();
|
|
168178
|
+
}
|
|
168161
168179
|
toast2({ title: "Success", description: `Subject "${itemToDelete.name}" deleted.` });
|
|
168162
|
-
refreshData();
|
|
168163
168180
|
} catch (error) {
|
|
168164
168181
|
toast2({ title: "Error", description: error.message || "Failed to delete subject.", variant: "destructive" });
|
|
168165
168182
|
} finally {
|
|
@@ -168173,40 +168190,32 @@ function SubjectManager() {
|
|
|
168173
168190
|
toast2({ title: "Validation Error", description: "Please enter Subject Name and Subject Code.", variant: "destructive" });
|
|
168174
168191
|
return;
|
|
168175
168192
|
}
|
|
168176
|
-
startTransition(() => {
|
|
168193
|
+
startTransition(async () => {
|
|
168177
168194
|
try {
|
|
168178
168195
|
if (currentSubject) {
|
|
168179
|
-
|
|
168196
|
+
if (isControlled && onUpdate) {
|
|
168197
|
+
await onUpdate({ id: currentSubject.id, name: subjectName, code: subjectCode });
|
|
168198
|
+
} else {
|
|
168199
|
+
MetadataService.updateSubject(currentSubject.id, subjectName, subjectCode);
|
|
168200
|
+
refreshData();
|
|
168201
|
+
}
|
|
168180
168202
|
toast2({ title: "Success", description: "Subject updated." });
|
|
168181
168203
|
} else {
|
|
168182
|
-
|
|
168204
|
+
if (isControlled && onAdd) {
|
|
168205
|
+
await onAdd({ name: subjectName, code: subjectCode });
|
|
168206
|
+
} else {
|
|
168207
|
+
MetadataService.addSubject(subjectName, subjectCode);
|
|
168208
|
+
refreshData();
|
|
168209
|
+
}
|
|
168183
168210
|
toast2({ title: "Success", description: "Subject added." });
|
|
168184
168211
|
}
|
|
168185
|
-
refreshData();
|
|
168186
168212
|
setIsDialogOpen(false);
|
|
168187
168213
|
} catch (error) {
|
|
168188
168214
|
toast2({ title: "Error", description: error.message || "Failed to save subject.", variant: "destructive" });
|
|
168189
168215
|
}
|
|
168190
168216
|
});
|
|
168191
168217
|
};
|
|
168192
|
-
return /* @__PURE__ */ React163__default.createElement(Card, null, /* @__PURE__ */ React163__default.createElement(CardHeader, null, /* @__PURE__ */ React163__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React163__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React163__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React163__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React163__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React163__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React163__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React163__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React163__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React163__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React163__default.createElement(Table3, null, /* @__PURE__ */ React163__default.createElement(TableHeader, null, /* @__PURE__ */ React163__default.createElement(TableRow, null, /* @__PURE__ */ React163__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React163__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React163__default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React163__default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React163__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React163__default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React163__default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React163__default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React163__default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React163__default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React163__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React163__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React163__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React163__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React163__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React163__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React163__default.createElement(DialogHeader, null, /* @__PURE__ */ React163__default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React163__default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React163__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React163__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React163__default.createElement(
|
|
168193
|
-
Input,
|
|
168194
|
-
{
|
|
168195
|
-
id: "subjectCode",
|
|
168196
|
-
value: subjectCode,
|
|
168197
|
-
onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()),
|
|
168198
|
-
placeholder: "e.g., MATH",
|
|
168199
|
-
disabled: !!currentSubject
|
|
168200
|
-
}
|
|
168201
|
-
)), /* @__PURE__ */ React163__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React163__default.createElement(
|
|
168202
|
-
Input,
|
|
168203
|
-
{
|
|
168204
|
-
id: "subjectName",
|
|
168205
|
-
value: subjectName,
|
|
168206
|
-
onChange: (e3) => setSubjectName(e3.target.value),
|
|
168207
|
-
placeholder: "e.g., Mathematics"
|
|
168208
|
-
}
|
|
168209
|
-
))), /* @__PURE__ */ React163__default.createElement(DialogFooter, null, /* @__PURE__ */ React163__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React163__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Save")))), /* @__PURE__ */ React163__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React163__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React163__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React163__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React163__default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '" (Code: ', itemToDelete?.code, "). Ensure no topics, questions, or learning objectives reference this subject.")), /* @__PURE__ */ React163__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React163__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React163__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Delete"))))));
|
|
168218
|
+
return /* @__PURE__ */ React163__default.createElement(Card, null, /* @__PURE__ */ React163__default.createElement(CardHeader, null, /* @__PURE__ */ React163__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React163__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React163__default.createElement(BookCopy, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Subjects"), /* @__PURE__ */ React163__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React163__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Subject"))), /* @__PURE__ */ React163__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React163__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React163__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : subjects.length === 0 ? /* @__PURE__ */ React163__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No subjects found. Add one to get started!") : /* @__PURE__ */ React163__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React163__default.createElement(Table3, null, /* @__PURE__ */ React163__default.createElement(TableHeader, null, /* @__PURE__ */ React163__default.createElement(TableRow, null, /* @__PURE__ */ React163__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React163__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React163__default.createElement(TableHead, null, "Created At"), /* @__PURE__ */ React163__default.createElement(TableHead, null, "Updated At"), /* @__PURE__ */ React163__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React163__default.createElement(TableBody, null, subjects.map((subject) => /* @__PURE__ */ React163__default.createElement(TableRow, { key: subject.id }, /* @__PURE__ */ React163__default.createElement(TableCell, { className: "font-mono text-xs" }, subject.code), /* @__PURE__ */ React163__default.createElement(TableCell, { className: "font-medium" }, subject.name), /* @__PURE__ */ React163__default.createElement(TableCell, null, format(new Date(subject.createdAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__default.createElement(TableCell, null, format(new Date(subject.updatedAt), "dd/MM/yyyy HH:mm")), /* @__PURE__ */ React163__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React163__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(subject), className: "mr-2" }, /* @__PURE__ */ React163__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React163__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(subject), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React163__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React163__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React163__default.createElement(DialogContent2, { className: "sm:max-w-md" }, /* @__PURE__ */ React163__default.createElement(DialogHeader, null, /* @__PURE__ */ React163__default.createElement(DialogTitle2, null, currentSubject ? "Edit Subject" : "Add New Subject"), /* @__PURE__ */ React163__default.createElement(DialogDescription2, null, currentSubject ? "Update the details of the subject." : "Enter details for the new subject.")), /* @__PURE__ */ React163__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React163__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React163__default.createElement(Input, { id: "subjectCode", value: subjectCode, onChange: (e3) => setSubjectCode(e3.target.value.toUpperCase()), placeholder: "e.g., MATH", disabled: !!currentSubject })), /* @__PURE__ */ React163__default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React163__default.createElement(Label2, { htmlFor: "subjectName" }, "Subject Name"), /* @__PURE__ */ React163__default.createElement(Input, { id: "subjectName", value: subjectName, onChange: (e3) => setSubjectName(e3.target.value), placeholder: "e.g., Mathematics" }))), /* @__PURE__ */ React163__default.createElement(DialogFooter, null, /* @__PURE__ */ React163__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !subjectName.trim() || !subjectCode.trim() }, isPending && /* @__PURE__ */ React163__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React163__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React163__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React163__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React163__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React163__default.createElement(AlertDialogDescription2, null, 'This action cannot be undone. This will permanently delete the subject "', itemToDelete?.name, '".')), /* @__PURE__ */ React163__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React163__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React163__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React163__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
168210
168219
|
}
|
|
168211
168220
|
|
|
168212
168221
|
// src/react-ui/components/metadata/GradeLevelManager.tsx
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { s as QuizConfig, g as QuizQuestion } from './quiz-config-o4j2dfsu.cjs';
|
|
4
|
-
import { QuestionInBank, QuestionFilters as QuestionFilters$1 } from './index.cjs';
|
|
4
|
+
import { QuestionInBank, QuestionFilters as QuestionFilters$1, Subject } from './index.cjs';
|
|
5
5
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
6
6
|
import * as ToastPrimitives from '@radix-ui/react-toast';
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
@@ -90,7 +90,31 @@ declare function ApiKeySettings(): React__default.JSX.Element;
|
|
|
90
90
|
|
|
91
91
|
declare function MetadataTabs(): React__default.JSX.Element;
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Props for the SubjectManager component.
|
|
95
|
+
* When these props are provided, the component operates in "controlled" mode.
|
|
96
|
+
* If they are omitted, it falls back to using its internal localStorage service.
|
|
97
|
+
*/
|
|
98
|
+
interface SubjectManagerProps {
|
|
99
|
+
/** Optional: An array of subjects to display. If provided, the component will not fetch its own data. */
|
|
100
|
+
initialData?: Subject[];
|
|
101
|
+
/** Optional: A flag to indicate if the parent component is loading data. */
|
|
102
|
+
isLoading?: boolean;
|
|
103
|
+
/** Optional: An async callback function to handle adding a new subject. */
|
|
104
|
+
onAdd?: (item: {
|
|
105
|
+
name: string;
|
|
106
|
+
code: string;
|
|
107
|
+
}) => Promise<void>;
|
|
108
|
+
/** Optional: An async callback function to handle updating an existing subject. */
|
|
109
|
+
onUpdate?: (item: {
|
|
110
|
+
id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
code: string;
|
|
113
|
+
}) => Promise<void>;
|
|
114
|
+
/** Optional: An async callback function to handle deleting a subject. */
|
|
115
|
+
onDelete?: (item: Subject) => Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
declare function SubjectManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }: SubjectManagerProps): React__default.JSX.Element;
|
|
94
118
|
|
|
95
119
|
declare function TopicManager(): React__default.JSX.Element;
|
|
96
120
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { s as QuizConfig, g as QuizQuestion } from './quiz-config-o4j2dfsu.js';
|
|
4
|
-
import { QuestionInBank, QuestionFilters as QuestionFilters$1 } from './index.js';
|
|
4
|
+
import { QuestionInBank, QuestionFilters as QuestionFilters$1, Subject } from './index.js';
|
|
5
5
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
6
6
|
import * as ToastPrimitives from '@radix-ui/react-toast';
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
@@ -90,7 +90,31 @@ declare function ApiKeySettings(): React__default.JSX.Element;
|
|
|
90
90
|
|
|
91
91
|
declare function MetadataTabs(): React__default.JSX.Element;
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Props for the SubjectManager component.
|
|
95
|
+
* When these props are provided, the component operates in "controlled" mode.
|
|
96
|
+
* If they are omitted, it falls back to using its internal localStorage service.
|
|
97
|
+
*/
|
|
98
|
+
interface SubjectManagerProps {
|
|
99
|
+
/** Optional: An array of subjects to display. If provided, the component will not fetch its own data. */
|
|
100
|
+
initialData?: Subject[];
|
|
101
|
+
/** Optional: A flag to indicate if the parent component is loading data. */
|
|
102
|
+
isLoading?: boolean;
|
|
103
|
+
/** Optional: An async callback function to handle adding a new subject. */
|
|
104
|
+
onAdd?: (item: {
|
|
105
|
+
name: string;
|
|
106
|
+
code: string;
|
|
107
|
+
}) => Promise<void>;
|
|
108
|
+
/** Optional: An async callback function to handle updating an existing subject. */
|
|
109
|
+
onUpdate?: (item: {
|
|
110
|
+
id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
code: string;
|
|
113
|
+
}) => Promise<void>;
|
|
114
|
+
/** Optional: An async callback function to handle deleting a subject. */
|
|
115
|
+
onDelete?: (item: Subject) => Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
declare function SubjectManager({ initialData, isLoading: isLoadingProp, onAdd, onUpdate, onDelete }: SubjectManagerProps): React__default.JSX.Element;
|
|
94
118
|
|
|
95
119
|
declare function TopicManager(): React__default.JSX.Element;
|
|
96
120
|
|
package/package.json
CHANGED