Show/hide toast logic
This commit is contained in:
parent
0d924a1226
commit
660ad41d4e
2 changed files with 91 additions and 11 deletions
|
|
@ -1,18 +1,55 @@
|
|||
import type { ReactElement } from 'react'
|
||||
import { PropsWithChildren, useEffect, useState } from 'react'
|
||||
import { add, format } from 'date-fns'
|
||||
import { getCookie } from 'cookies-next'
|
||||
|
||||
import { appState } from '~utils/appState'
|
||||
|
||||
import TopHeader from '~components/Header'
|
||||
import Toast from '~components/Toast'
|
||||
import UpdateToast from '~components/UpdateToast'
|
||||
|
||||
import './index.scss'
|
||||
interface Props {
|
||||
children: ReactElement
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Props) => {
|
||||
interface Props {}
|
||||
|
||||
const Layout = ({ children }: PropsWithChildren<Props>) => {
|
||||
const [updateToastOpen, setUpdateToastOpen] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const cookie = getToastCookie()
|
||||
const now = new Date()
|
||||
const updatedAt = new Date(appState.version.updated_at)
|
||||
const validUntil = add(updatedAt, { days: 7 })
|
||||
|
||||
if (now < validUntil && !cookie.seen) setUpdateToastOpen(true)
|
||||
}, [])
|
||||
|
||||
function getToastCookie() {
|
||||
const updatedAt = new Date(appState.version.updated_at)
|
||||
const cookieValues = getCookie(`update-${format(updatedAt, 'yyyy-MM-dd')}`)
|
||||
return cookieValues
|
||||
? (JSON.parse(cookieValues as string) as { seen: true })
|
||||
: { seen: false }
|
||||
}
|
||||
|
||||
function handleToastActionClicked() {
|
||||
setUpdateToastOpen(false)
|
||||
}
|
||||
|
||||
function handleToastOpenChanged(open: boolean) {
|
||||
setUpdateToastOpen(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TopHeader />
|
||||
<UpdateToast open={true} updateType="feature" />
|
||||
{/* TODO: Don't show toast on about pages */}
|
||||
<UpdateToast
|
||||
open={updateToastOpen}
|
||||
updateType="feature"
|
||||
onActionClicked={handleToastActionClicked}
|
||||
onOpenChange={handleToastOpenChanged}
|
||||
lastUpdated={appState.version.updated_at}
|
||||
/>
|
||||
<main>{children}</main>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
import React from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { setCookie } from 'cookies-next'
|
||||
import { add, format } from 'date-fns'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import Button from '~components/Button'
|
||||
|
|
@ -10,24 +13,64 @@ import { useTranslation } from 'next-i18next'
|
|||
interface Props {
|
||||
open: boolean
|
||||
updateType: 'feature' | 'content'
|
||||
lastUpdated: string
|
||||
onActionClicked: () => void
|
||||
onOpenChange: (open: boolean) => void
|
||||
}
|
||||
|
||||
const UpdateToast = (props: Props) => {
|
||||
const UpdateToast = ({
|
||||
open,
|
||||
updateType,
|
||||
lastUpdated,
|
||||
onActionClicked,
|
||||
onOpenChange,
|
||||
}: Props) => {
|
||||
const { t } = useTranslation('roadmap')
|
||||
|
||||
const classes = classNames({
|
||||
Update: true,
|
||||
})
|
||||
|
||||
function setToastCookie() {
|
||||
const updatedAt = new Date(lastUpdated)
|
||||
const expiresAt = add(updatedAt, { days: 7 })
|
||||
setCookie(
|
||||
`update-${format(updatedAt, 'yyyy-MM-dd')}`,
|
||||
{ seen: true },
|
||||
{ path: '/', expires: expiresAt }
|
||||
)
|
||||
}
|
||||
|
||||
function handleButtonClicked() {
|
||||
// TODO: Set a timestamped cookie to not show
|
||||
console.log('Primary button clicked')
|
||||
window.open('/about', '_blank')
|
||||
setToastCookie()
|
||||
onActionClicked()
|
||||
}
|
||||
|
||||
function handleOpenChanged(open: boolean) {
|
||||
if (!open) {
|
||||
setToastCookie()
|
||||
onOpenChange(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Toast
|
||||
className={classes}
|
||||
title={t(`toasts.title`)}
|
||||
content={t(`toasts.description.${props.updateType}`)}
|
||||
open={true}
|
||||
content={t(`toasts.description.${updateType}`)}
|
||||
open={open}
|
||||
type="background"
|
||||
onOpenChange={handleOpenChanged}
|
||||
>
|
||||
<Button buttonSize="small" contained={true} text={t('toasts.button')} />
|
||||
<Button
|
||||
buttonSize="small"
|
||||
contained={true}
|
||||
onClick={handleButtonClicked}
|
||||
text={t('toasts.button')}
|
||||
/>
|
||||
</Toast>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue