From 30d9a082ae0a4e3864e9a20dcebb67e313f3ff70 Mon Sep 17 00:00:00 2001 From: Natalie Date: Tue, 23 Jun 2026 06:53:41 -0400 Subject: [PATCH] fix(banners): show website logo as placeholder banner image when no platform-provided imgSrc - On /banners, if a VerifiedProfile has empty imgSrc (no banner from user/platform), render the site logo (/icon-512.png) as a branded visual placeholder inside linked or static frame. - Introduced LogoPreview, LogoPlaceholder, LogoImg styled components for contained square logo with padding/bg. - Removed redundant text-only ProfileLink (the logo image now provides the visual + click target when href present). - Updated comments and logic in BannerItem. - Always provides an image slot now for uniform card layout (real banner or site logo). - Typecheck clean; e2e smoke test for /banners passes. - Fallback only affects UI rendering (data can still omit imgSrc); matches request for transquinnftw.com/banners. - Uses existing static icon from manifest/public for the 'logo of the website'. --- .../frontend-public/src/pages/BannersPage.tsx | 85 ++++++++++++------- 1 file changed, 56 insertions(+), 29 deletions(-) diff --git a/codebase/@features/provider-website/frontend-public/src/pages/BannersPage.tsx b/codebase/@features/provider-website/frontend-public/src/pages/BannersPage.tsx index 2f9fef06..49a98784 100644 --- a/codebase/@features/provider-website/frontend-public/src/pages/BannersPage.tsx +++ b/codebase/@features/provider-website/frontend-public/src/pages/BannersPage.tsx @@ -107,22 +107,40 @@ const ImageFrame = styled.div` } `; -// Text link shown when a profile URL exists but no badge image has been provided. -const ProfileLink = styled.a` - display: inline-flex; - align-items: center; - gap: 0.4rem; +// Placeholder logo shown on /banners when a verified platform entry has no banner/badge image provided +// (by the platform or in the data). Uses the site's own icon as a branded fallback visual. +const LogoPlaceholder = styled.div` align-self: flex-start; - font-size: 0.85rem; - font-weight: ${p => p.theme.typography.fontWeight.medium}; - color: ${p => p.theme.colors.primary}; + border-radius: ${p => p.theme.borderRadius.sm}; + overflow: hidden; + background: ${p => p.theme.colors.background.primary}; + padding: 1rem; + line-height: 0; +`; + +const LogoPreview = styled.a` + display: block; + align-self: flex-start; + border-radius: ${p => p.theme.borderRadius.sm}; + overflow: hidden; + background: ${p => p.theme.colors.background.primary}; + padding: 1rem; + line-height: 0; text-decoration: none; + transition: opacity 150ms; &:hover { - text-decoration: underline; + opacity: 0.9; } `; +const LogoImg = styled.img` + width: 120px; + height: 120px; + object-fit: contain; + display: block; +`; + function BannerItem({ profile }: { profile: VerifiedProfile }): ReactNode { const trackOutlink = useOutlinkTracker(); @@ -134,6 +152,10 @@ function BannerItem({ profile }: { profile: VerifiedProfile }): ReactNode { const hasLink = profile.href.trim().length > 0; const hasDescription = profile.description.trim().length > 0; + // Fallback to the website's own logo (icon-512.png) when the platform/data provides no banner image. + const bannerSrc = hasImage ? profile.imgSrc : '/icon-512.png'; + const bannerAlt = hasImage ? profile.imgAlt : 'Quinn logo'; + return ( @@ -144,34 +166,39 @@ function BannerItem({ profile }: { profile: VerifiedProfile }): ReactNode { - {hasImage && (hasLink ? ( - + {bannerAlt} + + ) : ( + + {bannerAlt} + + ) + ) : hasLink ? ( + - {profile.imgAlt} - + + ) : ( - - {profile.imgAlt} - - ))} + + + + )} {hasDescription && {profile.description}} - - {!hasImage && hasLink && ( - - View verified profile → - - )} ); }