Skip to content

[APP] Add Expo Router formSheet modal for typical dish details#353

Merged
timothyrusso merged 24 commits into
mainfrom
feature/310
Jun 1, 2026
Merged

[APP] Add Expo Router formSheet modal for typical dish details#353
timothyrusso merged 24 commits into
mainfrom
feature/310

Conversation

@timothyrusso
Copy link
Copy Markdown
Owner

@timothyrusso timothyrusso commented May 30, 2026

Fixes #310

Summary by CodeRabbit

  • New Features

    • Added a "Typical Dishes" modal showing local dishes with images, descriptions, ingredients and dietary flags (vegetarian, gluten-free).
    • Automated dish image lookup from Wikimedia Commons; profile page now shows user profile images.
  • UI Improvements

    • New hero image component and adjusted image sizing.
    • Updated splash screen image and improved modal presentation/layout.
  • Chores

    • Dependency updates.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 30, 2026

Reviewer's Guide

Implements a new AI-powered "Typical Dishes" experience with Wikimedia-backed images and a dedicated modal flow, refactors modal infrastructure and trip food schema to support rich dish objects, and updates profile and splash UX while cleaning up obsolete modal state and avatar code.

Sequence diagram for Typical Dishes modal and Wikimedia image fetching

sequenceDiagram
  actor User
  participant FoodCard
  participant useFoodCardLogic
  participant navigationService
  participant TypicalDishesModalPage
  participant useTypicalDishesModalPageLogic
  participant useGetTripById
  participant TypicalDishesList
  participant DishItem
  participant useDishItemLogic
  participant useGetWikimediaDishImage
  participant FetchWikimediaDishImageUseCase
  participant WikimediaDishImageRepository
  participant IHttpClient as WikimediaCommonsAPI

  User->>FoodCard: press CustomButtonMedium
  FoodCard->>useFoodCardLogic: useFoodCardLogic(tripId)
  FoodCard->>useFoodCardLogic: handleOpenModal()
  useFoodCardLogic->>navigationService: toTypicalDishesModal({ tripId })
  navigationService-->>User: open TypicalDishesModalPage

  TypicalDishesModalPage->>useTypicalDishesModalPageLogic: useTypicalDishesModalPageLogic()
  useTypicalDishesModalPageLogic->>useGetTripById: useGetTripById(tripId)
  useGetTripById-->>useTypicalDishesModalPageLogic: trip
  useTypicalDishesModalPageLogic-->>TypicalDishesModalPage: { location, dishItems }

  TypicalDishesModalPage->>TypicalDishesList: dishItems
  TypicalDishesList->>DishItem: render DishItem(dish)

  DishItem->>useDishItemLogic: useDishItemLogic(dish.searchTerm)
  useDishItemLogic->>useGetWikimediaDishImage: useGetWikimediaDishImage(searchTerm)
  useGetWikimediaDishImage->>FetchWikimediaDishImageUseCase: execute(dish, options)
  FetchWikimediaDishImageUseCase->>WikimediaDishImageRepository: getImage(dish, options)
  WikimediaDishImageRepository->>IHttpClient: get<WikimediaSearchResponseDTO>(url)
  IHttpClient-->>WikimediaDishImageRepository: WikimediaSearchResponseDTO
  WikimediaDishImageRepository-->>FetchWikimediaDishImageUseCase: Result<ImageResult | null>
  FetchWikimediaDishImageUseCase-->>useGetWikimediaDishImage: Result<ImageResult | null>
  useGetWikimediaDishImage-->>useDishItemLogic: { data, isLoading }
  useDishItemLogic-->>DishItem: { image, isLoading }
  DishItem-->>User: show dish image and description
Loading

File-Level Changes

Change Details Files
Refactor core modal template and header to be simple layout primitives instead of react-native-modal driven containers with internal close behavior.
  • Replace ModalTemplate react-native-modal wrapper with a plain View that accepts children and optional style and update styles to use a main container with flex:1
  • Simplify ModalHeader layout to a left-aligned title/children container plus a right-side close button using CustomIconButtonMedium and updated typography
  • Remove ModalTemplate.Container and deprecated modal-related exports and state hooks from core UI/state index files
features/core/ui/components/dialogs/ModalTemplate/ModalTemplate.tsx
features/core/ui/components/dialogs/ModalTemplate/ModalTemplate.style.ts
features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/ModalTemplateHeader.tsx
features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/ModalTemplateHeader.style.ts
features/core/ui/index.ts
features/core/state/index.ts
Introduce "Typical Dishes" domain model and Convex/zod schemas, and wire it into trip entities and validators.
  • Extend generatedTripSchema.food.typicalDishes from string array to an array of structured dish objects with name, searchTerm, description, ingredients, and dietary flags plus detailed LLM descriptions
  • Add TypicalDish domain interface and update Food entity to reference TypicalDish[] instead of string[]
  • Update Convex Food validator to mirror new TypicalDish structure for backend validation and reading
features/trip-generation/domain/schemas/GenerateTripSchema.ts
features/trips/domain/entities/Food.ts
features/trips/domain/entities/TypicalDish.ts
convex/validators/Trips.ts
features/trips/index.ts
Add Wikimedia-based dish image fetching pipeline and hook, including DI wiring and food-specific filtering heuristics.
  • Create WikimediaDishImageRepository that queries Wikimedia Commons search API, filters pages by allowed image extensions, minimum dimensions, lack of restrictions, and food-related categories, and returns thumbnail URLs
  • Define DTO types and food category keyword constants used to interpret Wikimedia search responses and categories
  • Add FetchWikimediaDishImageUseCase with logging, DI bindings, and resolver exports, plus a useGetWikimediaDishImage hook that exposes cached image results with a local placeholder fallback
