Implemented UI for workout history page#108
Conversation
📝 WalkthroughWalkthroughIntroduces a new Workout History screen featuring calendar and list view modes to display user workout history. Updates navigation routing, enhances UI components with icon support, and adds supporting drawable resources for tabs and month navigation controls. Changes
Sequence DiagramsequenceDiagram
participant User
participant ProfileViewModel as ProfileViewModel
participant NavigationRepository as NavigationRepository
participant WorkoutHistoryScreen as WorkoutHistoryScreen
participant UpliftTabRow as UpliftTabRow
participant Views as Calendar/<br/>List Views
User->>ProfileViewModel: Triggers toHistory()
ProfileViewModel->>NavigationRepository: navigate(WorkoutHistory)
NavigationRepository->>WorkoutHistoryScreen: Render Screen
WorkoutHistoryScreen->>WorkoutHistoryScreen: Collect ProfileUiState
WorkoutHistoryScreen->>UpliftTabRow: Initialize with Calendar/List tabs
User->>UpliftTabRow: Select view mode
UpliftTabRow->>Views: Render selected view (Calendar or List)
Views->>Views: Display workout history
User->>WorkoutHistoryScreen: Click back header
WorkoutHistoryScreen->>User: Navigate back via onBack()
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
app/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.kt (2)
135-141: Sort history before grouping to keep month sections and rows deterministic.
groupBypreserves encounter order, so unsorted input can produce unstable month ordering and item ordering in the list.Proposed refactor
- val groupedItems = remember(historyItems) { - historyItems.groupBy { + val groupedItems = remember(historyItems) { + historyItems + .sortedByDescending { it.timestamp } + .groupBy { val date = Instant.ofEpochMilli(it.timestamp) .atZone(ZoneId.systemDefault()) .toLocalDate() date.format(DateTimeFormatter.ofPattern("MMMM yyyy", Locale.US)) } }Also applies to: 151-169
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.kt` around lines 135 - 141, The month grouping logic in WorkoutHistoryScreen uses historyItems.groupBy which preserves input order, causing non-deterministic month and row ordering; sort historyItems by timestamp before grouping (e.g., replace uses of historyItems.groupBy in the groupedItems calculation and the other grouping at the later block with historyItems.sortedBy { it.timestamp }.groupBy { /* same date logic */ }) so both groupedItems and the other grouping produce stable, deterministic month sections and item order.
85-86: Localize UI strings and date formatting instead of hardcoding English/US values.This screen currently hardcodes user-facing labels and forces U.S. month formatting, which will render incorrectly for non-English locales.
Also applies to: 122-122, 140-140, 207-207, 235-235
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.kt` around lines 85 - 86, Replace hardcoded UI labels and US-only date formatting with localized resources and locale-aware formatters: swap the inline strings in the tabs list (currently "Calendar", "List") for string resources (e.g., R.string.calendar, R.string.list) and use those resource IDs wherever user-facing text is hardcoded (also at the other affected spots). Replace any DateTimeFormatter or SimpleDateFormat instances forced to Locale.US with a locale-aware formatter (e.g., DateTimeFormatter.ofLocalizedDate(...) or android.text.format.DateFormat.getDateFormat(context) / DateFormat.getMediumDateInstance(Locale.getDefault())) so month and date order follow the device locale; ensure the code paths that build labels (the same places referenced by tabs/icons and the other mentioned lines) read context resources and Locale.getDefault() rather than hardcoded English/US values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@app/src/main/java/com/cornellappdev/uplift/ui/components/profile/workouts/HistorySection.kt`:
- Around line 74-78: The divider condition is comparing against the full
historyItems list instead of the visible subset; fix by materializing the
displayed list (e.g., val visibleItems = historyItems.take(5)) and iterate over
visibleItems.forEachIndexed { index, historyItem -> ... } then use index !=
visibleItems.size - 1 (or index != visibleItems.lastIndex) when deciding to
render HorizontalDivider in HistorySection (affecting the
HistoryItemRow/HorizontalDivider rendering logic).
In
`@app/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.kt`:
- Around line 116-118: The tap targets for the navigation icons in
WorkoutHistoryScreen are too small (currently using Modifier.size(24.dp) or 16dp
for previous/next month controls); update each icon container (the modifiers
that call .clickable { ... } — e.g., the back action using onBack() and the
previous/next month actions) to use a 48.dp touch target (e.g.,
Modifier.size(48.dp).clickable { ... }) while keeping the visual Icon content at
24.dp so the visual size stays the same but accessibility/tap area is increased.
---
Nitpick comments:
In
`@app/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.kt`:
- Around line 135-141: The month grouping logic in WorkoutHistoryScreen uses
historyItems.groupBy which preserves input order, causing non-deterministic
month and row ordering; sort historyItems by timestamp before grouping (e.g.,
replace uses of historyItems.groupBy in the groupedItems calculation and the
other grouping at the later block with historyItems.sortedBy { it.timestamp
}.groupBy { /* same date logic */ }) so both groupedItems and the other grouping
produce stable, deterministic month sections and item order.
- Around line 85-86: Replace hardcoded UI labels and US-only date formatting
with localized resources and locale-aware formatters: swap the inline strings in
the tabs list (currently "Calendar", "List") for string resources (e.g.,
R.string.calendar, R.string.list) and use those resource IDs wherever
user-facing text is hardcoded (also at the other affected spots). Replace any
DateTimeFormatter or SimpleDateFormat instances forced to Locale.US with a
locale-aware formatter (e.g., DateTimeFormatter.ofLocalizedDate(...) or
android.text.format.DateFormat.getDateFormat(context) /
DateFormat.getMediumDateInstance(Locale.getDefault())) so month and date order
follow the device locale; ensure the code paths that build labels (the same
places referenced by tabs/icons and the other mentioned lines) read context
resources and Locale.getDefault() rather than hardcoded English/US values.
🪄 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
Run ID: 3da717f9-8788-4c45-ab99-7d970f2a0692
📒 Files selected for processing (9)
app/src/main/java/com/cornellappdev/uplift/ui/MainNavigationWrapper.ktapp/src/main/java/com/cornellappdev/uplift/ui/components/general/UpliftTabRow.ktapp/src/main/java/com/cornellappdev/uplift/ui/components/profile/workouts/HistorySection.ktapp/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.ktapp/src/main/java/com/cornellappdev/uplift/ui/viewmodels/profile/ProfileViewModel.ktapp/src/main/res/drawable/ic_advance_month.xmlapp/src/main/res/drawable/ic_back_month.xmlapp/src/main/res/drawable/ic_calendar_tab.xmlapp/src/main/res/drawable/ic_list_tab.xml
| historyItems.take(5).forEachIndexed { index, historyItem -> | ||
| HistoryItemRow(historyItem = historyItem) | ||
| if (index != historyItems.size - 1) { | ||
| HorizontalDivider(color = GRAY01) | ||
| HorizontalDivider(color = GRAY01, thickness = 1.dp) | ||
| } |
There was a problem hiding this comment.
Divider condition uses the wrong collection length.
Line 76 compares against historyItems.size - 1, but rendering is over historyItems.take(5). When there are more than 5 items, this adds a trailing divider after the last visible row.
Proposed fix
fun HistoryList(
historyItems: List<HistoryItem>,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
- historyItems.take(5).forEachIndexed { index, historyItem ->
+ val visibleItems = historyItems.take(5)
+ visibleItems.forEachIndexed { index, historyItem ->
HistoryItemRow(historyItem = historyItem)
- if (index != historyItems.size - 1) {
+ if (index != visibleItems.lastIndex) {
HorizontalDivider(color = GRAY01, thickness = 1.dp)
}
}
}
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@app/src/main/java/com/cornellappdev/uplift/ui/components/profile/workouts/HistorySection.kt`
around lines 74 - 78, The divider condition is comparing against the full
historyItems list instead of the visible subset; fix by materializing the
displayed list (e.g., val visibleItems = historyItems.take(5)) and iterate over
visibleItems.forEachIndexed { index, historyItem -> ... } then use index !=
visibleItems.size - 1 (or index != visibleItems.lastIndex) when deciding to
render HorizontalDivider in HistorySection (affecting the
HistoryItemRow/HorizontalDivider rendering logic).
| modifier = Modifier | ||
| .size(24.dp) | ||
| .clickable { onBack() }, |
There was a problem hiding this comment.
Increase tap targets for icon actions to improve accessibility.
Back/month navigation actions are attached to 24dp/16dp icons, which are hard to tap reliably.
Proposed fix
- Icon(
- painter = painterResource(id = R.drawable.ic_back_arrow),
- contentDescription = "Back",
- modifier = Modifier
- .size(24.dp)
- .clickable { onBack() },
- tint = PRIMARY_BLACK
- )
+ Box(
+ modifier = Modifier
+ .size(48.dp)
+ .clickable { onBack() },
+ contentAlignment = Alignment.Center
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.ic_back_arrow),
+ contentDescription = "Back",
+ modifier = Modifier.size(24.dp),
+ tint = PRIMARY_BLACK
+ )
+ }Apply the same 48dp touch-target pattern to previous/next month controls.
Also applies to: 200-203, 219-222
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@app/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.kt`
around lines 116 - 118, The tap targets for the navigation icons in
WorkoutHistoryScreen are too small (currently using Modifier.size(24.dp) or 16dp
for previous/next month controls); update each icon container (the modifiers
that call .clickable { ... } — e.g., the back action using onBack() and the
previous/next month actions) to use a 48.dp touch target (e.g.,
Modifier.size(48.dp).clickable { ... }) while keeping the visual Icon content at
24.dp so the visual size stays the same but accessibility/tap area is increased.
Overview
Implemented the Workout History Page UI according to figma designs.
Changes Made
Implemented Calendar and List tab views of workout history.
Added nav from profile page to workout history page.
Next Steps
Build the workout history viewmodel and implement the drop down info functionality on days where a workout is logged according to designs.
Finish nav and networking.
Test once real workouts are logged.
Screenshots
Workout History UI Preview
WorkoutHistoryUiPreview.mp4
Summary by CodeRabbit