feat(my-plants): grouped card style for date groups
Aligne le rendu des date groups sur le pattern PracticalGuides : items encapsulés dans une card blanche rounded-16, séparés par une ligne grise indentée. - ScanListItem : nouvelles props grouped + showSeparator → désactive borderRadius/margins/border individuels et active la ligne séparatrice alignée sous le texte - DateGroupAccordion : wrappe les ScanListItem dans une View card avec shadow iOS / elevation Android Le même pattern est réutilisé par RecentScans (Home) — voir commit suivant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3781b1c0f4
commit
4ebbc692ff
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect } from 'react';
|
||||
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
|
||||
import { View, TouchableOpacity, Text, StyleSheet, Platform } from 'react-native';
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
|
|
@ -63,15 +63,19 @@ export function DateGroupAccordion({
|
|||
{/* Content */}
|
||||
{isOpen && (
|
||||
<View style={styles.content}>
|
||||
{scans.map((scan) => (
|
||||
<ScanListItem
|
||||
key={scan.id}
|
||||
scan={scan}
|
||||
onPress={() => onPressScan(scan)}
|
||||
onToggleFavorite={() => onToggleFavorite(scan.id)}
|
||||
onDelete={() => onDeleteScan(scan.id)}
|
||||
/>
|
||||
))}
|
||||
<View style={styles.card}>
|
||||
{scans.map((scan, index) => (
|
||||
<ScanListItem
|
||||
key={scan.id}
|
||||
scan={scan}
|
||||
onPress={() => onPressScan(scan)}
|
||||
onToggleFavorite={() => onToggleFavorite(scan.id)}
|
||||
onDelete={() => onDeleteScan(scan.id)}
|
||||
grouped
|
||||
showSeparator={index < scans.length - 1}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
|
@ -107,7 +111,24 @@ const styles = StyleSheet.create({
|
|||
color: '#8E8E93',
|
||||
},
|
||||
content: {
|
||||
paddingTop: 4,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
paddingHorizontal: 20,
|
||||
},
|
||||
card: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderRadius: 16,
|
||||
overflow: 'hidden',
|
||||
borderWidth: 1,
|
||||
borderColor: '#F0F0F0',
|
||||
...Platform.select({
|
||||
ios: {
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.04,
|
||||
shadowRadius: 8,
|
||||
},
|
||||
android: { elevation: 2 },
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ interface ScanListItemProps {
|
|||
onPress: () => void;
|
||||
onToggleFavorite: () => void;
|
||||
onDelete: () => void;
|
||||
grouped?: boolean;
|
||||
showSeparator?: boolean;
|
||||
}
|
||||
|
||||
const STATUS_FILL: Record<ScanStatus, string> = {
|
||||
|
|
@ -46,7 +48,14 @@ function getPlantName(scan: ScanRecord, t: (key: string) => string): string {
|
|||
return t('result.notVine');
|
||||
}
|
||||
|
||||
export function ScanListItem({ scan, onPress, onToggleFavorite, onDelete }: ScanListItemProps) {
|
||||
export function ScanListItem({
|
||||
scan,
|
||||
onPress,
|
||||
onToggleFavorite,
|
||||
onDelete,
|
||||
grouped = false,
|
||||
showSeparator = false,
|
||||
}: ScanListItemProps) {
|
||||
const { t } = useTranslation();
|
||||
const swipeableRef = useRef<Swipeable>(null);
|
||||
const isFav = scan.isFavorite === true;
|
||||
|
|
@ -117,7 +126,7 @@ export function ScanListItem({ scan, onPress, onToggleFavorite, onDelete }: Scan
|
|||
friction={2}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={styles.container}
|
||||
style={[styles.container, grouped && styles.containerGrouped]}
|
||||
onPress={() => {
|
||||
hapticLight();
|
||||
onPress();
|
||||
|
|
@ -160,6 +169,7 @@ export function ScanListItem({ scan, onPress, onToggleFavorite, onDelete }: Scan
|
|||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
{grouped && showSeparator && <View style={styles.separator} />}
|
||||
</Swipeable>
|
||||
);
|
||||
}
|
||||
|
|
@ -176,6 +186,19 @@ const styles = StyleSheet.create({
|
|||
borderWidth: 1,
|
||||
borderColor: '#F0F0F0',
|
||||
},
|
||||
containerGrouped: {
|
||||
borderRadius: 0,
|
||||
marginHorizontal: 0,
|
||||
marginVertical: 0,
|
||||
borderWidth: 0,
|
||||
paddingVertical: 14,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
separator: {
|
||||
height: 1,
|
||||
backgroundColor: '#F0F0F0',
|
||||
marginLeft: 92,
|
||||
},
|
||||
imageWrapper: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
|
|
|
|||
Loading…
Reference in a new issue