Merge pull request #178 from Compagnia-d-Arme-del-Santo-Luca/feat/event-popup-dialog
✨ feat(pop-up): add event pop up dialog
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 306 KiB |
@@ -0,0 +1,61 @@
|
|||||||
|
import { act, fireEvent, render, screen } from '@testing-library/react'
|
||||||
|
|
||||||
|
import EventDialog from './index.js'
|
||||||
|
|
||||||
|
describe('EventDialog', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.useFakeTimers()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.useRealTimers()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appears after a delay', () => {
|
||||||
|
vi.setSystemTime(new Date(2026, 9, 19))
|
||||||
|
render(<EventDialog />)
|
||||||
|
|
||||||
|
expect(screen.queryByRole('img')).not.toBeInTheDocument()
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
vi.advanceTimersByTime(3000)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(screen.getByRole('img', { name: /open day/i })).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can be dismissed', () => {
|
||||||
|
vi.setSystemTime(new Date(2026, 9, 19))
|
||||||
|
render(<EventDialog />)
|
||||||
|
act(() => {
|
||||||
|
vi.advanceTimersByTime(3000)
|
||||||
|
})
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole('button', { name: /close/i }))
|
||||||
|
act(() => {
|
||||||
|
vi.runAllTimers()
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(screen.queryByRole('img')).not.toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('still appears on October 25th', () => {
|
||||||
|
vi.setSystemTime(new Date(2026, 9, 25, 23, 59))
|
||||||
|
render(<EventDialog />)
|
||||||
|
act(() => {
|
||||||
|
vi.advanceTimersByTime(3000)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(screen.getByRole('img', { name: /open day/i })).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not appear after October 25th', () => {
|
||||||
|
vi.setSystemTime(new Date(2026, 9, 26))
|
||||||
|
render(<EventDialog />)
|
||||||
|
act(() => {
|
||||||
|
vi.advanceTimersByTime(10000)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(screen.queryByRole('img')).not.toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { Box, Dialog, IconButton } from '@mui/material'
|
||||||
|
import CloseIcon from '@mui/icons-material/Close'
|
||||||
|
|
||||||
|
const SHOW_DELAY_MS = 3000
|
||||||
|
// Local midnight after Oct 25th, so the event is promoted through the whole day.
|
||||||
|
const EXPIRES_AT = new Date(2026, 9, 26)
|
||||||
|
|
||||||
|
const EventDialog = () => {
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (Date.now() >= EXPIRES_AT.getTime()) return
|
||||||
|
const timer = setTimeout(() => setOpen(true), SHOW_DELAY_MS)
|
||||||
|
return () => clearTimeout(timer)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onClose={() => setOpen(false)} maxWidth={false} aria-label="Open Day event">
|
||||||
|
<IconButton
|
||||||
|
aria-label="Close"
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
sx={{ position: 'absolute', top: 4, right: 4, bgcolor: 'background.paper', '&:hover': { bgcolor: 'background.paper' } }}>
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
<Box
|
||||||
|
component="img"
|
||||||
|
src="/images/20261024_banner_open_day.webp"
|
||||||
|
alt="Open Day, October 24th"
|
||||||
|
sx={{
|
||||||
|
display: 'block',
|
||||||
|
width: 'auto',
|
||||||
|
height: 'auto',
|
||||||
|
maxWidth: 'calc(100vw - 64px)',
|
||||||
|
maxHeight: 'calc(100vh - 64px)',
|
||||||
|
objectFit: 'contain',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EventDialog
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { Outlet, useLocation } from 'react-router-dom'
|
import { Outlet, useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
|
import EventDialog from 'components/molecules/EventDialog/index.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route tracking component that wraps all routes and includes analytics page tracking
|
* Route tracking component that wraps all routes and includes analytics page tracking
|
||||||
*/
|
*/
|
||||||
@@ -11,7 +13,12 @@ const RouteTracker = () => {
|
|||||||
window.scrollTo(0, 0)
|
window.scrollTo(0, 0)
|
||||||
}, [location])
|
}, [location])
|
||||||
|
|
||||||
return <Outlet />
|
return (
|
||||||
|
<>
|
||||||
|
<Outlet />
|
||||||
|
<EventDialog />
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RouteTracker
|
export default RouteTracker
|
||||||
|
|||||||
Reference in New Issue
Block a user