Skip to content

Epic: Learn Page — Text Library Integration & Tiny Habits Scheduling #207

@evanyerburgh

Description

@evanyerburgh

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:

  1. Overdue + incomplete — plans whose scheduled time has already passed today but have not been completed. These surface at the top as "Next Up".
  2. Upcoming — plans whose scheduled time hasn't arrived yet today, in ascending time order.
  3. 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

  1. 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.
  2. 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.
  3. 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

  • Learn screen displays the Plans and Text Library pill tabs and is no longer a placeholder
  • Plans tab — new user state: Featured Plan + Explore More list with + enroll buttons render correctly
  • Plans tab — enrolled state: "Next Up", "Later Today", "See all", and "Explore More" sections render correctly
  • "Later Today" section is hidden when no plans are scheduled later today
  • "Explore More" only shows plans the user is not enrolled in; already-enrolled plans show no + button on any surface
  • Plan ordering follows the defined rules: overdue+incomplete → upcoming → completed hidden
  • Text Library tab — no saved texts state: Featured text + Explore More renders correctly
  • Text Library tab — with saved texts state: "My Texts" section with "Start"/"Continue" CTAs and ... context menu renders correctly
  • "My Library" drill-down screen works with correct card pattern and context menu actions

Scheduling Flow

  • Scheduling flow triggers from any enrollment entry point in the app
  • Guest users tapping enroll are prompted to sign in instead of entering the scheduling flow
  • Scheduling Step 1 ("Choose a time of day") renders the 2×2 grid and advances on selection
  • Scheduling Step 2 ("Link to a habit") filters the habit list based on Step 1 selection; "Next: Set the time" is disabled until a habit is selected; "Skip for now" exits the flow without scheduling
  • Scheduling Step 3 sets notification time with a pre-filled default; saving persists habit_anchor_id, ux_anchor_text, notification_time, and notifications_enabled = true to UserPlan
  • "Skip for now" sets notifications_enabled = false and completes enrollment without scheduling
  • If notification permissions are denied, the app prompts the user to enable them in device settings; enrollment still completes with notifications_enabled = false
  • A daily notification fires at the saved time and deep-links to the correct plan
  • Notification is cancelled when a user unenrols from a plan
  • Users can re-edit the notification time and habit anchor for an enrolled plan; the notification is rescheduled accordingly

Text Library

  • Saving a text to library calls POST /library/add; removing calls DELETE /library/remove
  • Reopening a saved text resumes at the segment saved in LibraryProgress.last_segment_id

General

  • All UI states handled: loading skeletons, empty states, error + retry
  • All three languages (English, Tibetan, Chinese) accounted for in every new text string

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    TO DO

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions