2023-02-16 14:30:37 +03:00
|
|
|
import React, { Fragment, useState, useEffect, useCallback, useRef } from "react";
|
2021-01-07 16:24:59 +03:00
|
|
|
import { withRouter } from "react-router-dom";
|
2020-03-04 18:24:18 +03:00
|
|
|
import Flatpickr from "react-flatpickr";
|
2022-10-04 13:20:51 +03:00
|
|
|
import { ChevronDownIcon } from '@heroicons/react/20/solid'
|
2021-07-22 11:27:10 +03:00
|
|
|
import { Transition } from '@headlessui/react'
|
2021-01-07 16:24:59 +03:00
|
|
|
import {
|
|
|
|
shiftDays,
|
|
|
|
shiftMonths,
|
|
|
|
formatDay,
|
|
|
|
formatMonthYYYY,
|
2022-03-31 13:52:26 +03:00
|
|
|
formatYear,
|
2021-01-07 16:24:59 +03:00
|
|
|
formatISO,
|
|
|
|
isToday,
|
|
|
|
lastMonth,
|
|
|
|
nowForSite,
|
|
|
|
isSameMonth,
|
|
|
|
isThisMonth,
|
2022-03-31 13:52:26 +03:00
|
|
|
isThisYear,
|
2021-01-07 16:24:59 +03:00
|
|
|
parseUTCDate,
|
2023-04-25 14:26:24 +03:00
|
|
|
parseNaiveDate,
|
2021-01-07 16:24:59 +03:00
|
|
|
isBefore,
|
2023-04-11 15:59:10 +03:00
|
|
|
isAfter,
|
|
|
|
formatDateRange
|
2021-12-03 14:59:32 +03:00
|
|
|
} from "./util/date";
|
2021-01-07 16:24:59 +03:00
|
|
|
import { navigateToQuery, QueryLink, QueryButton } from "./query";
|
2022-11-25 11:51:43 +03:00
|
|
|
import { shouldIgnoreKeypress } from "./keybinding.js"
|
2023-03-15 13:30:05 +03:00
|
|
|
import { COMPARISON_DISABLED_PERIODS, toggleComparisons, isComparisonEnabled } from "../dashboard/comparison-input.js"
|
2023-04-25 12:28:32 +03:00
|
|
|
import classNames from "classnames"
|
2019-11-19 07:30:42 +03:00
|
|
|
|
2021-07-22 11:27:10 +03:00
|
|
|
function renderArrow(query, site, period, prevDate, nextDate) {
|
2022-03-22 17:09:45 +03:00
|
|
|
const insertionDate = parseUTCDate(site.statsBegin);
|
2021-07-22 11:27:10 +03:00
|
|
|
const disabledLeft = isBefore(
|
|
|
|
parseUTCDate(prevDate),
|
|
|
|
insertionDate,
|
|
|
|
period
|
|
|
|
);
|
|
|
|
const disabledRight = isAfter(
|
|
|
|
parseUTCDate(nextDate),
|
|
|
|
nowForSite(site),
|
|
|
|
period
|
|
|
|
);
|
|
|
|
|
2023-04-25 12:28:32 +03:00
|
|
|
const isComparing = isComparisonEnabled(query.comparison)
|
|
|
|
|
|
|
|
const leftClass = classNames("flex items-center px-1 sm:px-2 border-r border-gray-300 rounded-l dark:border-gray-500 dark:text-gray-100", {
|
|
|
|
"bg-gray-300 dark:bg-gray-950": disabledLeft,
|
|
|
|
"hover:bg-gray-100 dark:hover:bg-gray-900": !disabledLeft,
|
|
|
|
})
|
|
|
|
|
|
|
|
const rightClass = classNames("flex items-center px-1 sm:px-2 rounded-r dark:text-gray-100", {
|
|
|
|
"bg-gray-300 dark:bg-gray-950": disabledRight,
|
|
|
|
"hover:bg-gray-100 dark:hover:bg-gray-900": !disabledRight,
|
|
|
|
})
|
|
|
|
|
|
|
|
const containerClass = classNames("rounded shadow bg-white mr-2 sm:mr-4 cursor-pointer dark:bg-gray-800", {
|
|
|
|
"hidden md:flex": isComparing,
|
|
|
|
"flex": !isComparing,
|
|
|
|
})
|
|
|
|
|
2021-07-22 11:27:10 +03:00
|
|
|
return (
|
2023-04-25 12:28:32 +03:00
|
|
|
<div className={containerClass}>
|
2021-07-22 11:27:10 +03:00
|
|
|
<QueryButton
|
|
|
|
to={{ date: prevDate }}
|
|
|
|
query={query}
|
2023-04-25 12:28:32 +03:00
|
|
|
className={leftClass}
|
2021-07-22 11:27:10 +03:00
|
|
|
disabled={disabledLeft}
|
|
|
|
>
|
|
|
|
<svg
|
|
|
|
className="feather h-4 w-4"
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
fill="none"
|
|
|
|
stroke="currentColor"
|
|
|
|
strokeWidth="2"
|
|
|
|
strokeLinecap="round"
|
|
|
|
strokeLinejoin="round"
|
|
|
|
>
|
|
|
|
<polyline points="15 18 9 12 15 6"></polyline>
|
|
|
|
</svg>
|
|
|
|
</QueryButton>
|
|
|
|
<QueryButton
|
|
|
|
to={{ date: nextDate }}
|
|
|
|
query={query}
|
2023-04-25 12:28:32 +03:00
|
|
|
className={rightClass}
|
2021-07-22 11:27:10 +03:00
|
|
|
disabled={disabledRight}
|
|
|
|
>
|
|
|
|
<svg
|
|
|
|
className="feather h-4 w-4"
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
fill="none"
|
|
|
|
stroke="currentColor"
|
|
|
|
strokeWidth="2"
|
|
|
|
strokeLinecap="round"
|
|
|
|
strokeLinejoin="round"
|
|
|
|
>
|
|
|
|
<polyline points="9 18 15 12 9 6"></polyline>
|
|
|
|
</svg>
|
|
|
|
</QueryButton>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function DatePickerArrows({site, query}) {
|
2022-03-31 13:52:26 +03:00
|
|
|
if (query.period === "year") {
|
|
|
|
const prevDate = formatISO(shiftMonths(query.date, -12));
|
|
|
|
const nextDate = formatISO(shiftMonths(query.date, 12));
|
|
|
|
|
|
|
|
return renderArrow(query, site, "year", prevDate, nextDate);
|
|
|
|
} else if (query.period === "month") {
|
2021-07-22 11:27:10 +03:00
|
|
|
const prevDate = formatISO(shiftMonths(query.date, -1));
|
|
|
|
const nextDate = formatISO(shiftMonths(query.date, 1));
|
|
|
|
|
|
|
|
return renderArrow(query, site, "month", prevDate, nextDate);
|
2022-03-31 13:52:26 +03:00
|
|
|
} else if (query.period === "day") {
|
2021-07-22 11:27:10 +03:00
|
|
|
const prevDate = formatISO(shiftDays(query.date, -1));
|
|
|
|
const nextDate = formatISO(shiftDays(query.date, 1));
|
|
|
|
|
|
|
|
return renderArrow(query, site, "day", prevDate, nextDate);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
function DisplayPeriod({query, site}) {
|
|
|
|
if (query.period === "day") {
|
|
|
|
if (isToday(site, query.date)) {
|
|
|
|
return "Today";
|
|
|
|
}
|
|
|
|
return formatDay(query.date);
|
|
|
|
} if (query.period === '7d') {
|
|
|
|
return 'Last 7 days'
|
|
|
|
} if (query.period === '30d') {
|
|
|
|
return 'Last 30 days'
|
|
|
|
} if (query.period === 'month') {
|
|
|
|
if (isThisMonth(site, query.date)) {
|
|
|
|
return 'Month to Date'
|
|
|
|
}
|
|
|
|
return formatMonthYYYY(query.date)
|
|
|
|
} if (query.period === '6mo') {
|
|
|
|
return 'Last 6 months'
|
|
|
|
} if (query.period === '12mo') {
|
|
|
|
return 'Last 12 months'
|
|
|
|
} if (query.period === 'year') {
|
|
|
|
if (isThisYear(site, query.date)) {
|
|
|
|
return 'Year to Date'
|
|
|
|
}
|
|
|
|
return formatYear(query.date)
|
|
|
|
} if (query.period === 'all') {
|
|
|
|
return 'All time'
|
|
|
|
} if (query.period === 'custom') {
|
2023-04-11 15:59:10 +03:00
|
|
|
return formatDateRange(site, query.from, query.to)
|
2019-11-19 07:30:42 +03:00
|
|
|
}
|
2023-02-16 14:30:37 +03:00
|
|
|
return 'Realtime'
|
|
|
|
}
|
2019-11-19 07:30:42 +03:00
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
function DatePicker({query, site, history}) {
|
|
|
|
const [open, setOpen] = useState(false)
|
|
|
|
const [mode, setMode] = useState('menu')
|
|
|
|
const dropDownNode = useRef(null)
|
|
|
|
const calendar = useRef(null)
|
2019-11-19 07:30:42 +03:00
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
const handleKeydown = useCallback((e) => {
|
2022-11-25 11:51:43 +03:00
|
|
|
if (shouldIgnoreKeypress(e)) return true
|
2020-10-19 10:56:03 +03:00
|
|
|
|
2020-11-11 13:30:29 +03:00
|
|
|
const newSearch = {
|
|
|
|
period: false,
|
|
|
|
from: false,
|
|
|
|
to: false,
|
2022-11-15 17:38:39 +03:00
|
|
|
date: false
|
2021-01-07 16:24:59 +03:00
|
|
|
};
|
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
const insertionDate = parseUTCDate(site.statsBegin);
|
2020-11-11 13:30:29 +03:00
|
|
|
|
2021-01-07 16:24:59 +03:00
|
|
|
if (e.key === "ArrowLeft") {
|
|
|
|
const prevDate = formatISO(shiftDays(query.date, -1));
|
|
|
|
const prevMonth = formatISO(shiftMonths(query.date, -1));
|
2022-03-31 13:52:26 +03:00
|
|
|
const prevYear = formatISO(shiftMonths(query.date, -12));
|
2021-01-07 16:24:59 +03:00
|
|
|
|
2022-03-31 13:52:26 +03:00
|
|
|
if (query.period === "day" && !isBefore(parseUTCDate(prevDate), insertionDate, query.period)) {
|
2021-01-07 16:24:59 +03:00
|
|
|
newSearch.period = "day";
|
|
|
|
newSearch.date = prevDate;
|
2022-03-31 13:52:26 +03:00
|
|
|
} else if (query.period === "month" && !isBefore(parseUTCDate(prevMonth), insertionDate, query.period)) {
|
2021-01-07 16:24:59 +03:00
|
|
|
newSearch.period = "month";
|
|
|
|
newSearch.date = prevMonth;
|
2022-03-31 13:52:26 +03:00
|
|
|
} else if (query.period === "year" && !isBefore(parseUTCDate(prevYear), insertionDate, query.period)) {
|
|
|
|
newSearch.period = "year";
|
|
|
|
newSearch.date = prevYear;
|
2019-11-19 07:30:42 +03:00
|
|
|
}
|
2021-01-07 16:24:59 +03:00
|
|
|
} else if (e.key === "ArrowRight") {
|
2023-02-16 14:30:37 +03:00
|
|
|
const now = nowForSite(site)
|
2021-01-07 16:24:59 +03:00
|
|
|
const nextDate = formatISO(shiftDays(query.date, 1));
|
|
|
|
const nextMonth = formatISO(shiftMonths(query.date, 1));
|
2022-03-31 13:52:26 +03:00
|
|
|
const nextYear = formatISO(shiftMonths(query.date, 12));
|
2021-01-07 16:24:59 +03:00
|
|
|
|
2022-03-31 13:52:26 +03:00
|
|
|
if (query.period === "day" && !isAfter(parseUTCDate(nextDate), now, query.period)) {
|
2021-01-07 16:24:59 +03:00
|
|
|
newSearch.period = "day";
|
|
|
|
newSearch.date = nextDate;
|
2022-03-31 13:52:26 +03:00
|
|
|
} else if (query.period === "month" && !isAfter(parseUTCDate(nextMonth), now, query.period)) {
|
2021-01-07 16:24:59 +03:00
|
|
|
newSearch.period = "month";
|
|
|
|
newSearch.date = nextMonth;
|
2022-03-31 13:52:26 +03:00
|
|
|
} else if (query.period === "year" && !isAfter(parseUTCDate(nextYear), now, query.period)) {
|
|
|
|
newSearch.period = "year";
|
|
|
|
newSearch.date = nextYear;
|
2019-11-19 07:30:42 +03:00
|
|
|
}
|
|
|
|
}
|
2020-11-11 13:30:29 +03:00
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
setOpen(false);
|
2021-01-22 14:29:16 +03:00
|
|
|
|
2023-03-15 13:30:05 +03:00
|
|
|
const keybindings = {
|
|
|
|
d: {date: false, period: 'day'},
|
|
|
|
e: {date: formatISO(shiftDays(nowForSite(site), -1)), period: 'day'},
|
|
|
|
r: {period: 'realtime'},
|
|
|
|
w: {date: false, period: '7d'},
|
|
|
|
m: {date: false, period: 'month'},
|
|
|
|
y: {date: false, period: 'year'},
|
|
|
|
t: {date: false, period: '30d'},
|
|
|
|
s: {date: false, period: '6mo'},
|
|
|
|
l: {date: false, period: '12mo'},
|
|
|
|
a: {date: false, period: 'all'},
|
|
|
|
}
|
2021-01-22 14:29:16 +03:00
|
|
|
|
2023-03-15 13:30:05 +03:00
|
|
|
const redirect = keybindings[e.key.toLowerCase()]
|
|
|
|
if (redirect) {
|
|
|
|
navigateToQuery(history, query, {...newSearch, ...redirect})
|
|
|
|
} else if (e.key.toLowerCase() === 'x') {
|
|
|
|
toggleComparisons(history, query, site)
|
2021-01-22 14:29:16 +03:00
|
|
|
} else if (e.key.toLowerCase() === 'c') {
|
2023-02-16 14:30:37 +03:00
|
|
|
setOpen(true)
|
|
|
|
setMode('calendar')
|
2021-01-22 14:29:16 +03:00
|
|
|
} else if (newSearch.date) {
|
2021-01-07 16:24:59 +03:00
|
|
|
navigateToQuery(history, query, newSearch);
|
2020-11-11 13:30:29 +03:00
|
|
|
}
|
2023-02-16 14:30:37 +03:00
|
|
|
}, [query])
|
2019-11-19 07:30:42 +03:00
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
const handleClick = useCallback((e) => {
|
|
|
|
if (dropDownNode.current && dropDownNode.current.contains(e.target)) return;
|
2020-03-04 18:24:18 +03:00
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
setOpen(false)
|
|
|
|
})
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (mode === 'calendar' && open) {
|
|
|
|
openCalendar()
|
|
|
|
}
|
|
|
|
}, [mode])
|
2020-03-04 18:24:18 +03:00
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
useEffect(() => {
|
|
|
|
document.addEventListener("keydown", handleKeydown);
|
|
|
|
return () => { document.removeEventListener("keydown", handleKeydown); }
|
|
|
|
}, [handleKeydown])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
document.addEventListener("mousedown", handleClick, false);
|
|
|
|
return () => { document.removeEventListener("mousedown", handleClick, false); }
|
|
|
|
}, [])
|
|
|
|
|
2023-04-25 14:26:24 +03:00
|
|
|
function setCustomDate([from, to], _dateStr, _instance) {
|
|
|
|
if (from && to) {
|
|
|
|
[from, to] = [parseNaiveDate(from), parseNaiveDate(to)]
|
|
|
|
|
|
|
|
if (from.isSame(to)) {
|
|
|
|
navigateToQuery( history, query, { period: 'day', date: formatISO(from), from: false, to: false })
|
2021-07-22 11:27:10 +03:00
|
|
|
} else {
|
2023-04-25 14:26:24 +03:00
|
|
|
navigateToQuery( history, query, { period: 'custom', date: false, from: formatISO(from), to: formatISO(to) })
|
2021-07-22 11:27:10 +03:00
|
|
|
}
|
2019-11-19 07:30:42 +03:00
|
|
|
}
|
2023-04-25 14:26:24 +03:00
|
|
|
|
|
|
|
setOpen(false)
|
2019-11-19 07:30:42 +03:00
|
|
|
}
|
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
function toggle() {
|
|
|
|
const newMode = mode === 'calendar' && !open ? 'menu' : mode
|
|
|
|
setOpen(!open)
|
|
|
|
setMode(newMode)
|
2020-03-04 18:24:18 +03:00
|
|
|
}
|
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
function openCalendar() {
|
|
|
|
calendar.current && calendar.current.flatpickr.open();
|
2021-07-22 11:27:10 +03:00
|
|
|
}
|
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
function renderLink(period, text, opts = {}) {
|
2020-03-04 18:24:18 +03:00
|
|
|
let boldClass;
|
2021-01-07 16:24:59 +03:00
|
|
|
if (query.period === "day" && period === "day") {
|
|
|
|
boldClass = isToday(site, query.date) ? "font-bold" : "";
|
|
|
|
} else if (query.period === "month" && period === "month") {
|
|
|
|
const linkDate = opts.date || nowForSite(site);
|
|
|
|
boldClass = isSameMonth(linkDate, query.date) ? "font-bold" : "";
|
2020-03-04 18:24:18 +03:00
|
|
|
} else {
|
2021-01-07 16:24:59 +03:00
|
|
|
boldClass = query.period === period ? "font-bold" : "";
|
2020-03-04 18:24:18 +03:00
|
|
|
}
|
|
|
|
|
2021-03-31 15:13:58 +03:00
|
|
|
opts.date = opts.date ? formatISO(opts.date) : false;
|
2020-09-09 11:13:55 +03:00
|
|
|
|
2021-01-22 14:29:16 +03:00
|
|
|
const keybinds = {
|
|
|
|
'Today': 'D',
|
|
|
|
'Realtime': 'R',
|
|
|
|
'Last 7 days': 'W',
|
|
|
|
'Month to Date': 'M',
|
2022-03-31 13:52:26 +03:00
|
|
|
'Year to Date': 'Y',
|
2022-04-04 11:48:54 +03:00
|
|
|
'Last 12 months': 'L',
|
2021-02-23 16:49:56 +03:00
|
|
|
'Last 30 days': 'T',
|
2022-03-31 13:52:26 +03:00
|
|
|
'All time': 'A',
|
2021-01-22 14:29:16 +03:00
|
|
|
};
|
|
|
|
|
2020-03-04 18:24:18 +03:00
|
|
|
return (
|
2021-01-07 16:24:59 +03:00
|
|
|
<QueryLink
|
2021-03-31 15:13:58 +03:00
|
|
|
to={{from: false, to: false, period, ...opts}}
|
2023-02-16 14:30:37 +03:00
|
|
|
onClick={() => setOpen(false)}
|
|
|
|
query={query}
|
2021-07-21 16:50:26 +03:00
|
|
|
className={`${boldClass } px-4 py-2 text-sm leading-tight hover:bg-gray-100 hover:text-gray-900
|
2021-10-12 12:50:24 +03:00
|
|
|
dark:hover:bg-gray-900 dark:hover:text-gray-100 flex items-center justify-between`}
|
2021-01-07 16:24:59 +03:00
|
|
|
>
|
2020-03-04 18:24:18 +03:00
|
|
|
{text}
|
2021-01-22 14:29:16 +03:00
|
|
|
<span className='font-normal'>{keybinds[text]}</span>
|
2020-11-13 03:26:53 +03:00
|
|
|
</QueryLink>
|
2021-01-07 16:24:59 +03:00
|
|
|
);
|
2020-03-04 18:24:18 +03:00
|
|
|
}
|
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
function renderDropDownContent() {
|
|
|
|
if (mode === "menu") {
|
2020-03-04 18:24:18 +03:00
|
|
|
return (
|
2021-01-07 16:24:59 +03:00
|
|
|
<div
|
|
|
|
id="datemenu"
|
2021-07-21 16:50:26 +03:00
|
|
|
className="absolute w-full left-0 right-0 md:w-56 md:absolute md:top-auto md:left-auto md:right-0 mt-2 origin-top-right z-10"
|
2021-01-07 16:24:59 +03:00
|
|
|
>
|
|
|
|
<div
|
2021-07-21 16:50:26 +03:00
|
|
|
className="rounded-md shadow-lg bg-white dark:bg-gray-800 ring-1 ring-black ring-opacity-5
|
2021-12-08 12:53:37 +03:00
|
|
|
font-medium text-gray-800 dark:text-gray-200 date-options"
|
2021-01-07 16:24:59 +03:00
|
|
|
>
|
2021-12-08 12:53:37 +03:00
|
|
|
<div className="py-1 border-b border-gray-200 dark:border-gray-500 date-option-group">
|
2023-02-16 14:30:37 +03:00
|
|
|
{renderLink("day", "Today")}
|
|
|
|
{renderLink("realtime", "Realtime")}
|
2020-03-04 18:24:18 +03:00
|
|
|
</div>
|
2021-12-08 12:53:37 +03:00
|
|
|
<div className="py-1 border-b border-gray-200 dark:border-gray-500 date-option-group">
|
2023-02-16 14:30:37 +03:00
|
|
|
{renderLink("7d", "Last 7 days")}
|
|
|
|
{renderLink("30d", "Last 30 days")}
|
2020-09-09 11:13:55 +03:00
|
|
|
</div>
|
2021-12-08 12:53:37 +03:00
|
|
|
<div className="py-1 border-b border-gray-200 dark:border-gray-500 date-option-group">
|
2023-02-16 14:30:37 +03:00
|
|
|
{ renderLink('month', 'Month to Date') }
|
|
|
|
{ renderLink('month', 'Last month', {date: lastMonth(site)}) }
|
2020-03-04 18:24:18 +03:00
|
|
|
</div>
|
2021-12-08 12:53:37 +03:00
|
|
|
<div className="py-1 border-b border-gray-200 dark:border-gray-500 date-option-group">
|
2023-02-16 14:30:37 +03:00
|
|
|
{renderLink("year", "Year to Date")}
|
|
|
|
{renderLink("12mo", "Last 12 months")}
|
2020-03-04 18:24:18 +03:00
|
|
|
</div>
|
2021-12-08 12:53:37 +03:00
|
|
|
<div className="py-1 date-option-group">
|
2023-02-16 14:30:37 +03:00
|
|
|
{renderLink("all", "All time")}
|
2021-01-07 16:24:59 +03:00
|
|
|
<span
|
2023-02-16 14:30:37 +03:00
|
|
|
onClick={() => setMode('calendar')}
|
|
|
|
onKeyPress={() => setMode('calendar')}
|
2021-07-21 16:50:26 +03:00
|
|
|
className="px-4 py-2 text-sm leading-tight hover:bg-gray-100
|
2021-01-07 16:24:59 +03:00
|
|
|
dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-gray-100
|
2021-01-22 14:29:16 +03:00
|
|
|
cursor-pointer flex items-center justify-between"
|
2021-01-07 16:24:59 +03:00
|
|
|
tabIndex="0"
|
|
|
|
role="button"
|
|
|
|
aria-haspopup="true"
|
|
|
|
aria-expanded="false"
|
|
|
|
aria-controls="calendar"
|
|
|
|
>
|
|
|
|
Custom range
|
2021-01-22 14:29:16 +03:00
|
|
|
<span className='font-normal'>C</span>
|
2021-01-07 16:24:59 +03:00
|
|
|
</span>
|
2020-03-04 18:24:18 +03:00
|
|
|
</div>
|
2023-03-15 13:30:05 +03:00
|
|
|
{ !COMPARISON_DISABLED_PERIODS.includes(query.period) && site.flags.comparisons &&
|
|
|
|
<div className="py-1 date-option-group border-t border-gray-200 dark:border-gray-500">
|
|
|
|
<span
|
|
|
|
onClick={() => {
|
|
|
|
toggleComparisons(history, query, site)
|
|
|
|
setOpen(false)
|
|
|
|
}}
|
|
|
|
className="px-4 py-2 text-sm leading-tight hover:bg-gray-100 dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-gray-100 cursor-pointer flex items-center justify-between">
|
|
|
|
{ isComparisonEnabled(query.comparison) ? 'Disable comparison' : 'Compare' }
|
|
|
|
<span className='font-normal'>X</span>
|
|
|
|
</span>
|
|
|
|
</div> }
|
2020-03-04 18:24:18 +03:00
|
|
|
</div>
|
|
|
|
</div>
|
2021-01-07 16:24:59 +03:00
|
|
|
);
|
2023-02-16 14:30:37 +03:00
|
|
|
} if (mode === "calendar") {
|
2021-01-07 16:24:59 +03:00
|
|
|
return (
|
2021-07-21 16:50:26 +03:00
|
|
|
<div className="h-0">
|
|
|
|
<Flatpickr
|
|
|
|
id="calendar"
|
|
|
|
options={{
|
|
|
|
mode: 'range',
|
|
|
|
maxDate: 'today',
|
2023-04-25 14:26:24 +03:00
|
|
|
minDate: site.statsBegin,
|
2021-07-21 16:50:26 +03:00
|
|
|
showMonths: 1,
|
|
|
|
static: true,
|
|
|
|
animate: true}}
|
2023-02-16 14:30:37 +03:00
|
|
|
ref={calendar}
|
2021-07-21 16:50:26 +03:00
|
|
|
className="invisible"
|
2023-04-25 14:26:24 +03:00
|
|
|
onClose={setCustomDate}
|
2021-07-21 16:50:26 +03:00
|
|
|
/>
|
|
|
|
</div>
|
2022-11-15 17:38:39 +03:00
|
|
|
)
|
2020-03-04 18:24:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
function renderPicker() {
|
2019-11-19 07:30:42 +03:00
|
|
|
return (
|
2021-07-21 16:50:26 +03:00
|
|
|
<div
|
2023-03-15 13:30:05 +03:00
|
|
|
className="min-w-32 md:w-48 md:relative"
|
2023-02-16 14:30:37 +03:00
|
|
|
ref={dropDownNode}
|
2021-07-21 16:50:26 +03:00
|
|
|
>
|
|
|
|
<div
|
2023-02-16 14:30:37 +03:00
|
|
|
onClick={toggle}
|
2021-07-21 16:50:26 +03:00
|
|
|
className="flex items-center justify-between rounded bg-white dark:bg-gray-800 shadow px-2 md:px-3
|
|
|
|
py-2 leading-tight cursor-pointer text-xs md:text-sm text-gray-800
|
|
|
|
dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-900"
|
|
|
|
tabIndex="0"
|
|
|
|
role="button"
|
|
|
|
aria-haspopup="true"
|
|
|
|
aria-expanded="false"
|
|
|
|
aria-controls="datemenu"
|
|
|
|
>
|
2021-08-23 12:39:43 +03:00
|
|
|
<span className="truncate mr-1 md:mr-2">
|
2023-02-16 14:30:37 +03:00
|
|
|
<span className="font-medium"><DisplayPeriod query={query} site={site} /></span>
|
2021-07-21 16:50:26 +03:00
|
|
|
</span>
|
|
|
|
<ChevronDownIcon className="hidden sm:inline-block h-4 w-4 md:h-5 md:w-5 text-gray-500" />
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<Transition
|
2023-02-16 14:30:37 +03:00
|
|
|
show={open}
|
2021-07-21 16:50:26 +03:00
|
|
|
as={Fragment}
|
2021-07-22 11:27:10 +03:00
|
|
|
enter="transition ease-out duration-100"
|
|
|
|
enterFrom="transform opacity-0 scale-95"
|
|
|
|
enterTo="transform opacity-100 scale-100"
|
|
|
|
leave="transition ease-in duration-75"
|
|
|
|
leaveFrom="transform opacity-100 scale-100"
|
|
|
|
leaveTo="transform opacity-0 scale-95"
|
2021-07-21 16:50:26 +03:00
|
|
|
>
|
2023-02-16 14:30:37 +03:00
|
|
|
{renderDropDownContent()}
|
2021-07-21 16:50:26 +03:00
|
|
|
</Transition>
|
2019-11-19 07:30:42 +03:00
|
|
|
</div>
|
2021-01-07 16:24:59 +03:00
|
|
|
);
|
2019-11-19 07:30:42 +03:00
|
|
|
}
|
2021-07-22 11:27:10 +03:00
|
|
|
|
2023-02-16 14:30:37 +03:00
|
|
|
return (
|
|
|
|
<div className="flex ml-auto pl-2">
|
|
|
|
<DatePickerArrows site={site} query={query} />
|
|
|
|
{renderPicker()}
|
|
|
|
</div>
|
|
|
|
)
|
2019-11-19 07:30:42 +03:00
|
|
|
}
|
|
|
|
|
2021-01-07 16:24:59 +03:00
|
|
|
export default withRouter(DatePicker);
|