fix: recipe card badge placement, missing tooltips, untranslated label
- Batch-cook indicator moved from next to the title into the icon row
alongside favorite/visibility (all three now get a tooltip, matching
the existing favorite-button pattern).
- Favorite button's tooltip text was hardcoded English ("Save"/
"Saved") instead of using the translation keys already used for its
aria-label.
- Shortened the batch-cook generate dialog's "Generating…" label
(fr.json edited by user) — the long text was the real cause of the
modal overlap, not the dialog structure.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -117,12 +117,9 @@ function GridCard({ recipe, selected, selectMode }: { recipe: Recipe; selected:
|
|||||||
>
|
>
|
||||||
<RecipeThumb recipe={recipe} selectMode={selectMode} selected={selected} className="aspect-video" />
|
<RecipeThumb recipe={recipe} selectMode={selectMode} selected={selected} className="aspect-video" />
|
||||||
<div className="flex flex-col flex-1 p-3 gap-1">
|
<div className="flex flex-col flex-1 p-3 gap-1">
|
||||||
<div className="flex items-center gap-1.5">
|
<h3 className={cn("font-semibold leading-tight line-clamp-2 text-sm transition-colors", !selectMode && "group-hover:text-primary")}>
|
||||||
<h3 className={cn("font-semibold leading-tight line-clamp-2 text-sm transition-colors", !selectMode && "group-hover:text-primary")}>
|
{recipe.title}
|
||||||
{recipe.title}
|
</h3>
|
||||||
</h3>
|
|
||||||
{recipe.isBatchCook && <ChefHat className="h-3.5 w-3.5 text-primary shrink-0" />}
|
|
||||||
</div>
|
|
||||||
{recipe.description && (
|
{recipe.description && (
|
||||||
<p className="text-xs text-muted-foreground line-clamp-2 leading-relaxed">
|
<p className="text-xs text-muted-foreground line-clamp-2 leading-relaxed">
|
||||||
{recipe.isBatchCook ? stripMarkdown(recipe.description) : recipe.description}
|
{recipe.isBatchCook ? stripMarkdown(recipe.description) : recipe.description}
|
||||||
@@ -154,12 +151,25 @@ function GridCard({ recipe, selected, selectMode }: { recipe: Recipe; selected:
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1 shrink-0">
|
<div className="flex items-center gap-1 shrink-0">
|
||||||
|
{recipe.isBatchCook && (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger render={<span className="p-1.5 inline-flex"><ChefHat className="h-3.5 w-3.5 text-primary" /></span>} />
|
||||||
|
<TooltipContent>{t("batchCookBadge")}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
{!selectMode && (
|
{!selectMode && (
|
||||||
<StopPropagation>
|
<StopPropagation>
|
||||||
<FavoriteButton recipeId={recipe.id} initialFavorited={recipe.isFavorited} />
|
<FavoriteButton recipeId={recipe.id} initialFavorited={recipe.isFavorited} />
|
||||||
</StopPropagation>
|
</StopPropagation>
|
||||||
)}
|
)}
|
||||||
<VisibilityIcon className="h-3 w-3" />
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger render={<span className="p-1.5 inline-flex"><VisibilityIcon className="h-3 w-3" /></span>} />
|
||||||
|
<TooltipContent>{t(`visibility.${recipe.visibility}`)}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -184,17 +194,29 @@ function ListRow({ recipe, selected, selectMode }: { recipe: Recipe; selected: b
|
|||||||
<RecipeThumb recipe={recipe} selectMode={selectMode} selected={selected} className="w-28 h-20 rounded-lg" />
|
<RecipeThumb recipe={recipe} selectMode={selectMode} selected={selected} className="w-28 h-20 rounded-lg" />
|
||||||
<div className="flex-1 min-w-0 flex flex-col gap-1">
|
<div className="flex-1 min-w-0 flex flex-col gap-1">
|
||||||
<div className="flex items-start justify-between gap-2">
|
<div className="flex items-start justify-between gap-2">
|
||||||
<h3 className={cn("font-semibold leading-tight line-clamp-1 text-sm flex items-center gap-1.5", !selectMode && "group-hover:text-primary")}>
|
<h3 className={cn("font-semibold leading-tight line-clamp-1 text-sm", !selectMode && "group-hover:text-primary")}>
|
||||||
{recipe.title}
|
{recipe.title}
|
||||||
{recipe.isBatchCook && <ChefHat className="h-3.5 w-3.5 text-primary shrink-0" />}
|
|
||||||
</h3>
|
</h3>
|
||||||
<div className="flex items-center gap-1 shrink-0">
|
<div className="flex items-center gap-1 shrink-0">
|
||||||
|
{recipe.isBatchCook && (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger render={<span className="p-1.5 inline-flex"><ChefHat className="h-3.5 w-3.5 text-primary" /></span>} />
|
||||||
|
<TooltipContent>{t("batchCookBadge")}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
{!selectMode && (
|
{!selectMode && (
|
||||||
<StopPropagation>
|
<StopPropagation>
|
||||||
<FavoriteButton recipeId={recipe.id} initialFavorited={recipe.isFavorited} />
|
<FavoriteButton recipeId={recipe.id} initialFavorited={recipe.isFavorited} />
|
||||||
</StopPropagation>
|
</StopPropagation>
|
||||||
)}
|
)}
|
||||||
<VisibilityIcon className="h-3.5 w-3.5 text-muted-foreground" />
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger render={<span className="p-1.5 inline-flex"><VisibilityIcon className="h-3.5 w-3.5 text-muted-foreground" /></span>} />
|
||||||
|
<TooltipContent>{t(`visibility.${recipe.visibility}`)}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{recipe.description && <p className="text-xs text-muted-foreground line-clamp-2 leading-relaxed">{recipe.isBatchCook ? stripMarkdown(recipe.description) : recipe.description}</p>}
|
{recipe.description && <p className="text-xs text-muted-foreground line-clamp-2 leading-relaxed">{recipe.isBatchCook ? stripMarkdown(recipe.description) : recipe.description}</p>}
|
||||||
@@ -231,9 +253,8 @@ function CompactRow({ recipe, selected, selectMode }: { recipe: Recipe; selected
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<RecipeThumb recipe={recipe} selectMode={selectMode} selected={selected} className="w-10 h-10 rounded-md shrink-0" />
|
<RecipeThumb recipe={recipe} selectMode={selectMode} selected={selected} className="w-10 h-10 rounded-md shrink-0" />
|
||||||
<h3 className={cn("font-medium text-sm truncate flex-1 min-w-0 flex items-center gap-1.5", !selectMode && "group-hover:text-primary")}>
|
<h3 className={cn("font-medium text-sm truncate flex-1 min-w-0", !selectMode && "group-hover:text-primary")}>
|
||||||
<span className="truncate">{recipe.title}</span>
|
{recipe.title}
|
||||||
{recipe.isBatchCook && <ChefHat className="h-3.5 w-3.5 text-primary shrink-0" />}
|
|
||||||
</h3>
|
</h3>
|
||||||
<span className="hidden sm:flex items-center gap-1 text-xs text-muted-foreground shrink-0"><Users className="h-3 w-3" />{recipe.baseServings}</span>
|
<span className="hidden sm:flex items-center gap-1 text-xs text-muted-foreground shrink-0"><Users className="h-3 w-3" />{recipe.baseServings}</span>
|
||||||
{totalMins > 0 && (
|
{totalMins > 0 && (
|
||||||
@@ -245,12 +266,25 @@ function CompactRow({ recipe, selected, selectMode }: { recipe: Recipe; selected
|
|||||||
<span className="hidden md:inline text-xs text-muted-foreground shrink-0 w-16 text-right">
|
<span className="hidden md:inline text-xs text-muted-foreground shrink-0 w-16 text-right">
|
||||||
{recipe.updatedAt.toLocaleDateString(locale, { month: "short", day: "numeric" })}
|
{recipe.updatedAt.toLocaleDateString(locale, { month: "short", day: "numeric" })}
|
||||||
</span>
|
</span>
|
||||||
|
{recipe.isBatchCook && (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger render={<span className="p-1.5 inline-flex shrink-0"><ChefHat className="h-3.5 w-3.5 text-primary" /></span>} />
|
||||||
|
<TooltipContent>{t("batchCookBadge")}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
{!selectMode && (
|
{!selectMode && (
|
||||||
<StopPropagation>
|
<StopPropagation>
|
||||||
<FavoriteButton recipeId={recipe.id} initialFavorited={recipe.isFavorited} />
|
<FavoriteButton recipeId={recipe.id} initialFavorited={recipe.isFavorited} />
|
||||||
</StopPropagation>
|
</StopPropagation>
|
||||||
)}
|
)}
|
||||||
<VisibilityIcon className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger render={<span className="p-1.5 inline-flex shrink-0"><VisibilityIcon className="h-3.5 w-3.5 text-muted-foreground" /></span>} />
|
||||||
|
<TooltipContent>{t(`visibility.${recipe.visibility}`)}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export function FavoriteButton({
|
|||||||
<Heart className={cn("h-4 w-4", favorited ? "fill-red-500 text-red-500" : iconClassName)} />
|
<Heart className={cn("h-4 w-4", favorited ? "fill-red-500 text-red-500" : iconClassName)} />
|
||||||
</Button>
|
</Button>
|
||||||
} />
|
} />
|
||||||
<TooltipContent>{favorited ? "Saved" : "Save"}</TooltipContent>
|
<TooltipContent>{favorited ? tSocial("favoriteRemove") : tSocial("favoriteAdd")}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -553,7 +553,7 @@
|
|||||||
"dietaryPrefsPlaceholder": "ex : végétarien, sans crustacés",
|
"dietaryPrefsPlaceholder": "ex : végétarien, sans crustacés",
|
||||||
"anyDifficulty": "Peu importe",
|
"anyDifficulty": "Peu importe",
|
||||||
"generate": "Générer",
|
"generate": "Générer",
|
||||||
"generating": "Génération… ça peut prendre une minute",
|
"generating": "Génération…",
|
||||||
"generateSuccess": "Session de batch cooking créée",
|
"generateSuccess": "Session de batch cooking créée",
|
||||||
"generateFailed": "Échec de la génération"
|
"generateFailed": "Échec de la génération"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user