features/core/images/domain/entities/foodCategoryKeywords.ts
features/core/images/data/dtos/WikimediaSearchResponseDTO.ts
features/core/images/data/repositories/WikimediaDishImageRepository.ts
features/core/images/useCases/FetchWikimediaDishImageUseCase.ts
features/core/images/di/types.ts
features/core/images/di/config.ts
features/core/images/di/resolve.ts
features/core/images/index.ts
features/core/images/facades/useGetWikimediaDishImage.ts
Implement the Typical Dishes modal flow, header, and dish list components, and connect them from the FoodCard and navigation layer.
  • Change FoodCard to accept tripId, remove inline typical dishes FlatList, and instead show a button that opens a new Typical Dishes modal using useFoodCardLogic and NavigationService.toTypicalDishesModal
  • Create TypicalDishesModalPage with logic hook that reads tripId from route, fetches the trip, derives location, dish count, and dish list, and renders TypicalDishesModalHeader plus TypicalDishesList in a ScrollView
  • Add DishItem component that uses useDishItemLogic and useGetWikimediaDishImage to display a circular dish image (or skeleton) with name/description, and TypicalDishesList that renders a separated list of DishItems
  • Introduce TypicalDishesModalHeader with location, dish count (pluralized via i18n), and close button, and corresponding styles
  • Wire up new modal route in create-trip stack (Modals.TypicalDishes with formSheetOptions), add Modals enum and formSheetOptions helper, and extend ListHeaderComponent and TripDetailsPage to pass tripId and open the modal
features/trips/ui/components/FoodCard/FoodCard.tsx
features/trips/ui/components/FoodCard/FoodCard.logic.ts
features/trips/ui/components/FoodCard/FoodCard.style.ts
features/trips/ui/components/FoodCard/components/DishItem/DishItem.tsx
features/trips/ui/components/FoodCard/components/DishItem/DishItem.logic.ts
features/trips/ui/components/FoodCard/components/DishItem/DishItem.style.ts
features/trips/ui/components/TypicalDishesModalHeader/TypicalDishesModalHeader.tsx
features/trips/ui/components/TypicalDishesModalHeader/TypicalDishesModalHeader.logic.ts
features/trips/ui/components/TypicalDishesModalHeader/TypicalDishesModalHeader.style.ts
features/trips/ui/components/TypicalDishesList/TypicalDishesList.tsx
features/trips/ui/components/TypicalDishesList/TypicalDishesList.style.ts
features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.tsx
features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.logic.ts
features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.style.ts
features/trips/pages.ts
app/(main)/(authenticated)/create-trip/_layout.tsx
app/(main)/(authenticated)/create-trip/typical-dishes-modal.tsx
features/core/navigation/domain/entities/Modals.ts
features/core/navigation/data/services/NavigationService.ts
features/core/navigation/domain/entities/services/INavigationService.ts
features/core/navigation/index.ts
features/core/navigation/libraries/formSheetOptions.ts
features/trips/ui/components/ListHeaderComponent/ListHeaderComponent.tsx
features/trips/ui/pages/TripDetailsPage/TripDetailsPage.tsx
Refine profile page to use Clerk profile images and simplify skeleton/loading states, while updating Clerk dependency and user repository contract.
  • Change useProfileData and IUserRepository/useUserRepository to use username/profileImageUrl from Clerk instead of firstName and dicebear avatar generation
  • Update ProfilePage.logic to compute a sized profileImage URL and drop dicebear avatar and email from the public API, and simplify ProfilePage to render CustomImage avatar and username only
  • Adjust ProfilePage styles: smaller avatar radius, explicit avatarImage style, remove email and emailSkeleton styling, and tweak spacing; also reduce global profileImageHeight constant
features/profile/facades/useProfileData.ts
features/user/domain/entities/repositories/IUserRepository.ts
features/user/data/repositories/useUserRepository.ts
features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts
features/profile/ui/pages/ProfilePage/ProfilePage.tsx
features/profile/ui/pages/ProfilePage/ProfilePage.style.ts
features/core/ui/style/dimensions/components.ts
package.json
package-lock.json
Clean up obsolete core modal system, reset-password modal, and adjust miscellaneous UI details (notes colors, splash assets).
  • Remove ActionModal, InfoModal, reset-password modal components, Zustand modal store, related logic, and exports from core state/UI
  • Change trip budget NotesCard background color to secondaryBlue to match new palette and update FoodCard CTA styling to a centered secondaryGreen button
  • Update app splash image configuration to use new logo asset with explicit width and tweak expo-splash-screen plugin config
  • Tweak image dimensions constants by adding dishImageSize and adjust images import usages; remove SCREEN_WIDTH-based FoodCard layout remnants
