Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 54 additions & 49 deletions apps/expo/app/(app)/(tabs)/(home)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ListSectionHeader,
} from '@packrat/ui/nativewindui';
import { Icon } from 'expo-app/components/Icon';
import { LargeTitleHeaderSearchContentContainer } from 'expo-app/components/LargeTitleHeaderSearchContentContainer';
import TabScreen from 'expo-app/components/TabScreen';
import { appConfig, featureFlags } from 'expo-app/config';
import { AIChatTile } from 'expo-app/features/ai/components/AIChatTile';
Expand Down Expand Up @@ -235,57 +236,61 @@ export default function DashboardScreen() {
ref: asNonNullableRef(searchBarRef),
onChangeText: setSearchValue,
placeholder: appConfig.dashboard.strings.searchPlaceholder,
content: searchValue ? (
<FlatList
data={filteredTiles}
keyExtractor={keyExtractor}
className="space-y-4 px-4"
renderItem={({ item }) => {
assertIsString(item);
if (!item.startsWith(DASHBOARD_GAP_PREFIX)) {
const Component = tileInfo[item as TileName].component;
return (
<Pressable
key={item}
className="rounded-2xl overflow-hidden "
onPress={() => {
setSearchValue('');
searchBarRef.current?.clearText();
}}
>
<Component />
</Pressable>
);
}
return null;
}}
ListHeaderComponent={() =>
filteredTiles.length > 0 ? (
<Text className="px-4 py-2 text-sm text-muted-foreground">
{filteredTiles.length}{' '}
{filteredTiles.length === 1
? appConfig.dashboard.strings.resultSingular
: appConfig.dashboard.strings.resultPlural}
</Text>
) : null
}
ListEmptyComponent={() => (
<View className="items-center justify-center p-6">
<Icon name="file-search-outline" size={48} color="#9ca3af" />
<View className="h-4" />
<Text className="text-lg font-medium text-muted-foreground">
{t('dashboard.noResults')}
</Text>
<Text className="mt-1 text-center text-sm text-muted-foreground">
{t('dashboard.tryDifferent')}
</Text>
content: (
<LargeTitleHeaderSearchContentContainer>
{searchValue ? (
<FlatList
data={filteredTiles}
keyExtractor={keyExtractor}
contentContainerClassName="gap-4 px-4 pb-4"
renderItem={({ item }) => {
assertIsString(item);
if (!item.startsWith(DASHBOARD_GAP_PREFIX)) {
const Component = tileInfo[item as TileName].component;
return (
<Pressable
key={item}
className="rounded-2xl overflow-hidden "
onPress={() => {
setSearchValue('');
searchBarRef.current?.clearText();
}}
>
<Component />
</Pressable>
);
}
return null;
}}
ListHeaderComponent={() =>
filteredTiles.length > 0 ? (
<Text className="px-4 py-2 text-sm text-muted-foreground">
{filteredTiles.length}{' '}
{filteredTiles.length === 1
? appConfig.dashboard.strings.resultSingular
: appConfig.dashboard.strings.resultPlural}
</Text>
) : null
}
ListEmptyComponent={() => (
<View className="items-center justify-center p-6">
<Icon name="file-search-outline" size={48} color="#9ca3af" />
<View className="h-4" />
<Text className="text-lg font-medium text-muted-foreground">
{t('dashboard.noResults')}
</Text>
<Text className="mt-1 text-center text-sm text-muted-foreground">
{t('dashboard.tryDifferent')}
</Text>
</View>
)}
/>
) : (
<View className="flex-1 items-center justify-center p-4">
<Text className="text-muted-foreground">{t('dashboard.searchPlaceholder')}</Text>
</View>
)}
/>
) : (
<View className="flex-1 items-center justify-center p-4">
<Text className="text-muted-foreground">{t('dashboard.searchPlaceholder')}</Text>
</View>
</LargeTitleHeaderSearchContentContainer>
),
}}
backVisible={false}
Expand Down
14 changes: 14 additions & 0 deletions apps/expo/components/LargeTitleHeaderSearchContentContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useColorScheme } from '@packrat/ui/nativewindui';
import { Platform, SafeAreaView, View } from 'react-native';

export const LargeTitleHeaderSearchContentContainer = ({
children,
}: {
children: React.ReactNode;
}) => {
const { colors } = useColorScheme();

const Container = Platform.OS === 'ios' ? SafeAreaView : View;

return <Container style={{ flex: 1, backgroundColor: colors.background }}>{children}</Container>;
};
5 changes: 3 additions & 2 deletions apps/expo/features/catalog/screens/CatalogItemsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LargeTitleHeader, type LargeTitleSearchBarMethods, Text } from '@packra
import { searchValueAtom } from 'expo-app/atoms/itemListAtoms';
import { CategoriesFilter } from 'expo-app/components/CategoriesFilter';
import { Icon } from 'expo-app/components/Icon';
import { LargeTitleHeaderSearchContentContainer } from 'expo-app/components/LargeTitleHeaderSearchContentContainer';
import TabScreen from 'expo-app/components/TabScreen';
import { withAuthWall } from 'expo-app/features/auth/hocs';
import { useColorScheme } from 'expo-app/lib/hooks/useColorScheme';
Expand Down Expand Up @@ -141,7 +142,7 @@ function CatalogItemsScreen() {

placeholder: t('catalog.searchPlaceholder'),
content: (
<View style={{ flex: 1, backgroundColor: colors.background }}>
<LargeTitleHeaderSearchContentContainer>
{isSearching ? (
isVectorLoading || !isQueryReady ? (
<View className="flex-1 items-center justify-center p-6">
Expand Down Expand Up @@ -199,7 +200,7 @@ function CatalogItemsScreen() {
<Text className="text-muted-foreground">{t('catalog.searchCatalog')}</Text>
</View>
)}
</View>
</LargeTitleHeaderSearchContentContainer>
),
}}
/>
Expand Down
49 changes: 23 additions & 26 deletions apps/expo/features/packs/components/SearchResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,30 @@ type SearchResultsProps = {
export function SearchResults({ results, searchValue, onResultPress }: SearchResultsProps) {
if (!searchValue) return null;

return (
<View className="max-h-80 w-full rounded-lg bg-card shadow-sm">
{results.length > 0 ? (
<FlatList
data={results}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<Pressable
onPress={() => onResultPress(item)}
className="flex-row items-center border-b border-border px-4 py-3 active:bg-muted"
>
<View className="mr-3 rounded-full bg-muted p-2">
<Icon name="backpack" size={16} color="text-muted-foreground" />
</View>
<View className="flex-1">
<Text className="font-medium text-foreground">{item.name}</Text>
<Text className="text-sm text-muted-foreground">{item.category}</Text>
</View>
<Icon name="chevron-right" size={16} color="text-muted-foreground" />
</Pressable>
)}
/>
) : (
<View className="items-center justify-center p-4">
<Text className="text-muted-foreground">No packs found for "{searchValue}"</Text>
</View>
return results.length > 0 ? (
<FlatList
data={results}
keyExtractor={(item) => item.id}
contentContainerClassName="pb-4"
renderItem={({ item }) => (
<Pressable
onPress={() => onResultPress(item)}
className="flex-row items-center border-b border-border px-4 py-3 active:bg-muted"
>
<View className="mr-3 rounded-full bg-muted p-2">
<Icon name="backpack" size={16} color="text-muted-foreground" />
</View>
<View className="flex-1">
<Text className="font-medium text-foreground">{item.name}</Text>
<Text className="text-sm text-muted-foreground">{item.category}</Text>
</View>
<Icon name="chevron-right" size={16} color="text-muted-foreground" />
</Pressable>
)}
/>
) : (
<View className="items-center justify-center p-4">
<Text className="text-muted-foreground">No packs found for "{searchValue}"</Text>
</View>
);
}
25 changes: 15 additions & 10 deletions apps/expo/features/packs/screens/PackListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
SegmentedControl,
} from '@packrat/ui/nativewindui';
import { Icon } from 'expo-app/components/Icon';
import { LargeTitleHeaderSearchContentContainer } from 'expo-app/components/LargeTitleHeaderSearchContentContainer';
import TabScreen from 'expo-app/components/TabScreen';
import { useAuth } from 'expo-app/features/auth/hooks/useAuth';
import { PackCard } from 'expo-app/features/packs/components/PackCard';
Expand Down Expand Up @@ -189,16 +190,20 @@ export function PackListScreen() {
onChangeText(text) {
setSearchValue(text);
},
content: searchValue ? (
<SearchResults
results={filteredPacks || []}
searchValue={searchValue}
onResultPress={handleSearchResultPress}
/>
) : (
<View className="flex-1 items-center justify-center">
<Text>{t('packs.searchPacks')}</Text>
</View>
content: (
<LargeTitleHeaderSearchContentContainer>
{searchValue ? (
<SearchResults
results={filteredPacks || []}
searchValue={searchValue}
onResultPress={handleSearchResultPress}
/>
) : (
<View className="flex-1 items-center justify-center">
<Text>{t('packs.searchPacks')}</Text>
</View>
)}
</LargeTitleHeaderSearchContentContainer>
),
}}
rightView={() => (
Expand Down
9 changes: 6 additions & 3 deletions apps/expo/features/trips/screens/TripListScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LargeTitleHeader, type LargeTitleSearchBarMethods } from '@packrat/ui/nativewindui';
import { Icon } from 'expo-app/components/Icon';
import { LargeTitleHeaderSearchContentContainer } from 'expo-app/components/LargeTitleHeaderSearchContentContainer';
import TabScreen from 'expo-app/components/TabScreen';
import { useColorScheme } from 'expo-app/lib/hooks/useColorScheme';
import { useTranslation } from 'expo-app/lib/hooks/useTranslation';
Expand Down Expand Up @@ -108,9 +109,11 @@ export function TripsListScreen() {
ref: asNonNullableRef(searchBarRef),
onChangeText: setSearchValue,
content: (
<View className="flex-1 items-center justify-center">
<Text>{t('trips.searchTrips')}</Text>
</View>
<LargeTitleHeaderSearchContentContainer>
<View className="flex-1 items-center justify-center">
<Text>{t('trips.searchTrips')}</Text>
</View>
</LargeTitleHeaderSearchContentContainer>
),
}}
rightView={() => (
Expand Down
Loading