Skip to content

implement unit and lesson screens#9

Merged
Retsomm merged 2 commits into
mainfrom
dev
May 19, 2026
Merged

implement unit and lesson screens#9
Retsomm merged 2 commits into
mainfrom
dev

Conversation

@Retsomm
Copy link
Copy Markdown
Owner

@Retsomm Retsomm commented May 19, 2026

Summary by CodeRabbit

  • New Features

    • Interactive AI Teacher session with audio lessons, controls, and feedback
    • Lesson browser with Lessons/Practice tabs, unit navigation, and status indicators
    • Lesson detail screen showing objectives, phrases, vocabulary, duration, and XP
    • Reusable lesson cards for browsing and practice navigation
  • Chores

    • Expanded lesson content and unit listings across languages; added lesson art assets

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 556bdf22-c17e-4f38-998d-c616b24fd72c

📥 Commits

Reviewing files that changed from the base of the PR and between 4989e6a and 3e8ac8e.

📒 Files selected for processing (4)
  • app/(tabs)/learn.tsx
  • components/audio-teacher-session.tsx
  • constants/images.ts
  • data/lessons.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • data/lessons.ts
  • components/audio-teacher-session.tsx
  • app/(tabs)/learn.tsx

📝 Walkthrough

Walkthrough

This PR replaces placeholder tabs with a full lesson experience: generated starter lessons and expanded unit references, new lesson image assets, a reusable LessonCard, an AudioTeacherSession, a Learn screen with Lessons/Practice tabs, a Lesson Detail screen, and AI Teacher wiring selecting per-language lessons.

Changes

Lesson Learning Experience

Layer / File(s) Summary
Data population and lesson assets
data/lessons.ts, data/units.ts, constants/images.ts
Lesson dataset is extended via generator helpers (createStarterLesson, getAdditionalStarterLessons, createLanguageStarterSet), unit lessonIds arrays are expanded, and new lesson image assets are added under images.lessonArt.
LessonCard component
components/lesson-card.tsx
Re-usable card renders lesson number/title/status with accessibility, status-based styling, and conditional right-side visuals (checkmark, image, lock).
AudioTeacherSession component
components/audio-teacher-session.tsx
Session UI for AI-teacher lessons showing hero phrase, controls, feedback metrics, lesson goal, phrases list, and optional embedded tab bar; includes HeaderAction and LessonControl helpers.
Learn screen with lessons and practice tabs
app/(tabs)/learn.tsx
Browse/practice screen that reads selected language, derives units and lessons, computes lesson status, and renders segmented "Lessons" and "Practice" tabs with navigation to lesson detail via LessonCard.
Lesson detail screen
app/lesson/[lessonId].tsx
Detail view resolving lesson+unit from route params, with hero, info pills (duration/XP/mode), goals, phrases, vocabulary lists, and back navigation.
AI Teacher screen wiring
app/(tabs)/ai-teacher.tsx
Replaces placeholder with AudioTeacherSession; selects a lesson for the current language using getTeacherLesson (prefers ai-teacher or audio modes) and passes it with activeTabLabel="AI Teacher".

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant LearnScreen
  participant useLanguageStore
  participant LessonCard
  User->>LearnScreen: View Learn tab
  LearnScreen->>useLanguageStore: Read selectedLanguageId
  useLanguageStore-->>LearnScreen: Language ID
  LearnScreen->>LearnScreen: Compute unitLessons and lesson status
  LearnScreen->>LessonCard: Render with status/image
  User->>LessonCard: Tap lesson
  LessonCard->>User: Navigate to lesson detail
Loading
sequenceDiagram
  participant Router
  participant LessonDetailScreen
  participant lessons
  participant units
  Router->>LessonDetailScreen: Route to lesson/:id
  LessonDetailScreen->>lessons: Look up lesson by ID
  lessons-->>LessonDetailScreen: Lesson object
  LessonDetailScreen->>units: Look up unit by ID
  units-->>LessonDetailScreen: Unit object
  LessonDetailScreen->>LessonDetailScreen: Render hero/goals/phrases/vocab
Loading
sequenceDiagram
  participant User
  participant AiTeacherScreen
  participant useLanguageStore
  participant getTeacherLesson
  participant lessons
  participant AudioTeacherSession
  User->>AiTeacherScreen: View AI Teacher tab
  AiTeacherScreen->>useLanguageStore: Read selectedLanguageId
  useLanguageStore-->>AiTeacherScreen: Language ID
  AiTeacherScreen->>getTeacherLesson: Find lesson for language
  getTeacherLesson->>lessons: Filter by language and mode
  lessons-->>getTeacherLesson: Matching lesson
  getTeacherLesson-->>AiTeacherScreen: Selected lesson
  AiTeacherScreen->>AudioTeacherSession: Pass lesson and activeTabLabel
  AudioTeacherSession-->>User: Render lesson content
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hop through cards and phrases bright,
From Learn to lesson, morning light,
AI Teacher hums a gentle tune,
Goals and art beneath the moon,
A tiny rabbit cheers your flight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'implement unit and lesson screens' directly and accurately summarizes the main changes: new/updated screens for units and lessons including LearnScreen, LessonDetailScreen, and AudioTeacherSession.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
components/audio-teacher-session.tsx (1)

33-37: ⚡ Quick win

Avoid dynamic NativeWind class composition for metric colors.

Use inline/style values for this runtime color selection instead of interpolated class strings.

