diff --git a/components/WebsiteList.js b/components/WebsiteList.js
index 2a44350d..31ba760a 100644
--- a/components/WebsiteList.js
+++ b/components/WebsiteList.js
@@ -19,10 +19,10 @@ export default function WebsiteList() {
return (
- {data?.map(({ website_id, name }) => (
+ {data.map(({ website_id, name }) => (
-
-
+
+
))}
{data.length === 0 && (
diff --git a/components/common/RefreshButton.js b/components/common/RefreshButton.js
new file mode 100644
index 00000000..c45d5c40
--- /dev/null
+++ b/components/common/RefreshButton.js
@@ -0,0 +1,7 @@
+import React from 'react';
+import Button from './Button';
+import Refresh from 'assets/redo.svg';
+
+export default function RefreshButton({ onClick }) {
+ return } size="small" onClick={onClick} />;
+}
diff --git a/components/metrics/BarChart.js b/components/metrics/BarChart.js
index 25c14fe5..9caa96d1 100644
--- a/components/metrics/BarChart.js
+++ b/components/metrics/BarChart.js
@@ -4,6 +4,7 @@ import classNames from 'classnames';
import ChartJS from 'chart.js';
import styles from './BarChart.module.css';
import { format } from 'date-fns';
+import { formatLongNumber } from '../../lib/format';
export default function BarChart({
chartId,
@@ -21,7 +22,7 @@ export default function BarChart({
const chart = useRef();
const [tooltip, setTooltip] = useState({});
- const renderLabel = (label, index, values) => {
+ const renderXLabel = (label, index, values) => {
const d = new Date(values[index].value);
const n = records;
@@ -40,6 +41,10 @@ export default function BarChart({
}
};
+ const renderYLabel = label => {
+ return +label > 1 ? formatLongNumber(label) : label;
+ };
+
const renderTooltip = model => {
const { opacity, title, body, labelColors } = model;
@@ -82,7 +87,7 @@ export default function BarChart({
tooltipFormat: 'ddd MMMM DD YYYY',
},
ticks: {
- callback: renderLabel,
+ callback: renderXLabel,
minRotation: 0,
maxRotation: 0,
},
@@ -96,6 +101,7 @@ export default function BarChart({
yAxes: [
{
ticks: {
+ callback: renderYLabel,
beginAtZero: true,
},
stacked,
@@ -119,7 +125,7 @@ export default function BarChart({
const { options } = chart.current;
options.scales.xAxes[0].time.unit = unit;
- options.scales.xAxes[0].ticks.callback = renderLabel;
+ options.scales.xAxes[0].ticks.callback = renderXLabel;
options.animation.duration = animationDuration;
onUpdate(chart.current);
diff --git a/components/metrics/MetricsBar.js b/components/metrics/MetricsBar.js
index dce7a459..111e550b 100644
--- a/components/metrics/MetricsBar.js
+++ b/components/metrics/MetricsBar.js
@@ -1,8 +1,9 @@
import React, { useState } from 'react';
import classNames from 'classnames';
import MetricCard from './MetricCard';
-import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format';
+import Loading from 'components/common/Loading';
import useFetch from 'hooks/useFetch';
+import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format';
import styles from './MetricsBar.module.css';
export default function MetricsBar({ websiteId, startDate, endDate, className }) {
@@ -18,26 +19,28 @@ export default function MetricsBar({ websiteId, startDate, endDate, className })
setFormat(state => !state);
}
- if (!data) {
- return null;
- }
-
- const { pageviews, uniques, bounces, totaltime } = data;
+ const { pageviews, uniques, bounces, totaltime } = data || {};
return (
-
-
- Number(n).toFixed(0) + '%'}
- />
- formatShortTime(n, ['m', 's'], ' ')}
- />
+ {!data ? (
+
+ ) : (
+ <>
+
+
+ Number(n).toFixed(0) + '%'}
+ />
+ formatShortTime(n, ['m', 's'], ' ')}
+ />
+ >
+ )}
);
}
diff --git a/components/metrics/MetricsBar.module.css b/components/metrics/MetricsBar.module.css
index b52fb900..4046634e 100644
--- a/components/metrics/MetricsBar.module.css
+++ b/components/metrics/MetricsBar.module.css
@@ -4,7 +4,7 @@
}
@media only screen and (max-width: 992px) {
- .container > div:last-child {
+ .bar > div:last-child {
display: none;
}
}
diff --git a/components/metrics/PageviewsChart.js b/components/metrics/PageviewsChart.js
index f8aa0cdc..6104949a 100644
--- a/components/metrics/PageviewsChart.js
+++ b/components/metrics/PageviewsChart.js
@@ -1,8 +1,9 @@
import React from 'react';
import CheckVisible from 'components/helpers/CheckVisible';
import BarChart from './BarChart';
+import { getDateLength } from '../../lib/date';
-export default function PageviewsChart({ websiteId, data, unit, className }) {
+export default function PageviewsChart({ websiteId, data, startDate, endDate, unit, className }) {
const handleUpdate = chart => {
const {
data: { datasets },
@@ -43,7 +44,7 @@ export default function PageviewsChart({ websiteId, data, unit, className }) {
},
]}
unit={unit}
- records={data.pageviews.length}
+ records={getDateLength(startDate, endDate, unit)}
animationDuration={visible ? 300 : 0}
onUpdate={handleUpdate}
/>
diff --git a/components/metrics/WebsiteHeader.js b/components/metrics/WebsiteHeader.js
index 459fd69f..0ece5878 100644
--- a/components/metrics/WebsiteHeader.js
+++ b/components/metrics/WebsiteHeader.js
@@ -1,38 +1,36 @@
import React from 'react';
import { useRouter } from 'next/router';
import PageHeader from 'components/layout/PageHeader';
-import Link from 'components/common/Link';
import Button from 'components/common/Button';
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';
-export default function WebsiteHeader({ websiteId, name, showLink = false }) {
+export default function WebsiteHeader({ websiteId, title, showLink = false, onRefresh }) {
const router = useRouter();
return (
- {showLink ? (
-
- {name}
-
- ) : (
- {name}
- )}
+ {title}
- {showLink && (
- }
- onClick={() =>
- router.push('/website/[...id]', `/website/${websiteId}/${name}`, {
- shallow: true,
- })
- }
- size="small"
- >
- View details
-
- )}
+
+
+ {showLink && (
+ }
+ onClick={() =>
+ router.push('/website/[...id]', `/website/${websiteId}/${name}`, {
+ shallow: true,
+ })
+ }
+ size="small"
+ >
+ View details
+
+ )}
+
);
}
diff --git a/hooks/useFetch.js b/hooks/useFetch.js
index 9f14e45e..b9b36c0f 100644
--- a/hooks/useFetch.js
+++ b/hooks/useFetch.js
@@ -35,5 +35,5 @@ export default function useFetch(url, params = {}, options = {}) {
}
}, [url, ...keys, ...update]);
- return { data, error };
+ return { data, error, loadData };
}
diff --git a/package.json b/package.json
index 17b79794..80bf5f9c 100644
--- a/package.json
+++ b/package.json
@@ -30,8 +30,7 @@
],
"**/*.css": [
"stylelint --fix",
- "prettier --write",
- "eslint"
+ "prettier --write"
]
},
"husky": {
@@ -53,6 +52,7 @@
"dotenv": "^8.2.0",
"formik": "^2.1.5",
"geolite2-redist": "^1.0.7",
+ "immer": "^7.0.8",
"is-localhost-ip": "^1.4.0",
"jose": "^1.28.0",
"maxmind": "^4.1.4",
diff --git a/yarn.lock b/yarn.lock
index 588dd177..73f0d4d6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4456,7 +4456,7 @@ ignore@^5.1.4, ignore@^5.1.8:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
-immer@^7.0.3:
+immer@^7.0.3, immer@^7.0.8:
version "7.0.8"
resolved "https://registry.yarnpkg.com/immer/-/immer-7.0.8.tgz#41dcbc5669a76500d017bef3ad0d03ce0a1d7c1e"
integrity sha512-XnpIN8PXBBaOD43U8Z17qg6RQiKQYGDGGCIbz1ixmLGwBkSWwmrmx5X7d+hTtXDM8ur7m5OdLE0PiO+y5RB3pw==