computer-scienceangular-roadmapbackend-roadmapblockchain-roadmapdba-roadmapdeveloper-roadmapdevops-roadmapfrontend-roadmapgo-roadmaphactoberfestjava-roadmapjavascript-roadmapnodejs-roadmappython-roadmapqa-roadmapreact-roadmaproadmapstudy-planvue-roadmapweb3-roadmap
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.5 KiB
88 lines
2.5 KiB
4 months ago
|
import { cn } from '../../lib/classname.ts';
|
||
|
import { useScrollPosition } from '../../hooks/use-scroll-position.ts';
|
||
|
import { X } from 'lucide-react';
|
||
|
import type { StickyTopSponsorType } from './PageSponsors.tsx';
|
||
|
import { useEffect, useState } from 'react';
|
||
|
import { isOnboardingStripHidden } from '../../stores/page.ts';
|
||
|
|
||
|
type StickyTopSponsorProps = {
|
||
|
sponsor: StickyTopSponsorType;
|
||
|
|
||
|
onSponsorImpression: () => void;
|
||
|
onSponsorClick: () => void;
|
||
|
onSponsorHidden: () => void;
|
||
|
};
|
||
|
|
||
|
const SCROLL_DISTANCE = 100;
|
||
|
|
||
|
export function StickyTopSponsor(props: StickyTopSponsorProps) {
|
||
|
const { sponsor, onSponsorHidden, onSponsorImpression, onSponsorClick } =
|
||
|
props;
|
||
|
|
||
|
const { y: scrollY } = useScrollPosition();
|
||
|
const [isImpressionLogged, setIsImpressionLogged] = useState(false);
|
||
|
const [isHidden, setIsHidden] = useState(false);
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (!sponsor) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// hide the onboarding strip when the sponsor is visible
|
||
|
isOnboardingStripHidden.set(true);
|
||
|
}, [sponsor]);
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (scrollY < SCROLL_DISTANCE || isImpressionLogged) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
setIsImpressionLogged(true);
|
||
|
onSponsorImpression();
|
||
|
}, [scrollY]);
|
||
|
|
||
|
if (scrollY < SCROLL_DISTANCE || isHidden) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<a
|
||
|
target="_blank"
|
||
|
href="https://www.google.com"
|
||
|
onClick={onSponsorClick}
|
||
|
className={cn(
|
||
|
'fixed left-0 right-0 top-0 z-[91] flex min-h-[45px] w-full flex-row items-center justify-center px-14 pb-2 pt-1.5 text-base font-medium text-yellow-950',
|
||
|
)}
|
||
|
style={{
|
||
|
backgroundImage: `linear-gradient(to bottom, ${sponsor.style?.fromColor}, ${sponsor.style?.toColor})`,
|
||
|
color: sponsor.style?.textColor,
|
||
|
}}
|
||
|
>
|
||
|
<img className="h-[23px]" src={sponsor.imageUrl} alt={'ad'} />
|
||
|
<span className="mx-3 truncate">{sponsor.description}</span>
|
||
|
<button
|
||
|
className="flex-truncate rounded-md px-3 py-1 text-sm transition-colors"
|
||
|
style={{
|
||
|
backgroundColor: sponsor.style?.buttonBackgroundColor,
|
||
|
color: sponsor.style?.buttonTextColor,
|
||
|
}}
|
||
|
>
|
||
|
{sponsor.buttonText}
|
||
|
</button>
|
||
|
<button
|
||
|
type="button"
|
||
|
className="absolute right-5 top-1/2 ml-1 -translate-y-1/2 px-1 py-1 opacity-70 hover:opacity-100"
|
||
|
onClick={(e) => {
|
||
|
e.preventDefault();
|
||
|
e.stopPropagation();
|
||
|
|
||
|
setIsHidden(true);
|
||
|
onSponsorHidden();
|
||
|
}}
|
||
|
>
|
||
|
<X className="h-4 w-4" strokeWidth={3} />
|
||
|
</button>
|
||
|
</a>
|
||
|
);
|
||
|
}
|