Suggested refactor
 const feedbackMetrics = [
-  { label: "Speaking", value: "Excellent", valueClassName: "text-[`#19D229`]" },
-  { label: "Pronunciation", value: "Great", valueClassName: "text-[`#2085FF`]" },
-  { label: "Grammar", value: "Good", valueClassName: "text-[`#5034FF`]" },
+  { label: "Speaking", value: "Excellent", valueColor: "`#19D229`" },
+  { label: "Pronunciation", value: "Great", valueColor: "`#2085FF`" },
+  { label: "Grammar", value: "Good", valueColor: "`#5034FF`" },
 ];
 ...
-<Text className={`font-poppins-semibold text-[18px] leading-[25px] ${metric.valueClassName}`}>
+<Text
+  className="font-poppins-semibold text-[18px] leading-[25px]"
+  style={{ color: metric.valueColor }}
+>
   {metric.value}
 </Text>

As per coding guidelines, "Use StyleSheet or inline styles instead of NativeWind classes for ... dynamic styles".

Also applies to: 189-191

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/audio-teacher-session.tsx` around lines 33 - 37, The dynamic
NativeWind class strings in feedbackMetrics (the array defined as
feedbackMetrics with objects containing valueClassName) must be replaced with
explicit inline style color values (e.g., add a color property or style object
like { color: "`#19D229`" }) and the component rendering those metrics must use
that style (instead of interpolating class names) to set the metric text color;
do the same refactor for the other occurrence that composes classes (the
rendering around the elements referenced at the other metric usage) so all
runtime color selection uses inline/style values or StyleSheet entries rather
than interpolated NativeWind class strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/`(tabs)/learn.tsx:
- Around line 142-155: unitLessons items with status "not-started" are visually
locked but still navigate because the onPress always calls router.push; update
the rendering logic in the unitLessons.map so LessonCard does not navigate when
getLessonStatus(index) === "not-started" — either pass a disabled/locked prop to
LessonCard (e.g., locked or disabled) and let LessonCard ignore taps, or wrap
the onPress so it only calls router.push({ pathname: "/lesson/[lessonId]",
params: { lessonId: lesson.id } }) when getLessonStatus(index) !==
"not-started"; refer to unitLessons.map, LessonCard, getLessonStatus, and the
onPress/router.push call to locate and change the behavior.

In `@components/audio-teacher-session.tsx`:
- Around line 129-135: The HeaderAction icon buttons (e.g., HeaderAction
iconName="videocam" and HeaderAction iconName="notifications-outline" in
components/audio-teacher-session.tsx, and the similar HeaderAction instances
around lines 231-243) are rendered as tappable but lack onPress handlers; either
wire them to the correct action handlers (e.g., openCamera/launchVideoCall and
openNotifications/showNotifications) by passing an onPress prop to HeaderAction,
or explicitly render them non-interactive/disabled (pass a disabled prop or
replace with a non-touchable View/Text and update accessibility props) so they
don’t appear tappable. Ensure accessibilityLabel and testID are set when adding
handlers.

In `@constants/images.ts`:
- Around line 39-41: Replace the hardcoded remote string assigned to
lessonArt.cafe in constants/images.ts with a require/import of a local asset and
reference that imported symbol in the centralized images object; specifically,
add an import or require for the local cafe image at the top of
constants/images.ts (e.g., import or const cafeImage = require(...)), then
change lessonArt.cafe to use that cafeImage instead of the remote uri so all
consumers import images via the centralized images object.

In `@data/lessons.ts`:
- Around line 669-705: The createLanguageStarterSet function currently accepts
rows: string[][] and uses hard-coded numeric indices (row[0]..row[13]); change
rows to a typed shape (either a named tuple type like type LessonRow =
[title:string, description:string, term1:string, translation1:string,
pronunciation1:string, example1:string, term2:string, translation2:string,
pronunciation2:string, example2:string, phrase:string, phraseTranslation:string,
phrasePronunciation:string, phraseContext:string] or an interface/object) and
update createLanguageStarterSet to accept rows: LessonRow[] and destructure each
row into named variables (e.g., const [title, description, term1, translation1,
...] = row) before calling createStarterLesson; update usages/call sites to
produce the typed tuple/object so compile-time checks catch malformed rows and
replace all row[0]..row[13] references with the new names in
createLanguageStarterSet and any related helpers such as createStarterLesson
invocation.

---

Nitpick comments:
In `@components/audio-teacher-session.tsx`:
- Around line 33-37: The dynamic NativeWind class strings in feedbackMetrics
(the array defined as feedbackMetrics with objects containing valueClassName)
must be replaced with explicit inline style color values (e.g., add a color
property or style object like { color: "`#19D229`" }) and the component rendering
those metrics must use that style (instead of interpolating class names) to set
the metric text color; do the same refactor for the other occurrence that
composes classes (the rendering around the elements referenced at the other
metric usage) so all runtime color selection uses inline/style values or
StyleSheet entries rather than interpolated NativeWind class strings.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 93364474-9547-42ac-9703-872045c29496

📥 Commits

Reviewing files that changed from the base of the PR and between a0c5627 and 4989e6a.

⛔ Files ignored due to path filters (4)
  • assets/images/ai-teacher-fox-sweater-source.png is excluded by !**/*.png
  • assets/images/ai-teacher-fox-sweater.png is excluded by !**/*.png
  • assets/images/lesson-cafe-scene.png is excluded by !**/*.png
  • assets/images/lesson-home-background.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • app/(tabs)/ai-teacher.tsx
  • app/(tabs)/learn.tsx
  • app/lesson/[lessonId].tsx
  • components/audio-teacher-session.tsx
  • components/lesson-card.tsx
  • constants/images.ts
  • data/lessons.ts
  • data/units.ts

Comment thread app/(tabs)/learn.tsx
Comment thread components/audio-teacher-session.tsx Outdated
Comment thread constants/images.ts Outdated
Comment thread data/lessons.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant