feat: improve home, setting, profile and error handling#15
feat: improve home, setting, profile and error handling#15
Conversation
QwertyMD
commented
Feb 28, 2026
- Refactor home screen to use RoutineContent component
- Move routine date logic to utils
- Create reusable SettingItem component
- Add loading and error states to profile display
- Enhance error handling in sign-in component with specific messages
- Refactor home screen to use RoutineContent component - Move routine date logic to utils - Create reusable SettingItem component - Add loading and error states to profile display - Enhance error handling in sign-in component with specific messages
There was a problem hiding this comment.
Pull request overview
This PR refactors the home and settings screens by extracting reusable UI components and centralizing routine date logic, while also improving profile loading behavior and sign-in error messaging.
Changes:
- Extracted
RoutineContentandSettingIteminto reusable components. - Moved routine date/day calculations into
lib/utils/routine.ts. - Added loading/error handling improvements for profile display and sign-in messaging.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/utils/routine.ts | Adds shared day/date helpers for routine UI. |
| lib/types/setting.ts | Introduces shared props typing for SettingItem. |
| lib/types/routine.ts | Adds props typing for RoutineContent. |
| components/sign-in.tsx | Improves toast messaging for specific sign-in errors. |
| components/setting-item.tsx | New reusable settings row component. |
| components/routine-content.tsx | New extracted routine rendering logic for home screen. |
| components/profile-display.tsx | Adds loading/error branching around profile query. |
| app/_layout.tsx | Configures global React Query defaults. |
| app/(tabs)/setting.tsx | Replaces inline settings item implementation with shared component. |
| app/(tabs)/home.tsx | Refactors home routine rendering to use shared utils/components. |
| app.json | Formats config and changes EAS project ownership identifiers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| isLast = false, | ||
| isDark = false, | ||
| }: SettingItemProps) { |
There was a problem hiding this comment.
isDark defaults to false, so if callers don’t explicitly pass it (e.g., the Settings screen after extracting this component), the icon/chevron colors will render with light-theme styling even in dark mode. Consider deriving dark mode inside the component (via useColorScheme) or making isDark required so incorrect styling can’t silently happen.
| import { TouchableOpacity, Text, View } from "react-native"; | ||
| import { TouchableOpacity, Text, View, ActivityIndicator } from "react-native"; | ||
| import Ionicons from "@expo/vector-icons/Ionicons"; | ||
| import {ProfileDisplayProps} from "@/lib/types/profile" |
There was a problem hiding this comment.
The import for ProfileDisplayProps is missing spacing and a trailing semicolon, which is inconsistent with the repo’s Biome formatting and will likely get re-written by the formatter. Please format this import to match the surrounding style.
| import {ProfileDisplayProps} from "@/lib/types/profile" | |
| import { ProfileDisplayProps } from "@/lib/types/profile"; |
| if (isLoading) return <ActivityIndicator />; | ||
|
|
||
| if (isError || !profile) { | ||
| return null; | ||
| } |
There was a problem hiding this comment.
The PR description mentions adding an error state for the profile display, but on isError this component currently returns null (same as when profile is missing). Consider rendering an explicit fallback (even a small inline message) so errors aren’t silently hidden and the loading/error states are distinguishable.
| isLoading: boolean; | ||
| routineData: RoutineData | undefined; | ||
| todayRoutine: WeekDay | undefined; |
There was a problem hiding this comment.
The new RoutineContentProps block uses spaces while the rest of this file is tab-indented. Please run the formatter (Biome) or adjust indentation for consistency to avoid noisy diffs later.
| isLoading: boolean; | |
| routineData: RoutineData | undefined; | |
| todayRoutine: WeekDay | undefined; | |
| isLoading: boolean; | |
| routineData: RoutineData | undefined; | |
| todayRoutine: WeekDay | undefined; |
| "extra": { | ||
| "router": {}, | ||
| "eas": { | ||
| "projectId": "57ef7f6c-5fc1-457a-96af-95ecc3e1ccd1" | ||
| "projectId": "4c7b89c2-7073-4c7d-b355-94ae9b09c3ce" | ||
| } | ||
| }, | ||
| "owner": "rojyqaxyl" | ||
| "owner": "walterwhite919" | ||
| } |
There was a problem hiding this comment.
Changing extra.eas.projectId and owner will repoint EAS builds/updates to a different Expo project/account. This isn’t mentioned in the PR description and is likely to break CI/CD or OTA updates for existing users. If this wasn’t intentional, revert these fields; if it was, please document why and ensure eas.json/deployment docs are updated accordingly.
| const weekDates = useMemo(() => getWeekDates(), []); | ||
| const todayRoutine = routineData?.week[activeDayIndex]; |
There was a problem hiding this comment.
weekDates is memoized with an empty dependency array, so the displayed date numbers will never update if the app stays mounted across a day/week boundary (e.g., leaving the app open overnight). Consider computing week dates per render or keying the memoization off a value that changes when the calendar day changes.
| export const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri"] as const; | ||
|
|
||
| export function getTodayIndex(): number { | ||
| const day = new Date().getDay(); | ||
| return day >= 6 ? 0 : day; | ||
| } |
There was a problem hiding this comment.
DAYS excludes Saturday but WeekDay.day includes "sat" and Date#getDay() returns 6 for Saturday. With the current logic, Saturday is forced to index 0 (Sunday), which will show the wrong routine if the API includes Saturday data. Align the DAYS list and index calculation with the actual week shape (6 vs 7 days).
| import Ionicons from "@expo/vector-icons/Ionicons"; | ||
|
|
||
| export interface SettingItemProps { | ||
| icon: keyof typeof Ionicons.glyphMap; |
There was a problem hiding this comment.
This lib/types module imports @expo/vector-icons/Ionicons as a runtime value to compute a type. Since the file only exports types/interfaces, this creates an avoidable runtime dependency (and can increase bundle size / complicate non-UI usage). Consider moving the prop type next to the component or defining the icon name type in the component using ComponentProps<typeof Ionicons>["name"] so this types file stays value-import free.
| import Ionicons from "@expo/vector-icons/Ionicons"; | |
| export interface SettingItemProps { | |
| icon: keyof typeof Ionicons.glyphMap; | |
| export interface SettingItemProps { | |
| icon: string; |