import { useMemo, useState } from 'react'; import { StatusLight, Icon, Text } from 'react-basics'; import { useIntl, FormattedMessage } from 'react-intl'; import { FixedSizeList } from 'react-window'; import firstBy from 'thenby'; import FilterButtons from 'components/common/FilterButtons'; import NoData from 'components/common/NoData'; import { getDeviceMessage, labels, messages } from 'components/messages'; import useLocale from 'hooks/useLocale'; import useCountryNames from 'hooks/useCountryNames'; import { BROWSERS } from 'lib/constants'; import { stringToColor } from 'lib/format'; import { dateFormat } from 'lib/date'; import { safeDecodeURI } from 'next-basics'; import Icons from 'components/icons'; import styles from './RealtimeLog.module.css'; const TYPE_ALL = 'all'; const TYPE_PAGEVIEW = 'pageview'; const TYPE_SESSION = 'session'; const TYPE_EVENT = 'event'; const icons = { [TYPE_PAGEVIEW]: , [TYPE_SESSION]: , [TYPE_EVENT]: , }; export default function RealtimeLog({ data, websiteDomain }) { const { formatMessage } = useIntl(); const { locale } = useLocale(); const countryNames = useCountryNames(locale); const [filter, setFilter] = useState(TYPE_ALL); const buttons = [ { label: formatMessage(labels.all), key: TYPE_ALL, }, { label: formatMessage(labels.views), key: TYPE_PAGEVIEW, }, { label: formatMessage(labels.visitors), key: TYPE_SESSION, }, { label: formatMessage(labels.events), key: TYPE_EVENT, }, ]; const getTime = ({ createdAt }) => dateFormat(new Date(createdAt), 'pp', locale); const getColor = ({ sessionId }) => stringToColor(sessionId); const getIcon = ({ __type }) => icons[__type]; const getDetail = log => { const { __type, eventName, url, browser, os, country, device } = log; if (__type === TYPE_EVENT) { return ( {eventName || formatMessage(labels.unknown)}, url: ( {url} ), }} /> ); } if (__type === TYPE_PAGEVIEW) { return ( {safeDecodeURI(url)} ); } if (__type === TYPE_SESSION) { return ( {countryNames[country] || formatMessage(labels.unknown)}, browser: {BROWSERS[browser]}, os: {os}, device: {formatMessage(getDeviceMessage(device))}, }} /> ); } }; const Row = ({ index, style }) => { const row = logs[index]; return (
{getTime(row)}
{getIcon(row)} {getDetail(row)}
); }; const logs = useMemo(() => { if (!data) { return []; } const { pageviews, visitors, events } = data; const logs = [...pageviews, ...visitors, ...events].sort(firstBy('createdAt', -1)); if (filter !== TYPE_ALL) { return logs.filter(({ __type }) => __type === filter); } return logs; }, [data, filter]); return (
{formatMessage(labels.logs)}
{logs?.length === 0 && } {logs?.length > 0 && ( {Row} )}
); }