recherche
This commit is contained in:
34
app/components/ui/DashboardSkeleton.tsx
Normal file
34
app/components/ui/DashboardSkeleton.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
57
app/components/ui/EmptyState.tsx
Normal file
57
app/components/ui/EmptyState.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
39
app/components/ui/ListSkeleton.tsx
Normal file
39
app/components/ui/ListSkeleton.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
37
app/components/ui/PipelineSkeleton.tsx
Normal file
37
app/components/ui/PipelineSkeleton.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user