diff --git a/src/app/(app)/pets/[petId]/page.tsx b/src/app/(app)/pets/[petId]/page.tsx index 35b8e25..17006dc 100644 --- a/src/app/(app)/pets/[petId]/page.tsx +++ b/src/app/(app)/pets/[petId]/page.tsx @@ -6,6 +6,7 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { buttonVariants } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; +import { getAvatarUrl } from "@/lib/avatar-url"; /** * Pet profile view — /pets/[petId] @@ -56,10 +57,7 @@ export default async function PetProfilePage({ params }: PageProps) { {/* Avatar — served from Cloudflare CDN via NEXT_PUBLIC_R2_PUBLIC_URL */} {pet.avatarKey && ( - + )} {getInitials(pet.name)} diff --git a/src/components/layout/MobileNav.tsx b/src/components/layout/MobileNav.tsx index 11f3d59..4e379db 100644 --- a/src/components/layout/MobileNav.tsx +++ b/src/components/layout/MobileNav.tsx @@ -20,6 +20,7 @@ import { import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { useActivePet } from "@/context/ActivePetContext"; +import { getAvatarUrl } from "@/lib/avatar-url"; type Pet = { id: string; @@ -70,7 +71,7 @@ export function MobileNav({ pets }: MobileNavProps) { {activePet.avatarKey && ( )} @@ -93,7 +94,7 @@ export function MobileNav({ pets }: MobileNavProps) { {pet.avatarKey && ( )} diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index 4bf996c..4da47b5 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -22,6 +22,7 @@ import { import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { useActivePet } from "@/context/ActivePetContext"; +import { getAvatarUrl } from "@/lib/avatar-url"; type Pet = { id: string; @@ -85,7 +86,7 @@ export function Sidebar({ pets }: SidebarProps) { {activePet.avatarKey && ( )} @@ -108,7 +109,7 @@ export function Sidebar({ pets }: SidebarProps) { {pet.avatarKey && ( )} diff --git a/src/components/pet/PetCard.tsx b/src/components/pet/PetCard.tsx index 5185f3a..68dc52a 100644 --- a/src/components/pet/PetCard.tsx +++ b/src/components/pet/PetCard.tsx @@ -3,6 +3,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; +import { getAvatarUrl } from "@/lib/avatar-url"; /** * PetCard — renders a pet's identity card for the My Pets grid. @@ -53,10 +54,7 @@ export function PetCard({ pet, isActive, onSelect }: PetCardProps) { }`} > {pet.avatarKey && ( - + )} {getInitials(pet.name)} diff --git a/src/lib/avatar-url.ts b/src/lib/avatar-url.ts new file mode 100644 index 0000000..9fd5477 --- /dev/null +++ b/src/lib/avatar-url.ts @@ -0,0 +1,8 @@ +/** + * Constructs the public CDN URL for a pet avatar stored in Supabase Storage. + * Safe to use in both server and client components (uses NEXT_PUBLIC_ env var). + */ +export function getAvatarUrl(key: string | null | undefined): string | null { + if (!key) return null; + return `${process.env.NEXT_PUBLIC_SUPABASE_URL}/storage/v1/object/public/pet-avatars/${key}`; +}