From 6b9361ad6ffa087ff51a0c006961b6f541ff9c26 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 11:00:23 +0000
Subject: [PATCH 1/9] Initial plan
From 4638cfb6dd4fdadc6a75378556dd15250f35cb29 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 11:10:58 +0000
Subject: [PATCH 2/9] Implement Trips feature: fix edit title bug, add barrel
export, date display, and search filtering
Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
---
.../features/trips/components/TripCard.tsx | 18 ++++++++++++++++++
apps/expo/features/trips/index.ts | 2 ++
.../features/trips/screens/TripListScreen.tsx | 18 +++++++++++++++---
3 files changed, 35 insertions(+), 3 deletions(-)
create mode 100644 apps/expo/features/trips/index.ts
diff --git a/apps/expo/features/trips/components/TripCard.tsx b/apps/expo/features/trips/components/TripCard.tsx
index d7f1884456..374c58e65f 100644
--- a/apps/expo/features/trips/components/TripCard.tsx
+++ b/apps/expo/features/trips/components/TripCard.tsx
@@ -10,6 +10,12 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useDeleteTrip } from '../hooks/useDeleteTrip';
import type { Trip } from '../types';
+function formatTripDate(dateString?: string): string {
+ if (!dateString) return '—';
+ const datePart = dateString.split('T')[0];
+ return datePart ?? '—';
+}
+
interface TripCardProps {
trip: Trip;
onPress?: (trip: Trip) => void;
@@ -117,6 +123,18 @@ export function TripCard({ trip, onPress }: TripCardProps) {
+ {/* Dates */}
+ {(trip.startDate || trip.endDate) && (
+
+
+
+ {formatTripDate(trip.startDate)}
+ {' → '}
+ {formatTripDate(trip.endDate)}
+
+
+ )}
+
{/* Description */}
{trip.description && (
diff --git a/apps/expo/features/trips/index.ts b/apps/expo/features/trips/index.ts
new file mode 100644
index 0000000000..a9a0a249f5
--- /dev/null
+++ b/apps/expo/features/trips/index.ts
@@ -0,0 +1,2 @@
+export * from './hooks';
+export * from './types';
diff --git a/apps/expo/features/trips/screens/TripListScreen.tsx b/apps/expo/features/trips/screens/TripListScreen.tsx
index 05f9a4dd5d..e16e97d69c 100644
--- a/apps/expo/features/trips/screens/TripListScreen.tsx
+++ b/apps/expo/features/trips/screens/TripListScreen.tsx
@@ -6,7 +6,7 @@ import { useTranslation } from 'expo-app/lib/hooks/useTranslation';
import { TestIds } from 'expo-app/lib/testIds';
import { asNonNullableRef } from 'expo-app/lib/utils/asNonNullableRef';
import { Link, useRouter } from 'expo-router';
-import { useCallback, useRef } from 'react';
+import { useCallback, useMemo, useRef, useState } from 'react';
import { FlatList, Pressable, Text, TouchableOpacity, View } from 'react-native';
import { TripCard } from '../components/TripCard';
import { useTrips } from '../hooks';
@@ -29,6 +29,18 @@ export function TripsListScreen() {
const { t } = useTranslation();
const trips = useTrips();
const searchBarRef = useRef(null);
+ const [searchValue, setSearchValue] = useState('');
+
+ const filteredTrips = useMemo(() => {
+ if (!searchValue.trim()) return trips;
+ const lower = searchValue.toLowerCase();
+ return trips.filter(
+ (trip) =>
+ trip.name.toLowerCase().includes(lower) ||
+ trip.description?.toLowerCase().includes(lower) ||
+ trip.location?.name?.toLowerCase().includes(lower),
+ );
+ }, [trips, searchValue]);
const handleTripPress = useCallback(
(trip: Trip) => {
@@ -64,7 +76,7 @@ export function TripsListScreen() {
searchBar={{
iosHideWhenScrolling: true,
ref: asNonNullableRef(searchBarRef),
- onChangeText() {}, // no search filtering
+ onChangeText: setSearchValue,
content: (
{t('trips.searchTrips')}
@@ -79,7 +91,7 @@ export function TripsListScreen() {
/>
trip.id}
renderItem={({ item: trip }) => (
From 744753c4ea8bcfaf53be2aee3284c3d19a7002a2 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 12:28:33 +0000
Subject: [PATCH 3/9] Address CodeRabbit feedback: locale-aware date
formatting, differentiated empty states
Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
---
apps/expo/features/trips/components/TripCard.tsx | 5 +++--
apps/expo/features/trips/screens/TripListScreen.tsx | 9 +++++++++
apps/expo/lib/i18n/locales/en.json | 1 +
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/apps/expo/features/trips/components/TripCard.tsx b/apps/expo/features/trips/components/TripCard.tsx
index 374c58e65f..42f944f93a 100644
--- a/apps/expo/features/trips/components/TripCard.tsx
+++ b/apps/expo/features/trips/components/TripCard.tsx
@@ -12,8 +12,9 @@ import type { Trip } from '../types';
function formatTripDate(dateString?: string): string {
if (!dateString) return '—';
- const datePart = dateString.split('T')[0];
- return datePart ?? '—';
+ const date = new Date(dateString);
+ if (Number.isNaN(date.getTime())) return '—';
+ return date.toLocaleDateString();
}
interface TripCardProps {
diff --git a/apps/expo/features/trips/screens/TripListScreen.tsx b/apps/expo/features/trips/screens/TripListScreen.tsx
index e16e97d69c..0acf6dd5e0 100644
--- a/apps/expo/features/trips/screens/TripListScreen.tsx
+++ b/apps/expo/features/trips/screens/TripListScreen.tsx
@@ -54,6 +54,15 @@ export function TripsListScreen() {
};
const renderEmptyState = () => {
+ if (searchValue.trim() && trips.length > 0) {
+ return (
+
+
+ {t('trips.noSearchResults')}
+
+
+ );
+ }
return (
diff --git a/apps/expo/lib/i18n/locales/en.json b/apps/expo/lib/i18n/locales/en.json
index a747dfd5a6..290569fbe9 100644
--- a/apps/expo/lib/i18n/locales/en.json
+++ b/apps/expo/lib/i18n/locales/en.json
@@ -389,6 +389,7 @@
"tripLocation": "Trip Location",
"noTrips": "No trips available",
"noTripsFound": "No trips found",
+ "noSearchResults": "No trips match your search.",
"noTripsYet": "You haven't created any trips yet.",
"createNewTrip": "Create New Trip",
"upcomingTrips": "Upcoming Trips",
From 35e7691b8713444ef469bb2e0330b881fc2cf748 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 16:55:13 +0000
Subject: [PATCH 4/9] fix: parse YYYY-MM-DD date strings as local dates to
avoid UTC offset bug
Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
---
apps/expo/features/trips/components/TripCard.tsx | 9 ++++++++-
.../expo/features/trips/components/UpcomingTripsTile.tsx | 9 ++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/apps/expo/features/trips/components/TripCard.tsx b/apps/expo/features/trips/components/TripCard.tsx
index 42f944f93a..3c1af6258a 100644
--- a/apps/expo/features/trips/components/TripCard.tsx
+++ b/apps/expo/features/trips/components/TripCard.tsx
@@ -12,7 +12,14 @@ import type { Trip } from '../types';
function formatTripDate(dateString?: string): string {
if (!dateString) return '—';
- const date = new Date(dateString);
+ const dateOnlyMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
+ const date = dateOnlyMatch
+ ? new Date(
+ Number(dateOnlyMatch[1]),
+ Number(dateOnlyMatch[2]) - 1,
+ Number(dateOnlyMatch[3]),
+ )
+ : new Date(dateString);
if (Number.isNaN(date.getTime())) return '—';
return date.toLocaleDateString();
}
diff --git a/apps/expo/features/trips/components/UpcomingTripsTile.tsx b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
index 29314dc994..8ff58329a9 100644
--- a/apps/expo/features/trips/components/UpcomingTripsTile.tsx
+++ b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
@@ -8,6 +8,13 @@ import { useRouter } from 'expo-router';
import { useMemo, useRef, useState } from 'react';
import { View } from 'react-native';
+function parseLocalDate(dateString: string): Date {
+ const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
+ return m
+ ? new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]))
+ : new Date(dateString);
+}
+
export function UpcomingTripsTile() {
const router = useRouter();
const { t } = useTranslation();
@@ -19,7 +26,7 @@ export function UpcomingTripsTile() {
// ✅ derive upcoming trips (in future)
const upcomingTrips = useMemo(
- () => trips.filter((t) => t.startDate && new Date(t.startDate) > new Date()),
+ () => trips.filter((t) => t.startDate && parseLocalDate(t.startDate) > new Date()),
[trips],
);
From e751b0274c5ffd847b26dd39b6f015d96b44b1cb Mon Sep 17 00:00:00 2001
From: Andrew Bierman
Date: Mon, 9 Mar 2026 12:16:32 -0600
Subject: [PATCH 5/9] refactor: extract shared date parsing utility and fix
Trip type definition
- Extract duplicated local-date parsing logic from TripCard.tsx and
UpcomingTripsTile.tsx into a shared dateUtils.ts utility (parseLocalDate
and formatLocalDate), addressing CodeRabbit review feedback
- Fix TripInStore type that was using Omit where Trip has
no 'trips' property, making the Omit a no-op
---
.../features/trips/components/TripCard.tsx | 19 +++----------
.../trips/components/UpcomingTripsTile.tsx | 14 +++++-----
apps/expo/features/trips/types.ts | 2 +-
apps/expo/lib/utils/dateUtils.ts | 27 +++++++++++++++++++
4 files changed, 37 insertions(+), 25 deletions(-)
create mode 100644 apps/expo/lib/utils/dateUtils.ts
diff --git a/apps/expo/features/trips/components/TripCard.tsx b/apps/expo/features/trips/components/TripCard.tsx
index 3c1af6258a..7fab009fbc 100644
--- a/apps/expo/features/trips/components/TripCard.tsx
+++ b/apps/expo/features/trips/components/TripCard.tsx
@@ -3,6 +3,7 @@ import { Alert, type AlertMethods, Button } from '@packrat/ui/nativewindui';
import { Icon } from '@roninoss/icons';
import { useColorScheme } from 'expo-app/lib/hooks/useColorScheme';
import { useTranslation } from 'expo-app/lib/hooks/useTranslation';
+import { formatLocalDate } from 'expo-app/lib/utils/dateUtils';
import { useRouter } from 'expo-router';
import { useRef } from 'react';
import { Pressable, Text, View } from 'react-native';
@@ -10,20 +11,6 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useDeleteTrip } from '../hooks/useDeleteTrip';
import type { Trip } from '../types';
-function formatTripDate(dateString?: string): string {
- if (!dateString) return '—';
- const dateOnlyMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
- const date = dateOnlyMatch
- ? new Date(
- Number(dateOnlyMatch[1]),
- Number(dateOnlyMatch[2]) - 1,
- Number(dateOnlyMatch[3]),
- )
- : new Date(dateString);
- if (Number.isNaN(date.getTime())) return '—';
- return date.toLocaleDateString();
-}
-
interface TripCardProps {
trip: Trip;
onPress?: (trip: Trip) => void;
@@ -136,9 +123,9 @@ export function TripCard({ trip, onPress }: TripCardProps) {
- {formatTripDate(trip.startDate)}
+ {formatLocalDate(trip.startDate)}
{' → '}
- {formatTripDate(trip.endDate)}
+ {formatLocalDate(trip.endDate)}
)}
diff --git a/apps/expo/features/trips/components/UpcomingTripsTile.tsx b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
index 8ff58329a9..6b0349433e 100644
--- a/apps/expo/features/trips/components/UpcomingTripsTile.tsx
+++ b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
@@ -4,17 +4,11 @@ import { Icon } from '@roninoss/icons';
import { featureFlags } from 'expo-app/config';
import { useTrips } from 'expo-app/features/trips/hooks';
import { useTranslation } from 'expo-app/lib/hooks/useTranslation';
+import { parseLocalDate } from 'expo-app/lib/utils/dateUtils';
import { useRouter } from 'expo-router';
import { useMemo, useRef, useState } from 'react';
import { View } from 'react-native';
-function parseLocalDate(dateString: string): Date {
- const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
- return m
- ? new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]))
- : new Date(dateString);
-}
-
export function UpcomingTripsTile() {
const router = useRouter();
const { t } = useTranslation();
@@ -26,7 +20,11 @@ export function UpcomingTripsTile() {
// ✅ derive upcoming trips (in future)
const upcomingTrips = useMemo(
- () => trips.filter((t) => t.startDate && parseLocalDate(t.startDate) > new Date()),
+ () => trips.filter((t) => {
+ if (!t.startDate) return false;
+ const parsed = parseLocalDate(t.startDate);
+ return parsed != null && parsed > new Date();
+ }),
[trips],
);
diff --git a/apps/expo/features/trips/types.ts b/apps/expo/features/trips/types.ts
index 81ac2418d1..2d59bb5b50 100644
--- a/apps/expo/features/trips/types.ts
+++ b/apps/expo/features/trips/types.ts
@@ -26,7 +26,7 @@ export interface Trip {
localUpdatedAt?: string;
}
-export type TripInStore = Omit;
+export type TripInStore = Trip;
export type TripInput = Omit<
TripInStore,
diff --git a/apps/expo/lib/utils/dateUtils.ts b/apps/expo/lib/utils/dateUtils.ts
new file mode 100644
index 0000000000..abfce8d1e7
--- /dev/null
+++ b/apps/expo/lib/utils/dateUtils.ts
@@ -0,0 +1,27 @@
+/**
+ * Parse a date string, handling YYYY-MM-DD strings as local dates
+ * instead of UTC (which is the default `new Date('YYYY-MM-DD')` behavior).
+ *
+ * Returns `null` for missing or invalid input.
+ */
+export function parseLocalDate(dateString?: string): Date | null {
+ if (!dateString) return null;
+ const dateOnlyMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
+ const date = dateOnlyMatch
+ ? new Date(
+ Number(dateOnlyMatch[1]),
+ Number(dateOnlyMatch[2]) - 1,
+ Number(dateOnlyMatch[3]),
+ )
+ : new Date(dateString);
+ return Number.isNaN(date.getTime()) ? null : date;
+}
+
+/**
+ * Format a date string for display, returning an em-dash for missing or
+ * invalid values. Uses the user's locale via `toLocaleDateString()`.
+ */
+export function formatLocalDate(dateString?: string): string {
+ const date = parseLocalDate(dateString);
+ return date ? date.toLocaleDateString() : '\u2014';
+}
From 16ae77e997f9fd78ffe6ee9ca068755b4fe81acb Mon Sep 17 00:00:00 2001
From: Andrew Bierman
Date: Mon, 9 Mar 2026 12:44:11 -0600
Subject: [PATCH 6/9] fix: resolve biome lint and type check errors
---
apps/expo/features/trips/components/TripCard.tsx | 2 +-
.../features/trips/components/UpcomingTripsTile.tsx | 11 ++++++-----
apps/expo/features/trips/screens/TripListScreen.tsx | 4 +---
apps/expo/lib/utils/dateUtils.ts | 6 +-----
4 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/apps/expo/features/trips/components/TripCard.tsx b/apps/expo/features/trips/components/TripCard.tsx
index 7fab009fbc..a4cf7ac505 100644
--- a/apps/expo/features/trips/components/TripCard.tsx
+++ b/apps/expo/features/trips/components/TripCard.tsx
@@ -121,7 +121,7 @@ export function TripCard({ trip, onPress }: TripCardProps) {
{/* Dates */}
{(trip.startDate || trip.endDate) && (
-
+
{formatLocalDate(trip.startDate)}
{' → '}
diff --git a/apps/expo/features/trips/components/UpcomingTripsTile.tsx b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
index 6b0349433e..5c1c9c0602 100644
--- a/apps/expo/features/trips/components/UpcomingTripsTile.tsx
+++ b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
@@ -20,11 +20,12 @@ export function UpcomingTripsTile() {
// ✅ derive upcoming trips (in future)
const upcomingTrips = useMemo(
- () => trips.filter((t) => {
- if (!t.startDate) return false;
- const parsed = parseLocalDate(t.startDate);
- return parsed != null && parsed > new Date();
- }),
+ () =>
+ trips.filter((t) => {
+ if (!t.startDate) return false;
+ const parsed = parseLocalDate(t.startDate);
+ return parsed != null && parsed > new Date();
+ }),
[trips],
);
diff --git a/apps/expo/features/trips/screens/TripListScreen.tsx b/apps/expo/features/trips/screens/TripListScreen.tsx
index 0acf6dd5e0..7a751bd0fe 100644
--- a/apps/expo/features/trips/screens/TripListScreen.tsx
+++ b/apps/expo/features/trips/screens/TripListScreen.tsx
@@ -57,9 +57,7 @@ export function TripsListScreen() {
if (searchValue.trim() && trips.length > 0) {
return (
-
- {t('trips.noSearchResults')}
-
+ {t('trips.noSearchResults')}
);
}
diff --git a/apps/expo/lib/utils/dateUtils.ts b/apps/expo/lib/utils/dateUtils.ts
index abfce8d1e7..ae9f24a66f 100644
--- a/apps/expo/lib/utils/dateUtils.ts
+++ b/apps/expo/lib/utils/dateUtils.ts
@@ -8,11 +8,7 @@ export function parseLocalDate(dateString?: string): Date | null {
if (!dateString) return null;
const dateOnlyMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
const date = dateOnlyMatch
- ? new Date(
- Number(dateOnlyMatch[1]),
- Number(dateOnlyMatch[2]) - 1,
- Number(dateOnlyMatch[3]),
- )
+ ? new Date(Number(dateOnlyMatch[1]), Number(dateOnlyMatch[2]) - 1, Number(dateOnlyMatch[3]))
: new Date(dateString);
return Number.isNaN(date.getTime()) ? null : date;
}
From 8246455a6d06da9c3d84005e27ed98545db77d4b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 19:40:15 +0000
Subject: [PATCH 7/9] Fix null-safety in trip filter and validate date
components in parseLocalDate
Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
---
.../features/trips/screens/TripListScreen.tsx | 4 ++--
apps/expo/lib/utils/dateUtils.ts | 15 ++++++++++++---
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/apps/expo/features/trips/screens/TripListScreen.tsx b/apps/expo/features/trips/screens/TripListScreen.tsx
index 7a751bd0fe..796ad0afe1 100644
--- a/apps/expo/features/trips/screens/TripListScreen.tsx
+++ b/apps/expo/features/trips/screens/TripListScreen.tsx
@@ -37,8 +37,8 @@ export function TripsListScreen() {
return trips.filter(
(trip) =>
trip.name.toLowerCase().includes(lower) ||
- trip.description?.toLowerCase().includes(lower) ||
- trip.location?.name?.toLowerCase().includes(lower),
+ (trip.description ?? '').toLowerCase().includes(lower) ||
+ (trip.location?.name ?? '').toLowerCase().includes(lower),
);
}, [trips, searchValue]);
diff --git a/apps/expo/lib/utils/dateUtils.ts b/apps/expo/lib/utils/dateUtils.ts
index ae9f24a66f..d8a4f20b70 100644
--- a/apps/expo/lib/utils/dateUtils.ts
+++ b/apps/expo/lib/utils/dateUtils.ts
@@ -7,9 +7,18 @@
export function parseLocalDate(dateString?: string): Date | null {
if (!dateString) return null;
const dateOnlyMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateString);
- const date = dateOnlyMatch
- ? new Date(Number(dateOnlyMatch[1]), Number(dateOnlyMatch[2]) - 1, Number(dateOnlyMatch[3]))
- : new Date(dateString);
+ if (dateOnlyMatch) {
+ const year = Number(dateOnlyMatch[1]);
+ const month = Number(dateOnlyMatch[2]);
+ const day = Number(dateOnlyMatch[3]);
+ const date = new Date(year, month - 1, day);
+ if (Number.isNaN(date.getTime())) return null;
+ if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
+ return null;
+ }
+ return date;
+ }
+ const date = new Date(dateString);
return Number.isNaN(date.getTime()) ? null : date;
}
From efae0aa2694a88cae01f24ffca1f08e383acce76 Mon Sep 17 00:00:00 2001
From: Andrew Bierman
Date: Mon, 9 Mar 2026 20:27:24 -0600
Subject: [PATCH 8/9] Fix CodeRabbit review issues on trips feature
- TripCard: Handle optional startDate/endDate with proper null checks,
only show arrow separator when both dates exist
- UpcomingTripsTile: Compare against start-of-today instead of current
time so same-day trips are included in upcoming filter
- TripListScreen: Trim search query before lowercasing to avoid missed
matches from trailing whitespace
---
apps/expo/features/trips/components/TripCard.tsx | 8 ++++----
apps/expo/features/trips/components/UpcomingTripsTile.tsx | 8 ++++++--
apps/expo/features/trips/screens/TripListScreen.tsx | 5 +++--
3 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/apps/expo/features/trips/components/TripCard.tsx b/apps/expo/features/trips/components/TripCard.tsx
index a4cf7ac505..3288d47391 100644
--- a/apps/expo/features/trips/components/TripCard.tsx
+++ b/apps/expo/features/trips/components/TripCard.tsx
@@ -119,13 +119,13 @@ export function TripCard({ trip, onPress }: TripCardProps) {
{/* Dates */}
- {(trip.startDate || trip.endDate) && (
+ {(trip.startDate != null || trip.endDate != null) && (
- {formatLocalDate(trip.startDate)}
- {' → '}
- {formatLocalDate(trip.endDate)}
+ {trip.startDate != null && trip.endDate != null
+ ? `${formatLocalDate(trip.startDate)} → ${formatLocalDate(trip.endDate)}`
+ : formatLocalDate(trip.startDate ?? trip.endDate)}
)}
diff --git a/apps/expo/features/trips/components/UpcomingTripsTile.tsx b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
index 5c1c9c0602..dd1a5d1765 100644
--- a/apps/expo/features/trips/components/UpcomingTripsTile.tsx
+++ b/apps/expo/features/trips/components/UpcomingTripsTile.tsx
@@ -18,13 +18,17 @@ export function UpcomingTripsTile() {
// ✅ get all trips
const trips = useTrips();
- // ✅ derive upcoming trips (in future)
+ // ✅ derive upcoming trips (today or in future)
const upcomingTrips = useMemo(
() =>
trips.filter((t) => {
if (!t.startDate) return false;
const parsed = parseLocalDate(t.startDate);
- return parsed != null && parsed > new Date();
+ if (parsed == null) return false;
+ // Compare against start-of-today so same-day trips are included
+ const startOfToday = new Date();
+ startOfToday.setHours(0, 0, 0, 0);
+ return parsed >= startOfToday;
}),
[trips],
);
diff --git a/apps/expo/features/trips/screens/TripListScreen.tsx b/apps/expo/features/trips/screens/TripListScreen.tsx
index 796ad0afe1..9fbdd6d797 100644
--- a/apps/expo/features/trips/screens/TripListScreen.tsx
+++ b/apps/expo/features/trips/screens/TripListScreen.tsx
@@ -32,8 +32,9 @@ export function TripsListScreen() {
const [searchValue, setSearchValue] = useState('');
const filteredTrips = useMemo(() => {
- if (!searchValue.trim()) return trips;
- const lower = searchValue.toLowerCase();
+ const trimmed = searchValue.trim();
+ if (!trimmed) return trips;
+ const lower = trimmed.toLowerCase();
return trips.filter(
(trip) =>
trip.name.toLowerCase().includes(lower) ||
From 9861f134030c3f900a32454cfcd80097e46fabd8 Mon Sep 17 00:00:00 2001
From: Andrew Bierman
Date: Fri, 10 Apr 2026 22:40:26 -0600
Subject: [PATCH 9/9] chore(trips): default enableTrips feature flag to false
The trips feature should ship disabled by default until it's
ready for release. Consumers can opt-in by toggling this flag.
---
apps/expo/config.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/expo/config.ts b/apps/expo/config.ts
index 04697d199d..1e50dd0d00 100644
--- a/apps/expo/config.ts
+++ b/apps/expo/config.ts
@@ -1,6 +1,6 @@
export const featureFlags = {
enableOAuth: true,
- enableTrips: true,
+ enableTrips: false,
enablePackInsights: false,
enableShoppingList: false,
enableSharedPacks: false,