All files / src/components/Recipe/RecipeCarousel RecipeCarousel.tsx

0% Statements 0/15
0% Branches 0/9
0% Functions 0/4
0% Lines 0/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                                                                                                                                         
'use client';
 
import { Carousel } from '@mantine/carousel';
import { Box, Skeleton, Text } from '@mantine/core';
import { useTranslations } from 'next-intl';
import { RecipeCard } from '../RecipeCard';
import classes from './RecipeCarousel.module.css';
import type { RecipeCarouselProps } from './types';
 
const CAROUSEL_PROPS = {
  slideSize: { base: '90%', sm: '45%', md: '30%', lg: '23%' },
  slideGap: 'md' as const,
  withControls: true,
  emblaOptions: { containScroll: 'trimSnaps' as const },
};
 
const RecipeCarousel = ({
  recipes,
  loading = false,
  withFavorite = true,
  emptyMessage,
  skeletonCount = 4,
}: RecipeCarouselProps) => {
  const t = useTranslations('recipe');
  const empty = emptyMessage ?? t('empty');
  if (loading) {
    const skeletonItems = Array.from({ length: skeletonCount }, (_, i) => i);
    return (
      <Carousel {...CAROUSEL_PROPS}>
        {skeletonItems.map((item) => (
          <Carousel.Slide
            key={`carousel-skeleton-${item}`}
            className={classes.carouselSlide}
          >
            <Skeleton height={320} radius="md" />
          </Carousel.Slide>
        ))}
      </Carousel>
    );
  }
 
  if (recipes.length === 0) {
    return (
      <Box className={classes.emptyCarousel}>
        <Text c="dimmed" size="lg">
          {empty}
        </Text>
      </Box>
    );
  }
 
  const shouldLoop = recipes.length > 4;
 
  return (
    <Carousel
      {...CAROUSEL_PROPS}
      emblaOptions={{ ...CAROUSEL_PROPS.emblaOptions, loop: shouldLoop }}
    >
      {recipes.map((recipe) => (
        <Carousel.Slide key={recipe.id} className={classes.carouselSlide}>
          <RecipeCard recipe={recipe} withFavorite={withFavorite} />
        </Carousel.Slide>
      ))}
    </Carousel>
  );
};
 
export default RecipeCarousel;