managarten/apps-archived/nutriphi/apps/mobile/components/meals/FoodItemList.tsx
Till-JS 61d181fbc2 chore: archive inactive projects to apps-archived/
Move inactive projects out of active workspace:
- bauntown (community website)
- maerchenzauber (AI story generation)
- memoro (voice memo app)
- news (news aggregation)
- nutriphi (nutrition tracking)
- reader (reading app)
- uload (URL shortener)
- wisekeep (AI wisdom extraction)

Update CLAUDE.md documentation:
- Add presi to active projects
- Document archived projects section
- Update workspace configuration

Archived apps can be re-activated by moving back to apps/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 07:03:59 +01:00

162 lines
3.9 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import { FoodItem } from '@/types/Database';
import { FoodItemCard } from './FoodItemCard';
interface FoodItemListProps {
foodItems: FoodItem[];
title?: string;
showTitle?: boolean;
}
export const FoodItemList: React.FC<FoodItemListProps> = ({
foodItems,
title = 'Erkannte Lebensmittel',
showTitle = true,
}) => {
if (!foodItems || foodItems.length === 0) {
return (
<View className="py-4">
{showTitle && <Text className="mb-3 text-lg font-semibold text-gray-900">{title}</Text>}
<View className="items-center rounded-lg bg-gray-50 p-6">
<Text className="mb-2 text-4xl">🍽</Text>
<Text className="text-center text-gray-600">Keine Lebensmittel erkannt</Text>
</View>
</View>
);
}
const getCategoryIcon = (category: string) => {
switch (category) {
case 'protein':
return '🥩';
case 'vegetable':
return '🥕';
case 'grain':
return '🌾';
case 'fruit':
return '🍎';
case 'dairy':
return '🥛';
case 'fat':
return '🥑';
case 'processed':
return '📦';
case 'beverage':
return '🥤';
default:
return '🍽️';
}
};
const getCategoryColor = (category: string) => {
switch (category) {
case 'protein':
return 'border-red-200 bg-red-50';
case 'vegetable':
return 'border-green-200 bg-green-50';
case 'grain':
return 'border-yellow-200 bg-yellow-50';
case 'fruit':
return 'border-orange-200 bg-orange-50';
case 'dairy':
return 'border-blue-200 bg-blue-50';
case 'fat':
return 'border-purple-200 bg-purple-50';
case 'processed':
return 'border-gray-200 bg-gray-50';
case 'beverage':
return 'border-cyan-200 bg-cyan-50';
default:
return 'border-gray-200 bg-gray-50';
}
};
// Group food items by category
const groupedByCategory = foodItems.reduce(
(acc, item) => {
const category = item.category || 'other';
if (!acc[category]) {
acc[category] = [];
}
acc[category].push(item);
return acc;
},
{} as Record<string, FoodItem[]>
);
const categoryOrder = [
'protein',
'vegetable',
'grain',
'fruit',
'dairy',
'fat',
'beverage',
'processed',
'other',
];
const sortedCategories = categoryOrder.filter((category) => groupedByCategory[category]);
const otherCategories = Object.keys(groupedByCategory).filter(
(category) => !categoryOrder.includes(category)
);
const allCategories = [...sortedCategories, ...otherCategories];
const getCategoryName = (category: string) => {
switch (category) {
case 'protein':
return 'Proteine';
case 'vegetable':
return 'Gemüse';
case 'grain':
return 'Getreide';
case 'fruit':
return 'Obst';
case 'dairy':
return 'Milchprodukte';
case 'fat':
return 'Fette';
case 'processed':
return 'Verarbeitete Lebensmittel';
case 'beverage':
return 'Getränke';
default:
return 'Sonstige';
}
};
return (
<View className="py-4">
{showTitle && (
<Text className="mb-4 text-lg font-semibold text-gray-900">
{title} ({foodItems.length})
</Text>
)}
<ScrollView showsVerticalScrollIndicator={false}>
{allCategories.map((category) => (
<View key={category} className="mb-6">
{/* Category Header */}
<View className="mb-3 flex-row items-center">
<Text className="mr-2 text-2xl">{getCategoryIcon(category)}</Text>
<Text className="text-base font-medium text-gray-800">
{getCategoryName(category)} ({groupedByCategory[category].length})
</Text>
</View>
{/* Category Items */}
<View className="space-y-2">
{groupedByCategory[category].map((item, index) => (
<FoodItemCard
key={item.id || `${category}-${index}`}
foodItem={item}
categoryColor={getCategoryColor(category)}
/>
))}
</View>
</View>
))}
</ScrollView>
</View>
);
};