feat(layout): wire CMS logo to Header and Footer with SVG fallback
This commit is contained in:
parent
bcdd2a3a2d
commit
0895f25434
3 changed files with 89 additions and 39 deletions
|
|
@ -1,8 +1,19 @@
|
|||
/* eslint-disable @next/next/no-img-element */
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { getGlobal } from '@/lib/payload'
|
||||
import type { FooterGlobal } from '@/types/globals'
|
||||
|
||||
function resolveLogoUrl(logo: unknown): string | null {
|
||||
if (!logo) return null
|
||||
if (typeof logo === 'string') return logo
|
||||
if (typeof logo === 'object' && logo !== null && 'url' in logo) {
|
||||
const url = (logo as { url?: string | null }).url
|
||||
return url ?? null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const IMG_BG = '/images/figma/footer-bg.webp'
|
||||
const LOGO_G1 = '/images/figma/logo-g1-lg.svg'
|
||||
const LOGO_G2 = '/images/figma/logo-g2-lg.svg'
|
||||
|
|
@ -41,6 +52,8 @@ export async function Footer() {
|
|||
const navLinks = footer?.navLinks?.length ? footer.navLinks : STATIC_NAV
|
||||
const contacts = footer?.contacts
|
||||
const socials = footer?.socials?.filter((s) => s.url)
|
||||
const logoUrl = resolveLogoUrl(footer?.logo)
|
||||
const cmsLogo = logoUrl ? { url: logoUrl, alt: footer?.logoAlt ?? 'Шуміленд' } : null
|
||||
|
||||
return (
|
||||
<footer className="relative overflow-hidden bg-[#223e0d]">
|
||||
|
|
@ -55,26 +68,36 @@ export async function Footer() {
|
|||
<div className="flex flex-col items-center gap-12 lg:flex-row lg:items-start lg:justify-between">
|
||||
{/* Logo */}
|
||||
<Link href="/" aria-label="Шуміленд — на головну" className="shrink-0">
|
||||
<div className="relative" style={{ width: '120px', height: '104px' }}>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '91.32%', right: '21.81%', bottom: '0.97%', left: '22.26%' }}
|
||||
>
|
||||
<img src={LOGO_G1} alt="" aria-hidden="true" className="block h-full w-full" />
|
||||
{cmsLogo ? (
|
||||
<Image
|
||||
src={cmsLogo.url}
|
||||
alt={cmsLogo.alt}
|
||||
width={140}
|
||||
height={50}
|
||||
className="object-contain"
|
||||
/>
|
||||
) : (
|
||||
<div className="relative" style={{ width: '120px', height: '104px' }}>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '91.32%', right: '21.81%', bottom: '0.97%', left: '22.26%' }}
|
||||
>
|
||||
<img src={LOGO_G1} alt="" aria-hidden="true" className="block h-full w-full" />
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '71.76%', right: '2.82%', bottom: '7.3%', left: '1.41%' }}
|
||||
>
|
||||
<img src={LOGO_G2} alt="" aria-hidden="true" className="block h-full w-full" />
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '1.61%', right: '2.82%', bottom: '38.73%', left: '21.27%' }}
|
||||
>
|
||||
<img src={LOGO_G3} alt="" aria-hidden="true" className="block h-full w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '71.76%', right: '2.82%', bottom: '7.3%', left: '1.41%' }}
|
||||
>
|
||||
<img src={LOGO_G2} alt="" aria-hidden="true" className="block h-full w-full" />
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '1.61%', right: '2.82%', bottom: '38.73%', left: '21.27%' }}
|
||||
>
|
||||
<img src={LOGO_G3} alt="" aria-hidden="true" className="block h-full w-full" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Link>
|
||||
|
||||
{/* Nav */}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@ import { safeCmsHref } from '@/lib/cn'
|
|||
import { HeaderClient, type NavLinkItem } from './HeaderClient'
|
||||
import type { HeaderGlobal } from '@/types/globals'
|
||||
|
||||
function resolveLogoUrl(logo: unknown): string | null {
|
||||
if (!logo) return null
|
||||
if (typeof logo === 'string') return logo
|
||||
if (typeof logo === 'object' && logo !== null && 'url' in logo) {
|
||||
const url = (logo as { url?: string | null }).url
|
||||
return url ?? null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const DEFAULT_NAV: NavLinkItem[] = [
|
||||
{ label: 'Головна', href: '/' },
|
||||
{
|
||||
|
|
@ -26,6 +36,7 @@ export async function Header() {
|
|||
let navLinks: NavLinkItem[] = DEFAULT_NAV
|
||||
let ctaHref = '/kvytky'
|
||||
let ctaLabel = 'Купити квиток'
|
||||
let logo: { url: string; alt?: string } | null = null
|
||||
|
||||
try {
|
||||
const [header, menuLocations] = await Promise.all([
|
||||
|
|
@ -36,6 +47,9 @@ export async function Header() {
|
|||
if (header?.ctaLabel) ctaLabel = header.ctaLabel
|
||||
if (header?.ctaHref) ctaHref = safeCmsHref(header.ctaHref) ?? header.ctaHref
|
||||
|
||||
const logoUrl = resolveLogoUrl(header?.logo)
|
||||
if (logoUrl) logo = { url: logoUrl, alt: header?.logoAlt ?? 'Шуміленд' }
|
||||
|
||||
if (header?.navLinks && header.navLinks.length > 0) {
|
||||
const parsed: NavLinkItem[] = header.navLinks
|
||||
.filter((l) => l.label && l.href)
|
||||
|
|
@ -71,6 +85,7 @@ export async function Header() {
|
|||
ctaLabel={ctaLabel}
|
||||
ctaHref={ctaHref}
|
||||
siteName="Шуміленд"
|
||||
logo={logo}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use client'
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
import { NavLink } from '@/components/ui/NavLink'
|
||||
|
|
@ -21,6 +22,7 @@ interface HeaderClientProps {
|
|||
ctaLabel: string
|
||||
ctaHref: string
|
||||
siteName: string
|
||||
logo?: { url: string; alt?: string } | null
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -32,7 +34,7 @@ interface HeaderClientProps {
|
|||
* - real backdrop-filter blur + saturate + a subtle dark-green tint
|
||||
* so the foliage behind shows through but text stays readable
|
||||
*/
|
||||
export function HeaderClient({ navLinks, ctaLabel, ctaHref }: HeaderClientProps) {
|
||||
export function HeaderClient({ navLinks, ctaLabel, ctaHref, logo }: HeaderClientProps) {
|
||||
const [menuOpen, setMenuOpen] = useState(false)
|
||||
|
||||
return (
|
||||
|
|
@ -62,26 +64,36 @@ export function HeaderClient({ navLinks, ctaLabel, ctaHref }: HeaderClientProps)
|
|||
<div className="relative flex items-center justify-between h-[60px] lg:h-[120px] px-[20px] lg:px-[30px]">
|
||||
{/* Logo */}
|
||||
<Link href="/" aria-label="Шуміленд — на головну" className="shrink-0">
|
||||
<div className="relative h-[44px] w-[50px] lg:h-[62px] lg:w-[71px]">
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '91.32%', right: '21.81%', bottom: '0.97%', left: '22.26%' }}
|
||||
>
|
||||
<img src={LOGO_G1} alt="" aria-hidden="true" className="block w-full h-full" />
|
||||
{logo ? (
|
||||
<Image
|
||||
src={logo.url}
|
||||
alt={logo.alt ?? 'Шуміленд'}
|
||||
width={140}
|
||||
height={50}
|
||||
className="object-contain"
|
||||
/>
|
||||
) : (
|
||||
<div className="relative h-[44px] w-[50px] lg:h-[62px] lg:w-[71px]">
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '91.32%', right: '21.81%', bottom: '0.97%', left: '22.26%' }}
|
||||
>
|
||||
<img src={LOGO_G1} alt="" aria-hidden="true" className="block w-full h-full" />
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '71.76%', right: '2.82%', bottom: '7.3%', left: '1.41%' }}
|
||||
>
|
||||
<img src={LOGO_G2} alt="" aria-hidden="true" className="block w-full h-full" />
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '1.61%', right: '2.82%', bottom: '38.73%', left: '21.27%' }}
|
||||
>
|
||||
<img src={LOGO_G3} alt="" aria-hidden="true" className="block w-full h-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '71.76%', right: '2.82%', bottom: '7.3%', left: '1.41%' }}
|
||||
>
|
||||
<img src={LOGO_G2} alt="" aria-hidden="true" className="block w-full h-full" />
|
||||
</div>
|
||||
<div
|
||||
className="absolute"
|
||||
style={{ top: '1.61%', right: '2.82%', bottom: '38.73%', left: '21.27%' }}
|
||||
>
|
||||
<img src={LOGO_G3} alt="" aria-hidden="true" className="block w-full h-full" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Link>
|
||||
|
||||
{/* Nav — desktop */}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue