fix footer & navbar
This commit is contained in:
parent
7c32116b28
commit
34c2390e21
|
|
@ -43,8 +43,7 @@ export default function Navbar() {
|
||||||
|
|
||||||
<ul className="nav-links desktop-links">
|
<ul className="nav-links desktop-links">
|
||||||
<li className={pathname === "/" ? "current-menu-item" : ""}>
|
<li className={pathname === "/" ? "current-menu-item" : ""}>
|
||||||
{/* eslint-disable-next-line @next/next/no-html-link-for-pages */}
|
<Link href="/" prefetch={true}>HEM</Link>
|
||||||
<a href="/">HEM</a>
|
|
||||||
</li>
|
</li>
|
||||||
<li className={pathname === "/products" ? "current-menu-item" : ""}>
|
<li className={pathname === "/products" ? "current-menu-item" : ""}>
|
||||||
<Link href="/products" prefetch={true}>PRODUKTER</Link>
|
<Link href="/products" prefetch={true}>PRODUKTER</Link>
|
||||||
|
|
@ -61,10 +60,8 @@ export default function Navbar() {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Center: Logo Only */}
|
|
||||||
<div className="nav-center">
|
<div className="nav-center">
|
||||||
{/* eslint-disable-next-line @next/next/no-html-link-for-pages */}
|
<Link href="/" className="logo-link" prefetch={true}>
|
||||||
<a href="/" className="logo-link">
|
|
||||||
<Image
|
<Image
|
||||||
src={logo}
|
src={logo}
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
|
|
@ -73,7 +70,7 @@ export default function Navbar() {
|
||||||
className="logo"
|
className="logo"
|
||||||
priority
|
priority
|
||||||
/>
|
/>
|
||||||
</a>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right side: profile + theme toggle */}
|
{/* Right side: profile + theme toggle */}
|
||||||
|
|
@ -87,11 +84,15 @@ function NavbarClientExtras({ isAuthenticated, isMounted }: { isAuthenticated: b
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const { unreadCount } = useNotification();
|
const { unreadCount } = useNotification();
|
||||||
const { theme, setTheme, resolvedTheme } = useTheme();
|
const { theme, setTheme, resolvedTheme } = useTheme();
|
||||||
|
|
||||||
|
// Start with true to match SSR, then update after mount based on consent
|
||||||
const [showThemeToggle, setShowThemeToggle] = useState(true);
|
const [showThemeToggle, setShowThemeToggle] = useState(true);
|
||||||
|
const [consentChecked, setConsentChecked] = useState(false);
|
||||||
|
|
||||||
// Determine profile destination safely to avoid hydration mismatch
|
// Determine profile destination safely to avoid hydration mismatch
|
||||||
const profileHref = isMounted && isAuthenticated ? "/me" : "/login";
|
const profileHref = isMounted && isAuthenticated ? "/me" : "/login";
|
||||||
|
|
||||||
|
// Check consent after mount to avoid hydration mismatch
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkConsent = () => {
|
const checkConsent = () => {
|
||||||
const saved = localStorage.getItem("cookie_consent");
|
const saved = localStorage.getItem("cookie_consent");
|
||||||
|
|
@ -100,13 +101,17 @@ function NavbarClientExtras({ isAuthenticated, isMounted }: { isAuthenticated: b
|
||||||
const parsed = JSON.parse(saved);
|
const parsed = JSON.parse(saved);
|
||||||
if (parsed.functional === false) {
|
if (parsed.functional === false) {
|
||||||
setShowThemeToggle(false);
|
setShowThemeToggle(false);
|
||||||
return;
|
} else {
|
||||||
|
setShowThemeToggle(true);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Failed to parse cookie consent", e);
|
console.error("Failed to parse cookie consent", e);
|
||||||
|
setShowThemeToggle(true);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setShowThemeToggle(true);
|
||||||
}
|
}
|
||||||
setShowThemeToggle(true);
|
setConsentChecked(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
checkConsent();
|
checkConsent();
|
||||||
|
|
@ -114,6 +119,9 @@ function NavbarClientExtras({ isAuthenticated, isMounted }: { isAuthenticated: b
|
||||||
return () => window.removeEventListener("cookie-consent-updated", checkConsent);
|
return () => window.removeEventListener("cookie-consent-updated", checkConsent);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Only show toggle if: mounted, consent checked, and consent is granted
|
||||||
|
const shouldShowToggle = isMounted && consentChecked && showThemeToggle;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (theme && typeof window !== "undefined") {
|
if (theme && typeof window !== "undefined") {
|
||||||
document.cookie = `theme=${theme}; path=/; max-age=31536000`; // 1-year expiry
|
document.cookie = `theme=${theme}; path=/; max-age=31536000`; // 1-year expiry
|
||||||
|
|
@ -168,7 +176,7 @@ function NavbarClientExtras({ isAuthenticated, isMounted }: { isAuthenticated: b
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Theme toggle (Always visible) */}
|
{/* Theme toggle (Always visible) */}
|
||||||
{showThemeToggle && (
|
{shouldShowToggle && (
|
||||||
<div className="theme-toggle flex">
|
<div className="theme-toggle flex">
|
||||||
<label className="flex items-center cursor-pointer">
|
<label className="flex items-center cursor-pointer">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
|
@ -239,7 +247,7 @@ function NavbarClientExtras({ isAuthenticated, isMounted }: { isAuthenticated: b
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Theme Toggle */}
|
{/* Mobile Theme Toggle */}
|
||||||
{showThemeToggle && (
|
{shouldShowToggle && (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-[var(--nav-text)] font-semibold uppercase tracking-wider">Tema</span>
|
<span className="text-[var(--nav-text)] font-semibold uppercase tracking-wider">Tema</span>
|
||||||
<div className="theme-toggle">
|
<div className="theme-toggle">
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,10 @@
|
||||||
color: var(--footer-text);
|
color: var(--footer-text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 0.3s ease;
|
transition: color 0.3s ease;
|
||||||
display: inline-block;
|
display: inline-flex;
|
||||||
padding: 0.5rem 0.25rem;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
min-width: 44px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__item a:hover {
|
.footer__item a:hover {
|
||||||
|
|
@ -54,15 +54,17 @@
|
||||||
.footer__link-button {
|
.footer__link-button {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.5rem 0.25rem;
|
padding: 0;
|
||||||
font-family: 'Montserrat', sans-serif;
|
font-family: 'Montserrat', sans-serif;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
color: var(--footer-text);
|
color: var(--footer-text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: color 0.3s ease;
|
transition: color 0.3s ease;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
min-width: 44px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__link-button:hover {
|
.footer__link-button:hover {
|
||||||
|
|
@ -74,16 +76,16 @@
|
||||||
font-family: 'Montserrat', sans-serif;
|
font-family: 'Montserrat', sans-serif;
|
||||||
font-size: clamp(0.75rem, 2vw, 0.85rem);
|
font-size: clamp(0.75rem, 2vw, 0.85rem);
|
||||||
color: var(--footer-contact-text);
|
color: var(--footer-contact-text);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__contact a {
|
.footer__contact a {
|
||||||
color: var(--footer-contact-text);
|
color: var(--footer-contact-text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 0.3s ease;
|
transition: color 0.3s ease;
|
||||||
display: inline-block;
|
|
||||||
padding: 0.5rem 0.25rem;
|
|
||||||
min-height: 44px;
|
|
||||||
min-width: 44px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__contact a:hover {
|
.footer__contact a:hover {
|
||||||
|
|
@ -123,23 +125,11 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
grid-template-rows: auto auto;
|
grid-template-rows: auto auto;
|
||||||
gap: 1rem 0;
|
gap: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Centered vertical divider using pseudo-element */
|
|
||||||
.footer__content::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 2px;
|
|
||||||
height: calc(100% - 3rem);
|
|
||||||
/* Stop before copyright */
|
|
||||||
background: rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer__links {
|
.footer__links {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
@ -147,6 +137,8 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
gap: 0;
|
||||||
|
border-right: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__contact-details {
|
.footer__contact-details {
|
||||||
|
|
@ -156,6 +148,7 @@
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__copyright {
|
.footer__copyright {
|
||||||
|
|
@ -163,7 +156,7 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
border-top: 2px solid rgba(0, 0, 0, 0.05);
|
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset text alignments to center */
|
/* Reset text alignments to center */
|
||||||
|
|
@ -184,11 +177,6 @@
|
||||||
padding: 0 clamp(0.5rem, 1.5vw, 0.75rem);
|
padding: 0 clamp(0.5rem, 1.5vw, 0.75rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__links,
|
|
||||||
.footer__contact-details {
|
|
||||||
gap: 0.4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer__item,
|
.footer__item,
|
||||||
.footer__contact {
|
.footer__contact {
|
||||||
font-size: clamp(0.65rem, 1.6vw, 0.75rem);
|
font-size: clamp(0.65rem, 1.6vw, 0.75rem);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue