Untitled

 avatar
unknown
plain_text
16 days ago
5.8 kB
2
Indexable
'use client';

import { useState, ComponentType, useMemo } from 'react';
import {
  Box,
  List,
  ListItem,
  ListItemText,
  ListItemIcon,
  Grid,
} from '@mui/material';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import { ListCard, CardType } from '@/types/components/ui/ui.types';
import * as cardslibery from '@/components/ui/cards';
import { SeparatorGrid } from '@/components/layouts/SeparatorGrid';

// Función para mapear las opciones desde list_card
const mapOptions = (list_card: ListCard[]): CardType[] => {
  return list_card.flatMap((card) => card.card_type || []);
};

export const ListCards: React.FC<{ list_card?: ListCard[], acf_fc_layout?: string }> = ({ list_card = [] }) => {
  // Memoiza las opciones para evitar cálculos innecesarios en renders
  const options = useMemo(() => mapOptions(list_card), [list_card]);

  const defaultOption: CardType = {
    acf_fc_layout: '',
    title: 'Sin datos',
    description: 'No hay información disponible.',
    image: '',
    icon: '',
    alt_icon: '',
    alt_image: '',
    url: '',
  };

  const [selectedOption, setSelectedOption] = useState<CardType>(
    options.length > 0 ? options[0] : defaultOption
  );

  // Renderiza la lista de opciones con el espaciado mejorado
  const renderOptionsList = () => (
    <Box
      sx={{
        bgcolor: 'white',
        borderRadius: 8,
        boxShadow: 1,
        overflow: 'hidden',
        p: 2,
        width: { xs: '90%', sm: '640px', md: '380px', xl: '160%' }, // 📏 Ancho fijo en desktop (md)
        mx: 'auto',
        mb: '8vh',
      }}
    >
      <List>
        {options.length > 0 ? (
          options.map((option, index) => (
            <ListItem
              key={index}
              component="button"
              onClick={() => setSelectedOption(option)}
              sx={{
                borderBottom: option.title === selectedOption.title ? '2px solid #1976d2' : 'none',
                width: '100%',
                minHeight: '56px', // 📏 Mantiene una altura mínima adecuada
                my: 1,
                display: 'flex',
                alignItems: 'center',
              }}
              className="animate__animated animate__fadeInLeft"
            >
              <ListItemText
                primary={option.title}
                sx={{
                  flexGrow: 1, // 📏 Permite que el texto use el espacio disponible
                  overflow: 'hidden', // 📌 Evita que el texto se desborde
                  wordBreak: 'break-word', // 📏 Si es demasiado largo, permite el salto de línea
                  whiteSpace: 'normal', // 📏 Solo pasa a dos líneas si es necesario
                }}
                primaryTypographyProps={{
                  fontSize: 16,
                  color: '#072458',
                  fontWeight: 500,
                }}
              />
              <ListItemIcon
                sx={{
                  justifyContent: 'flex-end', // 📏 Asegura que el icono siempre esté a la derecha
                  flexShrink: 0,
                }}
              >
                <ChevronRightIcon sx={{ color: '#072458' }} />
              </ListItemIcon>
            </ListItem>
          ))
        ) : (
          <ListItem>
            <ListItemText primary="No hay opciones disponibles" />
          </ListItem>
        )}
      </List>
    </Box>
  );

  // Renderiza la tarjeta de contenido
  const renderContentCard = () => {
    if (!selectedOption.acf_fc_layout || !cardslibery[selectedOption.acf_fc_layout]) return null;

    const CardComponent = cardslibery[selectedOption.acf_fc_layout] as ComponentType<CardType>;

    return <CardComponent key={selectedOption.acf_fc_layout} {...selectedOption} />;
  };

  return (
    <SeparatorGrid wrapper={true}>
      <Grid 
        container 
        spacing={{ xs: 1, md: 2 }} 
        justifyContent="center" 
        alignItems="flex-start"
        sx={{ 
          mt: 1,
          overflow: 'hidden',
          width: '100%',
          maxWidth: '1440px',
          margin: '0 auto',
          px: { xs: 2, md: 4 } // Padding lateral consistente (16px/32px)
        }}
      >
        {/* Lista de opciones (izquierda) */}
        <Grid item xs={12} sm={5} md={4} xl={3} sx={{ 
          width: '100%',
          px: { xs: 2, sm: 0 }, // Padding lateral mobile
          marginLeft: { sm: 0, md: 0 } // Elimina márgenes negativos
        }}>
          {renderOptionsList()}
        </Grid>
  
        {/* Tarjeta de contenido (derecha) */}
        <Grid item xs={12} sm={12} md={8} xl={9} sx={{ 
          position: 'relative',
          overflow: 'visible',
          width: '100%',
        }}>
          <Box
            sx={{
              width: { 
                xs: '100%', 
                md: 'calc(100% + 160px)' // 160px extra en desktop
              },
              minHeight: { xs: 'auto', md: '400px' }, // Altura fija en px
              marginLeft: { md: 20 }, // -64px para compensar (mitad de 160px)
              pl: { md: 8 }, // 64px padding interno
              boxSizing: 'border-box',
              display: 'flex',
              alignItems: 'center',
              backgroundColor: 'background.paper',
              borderRadius: 2,
              overflow: 'hidden'
            }}
            className={`animate__animated ${typeof window !== 'undefined' && window.innerWidth < 800 ? 'animate__fadeInUp' : 'animate__fadeInRight'}`}
          >
            {renderContentCard()}
          </Box>
        </Grid>
      </Grid>
    </SeparatorGrid>
  );
};
Editor is loading...
Leave a Comment