feat : début de EventCard

This commit is contained in:
Yaël Perret
2026-09-10 20:56:51 +02:00
parent 4685e39985
commit 3bc1149f05
5 changed files with 175 additions and 2 deletions

View File

@@ -26,6 +26,12 @@ export default function HomeTabScreen() {
onPress={() => router.push('/switch-demo')}
accessibilityLabel="Ouvrir la page de démonstration du switch"
/>
<Button
label="Voir la démo des cards"
variant="secondary"
onPress={() => router.push('/card-demo')}
accessibilityLabel="Ouvrir la page de présentation des cards"
/>
</View>
</View>
);

View File

@@ -50,6 +50,7 @@ export default function RootLayout() {
<Stack.Screen name="(tabs)" />
<Stack.Screen name="(org)" />
<Stack.Screen name="switch-demo" />
<Stack.Screen name="card-demo" />
<Stack.Screen name="event/[id]" />
<Stack.Screen name="create/event" options={{ presentation: 'modal' }} />
<Stack.Screen name="create/post" options={{ presentation: 'modal' }} />

80
src/app/card-demo.tsx Normal file
View File

@@ -0,0 +1,80 @@
import { StyleSheet, Text, View } from 'react-native';
import Card from '@/components/Card';
import { Screen } from '@/components/ui/Screen';
import { mockEvents } from '@/mocks';
import { colors } from '@/theme/colors';
import { spacing } from '@/theme/spacing';
import { typography } from '@/theme/typography';
const cardParticipants = [
{
id: 'lea',
source:
'https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&w=240&q=80',
name: 'Lea Martin',
},
{
id: 'yanis',
source:
'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=240&q=80',
name: 'Yanis Belaid',
},
{
id: 'omar',
source:
'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?auto=format&fit=crop&w=240&q=80',
name: 'Omar Khelifi',
},
];
export default function CardDemoScreen() {
const demoEvent = mockEvents[0];
if (!demoEvent) {
return (
<Screen contentContainerStyle={styles.content}>
<Text style={styles.emptyState}>Aucun événement de démo disponible.</Text>
</Screen>
);
}
return (
<Screen contentContainerStyle={styles.content}>
<View style={styles.header}>
<Text style={styles.kicker}>DESIGN SYSTEM · CARD</Text>
<Text style={styles.title}>Page de présentation Card</Text>
</View>
<Card
variant="hero"
event={demoEvent}
avatarStack={cardParticipants}
onPress={() => undefined}
/>
</Screen>
);
}
const styles = StyleSheet.create({
content: {
gap: spacing[16],
paddingTop: spacing[24],
},
header: {
gap: spacing[8],
marginBottom: spacing[8],
},
kicker: {
...typography.sectionLabel,
color: colors.textSecondary,
},
title: {
...typography.body,
color: colors.textPrimary,
},
emptyState: {
...typography.body,
color: colors.textSecondary,
},
});

88
src/components/Card.tsx Normal file
View File

@@ -0,0 +1,88 @@
import { Event } from '@/models/events';
import { StyleSheet, Text, View } from 'react-native';
import { Badge } from './Badge';
import { Button } from './Button';
import { AvatarStack, AvatarStackItem } from './ui/AvatarStack';
import { typography } from '@/theme';
import { colors } from '@/theme/colors';
import { borderRadius } from '@/theme/spacing';
import { Heart, MapPin } from 'lucide-react-native';
export type CardVariant = 'hero' | 'list' | 'compact';
export type CardProps = {
variant: CardVariant;
event: Event;
avatarStack?: AvatarStackItem[];
onPress?: () => void;
};
function Card({
variant,
event,
avatarStack,
onPress
}: CardProps) {
const eventDate = event.start_date;
const badgeDate = {
day: eventDate.getDate().toString().padStart(2, '0'),
month: new Intl.DateTimeFormat('fr-FR', { month: 'short' })
.format(eventDate)
.replace('.', ''),
};
return (
<View
style={styles.card}
>
<View style={styles.header}>
<Badge variant='date' date={badgeDate} />
<Button variant='ghost' icon={Heart} iconOnly onPress={onPress} />
</View>
<View style={styles.content}>
<Badge variant='tonight' label='CE SOIR' />
<Text style={styles.title}>
{event.name}
</Text>
<Text style={styles.subtitle}>
<MapPin size={16} color={colors.textBody} />{' '}
{event.address}, {event.city} - 18 km
</Text>
{avatarStack && <AvatarStack items={avatarStack} />}
</View>
</View>
);
}
const styles = StyleSheet.create({
card: {
borderRadius: borderRadius.card,
backgroundColor: colors.surface,
height: 230,
padding: 16,
},
header: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
},
content: {
flex: 3,
justifyContent: 'flex-end',
},
title: {
...typography.cardTitle,
color: colors.textPrimary,
},
subtitle: {
...typography.label,
color: colors.textBody
}
});
export default Card;

View File

@@ -9,8 +9,6 @@ export const theme = {
borderRadius,
} as const;
export * from './ThemeProvider';
export * from './useTheme';
export { borderRadius, colors, spacing, typography };
export default theme;