Use token authentication for API requests.

This commit is contained in:
Mike Cao 2020-09-17 22:52:20 -07:00
parent bff8806b61
commit 96bd7e5b47
34 changed files with 198 additions and 153 deletions

View file

@ -4,8 +4,8 @@ import useFetch from 'hooks/useFetch';
import styles from './ActiveUsers.module.css';
import { FormattedMessage } from 'react-intl';
export default function ActiveUsers({ websiteId, className }) {
const { data } = useFetch(`/api/website/${websiteId}/active`, {}, { interval: 60000 });
export default function ActiveUsers({ websiteId, token, className }) {
const { data } = useFetch(`/api/website/${websiteId}/active`, { token }, { interval: 60000 });
const count = useMemo(() => {
return data?.[0]?.x || 0;
}, [data]);

View file

@ -3,13 +3,14 @@ import { FormattedMessage } from 'react-intl';
import MetricsTable from './MetricsTable';
import { browserFilter } from 'lib/filters';
export default function BrowsersTable({ websiteId, limit, onExpand }) {
export default function BrowsersTable({ websiteId, token, limit, onExpand }) {
return (
<MetricsTable
title={<FormattedMessage id="metrics.browsers" defaultMessage="Browsers" />}
type="browser"
metric={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />}
websiteId={websiteId}
token={token}
limit={limit}
dataFilter={browserFilter}
onExpand={onExpand}

View file

@ -3,13 +3,20 @@ import MetricsTable from './MetricsTable';
import { countryFilter, percentFilter } from 'lib/filters';
import { FormattedMessage } from 'react-intl';
export default function CountriesTable({ websiteId, limit, onDataLoad = () => {}, onExpand }) {
export default function CountriesTable({
websiteId,
token,
limit,
onDataLoad = () => {},
onExpand,
}) {
return (
<MetricsTable
title={<FormattedMessage id="metrics.countries" defaultMessage="Countries" />}
type="country"
metric={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />}
websiteId={websiteId}
token={token}
limit={limit}
dataFilter={countryFilter}
onDataLoad={data => onDataLoad(percentFilter(data))}

View file

@ -4,13 +4,14 @@ import { deviceFilter } from 'lib/filters';
import { FormattedMessage } from 'react-intl';
import { getDeviceMessage } from 'components/messages';
export default function DevicesTable({ websiteId, limit, onExpand }) {
export default function DevicesTable({ websiteId, token, limit, onExpand }) {
return (
<MetricsTable
title={<FormattedMessage id="metrics.devices" defaultMessage="Devices" />}
type="device"
metric={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />}
websiteId={websiteId}
token={token}
limit={limit}
dataFilter={deviceFilter}
renderLabel={({ x }) => getDeviceMessage(x)}

View file

@ -3,7 +3,7 @@ import tinycolor from 'tinycolor2';
import BarChart from './BarChart';
import { getTimezone, getDateArray, getDateLength } from 'lib/date';
import useFetch from 'hooks/useFetch';
import { useDateRange } from 'hooks/useDateRange';
import useDateRange from 'hooks/useDateRange';
const COLORS = [
'#2680eb',
@ -16,7 +16,7 @@ const COLORS = [
'#85d044',
];
export default function EventsChart({ websiteId }) {
export default function EventsChart({ websiteId, token }) {
const dateRange = useDateRange(websiteId);
const { startDate, endDate, unit, modified } = dateRange;
const { data } = useFetch(
@ -26,6 +26,7 @@ export default function EventsChart({ websiteId }) {
end_at: +endDate,
unit,
tz: getTimezone(),
token,
},
{ update: [modified] },
);

View file

@ -3,13 +3,14 @@ import { FormattedMessage } from 'react-intl';
import MetricsTable from './MetricsTable';
import styles from './EventsTable.module.css';
export default function EventsTable({ websiteId, limit, onExpand, onDataLoad }) {
export default function EventsTable({ websiteId, token, limit, onExpand, onDataLoad }) {
return (
<MetricsTable
title={<FormattedMessage id="metrics.events" defaultMessage="Events" />}
type="event"
metric={<FormattedMessage id="metrics.actions" defaultMessage="Actions" />}
websiteId={websiteId}
token={token}
limit={limit}
renderLabel={({ x }) => <Label value={x} />}
onExpand={onExpand}

View file

@ -3,12 +3,12 @@ import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import Loading from 'components/common/Loading';
import useFetch from 'hooks/useFetch';
import { useDateRange } from 'hooks/useDateRange';
import useDateRange from 'hooks/useDateRange';
import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format';
import MetricCard from './MetricCard';
import styles from './MetricsBar.module.css';
export default function MetricsBar({ websiteId, className }) {
export default function MetricsBar({ websiteId, token, className }) {
const dateRange = useDateRange(websiteId);
const { startDate, endDate, modified } = dateRange;
const { data } = useFetch(
@ -16,6 +16,7 @@ export default function MetricsBar({ websiteId, className }) {
{
start_at: +startDate,
end_at: +endDate,
token,
},
{
update: [modified],

View file

@ -10,12 +10,13 @@ import useFetch from 'hooks/useFetch';
import Arrow from 'assets/arrow-right.svg';
import { percentFilter } from 'lib/filters';
import { formatNumber, formatLongNumber } from 'lib/format';
import { useDateRange } from 'hooks/useDateRange';
import useDateRange from 'hooks/useDateRange';
import styles from './MetricsTable.module.css';
export default function MetricsTable({
websiteId,
websiteDomain,
token,
title,
metric,
type,
@ -37,6 +38,7 @@ export default function MetricsTable({
start_at: +startDate,
end_at: +endDate,
domain: websiteDomain,
token,
},
{ onDataLoad, delay: 300, update: [modified] },
);

View file

@ -3,13 +3,14 @@ import MetricsTable from './MetricsTable';
import { osFilter } from 'lib/filters';
import { FormattedMessage } from 'react-intl';
export default function OSTable({ websiteId, limit, onExpand }) {
export default function OSTable({ websiteId, token, limit, onExpand }) {
return (
<MetricsTable
title={<FormattedMessage id="metrics.operating-systems" defaultMessage="Operating system" />}
type="os"
metric={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />}
websiteId={websiteId}
token={token}
limit={limit}
dataFilter={osFilter}
onExpand={onExpand}

View file

@ -5,7 +5,7 @@ import { urlFilter } from 'lib/filters';
import { FILTER_COMBINED, FILTER_RAW } from 'lib/constants';
import MetricsTable from './MetricsTable';
export default function PagesTable({ websiteId, websiteDomain, limit, onExpand }) {
export default function PagesTable({ websiteId, token, websiteDomain, limit, onExpand }) {
const [filter, setFilter] = useState(FILTER_COMBINED);
const buttons = [
@ -25,6 +25,7 @@ export default function PagesTable({ websiteId, websiteDomain, limit, onExpand }
limit ? null : <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />
}
websiteId={websiteId}
token={token}
limit={limit}
dataFilter={urlFilter}
filterOptions={{ domain: websiteDomain, raw: filter === FILTER_RAW }}

View file

@ -1,30 +0,0 @@
import React from 'react';
import ButtonGroup from 'components/common/ButtonGroup';
import { getDateRange } from 'lib/date';
import styles from './QuickButtons.module.css';
const options = [
{ label: '24h', value: '24hour' },
{ label: '7d', value: '7day' },
{ label: '30d', value: '30day' },
];
export default function QuickButtons({ value, onChange }) {
const selectedItem = options.find(item => item.value === value)?.value;
function handleClick(selected) {
if (selected !== value) {
onChange(getDateRange(selected));
}
}
return (
<ButtonGroup
size="xsmall"
className={styles.buttons}
items={options}
selectedItem={selectedItem}
onClick={handleClick}
/>
);
}

View file

@ -1,33 +0,0 @@
.buttons {
display: flex;
align-content: center;
position: absolute;
top: 0;
right: 0;
margin: auto;
}
.buttons button + button {
margin-left: 10px;
}
.buttons .button {
font-size: var(--font-size-xsmall);
padding: 4px 8px;
}
.active {
font-weight: 600;
}
@media only screen and (max-width: 768px) {
.buttons button:last-child {
display: none;
}
}
@media only screen and (max-width: 576px) {
.buttons {
display: none;
}
}

View file

@ -5,7 +5,13 @@ import { refFilter } from 'lib/filters';
import ButtonGroup from 'components/common/ButtonGroup';
import { FILTER_DOMAIN_ONLY, FILTER_COMBINED, FILTER_RAW } from 'lib/constants';
export default function ReferrersTable({ websiteId, websiteDomain, limit, onExpand = () => {} }) {
export default function ReferrersTable({
websiteId,
websiteDomain,
token,
limit,
onExpand = () => {},
}) {
const [filter, setFilter] = useState(FILTER_COMBINED);
const buttons = [
@ -40,6 +46,7 @@ export default function ReferrersTable({ websiteId, websiteDomain, limit, onExpa
}
websiteId={websiteId}
websiteDomain={websiteDomain}
token={token}
limit={limit}
dataFilter={refFilter}
filterOptions={{

View file

@ -3,17 +3,18 @@ import { useDispatch } from 'react-redux';
import classNames from 'classnames';
import PageviewsChart from './PageviewsChart';
import MetricsBar from './MetricsBar';
import WebsiteHeader from './WebsiteHeader';
import DateFilter from 'components/common/DateFilter';
import StickyHeader from 'components/helpers/StickyHeader';
import useFetch from 'hooks/useFetch';
import useDateRange from 'hooks/useDateRange';
import { getDateArray, getDateLength, getTimezone } from 'lib/date';
import { setDateRange } from 'redux/actions/websites';
import styles from './WebsiteChart.module.css';
import WebsiteHeader from './WebsiteHeader';
import { useDateRange } from '../../hooks/useDateRange';
export default function WebsiteChart({
websiteId,
token,
title,
stickyHeader = false,
showLink = false,
@ -30,6 +31,7 @@ export default function WebsiteChart({
end_at: +endDate,
unit,
tz: getTimezone(),
token,
},
{ onDataLoad, update: [modified] },
);
@ -50,7 +52,7 @@ export default function WebsiteChart({
return (
<>
<WebsiteHeader websiteId={websiteId} title={title} showLink={showLink} />
<WebsiteHeader websiteId={websiteId} token={token} title={title} showLink={showLink} />
<div className={classNames(styles.header, 'row')}>
<StickyHeader
className={classNames(styles.metrics, 'col row')}
@ -58,7 +60,7 @@ export default function WebsiteChart({
enabled={stickyHeader}
>
<div className="col-12 col-lg-9">
<MetricsBar websiteId={websiteId} />
<MetricsBar websiteId={websiteId} token={token} />
</div>
<div className={classNames(styles.filter, 'col-12 col-lg-3')}>
<DateFilter

View file

@ -2,18 +2,18 @@ import React from 'react';
import { FormattedMessage } from 'react-intl';
import Link from 'components/common/Link';
import PageHeader from 'components/layout/PageHeader';
import RefreshButton from 'components/common/RefreshButton';
import ButtonLayout from 'components/layout/ButtonLayout';
import Icon from 'components/common/Icon';
import ActiveUsers from './ActiveUsers';
import Arrow from 'assets/arrow-right.svg';
import styles from './WebsiteHeader.module.css';
import RefreshButton from '../common/RefreshButton';
import ButtonLayout from '../layout/ButtonLayout';
import Icon from '../common/Icon';
export default function WebsiteHeader({ websiteId, title, showLink = false }) {
export default function WebsiteHeader({ websiteId, token, title, showLink = false }) {
return (
<PageHeader>
<div className={styles.title}>{title}</div>
<ActiveUsers className={styles.active} websiteId={websiteId} />
<ActiveUsers className={styles.active} websiteId={websiteId} token={token} />
<ButtonLayout>
<RefreshButton websiteId={websiteId} />
{showLink && (