Gradeful
CoursesPricingAbout

How Gradeful connects

Raw markdown

Dashboard & workspace

Student home after login. Course study tabs are in 06-study-views.md. Settings overlay is 05-settings.md. Flows: 00-how-everything-connects.md.

Access: Workspace layout requires logged-in + onboarded (else /welcome or /login?next=/dashboard).
/dashboard is the only student home. Course workspaces (/my-courses/{slug}) stay entitlement-gated (proxy → /pricing if unpaid). Admins count as subscribed for that gate. Marketing / is separate: only users with current active access are redirected there from /.

Canonical home: /dashboard. /my-courses and /dashboard/my-packs redirect here (query q and error=no_access preserved). Course study URLs stay at /my-courses/{slug}.

Redirects: /my-courses/library|progress|semester-plan → /dashboard/…. /dashboard/course/[slug]/… → /my-courses/[slug].


Shared chrome (every workspace page)

SECTION: Desktop sidebar Copy: Expanded wordmark Gradeful; collapsed G. Nav labels below. Streak card This week plus a dynamic rhythm title. Account chip shows profiles.full_name or Your account, campus line or email. Data shown: profiles.*; streak from user_streaks / study_sessions; feature flag aiTutorEnabled; profiles.role for Admin

ELEMENT: Gradeful / G (brand) Action: navigate Destination: /dashboard Writes to: none Reads from: none

ELEMENT: Collapse / Expand sidebar Action: toggle Destination: none Writes to: cookie via setWorkspaceSidebarCollapsed (except on course routes: local only) Reads from: cookie

ELEMENT: Dashboard Action: navigate Destination: /dashboard Writes to: none Reads from: active on /dashboard (aliases /my-courses, /dashboard/my-packs redirect here)

ELEMENT: Library Action: navigate Destination: /dashboard/library Writes to: none Reads from: none

ELEMENT: Progress Action: navigate Destination: /dashboard/progress Writes to: none Reads from: none

ELEMENT: Semester Plan Action: navigate Destination: /dashboard/semester-plan Writes to: none Reads from: none

ELEMENT: AI Tutor Action: navigate Destination: On a course: same course URL + ?panel=ai; else /dashboard/ai-tutor Writes to: none Reads from: Visible when aiTutorEnabled

ELEMENT: Admin dashboard Action: navigate Destination: /admin Writes to: none Reads from: profiles.role is admin

ELEMENT: Streak card / flame (collapsed) Action: open modal Destination: calendar dialog (month grid; legend Streak day Missed Today) Writes to: none Reads from: user_streaks, study_sessions, profiles, platform weeklyStudyGoalMinutes

ELEMENT: Account chip (opens flyout) Action: open modal Destination: account menu Writes to: none Reads from: profiles.avatar_url, full_name, campus fields, Auth email

ELEMENT: Settings (flyout) Action: open modal Destination: Settings tab profile Writes to: none Reads from: none

ELEMENT: Get help (flyout) Action: open modal Destination: Settings tab help Writes to: none Reads from: none

ELEMENT: Upgrade plan (flyout) Action: navigate Destination: /pricing Writes to: none Reads from: none

ELEMENT: Dashboard (flyout) Action: navigate Destination: /dashboard Writes to: none Reads from: none

ELEMENT: Learn more (flyout) Action: toggle Destination: submenu Writes to: none Reads from: none

ELEMENT: About Gradeful / Privacy policy / Terms of service / Refund policy / Academic integrity / All policies Action: navigate Destination: /about /privacy /terms /refunds /academic-integrity /policies Writes to: none Reads from: none

ELEMENT: Log out / Logging out… Action: submit Destination: / Writes to: clears session Reads from: none

SECTION: Mobile header Copy: Logo Gradeful Data shown: same as sidebar account

ELEMENT: Open workspace menu (hamburger) Action: toggle Destination: drawer with full sidebar (showCollapseToggle=false) Writes to: none Reads from: none

ELEMENT: Close menu / backdrop / Escape Action: toggle Destination: closes drawer Writes to: none Reads from: none

ELEMENT: Gradeful Action: navigate Destination: /dashboard Writes to: none Reads from: none

ELEMENT: Open settings (gear) Action: open modal Destination: Settings profile Writes to: none Reads from: none

ELEMENT: Open account menu Action: open modal Destination: same flyout as sidebar Writes to: none Reads from: profiles.*

SECTION: Course right panel (course player only) Copy: Collapsed Open stats / Open AI tutor. Expanded tabs Stats AI Tutor. Stats labels Notes Quizzes Exam prep plus notes %, flashcards due, quiz scores, exam days. AI loading Loading AI tutor... Modes Explain Guide me Practice me Review my mistake Quiz me. Suggestions Explain this concept Help me practice What should I review for my upcoming exam? Data shown: content_progress, flashcard due counts, quiz scores, course_events

