Show product images

This commit is contained in:
2026-07-01 11:04:39 +02:00
parent 6776981db0
commit c730d36cfe
3 changed files with 69 additions and 3 deletions
+11 -3
View File
@@ -2,19 +2,25 @@ import { Pressable, StyleSheet, Text, View } from 'react-native';
import { colors } from '../../utils/constants';
import { formatPrice } from '../../utils/formatPrice';
import ProductImage from './ProductImage';
import ProductScoreBadge from './ProductScoreBadge';
export default function ProductCard({ product, rating, onPress }) {
return (
<Pressable accessibilityRole="button" onPress={onPress} style={styles.card}>
<View style={styles.topRow}>
<ProductImage imageUrl={product.imageUrl} />
<View style={styles.copy}>
<Text style={styles.name}>{product.name}</Text>
<Text style={styles.meta}>{product.brand || 'Ohne Marke'} · {formatPrice(product.price, product.currency)}</Text>
<Text style={styles.meta}>
{product.brand || 'Ohne Marke'} · {formatPrice(product.price, product.currency)}
</Text>
<Text style={styles.note}>
{product.category || 'Produkt'} · Barcode {product.barcode}
</Text>
</View>
{rating ? <ProductScoreBadge status={rating.overallStatus} score={rating.overallScore} /> : null}
</View>
<Text style={styles.note}>{product.category || 'Produkt'} · Barcode {product.barcode}</Text>
</Pressable>
);
}
@@ -48,6 +54,8 @@ const styles = StyleSheet.create({
},
note: {
color: colors.muted,
fontSize: 13
fontSize: 13,
lineHeight: 18,
marginTop: 8
}
});
+56
View File
@@ -0,0 +1,56 @@
import { Image, StyleSheet, Text, View } from 'react-native';
import { colors } from '../../utils/constants';
export default function ProductImage({ imageUrl, size = 'card' }) {
const style = size === 'large' ? styles.large : styles.card;
if (!imageUrl) {
return (
<View style={[styles.placeholder, style]}>
<Text style={styles.placeholderText}>Kein Bild</Text>
</View>
);
}
return (
<Image
accessibilityIgnoresInvertColors
resizeMode="contain"
source={{ uri: imageUrl }}
style={[styles.image, style]}
/>
);
}
const styles = StyleSheet.create({
image: {
backgroundColor: colors.surface,
borderColor: colors.border,
borderWidth: 1
},
card: {
borderRadius: 8,
height: 76,
width: 76
},
large: {
alignSelf: 'center',
borderRadius: 8,
height: 220,
width: '100%'
},
placeholder: {
alignItems: 'center',
backgroundColor: '#eef3ef',
borderColor: colors.border,
borderWidth: 1,
justifyContent: 'center'
},
placeholderText: {
color: colors.muted,
fontSize: 12,
fontWeight: '800',
textAlign: 'center'
}
});
+2
View File
@@ -6,6 +6,7 @@ import SecondaryButton from '../components/SecondaryButton';
import AppHeader from '../components/layout/AppHeader';
import ScreenContainer from '../components/layout/ScreenContainer';
import SectionTitle from '../components/layout/SectionTitle';
import ProductImage from '../components/product/ProductImage';
import ProductScoreBadge from '../components/product/ProductScoreBadge';
import RatingCategoryRow from '../components/product/RatingCategoryRow';
import { calculateProductRating } from '../services/ratingService';
@@ -26,6 +27,7 @@ export default function ProductDetailScreen({ product, preferences, onBack, onAd
<AppHeader title="Produktbewertung" subtitle="Persönliche Einschätzung" onBack={onBack} />
<View style={styles.productPanel}>
<ProductImage imageUrl={product.imageUrl} size="large" />
<View style={styles.topRow}>
<View style={styles.copy}>
<Text style={styles.brand}>{product.brand || 'Ohne Marke'}</Text>