chris 0576677523 feat: scroll-to-top button in estore; fix JS/CSS cache headers on main site
- Add ScrollToTop component matching main site's green Top button
  (appears after 130px scroll, same styling and font)
- Fix main-site server.js: JS/CSS now use max-age=3600 + must-revalidate
  instead of 30d immutable — changes reach users within 1 hour instead
  of being stuck in browser cache for a month
- Images/fonts keep 30d immutable (safe, as they are content-addressed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 14:41:42 -04:00

46 lines
1.4 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
export default function ScrollToTop() {
const [visible, setVisible] = useState(false)
useEffect(() => {
const onScroll = () => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
setVisible(scrollTop > 130)
}
window.addEventListener('scroll', onScroll, { passive: true })
return () => window.removeEventListener('scroll', onScroll)
}, [])
if (!visible) return null
return (
<button
aria-label="Back to top"
onClick={() => window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })}
style={{
position: 'fixed',
bottom: '12px',
right: '10px',
zIndex: 99,
border: '1px solid #363636',
outline: 'none',
background: '#94d601',
cursor: 'pointer',
padding: '15px',
borderRadius: '10px',
fontSize: '18px',
boxShadow: '3px 3px 3px #363636',
fontFamily: '"Autour One", serif',
lineHeight: 1,
}}
onMouseEnter={(e) => { (e.currentTarget as HTMLButtonElement).style.background = '#aedad3' }}
onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.background = '#94d601' }}
>
Top
</button>
)
}