feat: initial implementation — all 35 requirements across phases 1-3
Backend (Spring Boot 3.2 / Java 21 / PostgreSQL): - JWT auth with BCrypt password hashing - User profile + Mifflin-St Jeor BMR calculator - Food search + barcode via OpenFoodFacts API with local cache - Meal CRUD with user data isolation and ownership checks - AI photo analysis (OpenAI Vision) with confidence intervals - AI correction feedback loop for personalisation - Flyway DB migrations + RFC-7807 error responses Mobile (React Native / TypeScript): - Full navigation stack (Auth → Tabs → Home stack) - Design tokens (WCAG 2.2 AA colours, 8px grid, 48px touch targets) - 10 screens: Login, Register, Home, Search, Camera, AI Result, Edit Meal, Daily Details, History, Profile - Confidence-aware calorie display (kcal ± range) - Repeat last meal shortcut + macro tracking Docs: - docs/PLAN-AND-REQUIREMENTS.md - docs/traceability.csv (35 requirements, all Implemented)
This commit is contained in:
42
mobile/src/components/FoodRow.tsx
Normal file
42
mobile/src/components/FoodRow.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
// Generated by GitHub Copilot
|
||||
import React from 'react';
|
||||
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
|
||||
import { FoodItem } from '../services/api';
|
||||
import { Colors } from '../theme/colors';
|
||||
import { Spacing } from '../theme/spacing';
|
||||
|
||||
interface FoodRowProps {
|
||||
item: FoodItem;
|
||||
onSelect: (item: FoodItem) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single food result row in the search screen.
|
||||
* REQ-MOB-006
|
||||
*/
|
||||
export default function FoodRow({ item, onSelect }: FoodRowProps) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.row}
|
||||
onPress={() => onSelect(item)}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`${item.name}, ${item.caloriesPer100g} calories per 100 grams`}
|
||||
>
|
||||
<Text style={styles.name}>{item.name}</Text>
|
||||
<Text style={styles.kcal}>{item.caloriesPer100g} kcal / 100g</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
minHeight: Spacing.touchTarget,
|
||||
paddingHorizontal: Spacing.md,
|
||||
paddingVertical: Spacing.sm,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: Colors.gray100,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
name: { fontSize: 16, fontWeight: '500', color: Colors.gray900 },
|
||||
kcal: { fontSize: 13, color: Colors.gray500, marginTop: 2 },
|
||||
});
|
||||
Reference in New Issue
Block a user