ELEMENT: Open stats / Open AI tutor / Collapse panel Action: toggle Destination: none Writes to: cookie setWorkspaceAiPanelExpanded Reads from: cookie; aiTutorEnabled

ELEMENT: Stats / AI Tutor tabs Action: toggle Destination: none Writes to: none Reads from: none

ELEMENT: Module list row Action: navigate Destination: /my-courses/{slug}?module=&tab=notes Writes to: none Reads from: course_modules

ELEMENT: View all chapters → Action: navigate Destination: course overview Writes to: none Reads from: none

ELEMENT: AI suggestion chips / chat send Action: submit Destination: none Writes to: POST /api/ai-tutor with course/module IDs (usage metrics only; no transcript table) Reads from: entitled Gradeful pack items, student progress, student-entered exam dates

ELEMENT: Ask AI Tutor (floating) Action: toggle Destination: opens AI panel Writes to: none Reads from: aiTutorEnabled


PAGE: /dashboard Purpose: Restored pre-redesign student home (Git 89d0991): greeting, resume card, exam-mode banner, course cards, what needs attention, Today calendar, study hours, recent activity. Not the later next-study-action redesign. Access: logged-in + onboarded (not subscriber-gated). Unpaid accounts see the empty/onboarding pack state, not a marketing homepage inside the workspace. Entry points: / when the user has active access; /auth/home; welcome submit; login next; sidebar Dashboard; public header Dashboard; checkout Go to my courses → /dashboard

SECTION: Top bar Copy: Greeting Good morning, {firstName}. Search Search your courses... Data shown: profiles.full_name first name

ELEMENT: Search Action: submit Destination: paid /dashboard?q=…; free /courses?q=… Writes to: none Reads from: query q filters owned courses on the paid home

ELEMENT: Notification bell Action: toggle Destination: notification panel Writes to: notifications.is_read (markAllNotificationsRead; auto after 2s open) Reads from: notifications (limit 20) + realtime INSERT Empty: No notifications yet Badge: unread count Row: navigates action_url when set Note: evening streak-risk notifications are not generated

ELEMENT: Mark all read Action: submit Destination: none Writes to: notifications.is_read Reads from: unread rows

ELEMENT: Open settings (md+) Action: open modal Destination: Settings profile Writes to: none Reads from: none

ELEMENT: AccountChrome (mobile top bar) Action: open modal Destination: account flyout / settings Writes to: none Reads from: profiles.*

SECTION: Access error Copy: We couldn't open that course. Make sure it's in your plan, or try opening it again from the list below. Data shown: query error=no_access

SECTION: Resume where you left off Copy: Resume where you left off plus last content type / chapter. Data shown: latest content_progress.last_accessed_at among owned modules ELEMENT: Resume CTA Action: navigate Destination: /my-courses/{slug}?module=&tab= Writes to: none Reads from: content_progress

SECTION: Exam mode banner Copy: Exam mode plus nearest exam headline. CTA into that course. Data shown: exam_schedules / course_events on owned courses ELEMENT: Open course Action: navigate Destination: /my-courses/{slug} Writes to: none Reads from: exam-mode builder

SECTION: Your courses Copy: Your courses or Search your courses. Cards: progress bar, Content coming soon, flashcards due, exam badge. Empty: Your study space is waiting. / No courses yet with Browse the catalog and get access to your first pack. Data shown: user_access.course_ids via getCachedUserOwnedCourses; content_progress; flashcard due counts ELEMENT: Course card Action: navigate Destination: /my-courses/{slug} Writes to: none Reads from: owned courses ELEMENT: View all courses / Show fewer / Clear search Action: toggle / navigate Destination: /dashboard for clear search Writes to: none Reads from: owned course count

SECTION: What needs attention Copy: What needs attention / You're all caught up for now. Rows for due flashcards, quizzes, exams, unpublished content. Data shown: lib/workspace/attention-data.ts plus flashcard due/leech counts ELEMENT: Attention row Action: navigate Destination: study tab href when set Writes to: none Reads from: attention items ELEMENT: View all Action: navigate Destination: /dashboard/progress Writes to: none Reads from: attention total count

SECTION: Today (right column) Copy: Today plus month label, week strip, You're all caught up / {n} items need attention. Link Open semester plan. Data shown: calendar from now; stats.tasksDueToday ELEMENT: Open semester plan Action: navigate Destination: /dashboard/semester-plan Writes to: none Reads from: none

