analytics/assets/js/dashboard/nav-menu/query-periods/move-period-arrows.tsx

142 lines
3.9 KiB
TypeScript

import React, { useMemo } from 'react'
import { shiftQueryPeriod, getDateForShiftedPeriod } from '../../query'
import classNames from 'classnames'
import { useQueryContext } from '../../query-context'
import { useSiteContext } from '../../site-context'
import { NavigateKeybind } from '../../keybinding'
import { AppNavigationLink } from '../../navigation/use-app-navigate'
import { QueryPeriod } from '../../query-time-periods'
import { useMatch } from 'react-router-dom'
import { rootRoute } from '../../router'
const ArrowKeybind = ({
keyboardKey
}: {
keyboardKey: 'ArrowLeft' | 'ArrowRight'
}) => {
const site = useSiteContext()
const { query } = useQueryContext()
const search = useMemo(
() =>
shiftQueryPeriod({
query,
site,
direction: ({ ArrowLeft: -1, ArrowRight: 1 } as const)[keyboardKey],
keybindHint: keyboardKey
}),
[site, query, keyboardKey]
)
return (
<NavigateKeybind
type="keydown"
keyboardKey={keyboardKey}
navigateProps={{ search }}
/>
)
}
function ArrowIcon({
direction,
disabled = false
}: {
direction: 'left' | 'right'
disabled?: boolean
}) {
return (
<svg
className={classNames(
'feather size-4',
disabled
? 'text-gray-400 dark:text-gray-600'
: 'text-gray-700 dark:text-gray-300'
)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
{direction === 'left' && <polyline points="15 18 9 12 15 6"></polyline>}
{direction === 'right' && <polyline points="9 18 15 12 9 6"></polyline>}
</svg>
)
}
export function MovePeriodArrows({ className }: { className?: string }) {
const periodsWithArrows = [
QueryPeriod.year,
QueryPeriod.month,
QueryPeriod.day
]
const { query } = useQueryContext()
const site = useSiteContext()
const dashboardRouteMatch = useMatch(rootRoute.path)
if (!periodsWithArrows.includes(query.period)) {
return null
}
const canGoBack =
getDateForShiftedPeriod({ site, query, direction: -1 }) !== null
const canGoForward =
getDateForShiftedPeriod({ site, query, direction: 1 }) !== null
const sharedClass =
'flex items-center px-1 sm:px-2 dark:text-gray-100 transition-colors duration-150'
const enabledClass = 'hover:bg-gray-100 dark:hover:bg-gray-700'
const disabledClass = 'bg-gray-200 dark:bg-gray-850 cursor-not-allowed'
return (
<div
className={classNames(
'flex rounded shadow bg-white mr-2 sm:mr-4 cursor-pointer focus:z-10 dark:bg-gray-750',
className
)}
>
<AppNavigationLink
className={classNames(
sharedClass,
'rounded-l border-gray-300 dark:border-gray-500 focus:z-10',
{ [enabledClass]: canGoBack, [disabledClass]: !canGoBack }
)}
search={
canGoBack
? shiftQueryPeriod({
site,
query,
direction: -1,
keybindHint: null
})
: (search) => search
}
>
<ArrowIcon direction="left" disabled={!canGoBack} />
</AppNavigationLink>
<AppNavigationLink
className={classNames(sharedClass, 'rounded-r', {
[enabledClass]: canGoForward,
[disabledClass]: !canGoForward
})}
search={
canGoForward
? shiftQueryPeriod({
site,
query,
direction: 1,
keybindHint: null
})
: (search) => search
}
>
<ArrowIcon direction="right" disabled={!canGoForward} />
</AppNavigationLink>
{!!dashboardRouteMatch && <ArrowKeybind keyboardKey="ArrowLeft" />}
{!!dashboardRouteMatch && <ArrowKeybind keyboardKey="ArrowRight" />}
</div>
)
}