Untitled
unknown
plain_text
a month ago
13 kB
6
Indexable
'use client'; import React, { useState } from 'react'; import { Box, Grid, Typography } from '@mui/material'; import Slider from 'react-slick'; import 'slick-carousel/slick/slick.css'; import 'slick-carousel/slick/slick-theme.css'; import { customDot, dotsContainer, dotsWrapper } from './dotsStyles'; import * as Buttons from '@/components/ui/buttons'; import { IBannerCarousel } from '@/types/components/common/common.types'; import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward'; const MENU_HEIGHT = '64px'; // Ajusta este valor seg煤n la altura real de tu men煤 const SHORT_SCREEN_MEDIA_QUERY = '@media (min-width: 600px) and (max-width: 1024px) and (max-height: 700px)'; const BannerCarousel: React.FC<IBannerCarousel> = ({ banner_content }) => { const [activeIndex, setActiveIndex] = useState<number>(0); // =============================== // REACT SLICK SETTINGS // =============================== const settings = { dots: true, infinite: true, autoplay: false, autoplaySpeed: 5000, speed: 600, slidesToShow: 1, slidesToScroll: 1, arrows: false, afterChange: (current: number) => setActiveIndex(current), customPaging: (index: number) => ( <Box key={index} sx={{ ...customDot, ...(activeIndex === index && { backgroundColor: '#004E9B', borderColor: '#004E9B', transform: 'scale(1.2)', boxShadow: '0 0 5px rgba(0, 78, 155, 0.4)', }), }} /> ), appendDots: (dots: React.ReactNode) => ( <Box sx={dotsContainer}> <Grid container direction="row" justifyContent="center" alignItems="center" > <Grid item sx={dotsWrapper}> <Grid container direction="row" justifyContent="center" alignItems="center" width="100%" > {dots} </Grid> </Grid> </Grid> </Box> ), }; // =============================== // RENDER // =============================== return ( <Box sx={{ width: '100%', height: { xs: 'auto', sm: 'auto', md: `calc(100vh - ${MENU_HEIGHT})`, lg: '100vh', [SHORT_SCREEN_MEDIA_QUERY]: { height: `calc(100vh - ${MENU_HEIGHT})`, } }, overflow: 'hidden', }}> <Slider {...settings}> {banner_content?.map((slide, index) => ( <Box key={index} sx={{ width: '100%', height: { xs: 'auto', sm: 'auto', md: `calc(200vh - ${MENU_HEIGHT})`, lg: '100vh', [SHORT_SCREEN_MEDIA_QUERY]: { height: `calc(150vh - ${MENU_HEIGHT})`, } }, minHeight: { xs: '500px', sm: '600px', '@media (max-height: 700px)': '400px' }, backgroundImage: `url(${slide.background || ''})`, backgroundSize: 'cover', backgroundPosition: 'center', display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative', overflow: 'hidden' }} > {/* Contenedor de Texto y Bot贸n */} <Box sx={{ position: 'absolute', top: { xs: '50%', sm: '50%', md: '50%', [SHORT_SCREEN_MEDIA_QUERY]: '45%' }, left: '50%', transform: 'translate(-50%, -50%)', width: { xs: '90%', sm: '70%', md: '50%', lg: '45%', [SHORT_SCREEN_MEDIA_QUERY]: '80%' }, color: slide.theme === 'dark' ? '#FFFFFF' : '#1A3A53', textAlign: 'left', mt: { xs: '1rem', sm: '-2rem', md: '-1rem' }, // 馃敼 Ajusta el margen superior mb: { xs: '1rem', sm: '2rem', md: '3rem' }, // 馃敼 Ajusta el margen inferior ml: { xs: 'auto', sm: '-10%', md: 'auto' }, // 馃敼 Ajusta el margen izquierdo }} > <Typography variant="h2" sx={{ fontSize: { xs: '1rem', // 16px (m贸viles peque帽os) sm: '1.2rem', // 19px (tablets peque帽as) md: '1.5rem', // 24px (escritorio) }, fontWeight: 'bold', mr: { xs: '1.5rem', sm: '2rem', md: '4rem' }, mb: { xs: '0.5rem', sm: '1rem', md: '0.5rem' }, }} > {slide.title} </Typography> <Typography variant="h5" sx={{ fontSize: { xs: '1.75rem', // 28px (m贸viles peque帽os) sm: '2.125rem', // 34px (tablets) md: '2.875rem', // 46px (escritorio) }, fontWeight: 545, mb: { xs: '1.5rem', sm: '2rem', md: '2rem' }, mr: Array.isArray(slide.aditional_content?.list_button) ? { xs: '4rem', sm: '7rem', md: '10rem', lg: '12rem' } : { xs: '7rem', sm: '9rem', md: '8rem', lg: '8rem' }, lineHeight: 1.2, }} > {slide.subtitle} </Typography> <Typography sx={{ fontSize: { xs: '0.875rem', // 14px (m贸viles) sm: '1rem', // 16px (tablets peque帽as) md: '1.2rem', // 19px (tablets grandes) lg: '1.375rem', // 22px (escritorio) }, mr: Array.isArray(slide.aditional_content?.list_button) ? { xs: '0rem', sm: '-5rem', md: '10rem', lg: '12rem' } : { xs: '9rem', sm: '10rem', md: '9rem', lg: '9rem' }, mb: { xs: '2.8rem', sm: '2.8rem', md: '2.8rem' }, }} > {slide.description} </Typography> {/* Bot贸n */} {slide.banner_button?.title?.trim() && (() => { const ButtonComponent = (Buttons as Record<string, any>)[slide.banner_button?.class_name] || Buttons.ButtonFlat; const buttonText = slide.banner_button?.title?.trim(); return ( <Box sx={{ justifyContent: 'flex-start', // Alinea correctamente el bot贸n sin expandirlo }} > <ButtonComponent text={buttonText} href={slide.banner_button.url?.[0] ? `/${slide.banner_button.url[0]}` : '#'} sx={{ mt: 2, fontSize: { xs: '0.9rem', sm: '1rem', md: '1.1rem' }, }} /> </Box> ); })()} </Box> <Box sx={{ position: 'absolute', right: '8%', transform: 'translateY(-40%)', maxWidth: '60%', zIndex: 10, overflow: 'hidden', ...(Array.isArray(slide.aditional_content?.list_button) ? { top: '45.5%', '@media (max-width: 768px)': { position: 'static', transform: 'none', right: 'auto', maxWidth: '90%', mt: -5, ml: 2, }, '@media (max-width: 480px)': { maxWidth: '100%', mt: -2, ml: 1, }, } : { right: '1%', top: '62.5%', '@media (max-width: 768px)': { position: 'absolute', top: '60%', transform: 'translateY(-45%)', }, '@media (max-width: 480px)': { right: '-13%', top: '58s%', }, '@media (min-width: 1900px)': { marginRight: '5%', // 馃敼 Mueve la imagen a la derecha solo en pantallas grandes }, }), }} > {Array.isArray(slide.aditional_content?.list_button) ? ( <Grid container spacing={2} sx={{ width: '100%', height: '100%', display: 'grid', gridTemplateColumns: { xs: 'repeat(4, 1fr)', sm: 'repeat(4, 1fr)', md: 'repeat(2, 2fr)' }, // M贸vil: 2 por fila, Tablet: 4 por fila, Desktop: 2 arriba y 2 abajo gridTemplateRows: { md: 'repeat(2, 2fr)' }, // Desktop: 2 filas gap: { xs: 0, sm: 0, md: '1rem' }, // Ajuste de espacio entre 铆conos din谩mico justifyItems: 'center', // Asegura alineaci贸n horizontal alignItems: 'center', // Asegura alineaci贸n vertical (corrige el desajuste) textAlign: 'center', // Centra el texto debajo del icono mt: { xs: '34rem', sm: '40rem', md: '1rem' }, // Control de altura seg煤n resoluci贸n ml: {xl: '0vh'} }} > {slide.aditional_content.list_button.map((icon, iconIndex) => ( <Grid key={iconIndex} item sx={{ textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', }} > <a href={`/${icon.url?.[0] || '#'}`} target="_blank" rel="noopener noreferrer" style={{ textDecoration: 'none', color: 'inherit' }} > {/* 馃敼 Contenedor que agrupa todos los elementos y maneja el hover */} <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', '&:hover .hover-effect': { color: '#FF5800', // Cambia el color del texto y la flecha en hover }, '&:hover .hover-shadow': { boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.2)', // Aplica sombra al 铆cono en hover borderRadius: '12px', // 馃敼 Se redondea m谩s en hover }, }} > {/* 馃敼 Imagen del icono */} <Box component="img" className="hover-shadow" sx={{ width: { xs: '72px', sm: '100px', md: '200px' }, height: { xs: '72px', sm: '100px', md: '200px' }, objectFit: 'contain', transition: 'box-shadow 0.2s ease', }} alt={icon.title} src={icon.icon} /> {/* 馃敼 Contenedor del texto + icono de flecha */} <Box sx={{ display: 'flex', alignItems: 'center', // 馃敼 Asegura alineaci贸n vertical correcta justifyContent: 'center', gap: '6px', // 馃敼 Espaciado entre texto y flecha mt: 1, // 馃敼 Espaciado con la imagen }} > <Typography className="hover-effect" sx={{ fontSize: { xs: '0.85rem', sm: '1rem' }, fontWeight: 'bold', color: '#0F4DBC', display: 'inline', // 馃敼 Evita que se apile debajo de la flecha textAlign: 'center', transition: 'color 0.1s ease', }} > {icon.title} </Typography> {/* 馃敼 Flecha alineada con el texto */} <ArrowOutwardIcon className="hover-effect" sx={{ color: '#0F4DBC', fontSize: '20px', // 馃敼 Tama帽o reducido para mejor proporci贸n transition: 'color 0.1s ease', display: { xs: 'none', md: 'flex', lg: 'flex', xl: 'flex' }, }} /> </Box> </Box> </a> </Grid> ))} </Grid> ) : ( // Si hay una sola imagen, la renderizamos como imagen 煤nica <Box component="img" sx={{ width: { xs: '200px', sm: '320px', md: '450px', xl: '400px' }, mr: {xl: '6vh'}, height: 'auto', }} alt={slide.title} src={slide.aditional_content?.image} /> )} </Box> </Box> ))} </Slider> </Box> ); }; export default BannerCarousel;
Editor is loading...
Leave a Comment