fix: show recipe author with profile link on the recipe view page

/recipes/[id] never queried or displayed author info at all — viewing
someone else's public/unlisted recipe gave no way to see or visit
whoever wrote it. Add the author relation to the query and render an
avatar + "by {name}" link to /u/[username] under the title (hidden for
the owner's own recipes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Arnaud
2026-07-04 11:11:05 +02:00
parent c453cb395e
commit 68cbd5b4e4
3 changed files with 16 additions and 0 deletions
+14
View File
@@ -19,6 +19,7 @@ import { auth } from "@/lib/auth/server";
import { db, recipes, ratings, favorites, avg } from "@epicure/db";
import { and, eq, or, count, inArray } from "@epicure/db";
import { Badge } from "@/components/ui/badge";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { buttonVariants } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
@@ -62,6 +63,7 @@ export default async function RecipePage({ params }: Params) {
ingredients: { orderBy: (t, { asc }) => asc(t.order) },
steps: { orderBy: (t, { asc }) => asc(t.order) },
photos: { orderBy: (t, { asc }) => asc(t.order) },
author: { columns: { id: true, name: true, username: true, avatarUrl: true } },
},
}),
db.select({ avgScore: avg(ratings.score), total: count() }).from(ratings).where(eq(ratings.recipeId, id)),
@@ -91,6 +93,18 @@ export default async function RecipePage({ params }: Params) {
{/* Header */}
<div className="space-y-4">
<h1 className="text-3xl font-bold tracking-tight">{recipe.title}</h1>
{!isOwner && recipe.author.username && (
<Link
href={`/u/${recipe.author.username}`}
className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground"
>
<Avatar className="h-6 w-6">
{recipe.author.avatarUrl && <AvatarImage src={recipe.author.avatarUrl} alt={recipe.author.name} />}
<AvatarFallback className="text-[10px]">{recipe.author.name.slice(0, 2).toUpperCase()}</AvatarFallback>
</Avatar>
{formatMessage(m.recipe.byAuthor, { name: recipe.author.name })}
</Link>
)}
<TooltipProvider>
<div className="flex items-center gap-2 overflow-x-auto pb-0.5 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden">
{recipe.steps.length > 0 && (
+1
View File
@@ -29,6 +29,7 @@
"mention": "{name} mentioned you in a comment"
},
"recipe": {
"byAuthor": "by {name}",
"source": "Source",
"share": "Share",
"shareLinkCopied": "Link copied to clipboard",
+1
View File
@@ -29,6 +29,7 @@
"mention": "{name} vous a mentionné dans un commentaire"
},
"recipe": {
"byAuthor": "par {name}",
"source": "Source",
"share": "Partager",
"shareLinkCopied": "Lien copié dans le presse-papiers",