import React, { useCallback, useMemo } from "react"; import { FlatList, Image, StyleSheet, Text, View, useWindowDimensions, } from "react-native"; import { BlurView } from "expo-blur"; import Page from "../../layouts/Page"; import { background, img } from "../../assets"; import { Palette } from "../../styles"; import { FONT_FAMILY } from "../../styles/Fonts"; import { navigate } from "../../navigation/NavigationService"; import { Routes } from "../../navigation"; import { useUser } from "../../providers/UserDataProvider"; import ProjectDropDown from "../../components/ProjectDropDown/ProjectDropDown"; const ITEM_SPACING = 24; const Home = () => { const { userProjects = [], resetSelectedProject, selectProject, selectedProject, selectedProjectId, } = useUser(); const projects = useMemo( () => (Array.isArray(userProjects) ? userProjects : []), [userProjects], ); const { width: windowWidth } = useWindowDimensions(); const carouselItems = useMemo( () => [ { id: "project-vision", title: "Composez sans limites", description: "Créez instantanément des maquettes professionnelles et explorez de nouveaux genres.", image: img.placeholder, }, { id: "project-community", title: "Collaborez en équipe", description: "Partagez vos projets, échangez des idées et co-créez en temps réel.", image: img.placeholder2, }, { id: "project-ai", title: "Optimisé par l'IA", description: "Accédez à des suggestions intelligentes pour les paroles, arrangements et mixages.", image: img.placeholder3, }, { id: "project-stage", title: "Prêt pour la scène", description: "Finalisez vos titres et exportez-les facilement pour le live ou le streaming.", image: img.placeholder4, }, ], [], ); const carouselItemWidth = useMemo(() => { const baseWidth = Math.min(windowWidth * 0.9, 640); return Math.max(baseWidth, 320); }, [windowWidth]); const carouselItemHeight = useMemo(() => { const baseHeight = Math.min(windowWidth * 0.6, 360); return Math.max(baseHeight, 240); }, [windowWidth]); const snapInterval = useMemo( () => carouselItemHeight + ITEM_SPACING, [carouselItemHeight], ); const currentProject = useMemo(() => { if (!projects.length) return null; const activeId = selectedProject?.id || selectedProjectId; if (!activeId) { return projects[0]; } return projects.find((project) => project?.id === activeId) || projects[0]; }, [projects, selectedProject?.id, selectedProjectId]); const formatDate = useCallback((timestamp) => { try { const value = timestamp?.toDate ? timestamp.toDate() : timestamp; const date = value ? new Date(value) : null; if (!date || Number.isNaN(date.getTime())) { return ""; } const day = date.getDate().toString().padStart(2, "0"); const month = (date.getMonth() + 1).toString().padStart(2, "0"); return `${day}/${month}`; } catch (error) { console.warn("Home.web: formatDate error", error); return ""; } }, []); const handleSelectProject = (project) => { if (!project?.id) return; selectProject(project.id); }; const handleModifyProject = (project) => { if (!project?.id) return; selectProject(project.id); navigate(Routes.FlowSelection); }; const handleCreateNew = () => { resetSelectedProject(); navigate(Routes.FlowSelection); }; const renderCarouselItem = useCallback( ({ item, index }) => { const isImageOnRight = index % 2 === 1; let imageSize = Math.min(carouselItemHeight - 24, 280); let availableWidth = carouselItemWidth - imageSize - 48; if (availableWidth < 140) { const minImageSize = Math.max(carouselItemWidth - 140 - 48, 140); imageSize = Math.min(imageSize, minImageSize); availableWidth = carouselItemWidth - imageSize - 48; } const blurWidth = Math.min(Math.max(availableWidth, 120), 260); const blurHeight = Math.max( Math.min(imageSize * 0.75, carouselItemHeight - 48), 140, ); return ( {item.title} {item.description} ); }, [carouselItemHeight, carouselItemWidth], ); const keyExtractor = useCallback((item) => item.id, []); return ( ( )} /> ); }; export default Home; const styles = StyleSheet.create({ root: { flex: 1, paddingHorizontal: 24, position: "relative", justifyContent: "flex-start", alignItems: "center", width: "100%", }, heroImage: { position: "absolute", top: -60, alignSelf: "center", width: "80%", maxWidth: 920, height: 420, opacity: 0.9, }, dropdownArea: { width: "100%", alignItems: "center", justifyContent: "center", paddingTop: 72, zIndex: 2, }, dropdownContainer: { width: "100%", }, shareIcon: { width: 18, height: 18, tintColor: Palette.white, }, carouselSection: { width: "100%", marginTop: 48, }, carouselList: { width: "100%", }, carouselItem: { borderRadius: 18, backgroundColor: "rgba(0, 0, 0, 0.18)", borderWidth: 1, borderColor: "rgba(255, 255, 255, 0.1)", paddingVertical: 24, paddingHorizontal: 16, alignItems: "center", justifyContent: "center", }, carouselItemRight: { flexDirection: "row-reverse", alignItems: "center", }, carouselItemLeft: { flexDirection: "row", alignItems: "center", }, carouselImage: { borderRadius: 28, shadowColor: "#000", shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.25, shadowRadius: 20, }, carouselImageRight: { marginLeft: 20, }, carouselImageLeft: { marginRight: 20, }, carouselBlur: { borderRadius: 20, overflow: "hidden", paddingHorizontal: 18, paddingVertical: 16, justifyContent: "center", alignItems: "flex-start", backgroundColor: "rgba(0, 0, 0, 0.25)", gap: 8, }, carouselBlurRight: { marginRight: 12, }, carouselBlurLeft: { marginLeft: 12, }, carouselTextContainer: { width: "100%", }, carouselTitle: { fontSize: 20, color: Palette.white, fontFamily: FONT_FAMILY.InterSemiBold, marginBottom: 8, }, carouselDescription: { fontSize: 14, lineHeight: 20, color: "rgba(255, 255, 255, 0.7)", fontFamily: FONT_FAMILY.InterRegular, }, });