diff --git a/components/common/DateFilter.js b/components/common/DateFilter.js index ba3417d1..e001605c 100644 --- a/components/common/DateFilter.js +++ b/components/common/DateFilter.js @@ -1,14 +1,14 @@ -import React, { useState } from 'react'; -import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; -import { endOfYear, isSameDay } from 'date-fns'; -import Modal from './Modal'; -import DropDown from './DropDown'; -import DatePickerForm from 'components/forms/DatePickerForm'; -import useLocale from 'hooks/useLocale'; -import { getDateRange, dateFormat } from 'lib/date'; import Calendar from 'assets/calendar-alt.svg'; +import DatePickerForm from 'components/forms/DatePickerForm'; +import { endOfYear, isSameDay } from 'date-fns'; +import useLocale from 'hooks/useLocale'; +import { dateFormat, getDateRange } from 'lib/date'; +import PropTypes from 'prop-types'; +import { useState } from 'react'; +import { FormattedMessage } from 'react-intl'; +import DropDown from './DropDown'; import Icon from './Icon'; +import Modal from './Modal'; const filterOptions = [ { label: , value: '1day' }, @@ -52,9 +52,14 @@ const filterOptions = [ value: 'custom', divider: true, }, + { + label: , + value: '0all', + divider: true, + }, ]; -function DateFilter({ value, startDate, endDate, onChange, className }) { +function DateFilter({ value, startDate, endDate, onChange, className, createdAt }) { const { locale } = useLocale(); const [showPicker, setShowPicker] = useState(false); const displayValue = @@ -69,7 +74,7 @@ function DateFilter({ value, startDate, endDate, onChange, className }) { setShowPicker(true); return; } - onChange(getDateRange(value, locale)); + onChange(getDateRange(value, locale, createdAt)); } function handlePickerChange(value) { diff --git a/components/metrics/MetricsBar.js b/components/metrics/MetricsBar.js index 435870a1..06ed7646 100644 --- a/components/metrics/MetricsBar.js +++ b/components/metrics/MetricsBar.js @@ -1,20 +1,20 @@ -import React, { useState } from 'react'; -import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import Loading from 'components/common/Loading'; import ErrorMessage from 'components/common/ErrorMessage'; -import useFetch from 'hooks/useFetch'; +import Loading from 'components/common/Loading'; import useDateRange from 'hooks/useDateRange'; +import useFetch from 'hooks/useFetch'; import usePageQuery from 'hooks/usePageQuery'; import useShareToken from 'hooks/useShareToken'; -import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format'; -import { TOKEN_HEADER } from 'lib/constants'; +import { DEFAULT_DATE_RANGE, TOKEN_HEADER } from 'lib/constants'; +import { formatLongNumber, formatNumber, formatShortTime } from 'lib/format'; +import { useState } from 'react'; +import { FormattedMessage } from 'react-intl'; import MetricCard from './MetricCard'; import styles from './MetricsBar.module.css'; -export default function MetricsBar({ websiteId, className }) { +export default function MetricsBar({ websiteId, className, createdAt }) { const shareToken = useShareToken(); - const [dateRange] = useDateRange(websiteId); + const [dateRange] = useDateRange(websiteId, DEFAULT_DATE_RANGE, createdAt); const { startDate, endDate, modified } = dateRange; const [format, setFormat] = useState(true); const { diff --git a/components/metrics/WebsiteChart.js b/components/metrics/WebsiteChart.js index fca6d541..95740ac9 100644 --- a/components/metrics/WebsiteChart.js +++ b/components/metrics/WebsiteChart.js @@ -1,21 +1,22 @@ -import React, { useMemo } from 'react'; +import Times from 'assets/times.svg'; import classNames from 'classnames'; -import PageviewsChart from './PageviewsChart'; -import MetricsBar from './MetricsBar'; -import WebsiteHeader from './WebsiteHeader'; +import Button from 'components/common/Button'; import DateFilter from 'components/common/DateFilter'; import StickyHeader from 'components/helpers/StickyHeader'; -import Button from 'components/common/Button'; -import useFetch from 'hooks/useFetch'; import useDateRange from 'hooks/useDateRange'; -import useTimezone from 'hooks/useTimezone'; +import useFetch from 'hooks/useFetch'; import usePageQuery from 'hooks/usePageQuery'; +import useTimezone from 'hooks/useTimezone'; +import { DEFAULT_DATE_RANGE } from 'lib/constants'; import { getDateArray, getDateLength } from 'lib/date'; -import Times from 'assets/times.svg'; -import styles from './WebsiteChart.module.css'; -import ErrorMessage from '../common/ErrorMessage'; +import { useMemo } from 'react'; import useShareToken from '../../hooks/useShareToken'; import { TOKEN_HEADER } from '../../lib/constants'; +import ErrorMessage from '../common/ErrorMessage'; +import MetricsBar from './MetricsBar'; +import PageviewsChart from './PageviewsChart'; +import styles from './WebsiteChart.module.css'; +import WebsiteHeader from './WebsiteHeader'; export default function WebsiteChart({ websiteId, @@ -24,10 +25,11 @@ export default function WebsiteChart({ stickyHeader = false, showLink = false, hideChart = false, + createdAt, onDataLoad = () => {}, }) { const shareToken = useShareToken(); - const [dateRange, setDateRange] = useDateRange(websiteId); + const [dateRange, setDateRange] = useDateRange(websiteId, DEFAULT_DATE_RANGE, createdAt); const { startDate, endDate, unit, value, modified } = dateRange; const [timezone] = useTimezone(); const { @@ -77,7 +79,7 @@ export default function WebsiteChart({ > {url && }
- +
diff --git a/components/pages/WebsiteDetails.js b/components/pages/WebsiteDetails.js index 0ddc89e2..a1a4486b 100644 --- a/components/pages/WebsiteDetails.js +++ b/components/pages/WebsiteDetails.js @@ -1,27 +1,27 @@ -import React, { useState } from 'react'; -import { FormattedMessage } from 'react-intl'; +import Arrow from 'assets/arrow-right.svg'; import classNames from 'classnames'; -import WebsiteChart from 'components/metrics/WebsiteChart'; -import WorldMap from 'components/common/WorldMap'; -import Page from 'components/layout/Page'; -import GridLayout, { GridRow, GridColumn } from 'components/layout/GridLayout'; -import MenuLayout from 'components/layout/MenuLayout'; import Link from 'components/common/Link'; import Loading from 'components/common/Loading'; -import Arrow from 'assets/arrow-right.svg'; -import styles from './WebsiteDetails.module.css'; -import PagesTable from '../metrics/PagesTable'; -import ReferrersTable from '../metrics/ReferrersTable'; -import BrowsersTable from '../metrics/BrowsersTable'; -import OSTable from '../metrics/OSTable'; -import DevicesTable from '../metrics/DevicesTable'; -import CountriesTable from '../metrics/CountriesTable'; -import EventsTable from '../metrics/EventsTable'; -import EventsChart from '../metrics/EventsChart'; +import WorldMap from 'components/common/WorldMap'; +import GridLayout, { GridColumn, GridRow } from 'components/layout/GridLayout'; +import MenuLayout from 'components/layout/MenuLayout'; +import Page from 'components/layout/Page'; +import WebsiteChart from 'components/metrics/WebsiteChart'; import useFetch from 'hooks/useFetch'; import usePageQuery from 'hooks/usePageQuery'; import useShareToken from 'hooks/useShareToken'; import { DEFAULT_ANIMATION_DURATION, TOKEN_HEADER } from 'lib/constants'; +import { useState } from 'react'; +import { FormattedMessage } from 'react-intl'; +import BrowsersTable from '../metrics/BrowsersTable'; +import CountriesTable from '../metrics/CountriesTable'; +import DevicesTable from '../metrics/DevicesTable'; +import EventsChart from '../metrics/EventsChart'; +import EventsTable from '../metrics/EventsTable'; +import OSTable from '../metrics/OSTable'; +import PagesTable from '../metrics/PagesTable'; +import ReferrersTable from '../metrics/ReferrersTable'; +import styles from './WebsiteDetails.module.css'; const views = { url: PagesTable, @@ -114,6 +114,7 @@ export default function WebsiteDetails({ websiteId }) { websiteId={websiteId} title={data.name} domain={data.domain} + createdAt={data.created_at} onDataLoad={handleDataLoad} showLink={false} stickyHeader diff --git a/components/pages/WebsiteList.js b/components/pages/WebsiteList.js index f4c29979..dd4cf172 100644 --- a/components/pages/WebsiteList.js +++ b/components/pages/WebsiteList.js @@ -1,13 +1,13 @@ -import React, { useState } from 'react'; -import { FormattedMessage } from 'react-intl'; -import Link from 'components/common/Link'; -import WebsiteChart from 'components/metrics/WebsiteChart'; -import Page from 'components/layout/Page'; -import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; -import Button from 'components/common/Button'; -import useFetch from 'hooks/useFetch'; import Arrow from 'assets/arrow-right.svg'; import Chart from 'assets/chart-bar.svg'; +import Button from 'components/common/Button'; +import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; +import Link from 'components/common/Link'; +import Page from 'components/layout/Page'; +import WebsiteChart from 'components/metrics/WebsiteChart'; +import useFetch from 'hooks/useFetch'; +import { useState } from 'react'; +import { FormattedMessage } from 'react-intl'; import styles from './WebsiteList.module.css'; export default function WebsiteList({ userId }) { @@ -42,13 +42,14 @@ export default function WebsiteList({ userId }) {
- {data.map(({ website_id, name, domain }) => ( + {data?.map(({ website_id, name, domain, created_at }) => (
diff --git a/hooks/useDateRange.js b/hooks/useDateRange.js index a4ff159c..10e58793 100644 --- a/hooks/useDateRange.js +++ b/hooks/useDateRange.js @@ -1,13 +1,13 @@ -import { useDispatch, useSelector } from 'react-redux'; import { parseISO } from 'date-fns'; +import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE } from 'lib/constants'; import { getDateRange } from 'lib/date'; import { getItem, setItem } from 'lib/web'; +import { useDispatch, useSelector } from 'react-redux'; import { setDateRange } from '../redux/actions/websites'; -import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE } from 'lib/constants'; import useForceUpdate from './useForceUpdate'; import useLocale from './useLocale'; -export default function useDateRange(websiteId, defaultDateRange = DEFAULT_DATE_RANGE) { +export default function useDateRange(websiteId, defaultDateRange = DEFAULT_DATE_RANGE, createdAt) { const dispatch = useDispatch(); const { locale } = useLocale(); const dateRange = useSelector(state => state.websites[websiteId]?.dateRange); @@ -18,7 +18,7 @@ export default function useDateRange(websiteId, defaultDateRange = DEFAULT_DATE_ if (globalDefault) { if (typeof globalDefault === 'string') { - globalDateRange = getDateRange(globalDefault, locale); + globalDateRange = getDateRange(globalDefault, locale, createdAt); } else if (typeof globalDefault === 'object') { globalDateRange = { ...globalDefault, @@ -39,5 +39,8 @@ export default function useDateRange(websiteId, defaultDateRange = DEFAULT_DATE_ } } - return [dateRange || globalDateRange || getDateRange(defaultDateRange, locale), saveDateRange]; + return [ + dateRange || globalDateRange || getDateRange(defaultDateRange, locale, createdAt), + saveDateRange, + ]; } diff --git a/lib/date.js b/lib/date.js index 578d9014..6cf25972 100644 --- a/lib/date.js +++ b/lib/date.js @@ -1,32 +1,32 @@ -import moment from 'moment-timezone'; import { - addMinutes, - addHours, addDays, + addHours, + addMinutes, addMonths, addYears, - subHours, - subDays, - startOfMinute, - startOfHour, - startOfDay, - startOfWeek, - startOfMonth, - startOfYear, - endOfHour, - endOfDay, - endOfWeek, - endOfMonth, - endOfYear, - differenceInMinutes, - differenceInHours, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, + differenceInHours, + differenceInMinutes, + endOfDay, + endOfHour, + endOfMonth, + endOfWeek, + endOfYear, format, + startOfDay, + startOfHour, + startOfMinute, + startOfMonth, + startOfWeek, + startOfYear, + subDays, + subHours, } from 'date-fns'; import { enUS } from 'date-fns/locale'; import { dateLocales } from 'lib/lang'; +import moment from 'moment-timezone'; export function getTimezone() { return moment.tz.guess(); @@ -36,11 +36,20 @@ export function getLocalTime(t) { return addMinutes(new Date(t), new Date().getTimezoneOffset()); } -export function getDateRange(value, locale = 'en-US') { +export function getDateRange(value, locale = 'en-US', createdAt) { const now = new Date(); const localeOptions = dateLocales[locale]; - const { num, unit } = value.match(/^(?[0-9]+)(?hour|day|week|month|year)$/).groups; + const { num, unit } = value.match(/^(?[0-9]+)(?hour|day|week|month|year|all)$/).groups; + + if (unit === 'all') { + return { + startDate: startOfMonth(new Date(createdAt)), + endDate: endOfYear(now), + unit: 'month', + value, + }; + } if (+num === 1) { switch (unit) {