feat(home): recent scans + horizontal disease cards
Refonte HomeScreen : - 'Commencer votre collection' (HomeCta) → conditionnellement remplacé par les 3 derniers scans en mode \"grouped card\" via le nouveau composant RecentScans (fallback HomeCta si historique vide) - 'Maladies fréquentes' → SmallDiseaseCard remplacé par LargeDiseaseCard en mode compact, en scroll horizontal (FrequentDiseasesHorizontal) - Comment temporairement <SeasonAlert /> en attendant la page Notifications LargeDiseaseCard : nouvelle prop compact qui réduit hauteur (260→220), padding, font-sizes et lignes de description (3→2). Border + radius + shadow Android forcés en style inline pour clip elevation correctement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4ebbc692ff
commit
7457e64996
|
|
@ -1,94 +1,162 @@
|
||||||
import { View, Pressable, StyleSheet } from 'react-native';
|
import { View, Pressable, StyleSheet } from "react-native";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { Ionicons } from '@expo/vector-icons';
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { ArrowRight, AlertTriangle } from 'lucide-react-native';
|
import { ArrowRight, AlertTriangle } from "lucide-react-native";
|
||||||
import Animated, { FadeInDown } from 'react-native-reanimated';
|
import Animated, { FadeInDown } from "react-native-reanimated";
|
||||||
|
|
||||||
import { Text } from '@/components/ui/text';
|
import { Text } from "@/components/ui/text";
|
||||||
import { colors } from '@/theme/colors';
|
import { colors } from "@/theme/colors";
|
||||||
import type { Disease } from '@/data/diseases';
|
import type { Disease } from "@/data/diseases";
|
||||||
|
|
||||||
interface LargeDiseaseCardProps {
|
interface LargeDiseaseCardProps {
|
||||||
disease: Disease;
|
disease: Disease;
|
||||||
onPress: () => void;
|
onPress: () => void;
|
||||||
index?: number;
|
index?: number;
|
||||||
|
compact?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TYPE_TINT: Record<Disease['type'], { bg: string; fg: string }> = {
|
const TYPE_TINT: Record<Disease["type"], { bg: string; fg: string }> = {
|
||||||
fungal: { bg: '#7B1FA2', fg: '#FFFFFF' },
|
fungal: { bg: "#7B1FA2", fg: "#FFFFFF" },
|
||||||
bacterial: { bg: '#C62828', fg: '#FFFFFF' },
|
bacterial: { bg: "#C62828", fg: "#FFFFFF" },
|
||||||
pest: { bg: '#EF6C00', fg: '#FFFFFF' },
|
pest: { bg: "#EF6C00", fg: "#FFFFFF" },
|
||||||
abiotic: { bg: '#1565C0', fg: '#FFFFFF' },
|
abiotic: { bg: "#1565C0", fg: "#FFFFFF" },
|
||||||
};
|
};
|
||||||
|
|
||||||
const SEVERITY_TINT: Record<Disease['severity'], { bg: string; fg: string; labelKey: string }> = {
|
const SEVERITY_TINT: Record<
|
||||||
high: { bg: '#FBE9E7', fg: '#D32F2F', labelKey: 'guides.riskLevel.high' },
|
Disease["severity"],
|
||||||
medium: { bg: '#FFF8E1', fg: '#F9A825', labelKey: 'guides.riskLevel.medium' },
|
{ bg: string; fg: string; labelKey: string }
|
||||||
low: { bg: '#E8F5E9', fg: '#2E7D32', labelKey: 'guides.riskLevel.low' },
|
> = {
|
||||||
|
high: { bg: "#FBE9E7", fg: "#D32F2F", labelKey: "guides.riskLevel.high" },
|
||||||
|
medium: { bg: "#FFF8E1", fg: "#F9A825", labelKey: "guides.riskLevel.medium" },
|
||||||
|
low: { bg: "#E8F5E9", fg: "#2E7D32", labelKey: "guides.riskLevel.low" },
|
||||||
};
|
};
|
||||||
|
|
||||||
const TYPE_LABEL: Record<Disease['type'], string> = {
|
const TYPE_LABEL: Record<Disease["type"], string> = {
|
||||||
fungal: 'diseases.types.fungal',
|
fungal: "diseases.types.fungal",
|
||||||
bacterial: 'diseases.types.bacterial',
|
bacterial: "diseases.types.bacterial",
|
||||||
pest: 'diseases.types.pest',
|
pest: "diseases.types.pest",
|
||||||
abiotic: 'diseases.types.abiotic',
|
abiotic: "diseases.types.abiotic",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LargeDiseaseCard({
|
export default function LargeDiseaseCard({
|
||||||
disease,
|
disease,
|
||||||
onPress,
|
onPress,
|
||||||
index = 0,
|
index = 0,
|
||||||
|
compact = false,
|
||||||
}: LargeDiseaseCardProps) {
|
}: LargeDiseaseCardProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const type = TYPE_TINT[disease.type];
|
const type = TYPE_TINT[disease.type];
|
||||||
const severity = SEVERITY_TINT[disease.severity];
|
const severity = SEVERITY_TINT[disease.severity];
|
||||||
|
|
||||||
|
const cardRadius = compact ? 24 : 32;
|
||||||
|
const cardClassName = compact
|
||||||
|
? "bg-white p-5 min-h-[220px] justify-between"
|
||||||
|
: "bg-white p-6 min-h-[260px] justify-between";
|
||||||
|
const headerMb = compact ? "mb-3" : "mb-5";
|
||||||
|
const iconCircleClass = compact
|
||||||
|
? "w-9 h-9 bg-[#F8F9FA] rounded-full items-center justify-center"
|
||||||
|
: "w-11 h-11 bg-[#F8F9FA] rounded-full items-center justify-center";
|
||||||
|
const iconSize = compact ? 20 : 26;
|
||||||
|
const titleClass = compact
|
||||||
|
? "text-[18px] font-extrabold text-[#1A1A1A] leading-6 tracking-[-0.3px]"
|
||||||
|
: "text-[26px] font-extrabold text-[#1A1A1A] leading-8 tracking-[-0.6px]";
|
||||||
|
const descClass = compact
|
||||||
|
? "text-[13px] text-[#4A4A4A] leading-[18px]"
|
||||||
|
: "text-sm text-[#4A4A4A] leading-[21px]";
|
||||||
|
const descLines = compact ? 2 : 3;
|
||||||
|
const footerClass = compact
|
||||||
|
? "flex-row items-center justify-between mt-4 pt-3 border-t border-[#F5F5F5]"
|
||||||
|
: "flex-row items-center justify-between mt-6 pt-5 border-t border-[#F5F5F5]";
|
||||||
|
const badgeClass = compact
|
||||||
|
? "px-3 py-1 rounded-full"
|
||||||
|
: "px-3.5 py-1.5 rounded-full";
|
||||||
|
const badgeTextClass = compact
|
||||||
|
? "text-[10px] font-extrabold tracking-[1px]"
|
||||||
|
: "text-[11px] font-extrabold tracking-[1.2px]";
|
||||||
|
const severityClass = compact
|
||||||
|
? "flex-row items-center gap-1.5 px-3 py-1.5 rounded-2xl"
|
||||||
|
: "flex-row items-center gap-2 px-3.5 py-2 rounded-2xl";
|
||||||
|
const severityTextClass = compact
|
||||||
|
? "text-[10px] font-extrabold tracking-[0.8px]"
|
||||||
|
: "text-[11px] font-extrabold tracking-[1px]";
|
||||||
|
const arrowSize = compact ? "w-10 h-10" : "w-12 h-12";
|
||||||
|
const arrowIconSize = compact ? 18 : 20;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.View entering={FadeInDown.delay(index * 90).duration(550).springify().damping(16)}>
|
<Animated.View
|
||||||
|
entering={FadeInDown.delay(index * 90)
|
||||||
|
.duration(550)
|
||||||
|
.springify()
|
||||||
|
.damping(16)}
|
||||||
|
>
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
|
className={cardClassName}
|
||||||
style={({ pressed }) => [
|
style={({ pressed }) => [
|
||||||
styles.card,
|
styles.cardShadow,
|
||||||
|
{
|
||||||
|
borderRadius: cardRadius,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#EEEEEE",
|
||||||
|
},
|
||||||
pressed && { transform: [{ scale: 0.98 }] },
|
pressed && { transform: [{ scale: 0.98 }] },
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{/* Header: type badge + icon */}
|
{/* Header: type badge + icon */}
|
||||||
<View style={styles.header}>
|
<View className={`flex-row items-center justify-between ${headerMb}`}>
|
||||||
<View style={[styles.typeBadge, { backgroundColor: type.bg }]}>
|
<View
|
||||||
<Text style={[styles.typeLabel, { color: type.fg }]}>
|
className={badgeClass}
|
||||||
|
style={{ backgroundColor: type.bg }}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
className={badgeTextClass}
|
||||||
|
style={{ color: type.fg }}
|
||||||
|
>
|
||||||
{t(TYPE_LABEL[disease.type]).toUpperCase()}
|
{t(TYPE_LABEL[disease.type]).toUpperCase()}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.iconCircle}>
|
<View className={iconCircleClass}>
|
||||||
<Ionicons
|
<Ionicons
|
||||||
name={disease.icon as keyof typeof Ionicons.glyphMap}
|
name={disease.icon as keyof typeof Ionicons.glyphMap}
|
||||||
size={26}
|
size={iconSize}
|
||||||
color={disease.iconColor}
|
color={disease.iconColor}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<View style={styles.content}>
|
<View className="gap-2">
|
||||||
<Text style={styles.title} numberOfLines={2}>
|
<Text className={titleClass} numberOfLines={2}>
|
||||||
{t(disease.name)}
|
{t(disease.name)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={styles.description} numberOfLines={3}>
|
<Text className={descClass} numberOfLines={descLines}>
|
||||||
{t(disease.description)}
|
{t(disease.description)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Footer: severity tag + arrow button */}
|
{/* Footer: severity tag + arrow button */}
|
||||||
<View style={styles.footer}>
|
<View className={footerClass}>
|
||||||
<View style={[styles.severityTag, { backgroundColor: severity.bg }]}>
|
<View
|
||||||
<AlertTriangle size={14} color={severity.fg} strokeWidth={2.5} />
|
className={severityClass}
|
||||||
<Text style={[styles.severityLabel, { color: severity.fg }]}>
|
style={{ backgroundColor: severity.bg }}
|
||||||
|
>
|
||||||
|
<AlertTriangle size={compact ? 12 : 14} color={severity.fg} strokeWidth={2.5} />
|
||||||
|
<Text
|
||||||
|
className={severityTextClass}
|
||||||
|
style={{ color: severity.fg }}
|
||||||
|
>
|
||||||
{t(severity.labelKey).toUpperCase()}
|
{t(severity.labelKey).toUpperCase()}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.arrowButton}>
|
<View
|
||||||
<ArrowRight size={20} color="#FFFFFF" strokeWidth={2.6} />
|
className={`${arrowSize} rounded-full items-center justify-center`}
|
||||||
|
style={[
|
||||||
|
styles.arrowShadow,
|
||||||
|
{ backgroundColor: colors.primary[800] },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<ArrowRight size={arrowIconSize} color="#FFFFFF" strokeWidth={2.6} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
|
@ -97,88 +165,14 @@ export default function LargeDiseaseCard({
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
card: {
|
cardShadow: {
|
||||||
backgroundColor: '#FFFFFF',
|
shadowColor: "#000",
|
||||||
borderWidth: 1,
|
|
||||||
borderColor: '#EEEEEE',
|
|
||||||
borderRadius: 32,
|
|
||||||
padding: 24,
|
|
||||||
minHeight: 260,
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
shadowColor: '#000',
|
|
||||||
shadowOffset: { width: 0, height: 12 },
|
shadowOffset: { width: 0, height: 12 },
|
||||||
shadowOpacity: 0.08,
|
shadowOpacity: 0.08,
|
||||||
shadowRadius: 30,
|
shadowRadius: 30,
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
},
|
},
|
||||||
header: {
|
arrowShadow: {
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
alignItems: 'center',
|
|
||||||
marginBottom: 20,
|
|
||||||
},
|
|
||||||
typeBadge: {
|
|
||||||
paddingHorizontal: 14,
|
|
||||||
paddingVertical: 6,
|
|
||||||
borderRadius: 999,
|
|
||||||
},
|
|
||||||
typeLabel: {
|
|
||||||
fontSize: 11,
|
|
||||||
fontWeight: '800',
|
|
||||||
letterSpacing: 1.2,
|
|
||||||
},
|
|
||||||
iconCircle: {
|
|
||||||
width: 44,
|
|
||||||
height: 44,
|
|
||||||
borderRadius: 999,
|
|
||||||
backgroundColor: '#F8F9FA',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
gap: 10,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
fontSize: 26,
|
|
||||||
fontWeight: '800',
|
|
||||||
color: '#1A1A1A',
|
|
||||||
lineHeight: 32,
|
|
||||||
letterSpacing: -0.6,
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
fontSize: 14,
|
|
||||||
color: '#4A4A4A',
|
|
||||||
lineHeight: 21,
|
|
||||||
},
|
|
||||||
footer: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
marginTop: 24,
|
|
||||||
paddingTop: 20,
|
|
||||||
borderTopWidth: 1,
|
|
||||||
borderTopColor: '#F5F5F5',
|
|
||||||
},
|
|
||||||
severityTag: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 8,
|
|
||||||
paddingHorizontal: 14,
|
|
||||||
paddingVertical: 8,
|
|
||||||
borderRadius: 16,
|
|
||||||
},
|
|
||||||
severityLabel: {
|
|
||||||
fontSize: 11,
|
|
||||||
fontWeight: '800',
|
|
||||||
letterSpacing: 1,
|
|
||||||
},
|
|
||||||
arrowButton: {
|
|
||||||
width: 48,
|
|
||||||
height: 48,
|
|
||||||
borderRadius: 999,
|
|
||||||
backgroundColor: colors.primary[800],
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
shadowColor: colors.primary[900],
|
shadowColor: colors.primary[900],
|
||||||
shadowOffset: { width: 0, height: 4 },
|
shadowOffset: { width: 0, height: 4 },
|
||||||
shadowOpacity: 0.25,
|
shadowOpacity: 0.25,
|
||||||
|
|
|
||||||
54
VinEye/src/components/home/FrequentDiseasesHorizontal.tsx
Normal file
54
VinEye/src/components/home/FrequentDiseasesHorizontal.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { ScrollView, View } from "react-native";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||||
|
|
||||||
|
import LargeDiseaseCard from "@/components/guides/LargeDiseaseCard";
|
||||||
|
import { CarouselCardSkeleton } from "@/components/ui/Skeleton";
|
||||||
|
import type { Disease } from "@/data/diseases";
|
||||||
|
import type { RootStackParamList } from "@/types/navigation";
|
||||||
|
|
||||||
|
type Nav = NativeStackNavigationProp<RootStackParamList>;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
diseases: Disease[];
|
||||||
|
isLoading?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CARD_WIDTH = 260;
|
||||||
|
|
||||||
|
export default function FrequentDiseasesHorizontal({
|
||||||
|
diseases,
|
||||||
|
isLoading,
|
||||||
|
}: Props) {
|
||||||
|
const navigation = useNavigation<Nav>();
|
||||||
|
|
||||||
|
if (isLoading && diseases.length === 0) {
|
||||||
|
return (
|
||||||
|
<View className="flex-row gap-4 px-5">
|
||||||
|
<CarouselCardSkeleton />
|
||||||
|
<CarouselCardSkeleton />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView
|
||||||
|
horizontal
|
||||||
|
showsHorizontalScrollIndicator={false}
|
||||||
|
contentContainerStyle={{ paddingHorizontal: 20, gap: 12, paddingVertical: 8 }}
|
||||||
|
>
|
||||||
|
{diseases.map((d, i) => (
|
||||||
|
<View key={d.id} style={{ width: CARD_WIDTH }}>
|
||||||
|
<LargeDiseaseCard
|
||||||
|
disease={d}
|
||||||
|
index={i}
|
||||||
|
compact={true}
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate("DiseaseDetail", { diseaseId: d.id })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
67
VinEye/src/components/home/RecentScans.tsx
Normal file
67
VinEye/src/components/home/RecentScans.tsx
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { View, StyleSheet, Platform } from "react-native";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { ScanListItem } from "@/components/my-plants/ScanListItem";
|
||||||
|
import SectionHeader from "@/components/home/components/homeheader";
|
||||||
|
import HomeCta from "@/components/home/HomeCta";
|
||||||
|
import { useHistory } from "@/hooks/useHistory";
|
||||||
|
import type { RootStackParamList } from "@/types/navigation";
|
||||||
|
|
||||||
|
type Nav = NativeStackNavigationProp<RootStackParamList>;
|
||||||
|
|
||||||
|
const MAX_RECENT = 3;
|
||||||
|
|
||||||
|
export default function RecentScans() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const navigation = useNavigation<Nav>();
|
||||||
|
const { history, toggleFavorite, deleteScan } = useHistory();
|
||||||
|
|
||||||
|
if (history.length === 0) {
|
||||||
|
return <HomeCta />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recent = history.slice(0, MAX_RECENT);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="mb-6 mx-5 gap-3">
|
||||||
|
<SectionHeader
|
||||||
|
title={t("home.recentScans")}
|
||||||
|
onViewAll={() => navigation.navigate("Main", { screen: "MyPlants" })}
|
||||||
|
/>
|
||||||
|
<View style={styles.card}>
|
||||||
|
{recent.map((scan, index) => (
|
||||||
|
<ScanListItem
|
||||||
|
key={scan.id}
|
||||||
|
scan={scan}
|
||||||
|
onPress={() => navigation.navigate("ScanDetail", { scanId: scan.id })}
|
||||||
|
onToggleFavorite={() => toggleFavorite(scan.id)}
|
||||||
|
onDelete={() => deleteScan(scan.id)}
|
||||||
|
grouped
|
||||||
|
showSeparator={index < recent.length - 1}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
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 },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -10,10 +10,10 @@ import { useGuides } from "@/hooks/useGuides";
|
||||||
import SearchHeader from "@/components/home/SearchHeader";
|
import SearchHeader from "@/components/home/SearchHeader";
|
||||||
import SearchSection from "@/components/home/SearchSection";
|
import SearchSection from "@/components/home/SearchSection";
|
||||||
import SectionHeader from "@/components/home/components/homeheader";
|
import SectionHeader from "@/components/home/components/homeheader";
|
||||||
import FrequentDiseases from "@/components/home/FrequentDiseases";
|
import FrequentDiseasesHorizontal from "@/components/home/FrequentDiseasesHorizontal";
|
||||||
import SeasonAlert from "@/components/home/SeasonAlert";
|
// import SeasonAlert from "@/components/home/SeasonAlert"; // TODO: réactiver quand la page Notifications sera de retour
|
||||||
import PracticalGuides from "@/components/home/PracticalGuides";
|
import PracticalGuides from "@/components/home/PracticalGuides";
|
||||||
import HeroScanner from "@/components/home/HomeCta";
|
import RecentScans from "@/components/home/RecentScans";
|
||||||
|
|
||||||
type Nav = NativeStackNavigationProp<RootStackParamList>;
|
type Nav = NativeStackNavigationProp<RootStackParamList>;
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ export default function HomeScreen() {
|
||||||
|
|
||||||
<SearchSection />
|
<SearchSection />
|
||||||
|
|
||||||
<HeroScanner />
|
<RecentScans />
|
||||||
|
|
||||||
{/* Frequent diseases carousel */}
|
{/* Frequent diseases carousel */}
|
||||||
<View className="mb-6 gap-3">
|
<View className="mb-6 gap-3">
|
||||||
|
|
@ -44,11 +44,11 @@ export default function HomeScreen() {
|
||||||
onViewAll={() => navigation.navigate("Main", { screen: "Guides" })}
|
onViewAll={() => navigation.navigate("Main", { screen: "Guides" })}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<FrequentDiseases diseases={diseases} isLoading={diseasesLoading} />
|
<FrequentDiseasesHorizontal diseases={diseases} isLoading={diseasesLoading} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Season alert */}
|
{/* Season alert — désactivé tant que la page Notifications n'est pas prête */}
|
||||||
<SeasonAlert />
|
{/* <SeasonAlert /> */}
|
||||||
|
|
||||||
{/* Practical guides */}
|
{/* Practical guides */}
|
||||||
<View className="mx-5 mb-6 gap-3">
|
<View className="mx-5 mb-6 gap-3">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue