SFS/components/navbar.tsx
2025-12-16 10:03:26 +05:30

181 lines
6.5 KiB
TypeScript

"use client"
import Link from "next/link"
import { useEffect, useState } from "react"
import { Menu, X, Search } from "lucide-react"
import { ensureHttpsImageUrl } from "@/lib/utils"
const navItems = [
{ label: "Home", href: "#", isActive: true },
{ label: "About", href: "#" },
{ label: "ERP", href: "#" },
{ label: "Tech Lab Setup", href: "#" },
{ label: "Resources", href: "#" },
{ label: "Contact", href: "#" },
]
export default function Navbar() {
const [isOpen, setIsOpen] = useState(false)
const [logoUrl, setLogoUrl] = useState("")
useEffect(() => {
const loadLogo = async () => {
try {
// Use Next.js API route instead of direct Strapi call
const res = await fetch("/api/logo", {
headers: { Accept: "application/json" },
})
if (!res.ok) {
throw new Error(`logo status ${res.status}: ${res.statusText}`)
}
const json = await res.json()
// Handle both Strapi v4 formats: data.logo (direct) or data.attributes.logo.data (nested)
const logoData = json?.data?.logo || json?.data?.attributes?.logo?.data || json?.data?.attributes?.logo
if (!logoData) {
console.warn("No logo data found in response. Full response:", json)
return
}
const logo = Array.isArray(logoData) ? logoData[0] : logoData
// Logo object may have attributes or be direct
const logoObj = logo?.attributes || logo
const url =
logoObj?.url ||
logoObj?.formats?.small?.url ||
logoObj?.formats?.thumbnail?.url ||
logoObj?.formats?.medium?.url ||
logoObj?.formats?.large?.url ||
""
if (url) {
// Get base URL for constructing absolute URLs if needed
const baseUrl = process.env.NEXT_PUBLIC_STRAPI_BASE_URL || "http://160.187.167.213"
// Ensure HTTPS to prevent Mixed Content errors
const absolute = ensureHttpsImageUrl(url, baseUrl)
console.log("✅ Logo URL from API:", absolute)
console.log("🔍 Original URL:", url)
console.log("🔍 Base URL:", baseUrl)
if (absolute) {
setLogoUrl(absolute)
} else {
console.error("❌ ensureHttpsImageUrl returned empty string")
}
} else {
console.warn("⚠️ No logo URL found in logo object. Logo object:", logoObj)
}
} catch (err) {
console.error("❌ Failed to load navbar logo:", err)
// Don't set fallback - user wants only Strapi logo
}
}
loadLogo()
}, [])
return (
<nav className="w-full bg-white border-b border-gray-200">
<div className="w-full pl-6 sm:pl-8 lg:pl-12 pr-4 sm:pr-6 lg:pr-8">
<div className="flex justify-between items-center h-20">
{/* Logo */}
{logoUrl ? (
<div className="shrink-0 flex items-center">
{/* Use regular img tag for external URLs to avoid Next.js Image restrictions */}
<img
src={logoUrl}
alt="School for Schools"
className="h-7 md:h-10 w-auto object-contain"
style={{ maxWidth: "200px" }}
onError={(e) => {
console.error("❌ Image failed to load:", logoUrl)
console.error("Error event:", e)
// Try to reload after a delay
setTimeout(() => {
const img = e.currentTarget as HTMLImageElement
if (img.src !== logoUrl) {
img.src = logoUrl
}
}, 1000)
}}
onLoad={() => {
console.log("✅ Image loaded successfully:", logoUrl)
}}
/>
</div>
) : (
<div className="shrink-0 flex items-center">
<div className="h-7 md:h-10 w-32 bg-gray-200 animate-pulse rounded" />
</div>
)}
{/* Desktop Navigation */}
<div className="hidden md:flex items-center space-x-8">
{navItems.map((item) => (
<Link
key={item.label}
href={item.href}
className={`text-sm font-medium transition-colors whitespace-nowrap ${item.isActive ? "text-[#F48120]" : "text-[#353535] hover:text-[#F48120]"
}`}
>
{item.label}
</Link>
))}
{/* Desktop Search Icon */}
<button
onClick={() => {
// Add search functionality here
console.log("Search clicked")
}}
aria-label="Search"
className="inline-flex items-center justify-center p-2 rounded-md text-[#353535] hover:text-[#F48120] hover:bg-gray-100 transition-colors"
>
<Search className="h-5 w-5" />
</button>
</div>
{/* Mobile: Search icon and menu button */}
<div className="md:hidden flex items-center gap-2">
{/* Mobile Search Icon */}
<button
onClick={() => {
// Add search functionality here
console.log("Search clicked")
}}
aria-label="Search"
className="inline-flex items-center justify-center p-2 rounded-md text-[#353535] hover:text-[#F48120] hover:bg-gray-100 transition-colors"
>
<Search className="h-6 w-6" />
</button>
{/* Mobile menu button */}
<button
onClick={() => setIsOpen(!isOpen)}
className="inline-flex items-center justify-center p-2 rounded-md text-[#353535] hover:bg-gray-100"
>
{isOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
</button>
</div>
</div>
</div>
{/* Mobile Navigation */}
{isOpen && (
<div className="md:hidden bg-white border-t border-gray-200">
<div className="px-2 pt-2 pb-3 space-y-1">
{navItems.map((item) => (
<Link
key={item.label}
href={item.href}
className={`block px-3 py-2 rounded-md text-base font-medium transition-colors ${item.isActive ? "bg-orange-50 text-[#F48120]" : "text-[#353535] hover:bg-gray-50"
}`}
>
{item.label}
</Link>
))}
</div>
</div>
)}
</nav>
)
}