fdfa556d42
1) Header pill mode:
- Pill aktifken telefon link gizlenir
- Yerine kompakt 'Ara' butonu görünür (data-pill-show='true')
- header-scroll.tsx hem hide hem show class'larını yönetiyor
2) Hizmet detay sayfası — yeni unique hero (ServiceHero component):
- Gradient gradient icon (sky → purple, glow ile)
- Profesyonel hizmet badge'i
- Gradient text başlık
- 4 'quick trust' satırı (teslim, destek, ücretsiz taslak, yerel)
- 3 CTA: Teklif al (navy) / WhatsApp (yeşil) / Telefon ara
- Sağda: hero_image varsa görsel + 'Şimdi başla' floating badge
- Yoksa: dekoratif dark card + animasyonlu nokta deseni + glow +
floating '100% Memnuniyet' ve '150+ Proje' kartları
3) Hizmet detay sayfası — sidebar (ServiceSidebar component):
- QuickLeadForm (ad + telefon)
- Gradient CTA card (telefon + WhatsApp butonları)
- 'Risk almazsınız' garanti mini card
- Diğer hizmetler tam listesi (icon + isim, hover'da gradient)
- Site analizi lead magnet kartı
Önceki versiyonda sadece 1 boş CTA + 1 boş diğer hizmetler vardı —
artık doluyu doluya sidebar.
4) Layout: lg:grid-cols-[2fr_1fr] → lg:grid-cols-[1.5fr_1fr]
- Sidebar daha geniş, içerik orantılı dağıldı
106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect } from "react";
|
||
|
||
/**
|
||
* WordPress sitesindeki "floating pill" header efekti.
|
||
* Scroll'da header küçülür, kenar yuvarlanır, gölge alır.
|
||
* Mobilde scroll-down'da gizlenir, scroll-up'ta görünür.
|
||
*/
|
||
export function HeaderScrollEffect() {
|
||
useEffect(() => {
|
||
const wrap = document.getElementById("floating-header-wrap");
|
||
const pillWrap = document.getElementById("header-pill-wrap");
|
||
const header = document.getElementById("site-header");
|
||
const navBar = document.getElementById("header-nav-bar");
|
||
if (!wrap || !pillWrap || !header || !navBar) return;
|
||
|
||
let lastY = 0;
|
||
let ticking = false;
|
||
|
||
wrap.style.transition = "transform 0.3s ease, opacity 0.3s ease";
|
||
|
||
function applyScroll() {
|
||
const y = window.scrollY;
|
||
const mobile = window.innerWidth < 1024;
|
||
const scrolled = y > 10;
|
||
const goingDown = y > lastY;
|
||
|
||
if (!mobile && pillWrap && header && navBar && wrap) {
|
||
wrap.style.transform = "";
|
||
wrap.style.opacity = "";
|
||
// Pill mode toggle: data-pill-hide gizlenir, data-pill-show görünür
|
||
const hidables = document.querySelectorAll<HTMLElement>(
|
||
'[data-pill-hide="true"]',
|
||
);
|
||
const showables = document.querySelectorAll<HTMLElement>(
|
||
'[data-pill-show="true"]',
|
||
);
|
||
if (scrolled) {
|
||
pillWrap.style.padding = "12px 16px 0";
|
||
header.style.maxWidth = "1100px";
|
||
header.style.borderRadius = "1rem";
|
||
header.style.border = "1px solid #e5e7eb";
|
||
header.style.boxShadow = "0 8px 24px rgba(0,0,0,0.08)";
|
||
navBar.style.height = "52px";
|
||
navBar.style.padding = "0 1.25rem";
|
||
hidables.forEach((el) => {
|
||
el.style.display = "none";
|
||
});
|
||
showables.forEach((el) => {
|
||
el.style.display = "inline-flex";
|
||
});
|
||
} else {
|
||
pillWrap.style.padding = "";
|
||
header.style.maxWidth = "";
|
||
header.style.borderRadius = "";
|
||
header.style.border = "";
|
||
header.style.boxShadow = "";
|
||
navBar.style.height = "";
|
||
navBar.style.padding = "";
|
||
hidables.forEach((el) => {
|
||
el.style.display = "";
|
||
});
|
||
showables.forEach((el) => {
|
||
el.style.display = "none";
|
||
});
|
||
}
|
||
}
|
||
|
||
if (mobile && wrap && y > 80) {
|
||
if (goingDown) {
|
||
wrap.style.transform = "translateY(-110%)";
|
||
wrap.style.opacity = "0";
|
||
} else {
|
||
wrap.style.transform = "";
|
||
wrap.style.opacity = "";
|
||
}
|
||
} else if (mobile && wrap) {
|
||
wrap.style.transform = "";
|
||
wrap.style.opacity = "";
|
||
}
|
||
|
||
lastY = y;
|
||
ticking = false;
|
||
}
|
||
|
||
function onScroll() {
|
||
if (!ticking) {
|
||
requestAnimationFrame(applyScroll);
|
||
ticking = true;
|
||
}
|
||
}
|
||
|
||
window.addEventListener("scroll", onScroll, { passive: true });
|
||
window.addEventListener("resize", applyScroll);
|
||
applyScroll();
|
||
|
||
return () => {
|
||
window.removeEventListener("scroll", onScroll);
|
||
window.removeEventListener("resize", applyScroll);
|
||
};
|
||
}, []);
|
||
|
||
return null;
|
||
}
|