Epic: Learn Page — Plans + Text Library Tabs & Tiny Habits Scheduling
Overview
The Learn screen is currently a "Coming Soon" placeholder. This epic implements it as a unified study hub with two tabs — Plans and Text Library — and introduces a Tiny Habits scheduling flow that lets users anchor enrolled plans to existing daily routines.
Current State
| Area |
File |
Status |
| Learn screen |
lib/features/learn/presentation/screens/learn_screen.dart |
Placeholder — "Coming Soon" |
| Plans (browse + enrolled) |
lib/features/plans/presentation/screens/plans_screen.dart |
Working — not surfaced on Learn |
| Text library / collections |
lib/features/texts/presentation/screens/collections/collections_screen.dart |
Working — not surfaced on Learn |
| Notification infrastructure |
lib/features/notifications/data/services/notification_service.dart |
Exists — not connected to plans |
| Habit anchoring |
— |
Does not exist |
The UserPlansModel (lib/features/plans/data/models/user/user_plans_model.dart) and NotificationSettings (lib/features/notifications/domain/entities/notification_settings.dart) have no per-plan scheduling fields.
Screen Architecture (from Figma)
The Learn screen has a pill-style tab toggle at the top:
[ Plans ] [ Text Library ]
Plans Tab
State A — New user / browse only:
- "Featured Plan" section — large hero card with
+ enroll button
- "Explore More" section — scrollable list of plans, each with thumbnail, title, duration ("15 Days"),
+ enroll button
- Plans the user is already enrolled in do not show a
+ button
State B — User has enrolled plans:
- "Next Up" — the highest-priority plan for right now (see ordering rules below), with "Start Now" CTA
- "Later Today" — remaining enrolled plans scheduled later today; hidden entirely if none exist
- "See all" link → full list of all enrolled plans regardless of schedule
- "Explore More" — only shows plans the user is not enrolled in
Text Library Tab
State A — No saved texts:
- "Featured text" — large hero card with
+ save button
- "Explore More" — scrollable list of texts
State B — User has saved texts:
- "Featured text" — saved text with "Continue Reading" CTA
- "My Texts" section — saved texts list with "Start" / "Continue" CTA
- Each text card has a
... context menu: Text Info (ⓘ), Remove from my library (red, ⊖)
- "Explore More" section below
- "My Library" drill-down screen — full list of saved texts, same card pattern
Behavioural Rules
Plan ordering — "Next Up" and "Later Today"
The order resets each day. Within a given day, plans are sorted as follows:
- Overdue + incomplete — plans whose scheduled time has already passed today but have not been completed. These surface at the top as "Next Up".
- Upcoming — plans whose scheduled time hasn't arrived yet today, in ascending time order.
- Completed today — plans the user has finished are removed from the "Next Up" / "Later Today" list and will reappear tomorrow.
If a user opens the app after a plan's scheduled time and hasn't done it, it sits at the top of the list. If they have completed it, it does not appear on the main Learn view — only in "See all".
Enrollment entry points
The scheduling flow (Steps 1–3) is triggered from any + / enroll button in the app, not only from the Learn page. This includes plan detail screens and any other surface that exposes enrollment.
Already-enrolled plans
The + button and any other enroll CTAs are hidden for plans the user is already enrolled in, across all surfaces.
Guest users
Guest users cannot enroll in plans or save texts. Tapping + or any enroll/save button prompts them to sign in or create an account.
Notification permissions
If a user denies notification permissions during Step 3, the app must prompt them to enable notifications in device settings. Enrollment still completes — notifications_enabled is set to false until permissions are granted.
Re-editing a schedule
Users can re-edit the notification time for an enrolled plan after enrollment. This updates notification_time and reschedules the existing notification. The habit anchor (ux_anchor_text) should also be editable.
Custom habit anchors ("Write your own")
User-written habit anchors are stored as ux_anchor_text on UserPlan alongside system anchors — no separate table needed.
Featured text
Curated server-side. Hardcode an initial value until a CMS/admin feature is built to manage it.
Reading progress
Progress is stored as the last-viewed segment ID (LibraryProgress.last_segment_id). On reopen, the reader scrolls to that segment.
Tiny Habits Scheduling Flow
Triggered from any enrollment entry point in the app. Three-screen flow with a dot progress indicator:
Step 1 — Choose a time of day
- Title: "Choose a time of day"
- Subtitle: "Pick a time that fits in your schedule."
- Stem: "I'll learn:"
- 2×2 icon grid: in the morning / in the afternoon / in the evening / at night
- CTA: "Next: Link to a habit →"
Step 2 — Link to a habit
- Title: "Link it to something you do every day"
- Subtitle: "Habits stick when they follow something you already do."
- Stem: "I will learn [time of day]:" (e.g. "I will learn in the morning:")
- "+ Write your own" text link
- Searchable list of habit anchors filtered by the time-of-day selected in Step 1 (e.g. Morning → "After cleaning", "After breakfast", "Before housework", "After bathing")
- Radio button selection
- CTA: "Next: Set the time →" (disabled/grey until a habit is selected)
- "Skip for now" text link — bypasses scheduling, sets
notifications_enabled = false
Step 3 — Set the time
- Time picker pre-filled with a default per time-of-day slot (e.g. Morning → 08:00)
- CTA: "Save" / "Done"
User Stories
- As a user, I want a unified Learn page with Plans and Text Library tabs so that I can access all my study content from one place.
- As a user enrolling in a plan, I want to anchor it to an existing daily habit and set a notification time so that studying becomes part of my routine.
- As a user, I want to save texts to my library and resume reading where I left off so that I can work through reference material over time.
Backend Requirements
| Feature |
Requirement |
| Habit Anchoring |
UserPlan needs: habit_anchor_id (FK), ux_anchor_text (String), notification_time (Time), notifications_enabled (Boolean) |
| Habit List |
Static list on client initially; replace with /habit-anchors?time_of_day=morning endpoint later |
| Notification scheduling |
Per-plan — moves practiceTime ownership from the shared NotificationSettings entity to UserPlan |
| Save to Library |
POST /library/add and DELETE /library/remove endpoints |
| Reading Progress |
LibraryProgress schema: text_id, user_id, last_segment_id |
Flutter / Notification Wiring
- Extend
NotificationService (lib/features/notifications/data/services/notification_service.dart) to schedule per-plan daily notifications using UserPlan.notification_time
- Notification cancellation fires on unenroll — hook into the existing dismissible card logic in
MyPlansTab (lib/features/plans/presentation/widgets/my_plan_tab.dart)
- Reading progress hook:
lib/features/reader/presentation/providers/reader_notifier.dart
Definition of Done
Learn Screen
Scheduling Flow
Text Library
General
Epic: Learn Page — Plans + Text Library Tabs & Tiny Habits Scheduling
Overview
The Learn screen is currently a "Coming Soon" placeholder. This epic implements it as a unified study hub with two tabs — Plans and Text Library — and introduces a Tiny Habits scheduling flow that lets users anchor enrolled plans to existing daily routines.
Current State
lib/features/learn/presentation/screens/learn_screen.dartlib/features/plans/presentation/screens/plans_screen.dartlib/features/texts/presentation/screens/collections/collections_screen.dartlib/features/notifications/data/services/notification_service.dartThe
UserPlansModel(lib/features/plans/data/models/user/user_plans_model.dart) andNotificationSettings(lib/features/notifications/domain/entities/notification_settings.dart) have no per-plan scheduling fields.Screen Architecture (from Figma)
The Learn screen has a pill-style tab toggle at the top:
Plans Tab
State A — New user / browse only:
+enroll button+enroll button+buttonState B — User has enrolled plans:
Text Library Tab
State A — No saved texts:
+save buttonState B — User has saved texts:
...context menu: Text Info (ⓘ), Remove from my library (red, ⊖)Behavioural Rules
Plan ordering — "Next Up" and "Later Today"
The order resets each day. Within a given day, plans are sorted as follows:
If a user opens the app after a plan's scheduled time and hasn't done it, it sits at the top of the list. If they have completed it, it does not appear on the main Learn view — only in "See all".
Enrollment entry points
The scheduling flow (Steps 1–3) is triggered from any
+/ enroll button in the app, not only from the Learn page. This includes plan detail screens and any other surface that exposes enrollment.Already-enrolled plans
The
+button and any other enroll CTAs are hidden for plans the user is already enrolled in, across all surfaces.Guest users
Guest users cannot enroll in plans or save texts. Tapping
+or any enroll/save button prompts them to sign in or create an account.Notification permissions
If a user denies notification permissions during Step 3, the app must prompt them to enable notifications in device settings. Enrollment still completes —
notifications_enabledis set tofalseuntil permissions are granted.Re-editing a schedule
Users can re-edit the notification time for an enrolled plan after enrollment. This updates
notification_timeand reschedules the existing notification. The habit anchor (ux_anchor_text) should also be editable.Custom habit anchors ("Write your own")
User-written habit anchors are stored as
ux_anchor_textonUserPlanalongside system anchors — no separate table needed.Featured text
Curated server-side. Hardcode an initial value until a CMS/admin feature is built to manage it.
Reading progress
Progress is stored as the last-viewed segment ID (
LibraryProgress.last_segment_id). On reopen, the reader scrolls to that segment.Tiny Habits Scheduling Flow
Triggered from any enrollment entry point in the app. Three-screen flow with a dot progress indicator:
Step 1 — Choose a time of day
Step 2 — Link to a habit
notifications_enabled = falseStep 3 — Set the time
User Stories
Backend Requirements
UserPlanneeds:habit_anchor_id(FK),ux_anchor_text(String),notification_time(Time),notifications_enabled(Boolean)/habit-anchors?time_of_day=morningendpoint laterpracticeTimeownership from the sharedNotificationSettingsentity toUserPlanPOST /library/addandDELETE /library/removeendpointsLibraryProgressschema:text_id,user_id,last_segment_idFlutter / Notification Wiring
NotificationService(lib/features/notifications/data/services/notification_service.dart) to schedule per-plan daily notifications usingUserPlan.notification_timeMyPlansTab(lib/features/plans/presentation/widgets/my_plan_tab.dart)lib/features/reader/presentation/providers/reader_notifier.dartDefinition of Done
Learn Screen
+enroll buttons render correctly+button on any surface...context menu renders correctlyScheduling Flow
habit_anchor_id,ux_anchor_text,notification_time, andnotifications_enabled = truetoUserPlannotifications_enabled = falseand completes enrollment without schedulingnotifications_enabled = falseText Library
POST /library/add; removing callsDELETE /library/removeLibraryProgress.last_segment_idGeneral