recherche

This commit is contained in:
Bastien COIGNOUX
2026-05-04 21:52:51 +02:00
parent 432f8ce176
commit 2b8741de08
30 changed files with 2317 additions and 246 deletions

View File

@ -0,0 +1,34 @@
import { View } from 'react-native';
import { UI } from '@/constants/uiTheme';
export function DashboardSkeleton() {
return (
<View className="p-4" accessibilityLabel="Chargement du tableau de bord">
<View className="mb-2 h-7 w-[55%] rounded-lg" style={{ backgroundColor: '#E2E8F0' }} />
<View className="mb-4 h-24 rounded-2xl border" style={{ borderColor: UI.border, backgroundColor: UI.card }} />
<View className="mb-2 h-7 w-[40%] rounded-lg" style={{ backgroundColor: '#E2E8F0' }} />
<View className="mb-4 flex-row gap-3">
{[1, 2, 3].map((k) => (
<View
key={k}
className="h-24 flex-1 rounded-2xl border"
style={{ borderColor: UI.border, backgroundColor: UI.card }}
/>
))}
</View>
<View className="mb-2 h-7 w-[35%] rounded-lg" style={{ backgroundColor: '#E2E8F0' }} />
<View className="mb-4 h-20 rounded-2xl border" style={{ borderColor: UI.border, backgroundColor: '#F8FAFC' }} />
<View className="mb-2 h-7 w-[45%] rounded-lg" style={{ backgroundColor: '#E2E8F0' }} />
<View className="gap-3">
{[1, 2, 3].map((k) => (
<View
key={k}
className="h-16 rounded-2xl border"
style={{ borderColor: UI.border, backgroundColor: UI.card }}
/>
))}
</View>
</View>
);
}

View File

@ -0,0 +1,57 @@
import { Link, type Href } from 'expo-router';
import { Pressable, Text, View } from 'react-native';
import { UI } from '@/constants/uiTheme';
export type EmptyStateProps = {
title: string;
description?: string;
actionLabel?: string;
actionHref?: Href;
onAction?: () => void;
};
export function EmptyState({ title, description, actionLabel, actionHref, onAction }: EmptyStateProps) {
const actionNode =
actionLabel && actionHref != null ? (
<Link href={actionHref} asChild>
<Pressable
accessibilityRole="button"
className="mt-6 min-h-[52px] w-full max-w-sm items-center justify-center rounded-2xl px-5 active:opacity-90"
style={{ backgroundColor: UI.primary }}
>
<Text className="text-center text-lg font-semibold text-white">{actionLabel}</Text>
</Pressable>
</Link>
) : actionLabel && onAction ? (
<Pressable
accessibilityRole="button"
onPress={onAction}
className="mt-6 min-h-[52px] w-full max-w-sm items-center justify-center rounded-2xl px-5 active:opacity-90"
style={{ backgroundColor: UI.primary }}
>
<Text className="text-center text-lg font-semibold text-white">{actionLabel}</Text>
</Pressable>
) : null;
return (
<View className="items-center justify-center px-5 py-10">
<Text
className="text-center text-xl font-bold leading-7"
style={{ color: UI.text }}
accessibilityRole="header"
>
{title}
</Text>
{description ? (
<Text
className="mt-3 max-w-sm text-center text-base leading-6"
style={{ color: UI.textMuted }}
>
{description}
</Text>
) : null}
{actionNode}
</View>
);
}

View File

@ -0,0 +1,39 @@
import { View } from 'react-native';
import { UI } from '@/constants/uiTheme';
type Props = {
rows?: number;
/** Hauteur des cartes (liste verticale). */
variant?: 'card' | 'compact';
};
export function ListSkeleton({ rows = 6, variant = 'card' }: Props) {
const gap = variant === 'compact' ? 10 : 14;
const pad = variant === 'compact' ? 12 : 16;
return (
<View className="px-3 pt-3" accessibilityLabel="Chargement en cours">
{Array.from({ length: rows }).map((_, i) => (
<View
key={i}
className="mb-3 rounded-2xl border bg-white"
style={{
borderColor: UI.border,
padding: pad,
gap,
}}
>
<View
className="h-5 rounded-md"
style={{ width: '62%', backgroundColor: '#E2E8F0' }}
/>
<View className="h-4 rounded-md" style={{ width: '92%', backgroundColor: '#F1F5F9' }} />
<View className="h-4 rounded-md" style={{ width: '78%', backgroundColor: '#F1F5F9' }} />
{variant === 'card' ? (
<View className="h-4 rounded-md" style={{ width: '44%', backgroundColor: '#E2E8F0' }} />
) : null}
</View>
))}
</View>
);
}

View File

@ -0,0 +1,37 @@
import { ScrollView, View } from 'react-native';
import { UI } from '@/constants/uiTheme';
const COL_W = 216;
export function PipelineSkeleton() {
return (
<ScrollView
horizontal
className="flex-1"
contentContainerStyle={{ padding: 12, paddingBottom: 96 }}
accessibilityLabel="Chargement du pipeline"
>
{Array.from({ length: 4 }).map((_, col) => (
<View
key={col}
className="mr-3 rounded-2xl border bg-white p-3"
style={{ width: COL_W, borderColor: UI.border }}
>
<View className="mb-3 h-6 w-[85%] rounded-md" style={{ backgroundColor: '#E2E8F0' }} />
<View className="mb-2 h-3 w-10 rounded" style={{ backgroundColor: '#CBD5E1' }} />
{Array.from({ length: 3 }).map((__, row) => (
<View
key={row}
className="mb-2 rounded-xl border p-3"
style={{ borderColor: '#E2E8F0', backgroundColor: '#F8FAFC' }}
>
<View className="mb-2 h-4 w-[90%] rounded" style={{ backgroundColor: '#E2E8F0' }} />
<View className="h-3 w-[55%] rounded" style={{ backgroundColor: '#F1F5F9' }} />
</View>
))}
</View>
))}
</ScrollView>
);
}