Untitled
unknown
plain_text
9 months ago
13 kB
11
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