SECTION: Study hours Copy: weekly hours vs goal, 7-day bars. Data shown: study_sessions.active_minutes; platform weeklyStudyGoalMinutes

SECTION: Recent activity Copy: Recent activity / Activity appears after you open lessons, quizzes, or flashcards. (tool names follow restored Notes / Quiz / Flashcards labels.) Data shown: recent content_progress rows

Public weekly rank / “students studying now” are not shown (leaderboards stay retired). Schedule-confirm and syllabus-upload gates stay retired.


PAGE: /my-courses Purpose: Alias of /dashboard (redirect, query preserved). Access: logged-in + onboarded. Home path is not subscriber-gated. Entry points: old bookmarks; emails ELEMENT: none — redirect only. /my-courses/{slug} remains the course workspace.


PAGE: /dashboard/my-packs Purpose: Alias of /dashboard (redirect, query preserved). Access: logged-in + onboarded Entry points: old checkout CTA ELEMENT: none — redirect only


PAGE: /dashboard/library Purpose: Saved notes, favorited flashcards/quizzes, personal uploads. Access: logged-in + onboarded Entry points: Sidebar Library. Alias /my-courses/library redirects here.

SECTION: Header Copy: My Library Saved notes, flashcards, and your own materials Data shown: static

ELEMENT: All / Notes / Flashcards / Uploads Action: toggle Destination: none (filter) Writes to: none Reads from: library_items.item_type

SECTION: Cards Copy: Empty Nothing saved here yet. Uploads empty No uploads yet. Upload zone Upload your own materials PDF·images·Word ≤10MB. Data shown: library_items + course/module joins

ELEMENT: View → Action: navigate Destination: notes study href Writes to: none Reads from: saved note target

ELEMENT: Review → Action: navigate Destination: flashcards (+ optional &card=) Writes to: none Reads from: flashcard library item

ELEMENT: Retake → Action: navigate Destination: quiz Writes to: none Reads from: quiz library item

ELEMENT: Delete Action: submit Destination: none Writes to: deletes library_items (deleteLibraryItem) Reads from: item id

ELEMENT: Upload file Action: submit Destination: none Writes to: library_items via uploadLibraryFile Reads from: file


PAGE: /dashboard/progress Purpose: Weekly streak objective, course breakdown, 12-week heatmap, quiz notes. Access: logged-in + onboarded Entry points: Sidebar Progress. Alias /my-courses/progress redirects here.

SECTION: This week / Progress Copy: This week Progress plus objective copy (weekly goal + miss budget). Summary: all-time screen time, current streak, course completion. Course bars: Notes / Flashcards / Quizzes. Last 12 weeks. Quiz notes table headers Module, Attempts, Best, Latest, Direction. How streaks work (explanatory copy in the view). Data shown: profiles, owned courses, course_modules, study_sessions, course_xp, quiz_attempts, course_events, streak dates

ELEMENT: Keep studying Action: navigate Destination: first course overview or /courses Writes to: none Reads from: owned courses

ELEMENT: Open course → Action: navigate Destination: /my-courses/{slug} Writes to: none Reads from: courses.slug


PAGE: /dashboard/semester-plan Purpose: Upcoming assessments, recommended prep, course progress. Not a giant calendar. Syllabus is optional and private. Access: logged-in + onboarded Entry points: Sidebar Semester Plan. Alias /my-courses/semester-plan redirects here.

SECTION: Header Copy: Semester Plan Upcoming assessments, a short prep list, and course progress. CTA Add exam session length 20 min 45 min 90 min Exam cram Data shown: cookie gradeful_study_session; owned courses

ELEMENT: Add exam Action: open dialog Destination: AddExamDateDialog Writes to: exam_schedules (addStudentExamDate) Reads from: owned courses

ELEMENT: Session length Action: submit Destination: none Writes to: cookie via setStudySessionLength Reads from: cookie

SECTION: Upcoming assessments Copy: empty No assessments yet Add an exam in a few seconds. list shows course, title, when, optional topics, source when dates disagree Data shown: merged exam_schedules + course_events (lib/workspace/assessments.ts)

ELEMENT: Remove Action: submit Destination: none Writes to: deletes student exam_schedules row Reads from: student-owned assessment id

SECTION: Recommended prep Copy: session titles from generateStudyPlan; empty Add an exam or open a course Data shown: assessments, progress, flashcard due counts ELEMENT: Open → Action: navigate Destination: course overview or study href Writes to: none Reads from: session.href

SECTION: Course progress Copy: {code} {n}% complete Data shown: content_progress ELEMENT: Open → Action: navigate Destination: /my-courses/{slug}