features/auth/ui/components/ResetPasswordModal/ResetPasswordModal.logic.ts
features/auth/ui/components/ResetPasswordModal/ResetPasswordModal.tsx
features/core/state/modal/modalStore.ts
features/core/state/modal/useModalState.ts
features/core/ui/components/dialogs/ActionModal/ActionModal.logic.ts
features/core/ui/components/dialogs/ActionModal/ActionModal.tsx
features/core/ui/components/dialogs/InfoModal/InfoModal.logic.ts
features/core/ui/components/dialogs/InfoModal/InfoModal.tsx
features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.logic.ts
features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.style.ts
features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.tsx
features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/useKeyboardEffect.ts
features/trips/ui/components/ListHeaderComponent/ListHeaderComponent.tsx
app.json
features/core/ui/style/dimensions/images.ts
features/trips/ui/components/FoodCard/FoodCard.style.ts
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Warning

Review limit reached

@timothyrusso, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 39 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3bd57a08-7b0c-4ee3-a397-c8dff4673df9

📥 Commits

Reviewing files that changed from the base of the PR and between 788ddba and 40ef180.

📒 Files selected for processing (1)
  • features/core/images/data/repositories/WikimediaDishImageRepository.ts
📝 Walkthrough

Walkthrough

Adds a Typical Dishes form-sheet modal (data schemas, UI, navigation, DI, and Wikimedia image fetching), refactors modal infrastructure by removing the centralized modal store and simplifying ModalTemplate, updates profile mapping to username/profileImageUrl, and adjusts app splash/docs.

Changes

Typical Dishes Modal Feature

