Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 17 minutes and 25 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (11)
📝 WalkthroughWalkthroughAdds housing as a new activity category: extends the activities hook to accept an optional category, filters housing out of the main activities list, and introduces housing routes and UI (entry sheet, manual form, card, tab content) with navigation and authentication handling. Changes
Sequence DiagramsequenceDiagram
actor User
participant UI as HousingTabContent
participant Entry as AddHousingEntrySheet
participant Manual as AddHousingManualSheet
participant API as Activity API
participant Store as QueryClient/List
User->>UI: Open housing tab
UI->>API: Fetch housing activities (category="housing")
API-->>UI: Return list
UI->>Store: Render list
User->>UI: Tap "Add a housing option"
UI->>Entry: Open entry sheet
User->>Entry: Paste link
Entry->>API: parseActivityLink(tripID, url)
API-->>Entry: Parsed data
Entry->>Manual: Open manual sheet with prefill
User->>Manual: Fill form (price, dates, location) and save
Manual->>API: createActivity(tripID, payload with category_names:["housing"])
API-->>Manual: Created activity
Manual->>UI: onSaved callback (new activity)
UI->>Store: Prepend activity to list / update query cache
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/app/(app)/trips/[id]/activities/components/activities-tab-content.tsx (1)
236-239:⚠️ Potential issue | 🟡 MinorCount displays total activities, not filtered count.
The header shows
activities.lengthbut the list renderssortedActivitieswhich excludes housing. If any housing items exist, users will see a higher count than the actual number of visible items.Proposed fix
<Text variant="bodyDefault" color="gray500"> - {activities.length}{" "} - {activities.length === 1 ? "option" : "options"} added + {sortedActivities.length}{" "} + {sortedActivities.length === 1 ? "option" : "options"} added </Text>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/`(app)/trips/[id]/activities/components/activities-tab-content.tsx around lines 236 - 239, The header currently shows the total activities count using activities.length while the rendered list uses sortedActivities (which excludes housing), causing a mismatch; update the displayed count to reflect the visible/filtered items by using sortedActivities.length (or compute a visibleCount variable derived from sortedActivities) in the Text component, ensuring the pluralization logic (activities.length === 1 ? "option" : "options") also uses that same visible count.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@frontend/app/`(app)/trips/[id]/activities/components/activities-tab-content.tsx:
- Around line 116-122: Indentation for the useMemo block is inconsistent; adjust
the formatting of the sortedActivities useMemo so its body and return lines
follow the same indentation style as the rest of the file (match surrounding
2-space or 4-space convention). Locate the sortedActivities constant and the
useMemo callback (references: sortedActivities, useMemo, nonHousing, activities,
sortOrder) and reformat the callback opening, inner lines (filter, if, return)
and closing brace to use the file's standard indentation level so the block
visually aligns with neighboring code.
In `@frontend/app/`(app)/trips/[id]/housing/_layout.tsx:
- Around line 22-39: The Stack.Screen entries for the "index" and "[id]" routes
include redundant options (headerTitle and headerTransparent) that have no
effect when headerShown is false; edit the options objects for the Stack.Screen
components named "index" and "[id]" to remove headerTitle and headerTransparent,
leaving headerShown: false and gestureEnabled as-is so the screen configurations
are minimal and correct.
In
`@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx:
- Around line 298-327: The styles object contains hard-coded spacing and
typography numbers; update the StyleSheet (symbols: styles, formRows, formRow,
formRowInput, formRowInputEmpty, formRowInputFilled, formRowPlaceholder,
formRowValue) to use centralized design-system tokens instead of literals (e.g.,
replace 16, 8, 20, 0 and any fontFamily/fontSize values with your design
system's spacing and typography tokens like spacing.* and typography.* or
FontSizes/LineHeights constants), import those token constants and apply them in
each style entry so spacing, fontSize, lineHeight and padding use the shared
tokens rather than magic numbers.
- Around line 115-117: The catch block that currently only calls
setLocationName(prediction.description ?? null) leaves stale coordinates if a
prior selection set locationLat/locationLng; update the catch to also clear
those coordinates by calling setLocationLat(null) and setLocationLng(null)
alongside setLocationName so lat/lng cannot be submitted for a failed
place-details lookup (locate the catch in add-housing-manual-sheet.tsx where
setLocationName is called).
- Around line 138-139: The code currently formats calendar dates using
dateRange.start.toISOString().split("T")[0] and
dateRange.end.toISOString().split("T")[0], which converts to UTC and can shift
the local calendar day; update the serialization to build YYYY-MM-DD from the
local date parts instead (use dateRange.start.getFullYear(), getMonth()+1,
getDate() and similarly for dateRange.end), zero-pad month/day to two digits or
add a small helper like formatLocalDate(Date) and use that for the start and end
fields so the API receives the local calendar date.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-card.tsx:
- Around line 26-27: The thumbnailUrl and proposedBy props are mapped to
incorrect fields on the housing object; update the JSX where
thumbnailUrl={housing.thumbnail_url ?? undefined} and
proposedBy={housing.proposed_by ?? undefined} to use housing.media_url for
thumbnailUrl and housing.proposer_name for proposedBy (preserving the ??
undefined fallback) so the card shows the correct media and display name.
- Line 33: housing.comment_previews is typed as ModelsCommenterPreview[] (which
lacks created_at) but EntityCard expects CommentPreview[] and reads
commentPreviews[0]?.created_at; fix by aligning types or transforming the data
before passing. Two options: 1) update
ModelsActivityAPIResponse.comment_previews (and ModelsCommenterPreview) to
include created_at where the API actually provides it; or 2) map
housing.comment_previews to a CommentPreview shape before passing to EntityCard
(e.g., copy fields and add created_at: preview.created_at ?? undefined or a
parsed timestamp) so EntityCard receives CommentPreview[]; reference symbols:
housing.comment_previews, ModelsCommenterPreview,
ModelsActivityAPIResponse.comment_previews, CommentPreview, EntityCard,
formatCommentTimeLabel.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-tab-content.tsx:
- Line 79: The variable toast returned from useToast is declared but never used;
remove the unused call and related import: delete the line "const toast =
useToast();" in the HousingTabContent component (and remove the useToast import
if it exists at the top of the file) so no unused variable or import remains.
---
Outside diff comments:
In
`@frontend/app/`(app)/trips/[id]/activities/components/activities-tab-content.tsx:
- Around line 236-239: The header currently shows the total activities count
using activities.length while the rendered list uses sortedActivities (which
excludes housing), causing a mismatch; update the displayed count to reflect the
visible/filtered items by using sortedActivities.length (or compute a
visibleCount variable derived from sortedActivities) in the Text component,
ensuring the pluralization logic (activities.length === 1 ? "option" :
"options") also uses that same visible count.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: fe83eefa-0987-4f91-8935-3e0c82237c20
⛔ Files ignored due to path filters (1)
frontend/assets/images/house.pngis excluded by!**/*.png
📒 Files selected for processing (10)
frontend/api/activities/custom/useActivitiesList.tsfrontend/app/(app)/trips/[id]/_layout.tsxfrontend/app/(app)/trips/[id]/activities/[id]/index.tsxfrontend/app/(app)/trips/[id]/activities/components/activities-tab-content.tsxfrontend/app/(app)/trips/[id]/housing/_layout.tsxfrontend/app/(app)/trips/[id]/housing/components/add-housing-entry-sheet.tsxfrontend/app/(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsxfrontend/app/(app)/trips/[id]/housing/components/housing-card.tsxfrontend/app/(app)/trips/[id]/housing/components/housing-tab-content.tsxfrontend/app/(app)/trips/[id]/index.tsx
| <Stack.Screen | ||
| name="index" | ||
| options={{ | ||
| headerShown: false, | ||
| headerTitle: "", | ||
| headerTransparent: true, | ||
| gestureEnabled: false, | ||
| }} | ||
| /> | ||
| <Stack.Screen | ||
| name="[id]" | ||
| options={{ | ||
| headerShown: false, | ||
| headerTitle: "", | ||
| headerTransparent: true, | ||
| gestureEnabled: false, | ||
| }} | ||
| /> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Redundant options when headerShown: false.
For the index and [id] screens, headerTitle and headerTransparent are set but have no effect when headerShown: false. This is not a bug, just unnecessary configuration.
Optional cleanup
<Stack.Screen
name="index"
options={{
headerShown: false,
- headerTitle: "",
- headerTransparent: true,
gestureEnabled: false,
}}
/>
<Stack.Screen
name="[id]"
options={{
headerShown: false,
- headerTitle: "",
- headerTransparent: true,
gestureEnabled: false,
}}
/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Stack.Screen | |
| name="index" | |
| options={{ | |
| headerShown: false, | |
| headerTitle: "", | |
| headerTransparent: true, | |
| gestureEnabled: false, | |
| }} | |
| /> | |
| <Stack.Screen | |
| name="[id]" | |
| options={{ | |
| headerShown: false, | |
| headerTitle: "", | |
| headerTransparent: true, | |
| gestureEnabled: false, | |
| }} | |
| /> | |
| <Stack.Screen | |
| name="index" | |
| options={{ | |
| headerShown: false, | |
| gestureEnabled: false, | |
| }} | |
| /> | |
| <Stack.Screen | |
| name="[id]" | |
| options={{ | |
| headerShown: false, | |
| gestureEnabled: false, | |
| }} | |
| /> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/app/`(app)/trips/[id]/housing/_layout.tsx around lines 22 - 39, The
Stack.Screen entries for the "index" and "[id]" routes include redundant options
(headerTitle and headerTransparent) that have no effect when headerShown is
false; edit the options objects for the Stack.Screen components named "index"
and "[id]" to remove headerTitle and headerTransparent, leaving headerShown:
false and gestureEnabled as-is so the screen configurations are minimal and
correct.
| } catch { | ||
| setLocationName(prediction.description ?? null); | ||
| } |
There was a problem hiding this comment.
Clear stale coordinates when place-details lookup fails
On Line 115-117, fallback only updates locationName. If a previous selection set locationLat/locationLng, those stale coordinates remain and can be submitted with a different name.
Proposed fix
} catch {
setLocationName(prediction.description ?? null);
+ setLocationLat(null);
+ setLocationLng(null);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } catch { | |
| setLocationName(prediction.description ?? null); | |
| } | |
| } catch { | |
| setLocationName(prediction.description ?? null); | |
| setLocationLat(null); | |
| setLocationLng(null); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx
around lines 115 - 117, The catch block that currently only calls
setLocationName(prediction.description ?? null) leaves stale coordinates if a
prior selection set locationLat/locationLng; update the catch to also clear
those coordinates by calling setLocationLat(null) and setLocationLng(null)
alongside setLocationName so lat/lng cannot be submitted for a failed
place-details lookup (locate the catch in add-housing-manual-sheet.tsx where
setLocationName is called).
| start: dateRange.start.toISOString().split("T")[0]!, | ||
| end: dateRange.end.toISOString().split("T")[0]!, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find and examine the file
find . -type f -name "add-housing-manual-sheet.tsx" | head -5Repository: GenerateNU/toggo
Length of output: 139
🏁 Script executed:
# Verify the JavaScript Date.toISOString() behavior with a simple test
node << 'EOF'
// Test the toISOString behavior
const testDate = new Date("2024-01-15T00:00:00");
console.log("Test date object:", testDate);
console.log("toISOString():", testDate.toISOString());
console.log("split result:", testDate.toISOString().split("T")[0]);
console.log("getFullYear():", testDate.getFullYear());
console.log("getMonth():", testDate.getMonth() + 1);
console.log("getDate():", testDate.getDate());
// Test with timezone-aware scenario
const d = new Date();
console.log("\nCurrent date object:", d);
console.log("toISOString() result:", d.toISOString());
console.log("Local date methods - Y/M/D:", d.getFullYear(), d.getMonth() + 1, d.getDate());
EOFRepository: GenerateNU/toggo
Length of output: 347
🏁 Script executed:
# Read the file around lines 138-139 to confirm the code
sed -n '130,150p' ./frontend/app/\(app\)/trips/\[id\]/housing/components/add-housing-manual-sheet.tsxRepository: GenerateNU/toggo
Length of output: 630
🏁 Script executed:
# Let's examine more context around the dateRange to understand how it's being used
sed -n '100,160p' ./frontend/app/\(app\)/trips/\[id\]/housing/components/add-housing-manual-sheet.tsxRepository: GenerateNU/toggo
Length of output: 1837
🏁 Script executed:
# Check the Date type and where dateRange comes from
grep -n "dateRange" ./frontend/app/\(app\)/trips/\[id\]/housing/components/add-housing-manual-sheet.tsx | head -20Repository: GenerateNU/toggo
Length of output: 421
🏁 Script executed:
# Check the DateRange type definition
rg "type DateRange|interface DateRange" --type ts --type tsx -A 5Repository: GenerateNU/toggo
Length of output: 87
🏁 Script executed:
# Look at the top of the file to see imports and type definitions
head -70 ./frontend/app/\(app\)/trips/\[id\]/housing/components/add-housing-manual-sheet.tsxRepository: GenerateNU/toggo
Length of output: 2585
🏁 Script executed:
# Check the types to understand what dates format is expected by the API
rg "dates" ./frontend/app/\(app\)/trips/\[id\]/housing/components/add-housing-manual-sheet.tsx -B 2 -A 2 | grep -A 5 -B 5 "dates"Repository: GenerateNU/toggo
Length of output: 524
🏁 Script executed:
# Check the API types to see what format dates should be in
find . -type f -name "*.gen.ts" -o -name "types.ts" | xargs grep -l "ActivityAPI\|ParsedActivityData" | head -3Repository: GenerateNU/toggo
Length of output: 190
🏁 Script executed:
# Check the schema to understand the dates field format
rg "dates" ./frontend/types/schema.gen.ts -B 3 -A 3 | head -40Repository: GenerateNU/toggo
Length of output: 926
🏁 Script executed:
# Look at the activity-related types
rg "Activity.*API\|ParsedActivity" ./frontend/types/schema.gen.ts -A 10 | head -60Repository: GenerateNU/toggo
Length of output: 42
🏁 Script executed:
# Find the modelsDateRangeSchema definition
rg "modelsDateRangeSchema" ./frontend/types/schema.gen.ts -B 2 -A 5 | head -20Repository: GenerateNU/toggo
Length of output: 735
🏁 Script executed:
# Search for DateRange interface/type definition
rg "DateRange" ./frontend/design-system -B 2 -A 5 | head -40Repository: GenerateNU/toggo
Length of output: 3018
🏁 Script executed:
# Let's verify the timezone issue more thoroughly with a practical example
node << 'EOF'
// Simulate the timezone issue
const testCases = [
{ tz: "UTC+8", offset: 8 },
{ tz: "UTC-5", offset: -5 },
{ tz: "UTC+0", offset: 0 }
];
// Create a date representing midnight on Jan 15
const baseDate = new Date(2024, 0, 15, 0, 0, 0, 0);
console.log("Original date object (Jan 15 midnight):");
console.log("toISOString():", baseDate.toISOString());
console.log("split result:", baseDate.toISOString().split("T")[0]);
console.log("Using local methods - getFullYear/Month/Date:",
baseDate.getFullYear(),
(baseDate.getMonth() + 1).toString().padStart(2, '0'),
baseDate.getDate().toString().padStart(2, '0'));
console.log("\n--- The Issue ---");
console.log("In UTC+8 timezone, Jan 15 midnight local is Jan 14 at 4 PM UTC");
console.log("In UTC-5 timezone, Jan 15 midnight local is Jan 15 at 5 AM UTC");
console.log("\nToISO always returns UTC. If in UTC+X (east), previous day in UTC.");
console.log("The proposed fix correctly uses getDate() which gives local date.\n");
// Verify the proposed fix format
const toLocalISODate = (d) => {
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${y}-${m}-${day}`;
};
console.log("Proposed fix result:", toLocalISODate(baseDate));
EOFRepository: GenerateNU/toggo
Length of output: 533
🏁 Script executed:
# Search for other uses of toISOString() in the codebase that might have the same issue
rg "toISOString\(\)" ./frontend --type ts --type jsx -B 2 -A 2 | head -80Repository: GenerateNU/toggo
Length of output: 87
🏁 Script executed:
# Check if there are other timezone-related date issues in the codebase
rg "toISOString" ./frontend -l | head -20Repository: GenerateNU/toggo
Length of output: 766
🏁 Script executed:
# Check if other files use toISOString().split("T")[0] pattern
rg 'toISOString\(\)\.split\("T"\)\[0\]' ./frontendRepository: GenerateNU/toggo
Length of output: 901
🏁 Script executed:
# Look at the edit-dates file to see if it has the same pattern
rg "toISOString" ./frontend/app/\(app\)/trips/\[id\]/settings/edit-dates.tsx -B 3 -A 3Repository: GenerateNU/toggo
Length of output: 552
Use local date methods instead of toISOString() for calendar dates
Lines 138-139 extract calendar dates using toISOString().split("T")[0], which converts the local Date to UTC first. This causes the saved date to shift by one day in some timezones (e.g., UTC+8 would save Jan 14 instead of Jan 15). The API expects the local calendar date in YYYY-MM-DD format. Use getFullYear(), getMonth(), and getDate() to extract the local date instead.
Proposed fix
+ const toLocalISODate = (d: Date) => {
+ const y = d.getFullYear();
+ const m = String(d.getMonth() + 1).padStart(2, "0");
+ const day = String(d.getDate()).padStart(2, "0");
+ return `${y}-${m}-${day}`;
+ };
+
const dates =
dateRange.start && dateRange.end
? [
{
- start: dateRange.start.toISOString().split("T")[0]!,
- end: dateRange.end.toISOString().split("T")[0]!,
+ start: toLocalISODate(dateRange.start),
+ end: toLocalISODate(dateRange.end),
},
]
: undefined;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| start: dateRange.start.toISOString().split("T")[0]!, | |
| end: dateRange.end.toISOString().split("T")[0]!, | |
| const toLocalISODate = (d: Date) => { | |
| const y = d.getFullYear(); | |
| const m = String(d.getMonth() + 1).padStart(2, "0"); | |
| const day = String(d.getDate()).padStart(2, "0"); | |
| return `${y}-${m}-${day}`; | |
| }; | |
| const dates = | |
| dateRange.start && dateRange.end | |
| ? [ | |
| { | |
| start: toLocalISODate(dateRange.start), | |
| end: toLocalISODate(dateRange.end), | |
| }, | |
| ] | |
| : undefined; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx
around lines 138 - 139, The code currently formats calendar dates using
dateRange.start.toISOString().split("T")[0] and
dateRange.end.toISOString().split("T")[0], which converts to UTC and can shift
the local calendar day; update the serialization to build YYYY-MM-DD from the
local date parts instead (use dateRange.start.getFullYear(), getMonth()+1,
getDate() and similarly for dateRange.end), zero-pad month/day to two digits or
add a small helper like formatLocalDate(Date) and use that for the start and end
fields so the API receives the local calendar date.
| const styles = StyleSheet.create({ | ||
| formRows: { | ||
| gap: 16, | ||
| }, | ||
| formRow: { | ||
| flexDirection: "row", | ||
| alignItems: "center", | ||
| gap: 8, | ||
| }, | ||
| formRowPlaceholder: { | ||
| color: ColorPalette.blue500, | ||
| flex: 1, | ||
| }, | ||
| formRowValue: { | ||
| color: ColorPalette.gray700, | ||
| flex: 1, | ||
| }, | ||
| formRowInput: { | ||
| flex: 1, | ||
| fontFamily: FontFamily.semiBold, | ||
| fontSize: 16, | ||
| lineHeight: 20, | ||
| paddingVertical: 0, | ||
| }, | ||
| formRowInputEmpty: { | ||
| color: ColorPalette.blue500, | ||
| }, | ||
| formRowInputFilled: { | ||
| color: ColorPalette.gray700, | ||
| }, |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Replace style magic numbers with design-system tokens
Line 298-327 hard-codes spacing and typography numbers (16, 8, 20, 0). Move these to centralized design-system tokens to keep consistency and avoid drift.
As per coding guidelines, React/Expo UI must use a centralized design system; avoid hard-coded color values, magic spacing numbers, and duplicated style definitions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx
around lines 298 - 327, The styles object contains hard-coded spacing and
typography numbers; update the StyleSheet (symbols: styles, formRows, formRow,
formRowInput, formRowInputEmpty, formRowInputFilled, formRowPlaceholder,
formRowValue) to use centralized design-system tokens instead of literals (e.g.,
replace 16, 8, 20, 0 and any fontFamily/fontSize values with your design
system's spacing and typography tokens like spacing.* and typography.* or
FontSizes/LineHeights constants), import those token constants and apply them in
each style entry so spacing, fontSize, lineHeight and padding use the shared
tokens rather than magic numbers.
| thumbnailUrl={housing.thumbnail_url ?? undefined} | ||
| proposedBy={housing.proposed_by ?? undefined} |
There was a problem hiding this comment.
Incorrect field mappings for thumbnailUrl and proposedBy.
ModelsActivityAPIResponse includes fields like media_url, proposed_by, proposer_name, and proposer_picture_url. The type does not define a thumbnail_url field. Additionally, proposed_by is the user ID, not the display name.
thumbnailUrlshould usehousing.media_urlproposedByshould usehousing.proposer_name
Proposed fix
- thumbnailUrl={housing.thumbnail_url ?? undefined}
- proposedBy={housing.proposed_by ?? undefined}
+ thumbnailUrl={housing.media_url ?? undefined}
+ proposedBy={housing.proposer_name ?? undefined}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| thumbnailUrl={housing.thumbnail_url ?? undefined} | |
| proposedBy={housing.proposed_by ?? undefined} | |
| thumbnailUrl={housing.media_url ?? undefined} | |
| proposedBy={housing.proposer_name ?? undefined} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-card.tsx around
lines 26 - 27, The thumbnailUrl and proposedBy props are mapped to incorrect
fields on the housing object; update the JSX where
thumbnailUrl={housing.thumbnail_url ?? undefined} and
proposedBy={housing.proposed_by ?? undefined} to use housing.media_url for
thumbnailUrl and housing.proposer_name for proposedBy (preserving the ??
undefined fallback) so the card shows the correct media and display name.
| priceLabel={priceLabel} | ||
| actionButton={null} | ||
| commentCount={housing.comment_count ?? 0} | ||
| commentPreviews={housing.comment_previews ?? []} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if EntityCard handles missing created_at gracefully
rg -nA5 'formatCommentTimeLabel' frontend/app/\(app\)/trips/\[id\]/components/entity-card.tsxRepository: GenerateNU/toggo
Length of output: 453
🏁 Script executed:
# Find the definition of ModelsCommenterPreview or CommentPreview
rg -n 'ModelsCommenterPreview|interface CommentPreview|type CommentPreview' --type ts --type tsxRepository: GenerateNU/toggo
Length of output: 87
🏁 Script executed:
# Check the housing-card.tsx file around line 33 to see the actual prop
cat -n frontend/app/\(app\)/trips/\[id\]/housing/components/housing-card.tsx | head -50Repository: GenerateNU/toggo
Length of output: 1451
🏁 Script executed:
# Check the EntityCard component's prop types
rg -nB5 -A15 'interface.*Props|type.*Props' frontend/app/\(app\)/trips/\[id\]/components/entity-card.tsx | head -50Repository: GenerateNU/toggo
Length of output: 641
🏁 Script executed:
# Find ModelsActivityAPIResponse definition
rg -n 'ModelsActivityAPIResponse' --type ts | grep -i 'interface\|type'Repository: GenerateNU/toggo
Length of output: 2569
🏁 Script executed:
# Look for the types.gen file
fd 'types.gen' -t fRepository: GenerateNU/toggo
Length of output: 87
🏁 Script executed:
# Check if there's a ModelsCommenterPreview type
rg -n 'ModelsCommenterPreview' --type tsRepository: GenerateNU/toggo
Length of output: 705
🏁 Script executed:
# Check ModelsCommenterPreview definition in types.gen.ts
sed -n '101,120p' frontend/types/types.gen.tsRepository: GenerateNU/toggo
Length of output: 408
🏁 Script executed:
# Also verify the CommentPreview type definition in entity-card.tsx
sed -n '10,20p' frontend/app/\(app\)/trips/\[id\]/components/entity-card.tsxRepository: GenerateNU/toggo
Length of output: 318
Type mismatch: housing.comment_previews is ModelsCommenterPreview[] but EntityCard expects CommentPreview[].
ModelsCommenterPreview does not include the created_at field, while EntityCard attempts to access commentPreviews[0]?.created_at. The code uses a type assertion to work around this mismatch, and formatCommentTimeLabel gracefully returns an empty string for missing timestamps, so it won't crash—but comment timestamps will not display.
Align the types by either updating ModelsActivityAPIResponse.comment_previews to include created_at, or transform the data before passing to EntityCard.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-card.tsx at line
33, housing.comment_previews is typed as ModelsCommenterPreview[] (which lacks
created_at) but EntityCard expects CommentPreview[] and reads
commentPreviews[0]?.created_at; fix by aligning types or transforming the data
before passing. Two options: 1) update
ModelsActivityAPIResponse.comment_previews (and ModelsCommenterPreview) to
include created_at where the API actually provides it; or 2) map
housing.comment_previews to a CommentPreview shape before passing to EntityCard
(e.g., copy fields and add created_at: preview.created_at ?? undefined or a
parsed timestamp) so EntityCard receives CommentPreview[]; reference symbols:
housing.comment_previews, ModelsCommenterPreview,
ModelsActivityAPIResponse.comment_previews, CommentPreview, EntityCard,
formatCommentTimeLabel.
| >(({ tripID }, ref) => { | ||
| const entrySheetRef = useRef<AddHousingEntrySheetHandle>(null); | ||
| const manualSheetRef = useRef<AddHousingManualSheetHandle>(null); | ||
| const toast = useToast(); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Unused variable: toast is declared but never used.
The useToast hook is called but the result is never used in this component.
Remove unused import and variable
Box,
Button,
EmptyState,
SkeletonRect,
Text,
- useToast,
} from "@/design-system"; const entrySheetRef = useRef<AddHousingEntrySheetHandle>(null);
const manualSheetRef = useRef<AddHousingManualSheetHandle>(null);
- const toast = useToast();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const toast = useToast(); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-tab-content.tsx at
line 79, The variable toast returned from useToast is declared but never used;
remove the unused call and related import: delete the line "const toast =
useToast();" in the HousingTabContent component (and remove the useToast import
if it exists at the top of the file) so no unused variable or import remains.
2bc95a1 to
8d124f9
Compare
|
|
||
| return ( | ||
| <> | ||
| <AddItemManualSheet |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontend/app/(app)/trips/[id]/activities/components/activities-tab-content.tsx (1)
220-238:⚠️ Potential issue | 🟠 MajorActivity count does not match displayed list.
Line 220 checks
activities.length === 0for the empty state, and lines 237-238 displayactivities.lengthas the count. However, the FlatList at line 252 renderssortedActivities, which excludes housing. If a trip has only housing activities, the list appears empty but the count is non-zero and no empty state is shown.Use
sortedActivities.lengthfor both the empty state check and the displayed count.Proposed fix
- ) : activities.length === 0 ? ( + ) : sortedActivities.length === 0 ? ( <Box alignItems="center" justifyContent="center" paddingVertical="xl"> <EmptyState title="No activities yet" description="Tap + to add the first one!" /> </Box> ) : ( <> {/* Header row: count + sort toggle */} <Box flexDirection="row" justifyContent="space-between" alignItems="center" style={styles.headerRow} > <Text variant="bodyDefault" color="gray500"> - {activities.length}{" "} - {activities.length === 1 ? "option" : "options"} added + {sortedActivities.length}{" "} + {sortedActivities.length === 1 ? "option" : "options"} added </Text>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/`(app)/trips/[id]/activities/components/activities-tab-content.tsx around lines 220 - 238, The UI uses activities.length for the empty-state check and the header count while the list actually renders sortedActivities (which excludes housing), causing a mismatch; replace usages of activities.length in the empty-state conditional and the header Text that shows the count with sortedActivities.length so the EmptyState, count display in the header (the Text inside the headerRow) and the FlatList (which renders sortedActivities) are consistent; update the conditional that currently reads activities.length === 0 and the displayed count expression to use sortedActivities.length instead.frontend/api/activities/custom/useActivitiesList.ts (1)
88-95:⚠️ Potential issue | 🔴 CriticalBreaking change:
refetchremoved from hook return.The
refetchfunction is no longer returned fromuseActivitiesList, butfrontend/app/(app)/trips/[id]/activities/index.tsxdestructures and calls it (lines 43, 56). This will cause a runtime error during activity creation.Either restore
refetchin the return object or remove it from all callers.Proposed fix to restore refetch
const { data, isLoading, isFetchingNextPage, fetchNextPage, hasNextPage, isError, + refetch, } = useInfiniteQuery({ // ... }); return { activities, isLoading, isError, isLoadingMore: isFetchingNextPage, fetchMore, prependActivity, + refetch, };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/api/activities/custom/useActivitiesList.ts` around lines 88 - 95, The hook useActivitiesList no longer returns the refetch function but callers (e.g., the component that destructures useActivitiesList and calls refetch) still expect it; restore compatibility by adding refetch to the hook's returned object and map it to the refetch function produced by your query (the refetch from useInfiniteQuery / the internal refetch variable), i.e., include "refetch" alongside activities, isLoading, isError, isLoadingMore, fetchMore, prependActivity so existing callers keep working.
♻️ Duplicate comments (5)
frontend/app/(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx (3)
134-142:⚠️ Potential issue | 🟠 MajorTimezone drift when formatting dates.
Lines 138-139 use
toISOString().split("T")[0]which converts to UTC first. In timezones east of UTC, this shifts the date back by one day. Use local date methods instead.Proposed fix
+ const toLocalISODate = (d: Date) => { + const y = d.getFullYear(); + const m = String(d.getMonth() + 1).padStart(2, "0"); + const day = String(d.getDate()).padStart(2, "0"); + return `${y}-${m}-${day}`; + }; + const dates = dateRange.start && dateRange.end ? [ { - start: dateRange.start.toISOString().split("T")[0]!, - end: dateRange.end.toISOString().split("T")[0]!, + start: toLocalISODate(dateRange.start), + end: toLocalISODate(dateRange.end), }, ] : undefined;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx around lines 134 - 142, The date formatting for the dates array uses toISOString().split("T")[0] which converts the Date to UTC and causes timezone drift; update the logic in the dates construction (where dateRange.start and dateRange.end are used) to format using local date components (e.g., getFullYear(), getMonth()+1, getDate()) or a locale-safe formatter so the produced "YYYY-MM-DD" reflects the local date instead of converting to UTC. Ensure both dateRange.start and dateRange.end are handled the same way and preserve the existing array shape when assigning to the dates constant.
298-327: 🛠️ Refactor suggestion | 🟠 MajorReplace magic numbers with design-system tokens.
Lines 300, 305, 318-320 use hardcoded spacing and typography values (16, 8, 20, 0) instead of centralized design-system tokens. As per coding guidelines, avoid hard-coded magic spacing numbers.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx around lines 298 - 327, Replace the hardcoded numeric values in the StyleSheet with design-system tokens: change gap: 16 in styles.formRows to the appropriate spacing token (e.g., Spacing.md), gap: 8 in styles.formRow to the smaller spacing token (e.g., Spacing.sm), lineHeight: 20 in styles.formRowInput to the corresponding typography token (e.g., Typography.lineHeightBase) and paddingVertical: 0 to the design token for vertical padding (e.g., Spacing.none or Padding.none); update styles.formRowInputEmpty/formRowInputFilled only if they rely on explicit numeric values—use existing ColorPalette and FontFamily tokens already imported. Ensure you import or reference the correct token names used across the codebase and replace each numeric literal in the formRows/formRow/formRowInput blocks accordingly.
115-117:⚠️ Potential issue | 🟠 MajorStale coordinates not cleared on place-details failure.
When
getPlaceDetailsCustomfails, onlylocationNameis updated. If a previous selection setlocationLat/locationLng, those stale coordinates remain and can be submitted with a mismatched name.Proposed fix
} catch { setLocationName(prediction.description ?? null); + setLocationLat(null); + setLocationLng(null); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx around lines 115 - 117, The catch block after calling getPlaceDetailsCustom only sets setLocationName(prediction.description ?? null) and leaves any previously set coordinates (locationLat/locationLng) intact; update the failure path in add-housing-manual-sheet.tsx so that when getPlaceDetailsCustom fails you also clear the stale coordinates by calling the corresponding setters (e.g., setLocationLat(null) and setLocationLng(null) or the app's equivalent) alongside updating locationName to avoid submitting mismatched name/coords.frontend/app/(app)/trips/[id]/housing/_layout.tsx (1)
22-39: 🧹 Nitpick | 🔵 TrivialRedundant options when header is hidden.
For the
indexand[id]screens,headerTitleandheaderTransparenthave no effect whenheaderShown: false. This adds unnecessary configuration.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/`(app)/trips/[id]/housing/_layout.tsx around lines 22 - 39, The screen option objects for the Stack.Screen entries named "index" and "[id]" include redundant properties: when headerShown is false, headerTitle and headerTransparent are ignored; remove headerTitle and headerTransparent from the options for both Stack.Screen declarations and keep only the required options (e.g., headerShown: false and gestureEnabled: false) to simplify the config and avoid clutter.frontend/app/(app)/trips/[id]/housing/components/housing-card.tsx (1)
25-28:⚠️ Potential issue | 🟠 MajorMap the card props from the display fields, not the backend ids.
proposedBy={housing.proposed_by}passes the proposer id into a UI label, andthumbnailUrl={housing.thumbnail_url}does not use the activity media field. This will show the wrong proposer text and can drop the housing image. Usehousing.proposer_nameandhousing.media_urlhere instead.Proposed fix
- thumbnailUrl={housing.thumbnail_url ?? undefined} - proposedBy={housing.proposed_by ?? undefined} + thumbnailUrl={housing.media_url ?? undefined} + proposedBy={housing.proposer_name ?? undefined}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/app/`(app)/trips/[id]/housing/components/housing-card.tsx around lines 25 - 28, The EntityCard prop mappings are using backend IDs and the wrong media field; update the props in housing-card.tsx so thumbnailUrl uses housing.media_url (not housing.thumbnail_url) and proposedBy uses housing.proposer_name (not housing.proposed_by), keeping proposerPictureUrl as housing.proposer_picture_url if that contains the image; adjust the EntityCard prop assignments (thumbnailUrl, proposedBy, proposerPictureUrl) to those display fields to ensure correct label and image rendering.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/app/`(app)/trips/[id]/components/add-item-entry-sheet.tsx:
- Around line 203-205: The close button (Pressable using onClose and
styles.closeButton with the X icon) currently bypasses the bottom sheet's
disableClose behavior; update the render so the close control is hidden or
disabled when isAutofilling is true—e.g., conditionally render nothing or a
non-interactive element instead of the Pressable when isAutofilling, or pass
disabled prop and adjust hitSlop/opacity—but do not call onClose while
isAutofilling; ensure references are to Pressable, onClose, isAutofilling, and
the disableClose prop on the bottom sheet.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-tab-content.tsx:
- Around line 107-114: The housing tab currently collapses query failures into
the empty state; update the HousingTabContent component to surface a dedicated
error UI instead of falling through to "No housing options yet": read the error
flag/obj returned by useActivitiesList (in addition to isLoading/isLoadingMore
and housingOptions) and render the app's ErrorState component with a
user-friendly message and a retry handler that calls fetchMore (or refetch) and
does not show raw API error text; only if there is no error and the list is
empty should you render the EmptyState branch (also update the same logic around
the other empty-state branch referenced near the existing empty handling).
---
Outside diff comments:
In `@frontend/api/activities/custom/useActivitiesList.ts`:
- Around line 88-95: The hook useActivitiesList no longer returns the refetch
function but callers (e.g., the component that destructures useActivitiesList
and calls refetch) still expect it; restore compatibility by adding refetch to
the hook's returned object and map it to the refetch function produced by your
query (the refetch from useInfiniteQuery / the internal refetch variable), i.e.,
include "refetch" alongside activities, isLoading, isError, isLoadingMore,
fetchMore, prependActivity so existing callers keep working.
In
`@frontend/app/`(app)/trips/[id]/activities/components/activities-tab-content.tsx:
- Around line 220-238: The UI uses activities.length for the empty-state check
and the header count while the list actually renders sortedActivities (which
excludes housing), causing a mismatch; replace usages of activities.length in
the empty-state conditional and the header Text that shows the count with
sortedActivities.length so the EmptyState, count display in the header (the Text
inside the headerRow) and the FlatList (which renders sortedActivities) are
consistent; update the conditional that currently reads activities.length === 0
and the displayed count expression to use sortedActivities.length instead.
---
Duplicate comments:
In `@frontend/app/`(app)/trips/[id]/housing/_layout.tsx:
- Around line 22-39: The screen option objects for the Stack.Screen entries
named "index" and "[id]" include redundant properties: when headerShown is
false, headerTitle and headerTransparent are ignored; remove headerTitle and
headerTransparent from the options for both Stack.Screen declarations and keep
only the required options (e.g., headerShown: false and gestureEnabled: false)
to simplify the config and avoid clutter.
In
`@frontend/app/`(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsx:
- Around line 134-142: The date formatting for the dates array uses
toISOString().split("T")[0] which converts the Date to UTC and causes timezone
drift; update the logic in the dates construction (where dateRange.start and
dateRange.end are used) to format using local date components (e.g.,
getFullYear(), getMonth()+1, getDate()) or a locale-safe formatter so the
produced "YYYY-MM-DD" reflects the local date instead of converting to UTC.
Ensure both dateRange.start and dateRange.end are handled the same way and
preserve the existing array shape when assigning to the dates constant.
- Around line 298-327: Replace the hardcoded numeric values in the StyleSheet
with design-system tokens: change gap: 16 in styles.formRows to the appropriate
spacing token (e.g., Spacing.md), gap: 8 in styles.formRow to the smaller
spacing token (e.g., Spacing.sm), lineHeight: 20 in styles.formRowInput to the
corresponding typography token (e.g., Typography.lineHeightBase) and
paddingVertical: 0 to the design token for vertical padding (e.g., Spacing.none
or Padding.none); update styles.formRowInputEmpty/formRowInputFilled only if
they rely on explicit numeric values—use existing ColorPalette and FontFamily
tokens already imported. Ensure you import or reference the correct token names
used across the codebase and replace each numeric literal in the
formRows/formRow/formRowInput blocks accordingly.
- Around line 115-117: The catch block after calling getPlaceDetailsCustom only
sets setLocationName(prediction.description ?? null) and leaves any previously
set coordinates (locationLat/locationLng) intact; update the failure path in
add-housing-manual-sheet.tsx so that when getPlaceDetailsCustom fails you also
clear the stale coordinates by calling the corresponding setters (e.g.,
setLocationLat(null) and setLocationLng(null) or the app's equivalent) alongside
updating locationName to avoid submitting mismatched name/coords.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-card.tsx:
- Around line 25-28: The EntityCard prop mappings are using backend IDs and the
wrong media field; update the props in housing-card.tsx so thumbnailUrl uses
housing.media_url (not housing.thumbnail_url) and proposedBy uses
housing.proposer_name (not housing.proposed_by), keeping proposerPictureUrl as
housing.proposer_picture_url if that contains the image; adjust the EntityCard
prop assignments (thumbnailUrl, proposedBy, proposerPictureUrl) to those display
fields to ensure correct label and image rendering.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7b0960a3-ae1b-4a8b-b555-9bcfbeba2695
⛔ Files ignored due to path filters (1)
frontend/assets/images/house.pngis excluded by!**/*.png
📒 Files selected for processing (11)
frontend/api/activities/custom/useActivitiesList.tsfrontend/app/(app)/trips/[id]/_layout.tsxfrontend/app/(app)/trips/[id]/activities/[id]/index.tsxfrontend/app/(app)/trips/[id]/activities/components/activities-tab-content.tsxfrontend/app/(app)/trips/[id]/components/add-item-entry-sheet.tsxfrontend/app/(app)/trips/[id]/housing/_layout.tsxfrontend/app/(app)/trips/[id]/housing/components/add-housing-entry-sheet.tsxfrontend/app/(app)/trips/[id]/housing/components/add-housing-manual-sheet.tsxfrontend/app/(app)/trips/[id]/housing/components/housing-card.tsxfrontend/app/(app)/trips/[id]/housing/components/housing-tab-content.tsxfrontend/app/(app)/trips/[id]/index.tsx
| <Pressable onPress={onClose} hitSlop={12} style={styles.closeButton}> | ||
| <X size={20} color={ColorPalette.gray950} /> | ||
| </Pressable> |
There was a problem hiding this comment.
Close button bypasses autofill lock.
The close button calls onClose directly, but the bottom sheet has disableClose={isAutofilling} to prevent dismissal during autofill. This button circumvents that protection and allows the user to dismiss the sheet while autofill is in progress.
Disable the close button or hide it when isAutofilling is true.
Proposed fix
- <Pressable onPress={onClose} hitSlop={12} style={styles.closeButton}>
+ <Pressable
+ onPress={onClose}
+ hitSlop={12}
+ style={styles.closeButton}
+ disabled={isAutofilling}
+ >
- <X size={20} color={ColorPalette.gray950} />
+ <X size={20} color={isAutofilling ? ColorPalette.gray300 : ColorPalette.gray950} />
</Pressable>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Pressable onPress={onClose} hitSlop={12} style={styles.closeButton}> | |
| <X size={20} color={ColorPalette.gray950} /> | |
| </Pressable> | |
| <Pressable | |
| onPress={onClose} | |
| hitSlop={12} | |
| style={styles.closeButton} | |
| disabled={isAutofilling} | |
| > | |
| <X size={20} color={isAutofilling ? ColorPalette.gray300 : ColorPalette.gray950} /> | |
| </Pressable> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/app/`(app)/trips/[id]/components/add-item-entry-sheet.tsx around
lines 203 - 205, The close button (Pressable using onClose and
styles.closeButton with the X icon) currently bypasses the bottom sheet's
disableClose behavior; update the render so the close control is hidden or
disabled when isAutofilling is true—e.g., conditionally render nothing or a
non-interactive element instead of the Pressable when isAutofilling, or pass
disabled prop and adjust hitSlop/opacity—but do not call onClose while
isAutofilling; ensure references are to Pressable, onClose, isAutofilling, and
the disableClose prop on the bottom sheet.
| const { | ||
| activities: housingOptions, | ||
| isLoading, | ||
| isLoadingMore, | ||
| fetchMore, | ||
| prependActivity: prependHousing, | ||
| } = useActivitiesList(tripID, { category: "housing" }); | ||
|
|
There was a problem hiding this comment.
Do not collapse fetch failures into the empty state.
This screen only distinguishes loading from empty. If the housing query fails, users can fall through to “No housing options yet,” which is misleading for a network or backend error. Render a dedicated error state with retry handling before the empty state branch.
As per coding guidelines "React/Expo UI error handling must not expose raw API errors; use UI states (LoadingState, ErrorState, EmptyState); errors shown to users must be clear and user-friendly".
Also applies to: 180-190
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/app/`(app)/trips/[id]/housing/components/housing-tab-content.tsx
around lines 107 - 114, The housing tab currently collapses query failures into
the empty state; update the HousingTabContent component to surface a dedicated
error UI instead of falling through to "No housing options yet": read the error
flag/obj returned by useActivitiesList (in addition to isLoading/isLoadingMore
and housingOptions) and render the app's ErrorState component with a
user-friendly message and a retry handler that calls fetchMore (or refetch) and
does not show raw API error text; only if there is no error and the list is
empty should you render the EmptyState branch (also update the same logic around
the other empty-state branch referenced near the existing empty handling).
0d2b129 to
11c6cfe
Compare
lint and format
4888af9 to
7bd76fc
Compare

Description
This PR implements the housing creation flow using the abstracted activity entry sheet, manual sheet, and activity card. This supports both autofill and manual housing creation.
How has this been tested?
Checklist
Features
Improvements
Infra
Sequence (flow)
User -> Housing Tab -> Add button -> AddHousingEntrySheet
AddHousingEntrySheet -> parseActivityLink -> (autofill success) -> open AddHousingManualSheet (prefilled)
AddHousingManualSheet -> user edits -> useCreateActivity.mutateAsync -> API create -> HousingTabContent prepends new item
Author contribution