parent
9895956531
commit
6728010173
5 changed files with 164 additions and 58 deletions
@ -0,0 +1,69 @@ |
|||||||
|
import { cn } from '../lib/classname.ts'; |
||||||
|
import { memo, useEffect, useState } from 'react'; |
||||||
|
import { useScrollPosition } from '../hooks/use-scroll-position.ts'; |
||||||
|
import { X } from 'lucide-react'; |
||||||
|
|
||||||
|
type OnboardingNudgeProps = { |
||||||
|
onStartOnboarding: () => void; |
||||||
|
}; |
||||||
|
|
||||||
|
const NUDGE_ONBOARDING_KEY = 'should_nudge_onboarding'; |
||||||
|
|
||||||
|
export function OnboardingNudge(props: OnboardingNudgeProps) { |
||||||
|
const { onStartOnboarding } = props; |
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(false); |
||||||
|
|
||||||
|
const { y: scrollY } = useScrollPosition(); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (localStorage.getItem(NUDGE_ONBOARDING_KEY) === null) { |
||||||
|
localStorage.setItem(NUDGE_ONBOARDING_KEY, 'true'); |
||||||
|
} |
||||||
|
}, []); |
||||||
|
|
||||||
|
if (localStorage.getItem(NUDGE_ONBOARDING_KEY) !== 'true') { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
if (scrollY < 100) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className={cn( |
||||||
|
'fixed left-0 right-0 top-0 z-[91] flex w-full items-center justify-center bg-yellow-300 py-1.5', |
||||||
|
{ |
||||||
|
'striped-loader': isLoading, |
||||||
|
}, |
||||||
|
)} |
||||||
|
> |
||||||
|
<p className="text-base font-semibold text-yellow-950"> |
||||||
|
Welcome! Please take a moment to{' '} |
||||||
|
<button |
||||||
|
type="button" |
||||||
|
onClick={() => { |
||||||
|
setIsLoading(true); |
||||||
|
localStorage.setItem(NUDGE_ONBOARDING_KEY, 'false'); |
||||||
|
onStartOnboarding(); |
||||||
|
}} |
||||||
|
className="underline" |
||||||
|
> |
||||||
|
complete onboarding |
||||||
|
</button> |
||||||
|
<button |
||||||
|
type="button" |
||||||
|
className="relative top-[3px] ml-1 px-1 py-1 text-yellow-600 hover:text-yellow-950" |
||||||
|
onClick={(e) => { |
||||||
|
e.stopPropagation(); |
||||||
|
localStorage.setItem(NUDGE_ONBOARDING_KEY, 'false'); |
||||||
|
setIsLoading(true); |
||||||
|
}} |
||||||
|
> |
||||||
|
<X className="h-4 w-4" strokeWidth={3} /> |
||||||
|
</button> |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
import { useEffect, useState } from 'react'; |
||||||
|
|
||||||
|
export function useScrollPosition() { |
||||||
|
const [scrollPosition, setScrollPosition] = useState<{ |
||||||
|
x: number; |
||||||
|
y: number; |
||||||
|
}>({ |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
}); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const handleScroll = () => { |
||||||
|
setScrollPosition({ x: window.scrollX, y: window.scrollY }); |
||||||
|
}; |
||||||
|
|
||||||
|
window.addEventListener('scroll', handleScroll); |
||||||
|
return () => window.removeEventListener('scroll', handleScroll); |
||||||
|
}, []); |
||||||
|
|
||||||
|
return scrollPosition; |
||||||
|
} |
Loading…
Reference in new issue