diff --git a/components/layout/GridLayout.js b/components/layout/GridLayout.js
new file mode 100644
index 00000000..01ec1e8f
--- /dev/null
+++ b/components/layout/GridLayout.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import classNames from 'classnames';
+import styles from './GridLayout.module.css';
+
+export default function GridLayout({ className, children }) {
+ return
{children}
;
+}
+
+export const GridRow = ({ className, children }) => {
+ return {children}
;
+};
+
+export const GridColumn = ({ xs, sm, md, lg, xl, className, children }) => {
+ const classes = [];
+
+ classes.push(xs ? `col-${xs}` : 'col');
+
+ if (sm) {
+ classes.push(`col-sm-${sm}`);
+ }
+ if (md) {
+ classes.push(`col-md-${md}`);
+ }
+ if (lg) {
+ classes.push(`col-lg-${lg}`);
+ }
+ if (xl) {
+ classes.push(`col-lg-${xl}`);
+ }
+ return {children}
;
+};
diff --git a/components/layout/GridLayout.module.css b/components/layout/GridLayout.module.css
new file mode 100644
index 00000000..f17c195e
--- /dev/null
+++ b/components/layout/GridLayout.module.css
@@ -0,0 +1,40 @@
+.grid {
+ display: flex;
+ flex-direction: column;
+}
+
+.col {
+ display: flex;
+ flex-direction: column;
+}
+
+.row {
+ border-top: 1px solid var(--gray300);
+ min-height: 430px;
+}
+
+.row > .col {
+ border-left: 1px solid var(--gray300);
+ padding: 20px;
+}
+
+.row > .col:first-child {
+ border-left: 0;
+ padding-left: 0;
+}
+
+.row > .col:last-child {
+ padding-right: 0;
+}
+
+@media only screen and (max-width: 992px) {
+ .row {
+ border: 0;
+ }
+
+ .row > .col {
+ border-top: 1px solid var(--gray300);
+ border-left: 0;
+ padding: 0;
+ }
+}
diff --git a/components/metrics/EventsChart.js b/components/metrics/EventsChart.js
index c2804f9e..e401402d 100644
--- a/components/metrics/EventsChart.js
+++ b/components/metrics/EventsChart.js
@@ -8,7 +8,7 @@ import useTimezone from 'hooks/useTimezone';
import usePageQuery from 'hooks/usePageQuery';
import { EVENT_COLORS } from 'lib/constants';
-export default function EventsChart({ websiteId, token }) {
+export default function EventsChart({ websiteId, className, token }) {
const [dateRange] = useDateRange(websiteId);
const { startDate, endDate, unit, modified } = dateRange;
const [timezone] = useTimezone();
@@ -79,6 +79,7 @@ export default function EventsChart({ websiteId, token }) {
return (
+
+
+
diff --git a/components/metrics/RealtimeLog.module.css b/components/metrics/RealtimeLog.module.css
index af100708..5fa3d7ae 100644
--- a/components/metrics/RealtimeLog.module.css
+++ b/components/metrics/RealtimeLog.module.css
@@ -2,13 +2,20 @@
font-size: var(--font-size-xsmall);
}
+.header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ line-height: 40px;
+ font-weight: 600;
+}
+
.row {
display: flex;
border-bottom: 1px solid var(--gray300);
}
.body {
- height: 600px;
overflow: auto;
}
diff --git a/components/pages/RealtimeDashboard.js b/components/pages/RealtimeDashboard.js
index fd123f8b..2b878f1a 100644
--- a/components/pages/RealtimeDashboard.js
+++ b/components/pages/RealtimeDashboard.js
@@ -1,12 +1,12 @@
import React, { useState, useEffect, useMemo } from 'react';
-import classNames from 'classnames';
import { subMinutes, startOfMinute } from 'date-fns';
import Page from 'components/layout/Page';
-import useFetch from 'hooks/useFetch';
+import GridLayout, { GridRow, GridColumn } from 'components/layout/GridLayout';
import RealtimeChart from '../metrics/RealtimeChart';
import RealtimeLog from '../metrics/RealtimeLog';
import styles from './RealtimeDashboard.module.css';
import RealtimeHeader from '../metrics/RealtimeHeader';
+import useFetch from 'hooks/useFetch';
const REALTIME_RANGE = 30;
const REALTIME_INTERVAL = 5000;
@@ -36,10 +36,22 @@ export default function RealtimeDashboard() {
const realtimeData = useMemo(() => {
if (websiteId) {
const { pageviews, sessions, events, ...props } = data;
+ const countries = sessions.reduce((obj, { country }) => {
+ if (country) {
+ if (!obj[country]) {
+ obj[country] = 1;
+ } else {
+ obj[country] += 1;
+ }
+ }
+ return obj;
+ }, {});
+
return {
pageviews: filterWebsite(pageviews, websiteId),
sessions: filterWebsite(sessions, websiteId),
events: filterWebsite(events, websiteId),
+ countries,
...props,
};
}
@@ -83,12 +95,24 @@ export default function RealtimeDashboard() {
records={REALTIME_RANGE}
/>
-
+
+
+
+
+
+
+ x
+
+
+
+
+ x
+
+
+ x
+
+
+
);
}
diff --git a/components/pages/WebsiteDetails.js b/components/pages/WebsiteDetails.js
index 23b19f19..7f64b6f6 100644
--- a/components/pages/WebsiteDetails.js
+++ b/components/pages/WebsiteDetails.js
@@ -4,6 +4,7 @@ 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';
@@ -19,6 +20,7 @@ import EventsTable from '../metrics/EventsTable';
import EventsChart from '../metrics/EventsChart';
import useFetch from 'hooks/useFetch';
import usePageQuery from 'hooks/usePageQuery';
+import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
const views = {
url: PagesTable,
@@ -100,7 +102,7 @@ export default function WebsiteDetails({ websiteId, token }) {
function handleDataLoad() {
if (!chartLoaded) {
- setTimeout(() => setChartLoaded(true), 300);
+ setTimeout(() => setChartLoaded(true), DEFAULT_ANIMATION_DURATION);
}
}
@@ -124,45 +126,43 @@ export default function WebsiteDetails({ websiteId, token }) {
{!chartLoaded && }
{chartLoaded && !view && (
- <>
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
- 0 })}
- >
-
+
+
+ 0 })}>
+
-
-
-
-
-
- >
+
+
+
+
+
+
)}
{view && (
[class*='col-'] {
- border-left: 1px solid var(--gray300);
- padding: 20px;
-}
-
-.row > [class*='col-']:first-child {
- border-left: 0;
- padding-left: 0;
-}
-
-.row > [class*='col-']:last-child {
- padding-right: 0;
-}
-
.hidden {
display: none;
}
-@media only screen and (max-width: 992px) {
- .row {
- border: 0;
- }
-
- .row > [class*='col-'] {
- border-top: 1px solid var(--gray300);
- border-left: 0;
- padding: 0;
- }
+.eventschart {
+ padding: 30px 0;
}
diff --git a/styles/index.css b/styles/index.css
index c0e2ae6d..c695a2cf 100644
--- a/styles/index.css
+++ b/styles/index.css
@@ -37,6 +37,9 @@ h4,
h5,
h6 {
font-weight: 400;
+ line-height: 30px;
+ padding: 0;
+ margin: 0;
}
button,