Untitled

 avatar
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