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; |