feat: add student tiles to dashboard - #1833
Conversation
Japrolol
left a comment
There was a problem hiding this comment.
Generated api client is missing new methods, practice-session table is missing rls, getStudentDashboardSummary will crash the app in scenarios with more data. Practice retry/generation is not idempotent and separation of concerns is weak.
Let's fix all that
| ), | ||
| type: sql<AiMentorType>`${aiMentorLessons.type}`, | ||
| name: this.localizationService.getLocalizedSqlField(aiMentorLessons.name, language), | ||
| title: sql<string>`COALESCE( |
There was a problem hiding this comment.
Why give these repository methods more to do? Since practice sessions work separately, can we use separate "entrypoints"
| currentUser.userId, | ||
| practiceDate, | ||
| ); | ||
| if (!existing) throw new ConflictException("AI Mentor practice already exists"); |
| currentUser: CurrentUserType, | ||
| ): Promise<AiMentorPracticeSessionResponse> { | ||
| const session = await this.aiRepository.findPracticeSessionById(sessionId); | ||
| if (!session) throw new NotFoundException("AI Mentor practice not found"); |
| const session = await this.aiRepository.findPracticeSessionById(sessionId); | ||
| if (!session) throw new NotFoundException("AI Mentor practice not found"); | ||
| if (session.userId !== currentUser.userId) | ||
| throw new ForbiddenException("You don't have access to this AI Mentor practice"); |
There was a problem hiding this comment.
translations in entire file
| }); | ||
| const { generateObject, jsonSchema } = await loadAiSdk(); | ||
| const openai = await this.aiRuntimeService.getAISdkOpenAI(); | ||
| const { object } = await generateObject({ |
There was a problem hiding this comment.
Let's add fallback to luma service
| ); | ||
| } | ||
|
|
||
| if (practice.status === "queued" || practice.status === "processing") { |
There was a problem hiding this comment.
Too much is happening in one file, extract
| const containerRef = useRef<HTMLDivElement>(null); | ||
| const transport = useMemo(() => createAiMentorChatTransport(threadId), [threadId]); | ||
| const { messages, setMessages, sendMessage, status } = useChat({ transport }); | ||
| const isProcessing = status === "submitted" || status === "streaming"; |
There was a problem hiding this comment.
I know this status comes from ai-sdk, but can we use enum for it and use it in other places where we have ai chat too?
| const { data, isLoading, isError, refetch } = useStudentDashboardSummary(); | ||
| const metadata = DASHBOARD_WIDGET_REGISTRY[DASHBOARD_WIDGET_IDS.STUDENT_REQUIRED_COURSE]; | ||
| const courses = data?.requiredCourses ?? []; | ||
| const overdueCount = courses.filter((course) => course.urgency === "overdue").length; |
| "border-error-100 bg-error-50 hover:border-error-300 focus-visible:ring-error-300": | ||
| course.urgency === "overdue", | ||
| "border-warning-100 bg-warning-50 hover:border-warning-300 focus-visible:ring-warning-300": | ||
| course.urgency === "dueSoon", |
a17f718 to
e1eb3c2
Compare
bc66d1f to
41dc8cf
Compare
f18483c to
192f1bc
Compare
6958969
into
pz_feat_1717_add_dashboard_admin_tiles
Issue(s)
Overview
Student Dashboard Tiles turn the Mentingo home page into a personalized learning action center. Learners can quickly continue active courses, review mandatory training, track completion, access certificates, and start daily AI Mentor practice.
Business Value
The feature reduces navigation, highlights urgent learning, and makes progress and achievements more visible. It supports higher engagement, better compliance follow-through, and a more consistent learner experience without additional administrative effort.
Screenshots / Video