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

0% Statements 0/7
0% Branches 0/12
0% Functions 0/1
0% Lines 0/7

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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119                                                                                                                                                                                                                                             
'use client';
 
import { Badge, Box, Card, Group, Image, Rating, Text } from '@mantine/core';
import {
  IconChefHat,
  IconClock,
  IconStar,
  IconUsers,
} from '@tabler/icons-react';
import type { Route } from 'next';
import Link from 'next/link';
import { useTranslations } from 'next-intl';
import { getDifficultyColor } from '@/app/recipes/[id]/utils';
import { FavoriteButton } from '@/components/buttons/FavoriteButton';
import classes from './RecipeCard.module.css';
import type { RecipeCardProps } from './types';
 
const RecipeCard = ({ recipe, withFavorite = true }: RecipeCardProps) => {
  const translate = useTranslations('misc');
  const tCommon = useTranslations();
 
  const {
    id,
    title,
    description,
    imgSrc,
    cookingTime,
    servings,
    category,
    difficultyLevel,
    averageRating = 0,
    ratingsCount = 0,
    isFavorite = false,
  } = recipe;
 
  const difficultyColor = getDifficultyColor(difficultyLevel.key);
  return (
    <Card
      component={Link}
      href={`/recipes/${id}` as Route}
      shadow="sm"
      radius="md"
      withBorder
      className={classes.card}
      padding={0}
    >
      <Card.Section className={classes.imageSection}>
        {imgSrc ? (
          <Image src={imgSrc} height={180} alt={title} fit="cover" />
        ) : (
          <Box className={classes.placeholderImage}>
            <IconChefHat size={48} color="var(--mantine-color-pink-4)" />
          </Box>
        )}
        {withFavorite && (
          <Box className={classes.favoriteButton}>
            <FavoriteButton recipeId={id} isFavorite={isFavorite} size="sm" />
          </Box>
        )}
      </Card.Section>
 
      <Box p="sm" pb="md">
        <Group justify="space-between" mb={4}>
          <Badge variant="light" size="sm" className={classes.badge}>
            {translate(`category-${category.key}`)}
          </Badge>
          <Badge
            variant="light"
            color={difficultyColor}
            size="sm"
            className={classes.badge}
          >
            {translate(`level-${difficultyLevel.key}`)}
          </Badge>
        </Group>
 
        <Text fw={600} size="md" mt={4} className={classes.title}>
          {title}
        </Text>
 
        {description && (
          <Text size="xs" c="dimmed" mt={4} className={classes.description}>
            {description}
          </Text>
        )}
 
        <Group mt="sm" gap="md">
          <Group gap={4} className={classes.metaRow}>
            <IconClock size={14} color="var(--mantine-color-dimmed)" />
            <Text size="xs" c="dimmed">
              {cookingTime} {tCommon('units.minuteShort')}
            </Text>
          </Group>
          <Group gap={4} className={classes.metaRow}>
            <IconUsers size={14} color="var(--mantine-color-dimmed)" />
            <Text size="xs" c="dimmed">
              {servings}
            </Text>
          </Group>
        </Group>
 
        {ratingsCount > 0 && (
          <Group mt="xs" gap="xs">
            <Rating value={averageRating} readOnly fractions={2} size="xs" />
            <Group gap={2}>
              <IconStar size={12} color="var(--mantine-color-dimmed)" />
              <Text size="xs" c="dimmed">
                ({ratingsCount})
              </Text>
            </Group>
          </Group>
        )}
      </Box>
    </Card>
  );
};
 
export default RecipeCard;