Layer / File(s) Summary
TypicalDish contracts & schemas
features/trips/domain/entities/TypicalDish.ts, features/trips/domain/entities/Food.ts, convex/validators/Trips.ts, features/trip-generation/domain/schemas/GenerateTripSchema.ts, features/trips/index.ts
Adds TypicalDish interface and updates Food/validator/schema to use structured dish objects with name/searchTerm/description/ingredients/isGlutenFree/isVegetarian.
Modal page & UI components
features/trips/ui/pages/TypicalDishesModalPage/*, features/trips/ui/components/TypicalDishesModalHeader/*, features/trips/ui/components/TypicalDishesList/*, features/trips/ui/components/FoodCard/components/DishItem/*, app/(main)/(authenticated)/create-trip/typical-dishes-modal.tsx
Implements TypicalDishesModalPage, header, list, DishItem (image/description), styles, and Next.js wrapper; DishItem uses image hook to show Wikimedia images.
FoodCard & TripDetails integration
features/trips/ui/components/FoodCard/*, features/trips/ui/components/ListHeaderComponent/*, features/trips/ui/pages/TripDetailsPage/*
FoodCard now accepts tripId, uses useFoodCardLogic to open the Typical Dishes modal (button), and TripDetails/ListHeader pass tripId through.

Wikimedia image fetching

Layer / File(s) Summary
Repository, DTOs, and validation
features/core/images/data/dtos/WikimediaSearchResponseDTO.ts, features/core/images/data/repositories/WikimediaDishImageRepository.ts
Adds DTOs and WikimediaDishImageRepository that queries MediaWiki API, parses pages/imageinfo, and validates candidate images (extensions, dimensions, restrictions, category matching).
Use-case, DI, keywords, and facade
features/core/images/useCases/FetchWikimediaDishImageUseCase.ts, features/core/images/di/types.ts, features/core/images/di/config.ts, features/core/images/di/resolve.ts, features/core/images/domain/entities/foodCategoryKeywords.ts, features/core/images/facades/useGetWikimediaDishImage.ts, features/core/images/index.ts
Adds FetchWikimediaDishImageUseCase, DI tokens/bindings, 151-entry FOOD_CATEGORY_KEYWORDS, and useGetWikimediaDishImage hook (react-query) that returns image result or fallback placeholder and is exported via images index.

Navigation & form-sheet options

Layer / File(s) Summary
Navigation contracts & options
features/core/navigation/domain/entities/Modals.ts, features/core/navigation/domain/entities/services/INavigationService.ts, features/core/navigation/libraries/formSheetOptions.ts, features/core/navigation/index.ts
Adds Modals constant/type, toTypicalDishesModal navigation contract, and formSheetOptions (presentation, detents, corner radius).
Navigation service & route registration
features/core/navigation/data/services/NavigationService.ts, app/(main)/(authenticated)/create-trip/_layout.tsx
Implements NavigationService.toTypicalDishesModal and registers Modals.TypicalDishes in the create-trip stack using formSheetOptions.

Modal System Refactoring

Layer / File(s) Summary
Zustand modal store removal
features/core/state/modal/modalStore.ts, features/core/state/modal/useModalState.ts, features/core/state/index.ts
Removes modal Zustand store, selectors, modal type aliases, and useModalState wrapper; clears modal re-exports from core state index.
ModalTemplate simplification & header updates
features/core/ui/components/dialogs/ModalTemplate/*, features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/*
Rewrites ModalTemplate as a simple View wrapper (props now accept children/style), removes ModalTemplateContainer/useKeyboardEffect, updates header styles and button to CustomIconButtonMedium.
ActionModal & InfoModal removal
features/core/ui/components/dialogs/ActionModal/*, features/core/ui/components/dialogs/InfoModal/*, features/core/ui/index.ts
Deletes generic ActionModal and InfoModal components and their logic; cleans barrel exports.

Profile Feature Updates

Layer / File(s) Summary
User data shape changes
features/user/domain/entities/repositories/IUserRepository.ts, features/user/data/repositories/useUserRepository.ts
Updates getUser shape to include username and profileImageUrl (removes firstName).
Profile page logic & rendering
features/profile/facades/useProfileData.ts, features/profile/ui/pages/ProfilePage/*
useProfileData exposes username and profileImageUrl; useProfilePageLogic builds profileImage URI and ProfilePage renders CustomImage (no email/old avatar).
UI dimensions
features/core/ui/style/dimensions/components.ts, features/core/ui/style/dimensions/images.ts
Reduces profileImageHeight from 150→100 and adds images.dishImageSize = 80.

Configuration & Documentation

Layer / File(s) Summary
Splash screen config
app.json
Switches splash asset to logo.png, sets plugin imageWidth: 150, adds dark splash config with backgroundColor, and removes the previous iOS-specific imageWidth.
Docs, dependency, UpcomingTrip/HeroImage
README.md, package.json, features/trips/ui/components/HeroImage/*, features/trips/ui/pages/UpcomingTripPage/*
Adds README "AI Generation Pipeline" section with diagram, bumps @clerk/expo to ^3.2.14, introduces HeroImage component and refactors UpcomingTripPage to use it and early-return rendering flows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

"

🐰 I hopped through code to fetch a dish,
Wikimedia pictures served my wish,
Modals trimmed and pages neat,
Profile pics now look so sweet,
A tiny rabbit's tasty sprint!
"

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning PR implements the core navigation requirements from #310, but the implementation diverges significantly from the specified design (uses bottom-sheet modal page instead of simple route-passing approach). The PR implements TypicalDishesModalPage instead of TypicalDishDetailsPage, adds extensive dish content features not scoped in #310 (Wikimedia images, dietary flags, descriptions), and removes legacy modal system. Align implementation with issue scope or update issue requirements.
Out of Scope Changes check ⚠️ Warning PR includes substantial out-of-scope changes: complete modal system refactoring, Wikimedia image integration, dietary flags, reset password removal, profile image changes, and cuisine/keyword additions beyond the navigation routing task. Remove out-of-scope changes: modal refactoring (ModalTemplate changes), Wikimedia repository/use-case, dietary flag schemas, reset password component removal, profile image updates, and food category keywords. Keep only navigation structure and FoodCard interaction changes.
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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately describes the main change: adding a formSheet modal for typical dish details via Expo Router, which is the primary objective of this PR.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/310

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.

❤️ Share

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

@github-actions github-actions Bot changed the title Feature/310 [APP] Add Expo Router formSheet modal for typical dish details May 30, 2026
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 4 issues, and left some high level feedback:

  • The ModalTemplate component has been reduced to a plain View and no longer accepts ModalProps (e.g., isVisible, backdrop behavior) or exposes .Container; double‑check all existing usages to ensure expectations about modal behavior (animations, backdrop, dismissal) are still met or consider introducing a separate non-modal wrapper to avoid silently changing semantics.
  • In ModalHeader, the children prop is typed as React.ReactElement but React (or ReactElement) is not imported in this file; either import the type explicitly or switch the prop type to something like ReactNode from react to avoid type errors.
  • For useGetWikimediaDishImage, consider normalizing the dish key (e.g., dish.trim().toLowerCase()) in the queryKey to avoid unnecessary cache misses when the same dish string is passed in with different casing or incidental whitespace.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `ModalTemplate` component has been reduced to a plain `View` and no longer accepts `ModalProps` (e.g., `isVisible`, backdrop behavior) or exposes `.Container`; double‑check all existing usages to ensure expectations about modal behavior (animations, backdrop, dismissal) are still met or consider introducing a separate non-modal wrapper to avoid silently changing semantics.
- In `ModalHeader`, the `children` prop is typed as `React.ReactElement` but `React` (or `ReactElement`) is not imported in this file; either import the type explicitly or switch the prop type to something like `ReactNode` from `react` to avoid type errors.
- For `useGetWikimediaDishImage`, consider normalizing the `dish` key (e.g., `dish.trim().toLowerCase()`) in the `queryKey` to avoid unnecessary cache misses when the same dish string is passed in with different casing or incidental whitespace.

## Individual Comments

### Comment 1
<location path="features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts" line_range="20" />
<code_context>
     navigationService.toTripList();
   };

+  const profileImage = `${profileImageUrl}?height=${components.profileImageHeight}&width=${components.profileImageHeight}&quality=100&fit=crop`;
+
   return {
</code_context>
<issue_to_address>
**issue (bug_risk):** Guard against missing `profileImageUrl` to avoid constructing an invalid image URL.

If `profileImageUrl` is `undefined`, this expression produces a URL like `"undefined?height=..."`, which will cause image load failures and noisy network errors in `CustomImage`. Consider only building `profileImage` when `profileImageUrl` is truthy, or returning `null`/`undefined` here and conditionally rendering the avatar image in the consumer component.
</issue_to_address>

### Comment 2
<location path="features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.logic.ts" line_range="9-11" />
<code_context>
+  const { tripId } = useLocalSearchParams<{ tripId: string }>();
+  const { trip } = useGetTripById(tripId);
+
+  const location = trip?.tripAiResp.tripDetails.location.split(',')[0] ?? '';
+  const food = trip?.tripAiResp?.food;
+  const dishNumber = food?.typicalDishes.length ?? 0;
+
+  const handleClose = () => navigationService.back();
</code_context>
<issue_to_address>
**issue (bug_risk):** Access to `tripAiResp.tripDetails` is not fully null-safe and may throw if `tripAiResp` is missing.

The optional chaining only applies to `trip`, not `trip.tripAiResp`. If `trip` exists but `tripAiResp` is `undefined`, `trip?.tripAiResp.tripDetails` will still throw when accessing `tripDetails`. This is already handled correctly for `food` via `trip?.tripAiResp?.food`, but not for `location`.

Consider updating to something like:
```ts
const location = trip?.tripAiResp?.tripDetails.location.split(',')[0] ?? '';
```
or, more defensively:
```ts
const rawLocation = trip?.tripAiResp?.tripDetails?.location;
const location = rawLocation ? rawLocation.split(',')[0] : '';
```
</issue_to_address>

### Comment 3
<location path="features/trips/ui/components/TypicalDishesList/TypicalDishesList.tsx" line_range="16-17" />
<code_context>
+
+export const TypicalDishesList: FC<TypicalDishesListProps> = ({ dishItems }) => (
+  <>
+    {dishItems?.map((item, index) => (
+      <Fragment key={item.name}>
+        {index > 0 && <Separator />}
+        <DishItem dish={item} />
+      </Fragment>
+    ))}
+  </>
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Using `item.name` as the React key may cause collisions if dish names repeat.

This assumes all dish names are unique. Since these come from an AI response, duplicates are likely and can cause unstable list rendering. Prefer a more robust key, such as combining name and index (or a stable id if available):
```tsx
<Fragment key={`${item.name}-${index}`}>
```

```suggestion
    {dishItems?.map((item, index) => (
      <Fragment key={`${item.name}-${index}`}>
```
</issue_to_address>

### Comment 4
<location path="features/core/images/data/repositories/WikimediaDishImageRepository.ts" line_range="65-67" />
<code_context>
+    return true;
+  }
+
+  private isAllowedImageExtension(url: string): boolean {
+    const lower = url.toLowerCase();
+    return ALLOWED_IMAGE_EXTENSIONS.some(ext => lower.includes(ext));
+  }
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Filtering image extensions via `includes` may misclassify URLs; `endsWith` is safer.

Because the extension check isn’t anchored to the end of the string, URLs like `/file.jpg.svg` or URLs with query params containing `.jpg` could be incorrectly accepted as JPGs. To avoid this, explicitly match the file extension at the end of the URL:
```ts
return ALLOWED_IMAGE_EXTENSIONS.some(ext => lower.endsWith(ext));
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts
Comment thread features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.logic.ts Outdated
Comment thread features/trips/ui/components/TypicalDishesList/TypicalDishesList.tsx Outdated
Comment thread features/core/images/data/repositories/WikimediaDishImageRepository.ts Outdated
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a feature to display typical dishes for a trip, leveraging Wikimedia Commons to fetch dish images. It defines structured schemas and validators for typical dishes, adds a dedicated typical dishes modal page, integrates a Wikimedia image search repository, cleans up unused reset password modal code, and updates the profile page to use Clerk profile images. The review feedback highlights several key improvements: using optional chaining in TypicalDishesModalPage.logic.ts to prevent runtime crashes, ensuring the fallback image is returned in useGetWikimediaDishImage.ts when data is unavailable, correcting the image dimension check logic in WikimediaDishImageRepository.ts to reject low-resolution images, and adopting unified pluralized translation keys in the typical dishes modal header to follow localization best practices.

Comment thread features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.logic.ts Outdated
Comment thread features/core/images/facades/useGetWikimediaDishImage.ts
Comment thread features/core/translations/libraries/locales/en.json
Comment thread features/core/translations/libraries/locales/it.json
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

6 issues found across 74 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="README.md">

<violation number="1" location="README.md:10">
P2: The referenced image `wiki/docs/diagrams/AI_Generation_Pipeline.png` is not a valid PNG (it contains placeholder text instead). The image will appear broken in the rendered README.</violation>
</file>

<file name="features/core/images/data/repositories/WikimediaDishImageRepository.ts">

<violation number="1" location="features/core/images/data/repositories/WikimediaDishImageRepository.ts:58">
P2: The minimum-dimension check is too permissive: it allows images where one dimension is below the configured minimum.</violation>
</file>

<file name="features/core/ui/components/dialogs/ModalTemplate/ModalTemplate.tsx">

<violation number="1" location="features/core/ui/components/dialogs/ModalTemplate/ModalTemplate.tsx:11">
P1: The modal template now always renders and has no visibility prop, so dialog content can no longer be conditionally shown/hidden through this component.</violation>
</file>

<file name="app.json">

<violation number="1" location="app.json:57">
P2: The iOS splash screen `imageWidth` effectively changes from **100** to **150** because the iOS-specific override (`ios.imageWidth: 100`) was removed and a root-level `imageWidth: 150` was added. The old config intentionally used platform-specific widths (100 iOS, 150 Android). Verify this iOS width increase is intentional for the new non-round logo, or keep the `ios.imageWidth: 100` override if iOS should remain at 100.</violation>
</file>

<file name="features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts">

<violation number="1" location="features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts:20">
P2: Profile image URL construction is fragile: it does not handle missing URLs or existing query parameters, which can generate invalid image URIs.</violation>
</file>

<file name="features/core/images/facades/useGetWikimediaDishImage.ts">

<violation number="1" location="features/core/images/facades/useGetWikimediaDishImage.ts:18">
P2: Using infinite `gcTime` on a dynamic query key can cause unbounded React Query cache growth.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread features/core/ui/components/dialogs/ModalTemplate/ModalTemplate.tsx
Comment thread README.md
Comment thread app.json
Comment thread features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts
Comment thread features/core/images/facades/useGetWikimediaDishImage.ts
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: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
features/trips/ui/components/ListHeaderComponent/ListHeaderComponent.tsx (1)

55-57: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

The custom memo comparator now drops tripId updates.

This comparator only checks tripDetails, but the component also renders food, tripId, weather, notes, map props, and the new modal button. If any of those change while tripDetails keeps the same reference, FoodCard can keep a stale tripId and open the wrong modal.

💡 Safer fix
 export const ListHeaderComponent: FC<ListHeaderComponentProps> = memo(
   ({ region, allCoordinates, budgetNotes, transportationNotes, weather, tripDetails, food, tripId }) => {
     return (
       <View style={style.container}>
         <TripDetailsCard tripDetails={tripDetails} />
         {allCoordinates && <MapListHeaderComponent region={region} allCoordinates={allCoordinates} />}
         {weather && <WeatherCard weather={weather} />}
         {food && <FoodCard food={food} tripId={tripId} />}
         {budgetNotes && (
           <NotesCard
             title="TRIP_DETAILS.BUDGET_NOTES"
             icon={icons.card}
             notes={budgetNotes}
             backgroundColor={colors.secondaryBlue}
           />
         )}
         {transportationNotes && (
           <NotesCard
             title="TRIP_DETAILS.TRANSPORTATION_NOTES"
             icon={icons.bus}
             notes={transportationNotes}
             isTitleInverted
             backgroundColor={colors.secondaryPink}
           />
         )}
       </View>
     );
-  },
-  (prevProps, nextProps) => {
-    return prevProps.tripDetails === nextProps.tripDetails;
-  },
+  },
 );
🤖 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 `@features/trips/ui/components/ListHeaderComponent/ListHeaderComponent.tsx`
around lines 55 - 57, The current custom memo comparator for ListHeaderComponent
(the (prevProps, nextProps) => prevProps.tripDetails === nextProps.tripDetails)
ignores changes to tripId, food, weather, notes, map props and the modal button,
causing FoodCard to get a stale tripId; fix by replacing this custom comparator
with either the default React.memo shallow compare (remove the custom function)
or by expanding the comparator to explicitly compare prevProps.tripDetails,
prevProps.tripId, prevProps.food, prevProps.weather, prevProps.notes,
prevProps.mapProps and any modal handler/flag (e.g., onOpenModal) against
nextProps so updates to tripId and other relevant props propagate to
ListHeaderComponent/FoodCard.
🧹 Nitpick comments (1)
features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/ModalTemplateHeader.tsx (1)

16-23: ⚡ Quick win

Widen the children slot to ReactNode.

ReactElement is narrower than what this component actually renders. It rejects common valid children such as fragments, arrays, text, and falsy conditional children, which makes the new header slot harder to consume than necessary.

♻️ Proposed fix
+import type { ReactNode } from 'react';
 import type { StyleProp, TextStyle } from 'react-native';
 import { View } from 'react-native';
@@
-  children?: React.ReactElement;
+  children?: ReactNode;
#!/bin/bash
# Inspect current ModalHeader / ModalTemplate.Header call sites to confirm whether
# any consumers already pass fragments, text nodes, arrays, or conditional children.
rg -n -C3 --type=tsx '<(ModalHeader|ModalTemplate\.Header)\b'
🤖 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
`@features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/ModalTemplateHeader.tsx`
around lines 16 - 23, The children prop for the ModalTemplateHeader component is
overly restrictive: change its type from React.ReactElement to React.ReactNode
in the ModalTemplateHeader props so the header accepts fragments, arrays, text,
and conditional/falsy children; update the declaration where children is typed
(the ModalTemplateHeader props object) and run a quick grep/tsc check of
ModalHeader / ModalTemplate.Header call sites (e.g., search for "ModalHeader" or
"ModalTemplate.Header") to ensure no consumers rely on the narrower type and
adjust any typings if needed.
🤖 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/`(main)/(authenticated)/create-trip/_layout.tsx:
- Line 2: Remove the unused import "spacing" from the import list in the
_layout.tsx file; update the statement that currently imports { CustomHeader,
icons, spacing } to only import the actually used symbols (e.g., CustomHeader
and icons) so the unused "spacing" identifier is dropped and Biome's
noUnusedImports check will pass.
- Around line 75-78: Reformat the JSX <Stack.Screen> block so it passes Biome by
collapsing the current multiline element into a single-line self-closing
element: update the <Stack.Screen> instance for Modals.TypicalDishes to be
written on one line and keep the same props (name={Modals.TypicalDishes} and
options={formSheetOptions}) so the JSX is compact and correctly formatted.

In `@features/core/images/data/repositories/WikimediaDishImageRepository.ts`:
- Line 58: The image-dimension check currently rejects only when both sides are
below MIN_IMAGE_DIMENSION_PX; update the conditional in
WikimediaDishImageRepository (the check using info.width, info.height and
MIN_IMAGE_DIMENSION_PX) to reject when either dimension is below the threshold
by changing the logical operator from && to || so images with one small side
(e.g., 1200x150) are filtered out.

In `@features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts`:
- Around line 20-21: The profileImage URL is built unguarded using
profileImageUrl which can be undefined, producing invalid URLs like
"undefined?..."; update the logic around profileImage (and the similar
expression at the other occurrence) to check profileImageUrl first and only
construct the query-string URL when profileImageUrl is truthy, otherwise set
profileImage to undefined (or a chosen fallback), referencing the existing
symbols profileImage, profileImageUrl, and components.profileImageHeight so
callers receive a safe value.

In `@features/trip-generation/domain/schemas/GenerateTripSchema.ts`:
- Around line 61-82: The typicalDishes item schema currently only documents
rules for searchTerm and description; update the Zod validators for those fields
in the typicalDishes object so they enforce the constraints: change searchTerm
to a z.string() with trim plus a regex or .refine that ensures lowercase ASCII
(no diacritics/special chars), contains 1–3 words (max 3 space-separated tokens)
and rejects punctuation; change description to a z.string().trim() with a
.refine that counts words and enforces between 20 and 50 words (and optionally a
min/max character sanity check); keep the existing .describe() texts but replace
the loose strings with these stricter validators so invalid generated dishes
fail schema validation.

In `@features/trips/ui/components/TypicalDishesList/TypicalDishesList.tsx`:
- Line 17: The Fragment in TypicalDishesList uses item.name as the key which can
collide; update the key on the Fragment (or the mapped element) to use a stable
unique identifier such as item.id if available, or a composite stable key like
`${item.id ?? item.name}-${index}` from the map callback (ensure you reference
the map index parameter) so each <Fragment> key is unique and stable across
renders.

In
`@features/trips/ui/components/TypicalDishesModalHeader/TypicalDishesModalHeader.tsx`:
- Around line 20-24: The header layout can overflow when `location` is long;
update the `TypicalDishesModalHeader` JSX so the location and icon remain on the
first horizontal row (keep the existing View using styles.locationRow with
`CustomIcon` and the `CustomText` for `location`), and move the dish count
(`CustomText` using `dishNumber`/`dishLabel`) into a separate row beneath it
(new View or reuse styles) so the count is on its own line and cannot be pushed
off-screen; adjust/ensure styles (e.g., styles.locationRow, styles.location,
styles.dishNumber) for spacing and alignment after this change.

In
`@features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.logic.ts`:
- Line 9: The current assignment to location uses
trip?.tripAiResp.tripDetails.location.split(',')[0] which can throw if
tripAiResp/tripDetails/location are undefined; update this to guard each nested
property before calling split (e.g., use optional chaining on tripAiResp,
tripDetails, and location and nullish-coalescing to ''), so replace the
expression for location with a fully null-safe chain that only calls split when
location is defined.

---

Outside diff comments:
In `@features/trips/ui/components/ListHeaderComponent/ListHeaderComponent.tsx`:
- Around line 55-57: The current custom memo comparator for ListHeaderComponent
(the (prevProps, nextProps) => prevProps.tripDetails === nextProps.tripDetails)
ignores changes to tripId, food, weather, notes, map props and the modal button,
causing FoodCard to get a stale tripId; fix by replacing this custom comparator
with either the default React.memo shallow compare (remove the custom function)
or by expanding the comparator to explicitly compare prevProps.tripDetails,
prevProps.tripId, prevProps.food, prevProps.weather, prevProps.notes,
prevProps.mapProps and any modal handler/flag (e.g., onOpenModal) against
nextProps so updates to tripId and other relevant props propagate to
ListHeaderComponent/FoodCard.

---

Nitpick comments:
In
`@features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/ModalTemplateHeader.tsx`:
- Around line 16-23: The children prop for the ModalTemplateHeader component is
overly restrictive: change its type from React.ReactElement to React.ReactNode
in the ModalTemplateHeader props so the header accepts fragments, arrays, text,
and conditional/falsy children; update the declaration where children is typed
(the ModalTemplateHeader props object) and run a quick grep/tsc check of
ModalHeader / ModalTemplate.Header call sites (e.g., search for "ModalHeader" or
"ModalTemplate.Header") to ensure no consumers rely on the narrower type and
adjust any typings if needed.
🪄 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: CHILL

Plan: Pro

Run ID: 86448ce8-1728-49e3-adda-752ab8e78d4d

📥 Commits

Reviewing files that changed from the base of the PR and between fc22007 and 96db286.

⛔ Files ignored due to path filters (5)
  • features/core/ui/assets/images/android-icon.png is excluded by !**/*.png
  • features/core/ui/assets/images/food_placeholder.jpg is excluded by !**/*.jpg
  • features/core/ui/assets/images/logo.png is excluded by !**/*.png
  • package-lock.json is excluded by !**/package-lock.json
  • wiki/docs/diagrams/AI_Generation_Pipeline.png is excluded by !**/*.png
📒 Files selected for processing (69)
  • README.md
  • app.json
  • app/(main)/(authenticated)/create-trip/_layout.tsx
  • app/(main)/(authenticated)/create-trip/typical-dishes-modal.tsx
  • convex/validators/Trips.ts
  • features/auth/ui/components/ResetPasswordModal/ResetPasswordModal.logic.ts
  • features/auth/ui/components/ResetPasswordModal/ResetPasswordModal.tsx
  • features/core/images/data/dtos/WikimediaSearchResponseDTO.ts
  • features/core/images/data/repositories/WikimediaDishImageRepository.ts
  • features/core/images/di/config.ts
  • features/core/images/di/resolve.ts
  • features/core/images/di/types.ts
  • features/core/images/domain/entities/foodCategoryKeywords.ts
  • features/core/images/facades/useGetWikimediaDishImage.ts
  • features/core/images/index.ts
  • features/core/images/useCases/FetchWikimediaDishImageUseCase.ts
  • features/core/navigation/data/services/NavigationService.ts
  • features/core/navigation/domain/entities/Modals.ts
  • features/core/navigation/domain/entities/services/INavigationService.ts
  • features/core/navigation/index.ts
  • features/core/navigation/libraries/formSheetOptions.ts
  • features/core/state/index.ts
  • features/core/state/modal/modalStore.ts
  • features/core/state/modal/useModalState.ts
  • features/core/translations/libraries/locales/en.json
  • features/core/translations/libraries/locales/it.json
  • features/core/ui/components/dialogs/ActionModal/ActionModal.logic.ts
  • features/core/ui/components/dialogs/ActionModal/ActionModal.tsx
  • features/core/ui/components/dialogs/InfoModal/InfoModal.logic.ts
  • features/core/ui/components/dialogs/InfoModal/InfoModal.tsx
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplate.style.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplate.tsx
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.logic.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.style.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.tsx
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/useKeyboardEffect.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/ModalTemplateHeader.style.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateHeader/ModalTemplateHeader.tsx
  • features/core/ui/index.ts
  • features/core/ui/style/dimensions/components.ts
  • features/core/ui/style/dimensions/images.ts
  • features/profile/facades/useProfileData.ts
  • features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts
  • features/profile/ui/pages/ProfilePage/ProfilePage.style.ts
  • features/profile/ui/pages/ProfilePage/ProfilePage.tsx
  • features/trip-generation/domain/schemas/GenerateTripSchema.ts
  • features/trips/domain/entities/Food.ts
  • features/trips/domain/entities/TypicalDish.ts
  • features/trips/index.ts
  • features/trips/pages.ts
  • features/trips/ui/components/FoodCard/FoodCard.logic.ts
  • features/trips/ui/components/FoodCard/FoodCard.style.ts
  • features/trips/ui/components/FoodCard/FoodCard.tsx
  • features/trips/ui/components/FoodCard/components/DishItem/DishItem.logic.ts
  • features/trips/ui/components/FoodCard/components/DishItem/DishItem.style.ts
  • features/trips/ui/components/FoodCard/components/DishItem/DishItem.tsx
  • features/trips/ui/components/ListHeaderComponent/ListHeaderComponent.tsx
  • features/trips/ui/components/TypicalDishesList/TypicalDishesList.style.ts
  • features/trips/ui/components/TypicalDishesList/TypicalDishesList.tsx
  • features/trips/ui/components/TypicalDishesModalHeader/TypicalDishesModalHeader.logic.ts
  • features/trips/ui/components/TypicalDishesModalHeader/TypicalDishesModalHeader.style.ts
  • features/trips/ui/components/TypicalDishesModalHeader/TypicalDishesModalHeader.tsx
  • features/trips/ui/pages/TripDetailsPage/TripDetailsPage.tsx
  • features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.logic.ts
  • features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.style.ts
  • features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.tsx
  • features/user/data/repositories/useUserRepository.ts
  • features/user/domain/entities/repositories/IUserRepository.ts
  • package.json
💤 Files with no reviewable changes (14)
  • features/core/ui/index.ts
  • features/core/ui/components/dialogs/ActionModal/ActionModal.tsx
  • features/core/ui/components/dialogs/ActionModal/ActionModal.logic.ts
  • features/core/ui/components/dialogs/InfoModal/InfoModal.tsx
  • features/core/ui/components/dialogs/InfoModal/InfoModal.logic.ts
  • features/core/state/modal/useModalState.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.style.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.logic.ts
  • features/auth/ui/components/ResetPasswordModal/ResetPasswordModal.tsx
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/useKeyboardEffect.ts
  • features/core/ui/components/dialogs/ModalTemplate/ModalTemplateContainer/ModalTemplateContainer.tsx
  • features/core/state/modal/modalStore.ts
  • features/core/state/index.ts
  • features/auth/ui/components/ResetPasswordModal/ResetPasswordModal.logic.ts

Comment thread app/(main)/(authenticated)/create-trip/_layout.tsx Outdated
Comment thread app/(main)/(authenticated)/create-trip/_layout.tsx Outdated
Comment thread features/profile/ui/pages/ProfilePage/ProfilePage.logic.ts
Comment thread features/trip-generation/domain/schemas/GenerateTripSchema.ts
Comment thread features/trips/ui/components/TypicalDishesList/TypicalDishesList.tsx Outdated
Comment thread features/trips/ui/pages/TypicalDishesModalPage/TypicalDishesModalPage.logic.ts Outdated
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

…eRepository

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@timothyrusso timothyrusso merged commit bba3281 into main Jun 1, 2026
4 checks passed
@timothyrusso timothyrusso deleted the feature/310 branch June 1, 2026 13:14
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.

[APP] Add Expo Router formSheet modal for typical dish details

1 participant