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