SECTION: Syllabus (optional) Copy: Private to you. Upload / Delete Data shown: syllabuses ELEMENT: Upload Action: open modal Destination: SyllabusUploadModal (skippable) Writes to: syllabuses ELEMENT: Delete Action: submit Destination: none Writes to: deletes storage object + syllabuses row


PAGE: /dashboard/ai-tutor Purpose: Standalone AI page when opened off-course. Access: logged-in; if aiTutorEnabled false → /dashboard Entry points: Sidebar AI Tutor when not in a course.

SECTION: Help Copy: AI Tutor plus instruction to open a course and use the right AI panel Data shown: static

ELEMENT: Back to dashboard Action: navigate Destination: /dashboard Writes to: none Reads from: none


PAGE: /my-courses/[courseSlug] Purpose: Course overview + in-place study player (?module=&tab=&variant=&chapter=&panel=). Access: logged-in + onboarded; must own the course else /dashboard?error=no_access; anonymous → login with next Entry points: dashboard cards, resume, attention, progress, library, right panel, public catalog formula-sheet preview (may bounce to login)

SECTION: Course shell header Copy: Breadcrumb Dashboard / {courseCode} / compact chapter picker / current study tool / progress. Tabs: Overview Notes Formula sheet Flashcards Quiz Exam Exam review Mistake fixes Exercises Ask Tutor (Ask Tutor hidden unless aiTutorEnabled). Locked title Not published yet. Picker trigger Ch. {n} · {title} or Select chapter. Layout: restored pre-redesign tab strip + chapter picker (Git c7fc162). No Learn / Practice / Review strip and no course-outline column. Right AI panel is a full-screen drawer on small screens. Data shown: courses.code, course_modules, available module_pack_items mapped through lib/workspace/learning-intent.ts

ELEMENT: Dashboard Action: navigate Destination: /dashboard Writes to: none Reads from: none

ELEMENT: {courseCode} Action: navigate Destination: /my-courses/{slug} overview Writes to: none Reads from: courses.slug

ELEMENT: Course settings (gear) Action: navigate Destination: /my-courses/{slug}/settings Writes to: none Reads from: none

ELEMENT: Overview / Notes / Formula sheet / Flashcards / Quiz / Exam / Exam review / Mistake fixes / Exercises Action: navigate Destination: overview, or /my-courses/{slug}?module={id}&tab={item_type}. Ask Tutor still uses ?panel=ai. Legacy ?intent=learn URLs may still resolve to the first matching tab, but Learn / Practice / Review is not the student IA. Writes to: none Reads from: published module_pack_items for the chapter

ELEMENT: Chapter option Ch. {n} · {title} Action: navigate Destination: same intent, new module Writes to: none Reads from: course_modules

Study body for each tab: 06-study-views.md.


PAGE: /my-courses/[courseSlug]/settings Purpose: Per-course flashcard scheduler, syllabus, exam dates. Access: logged-in; must own course else public /courses/{slug} Entry points: Course shell settings gear. /dashboard/course/{slug}/settings redirects here.

SECTION: Header Copy: {code} settings Data shown: courses.code, courses.title

ELEMENT: ← Back to course Action: navigate Destination: course overview Writes to: none Reads from: none

SECTION: Flashcard study Copy: Flashcard study How well should cards stick? New cards per day More options Maximum reviews per day placeholder No limit Study order options mixed / Reviews first / New cards first related-cards checkbox Timezone Developer settings Data shown: flashcard_deck_settings. Raw scheduler parameter vectors are not shown.

ELEMENT: Save flashcard settings / Saving… Action: submit Destination: none Writes to: flashcard_deck_settings (updateFlashcardDeckSettings) Reads from: form Toast: Flashcard settings saved.

SECTION: Syllabus Copy: Syllabus Optional and private. empty No syllabus uploaded. Data shown: syllabuses

ELEMENT: Upload / Replace Action: open modal Destination: SyllabusUploadModal Writes to: syllabuses Reads from: existing row

ELEMENT: Delete syllabus Action: submit Destination: none Writes to: deletes storage object + syllabuses row

SECTION: Exams Copy: Exams empty No exams yet. Add exam Data shown: merged exam_schedules + course_events ELEMENT: Add exam Action: open dialog Destination: AddExamDateDialog Writes to: exam_schedules

Gradeful

Course-specific study packs for AUB and LAU students. Built for focused self-study.

Gradeful is an independent study-support service. Universities named on this site are listed only so you can match a Gradeful pack to the course you are taking. Those universities do not provide, sponsor, or endorse Gradeful, and Gradeful does not claim access to their official materials or assessments.

© 2026 Gradeful.

Platform

HomeCoursesPricing

Policies

Privacy PolicyTerms of ServiceRefund PolicyAcademic Integrity