From c815e7cd51395e78194d319fb35c44bbbefc3d0b Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Fri, 10 Feb 2023 03:26:57 -0800 Subject: [PATCH] More refactoring and clean-up. --- components/common/FilterButtons.js | 27 ++++----------- components/helpers/StickyHeader.js | 33 ++++++++++++------- components/layout/AppLayout.js | 3 +- components/layout/ButtonLayout.js | 16 --------- components/layout/ButtonLayout.module.css | 21 ------------ components/layout/Page.module.css | 2 +- components/messages.js | 4 +++ components/metrics/PagesTable.js | 18 ++++------ components/metrics/ReferrersTable.js | 26 +++++---------- components/metrics/WebsiteChart.js | 8 ++--- components/metrics/WebsiteChart.module.css | 8 ++--- .../dashboard/DashboardSettingsButton.js | 24 +++++++++----- components/pages/websites/WebsiteMenuView.js | 19 ++++++----- .../pages/websites/WebsiteMenuView.module.css | 13 ++++++++ hooks/useSticky.js | 11 +++---- lib/constants.ts | 2 ++ 16 files changed, 101 insertions(+), 134 deletions(-) delete mode 100644 components/layout/ButtonLayout.js delete mode 100644 components/layout/ButtonLayout.module.css create mode 100644 components/pages/websites/WebsiteMenuView.module.css diff --git a/components/common/FilterButtons.js b/components/common/FilterButtons.js index b4b42291..ba985110 100644 --- a/components/common/FilterButtons.js +++ b/components/common/FilterButtons.js @@ -1,24 +1,11 @@ -import PropTypes from 'prop-types'; -import ButtonLayout from 'components/layout/ButtonLayout'; -import { ButtonGroup } from 'react-basics'; +import { ButtonGroup, Button, Flexbox } from 'react-basics'; -function FilterButtons({ buttons, selected, onClick }) { +export default function FilterButtons({ items, selected, onSelect }) { return ( - - - + + + {({ key, label }) => } + + ); } - -FilterButtons.propTypes = { - buttons: PropTypes.arrayOf( - PropTypes.shape({ - label: PropTypes.node, - value: PropTypes.any.isRequired, - }), - ), - selected: PropTypes.any, - onClick: PropTypes.func, -}; - -export default FilterButtons; diff --git a/components/helpers/StickyHeader.js b/components/helpers/StickyHeader.js index 12cab515..29daeb51 100644 --- a/components/helpers/StickyHeader.js +++ b/components/helpers/StickyHeader.js @@ -1,23 +1,32 @@ import { useEffect, useRef } from 'react'; +import { useMeasure, useCombinedRefs } from 'react-basics'; import classNames from 'classnames'; import useSticky from 'hooks/useSticky'; +import { UI_LAYOUT_BODY } from 'lib/constants'; -export default function StickyHeader({ className, stickyClassName, stickyStyle, children }) { - const { ref, isSticky } = useSticky(); - const initialWidth = useRef(0); - - useEffect(() => { - initialWidth.current = ref.current.clientWidth; - }, [ref]); +export default function StickyHeader({ + className, + stickyClassName, + stickyStyle, + enabled = true, + children, +}) { + const { ref: scrollRef, isSticky } = useSticky({ scrollElementId: UI_LAYOUT_BODY }); + const { ref: measureRef, dimensions } = useMeasure(); return (
- {children} +
+ {children} +
); } diff --git a/components/layout/AppLayout.js b/components/layout/AppLayout.js index 835f64d4..d89c34b9 100644 --- a/components/layout/AppLayout.js +++ b/components/layout/AppLayout.js @@ -2,6 +2,7 @@ import { Container } from 'react-basics'; import Head from 'next/head'; import NavBar from 'components/layout/NavBar'; import useRequireLogin from 'hooks/useRequireLogin'; +import { UI_LAYOUT_BODY } from 'lib/constants'; import styles from './AppLayout.module.css'; export default function AppLayout({ title, children }) { @@ -19,7 +20,7 @@ export default function AppLayout({ title, children }) {
-
+
{children}
diff --git a/components/layout/ButtonLayout.js b/components/layout/ButtonLayout.js deleted file mode 100644 index dd6a390d..00000000 --- a/components/layout/ButtonLayout.js +++ /dev/null @@ -1,16 +0,0 @@ -import classNames from 'classnames'; -import styles from './ButtonLayout.module.css'; - -export default function ButtonLayout({ className, children, align = 'center' }) { - return ( -
- {children} -
- ); -} diff --git a/components/layout/ButtonLayout.module.css b/components/layout/ButtonLayout.module.css deleted file mode 100644 index 5b979360..00000000 --- a/components/layout/ButtonLayout.module.css +++ /dev/null @@ -1,21 +0,0 @@ -.buttons { - display: flex; - align-items: center; - width: 100%; -} - -.buttons button + * { - margin-left: 10px; -} - -.center { - justify-content: center; -} - -.left { - justify-content: flex-start; -} - -.right { - justify-content: flex-end; -} diff --git a/components/layout/Page.module.css b/components/layout/Page.module.css index 4bd02d05..225f081f 100644 --- a/components/layout/Page.module.css +++ b/components/layout/Page.module.css @@ -2,7 +2,7 @@ flex: 1; display: flex; flex-direction: column; - padding: 30px; background: var(--base50); position: relative; + padding: 30px; } diff --git a/components/messages.js b/components/messages.js index e4c5d7ca..9a72ff75 100644 --- a/components/messages.js +++ b/components/messages.js @@ -79,6 +79,10 @@ export const labels = defineMessages({ query: { id: 'label.query-parameters', defaultMessage: 'Query parameters' }, back: { id: 'label.back', defaultMessage: 'Back' }, visitors: { id: 'label.visitors', defaultMessage: 'Visitors' }, + filterCombined: { id: 'label.filter-combined', defaultMessage: 'Combined' }, + filterRaw: { id: 'label.filter-raw', defaultMessage: 'Raw' }, + views: { id: 'label.views', defaultMessage: 'View' }, + none: { id: 'label.none', defaultMessage: 'None' }, }); export const messages = defineMessages({ diff --git a/components/metrics/PagesTable.js b/components/metrics/PagesTable.js index 8b53dec0..fab22993 100644 --- a/components/metrics/PagesTable.js +++ b/components/metrics/PagesTable.js @@ -1,31 +1,25 @@ import { useState } from 'react'; -import { useIntl, defineMessage } from 'react-intl'; +import { useIntl } from 'react-intl'; import FilterLink from 'components/common/FilterLink'; import FilterButtons from 'components/common/FilterButtons'; import { urlFilter } from 'lib/filters'; +import { labels } from 'components/messages'; import MetricsTable from './MetricsTable'; export const FILTER_COMBINED = 0; export const FILTER_RAW = 1; -const messages = defineMessage({ - combined: { id: 'metrics.filter.combined', defaultMessage: 'Combined' }, - raw: { id: 'metrics.filter.raw', defaultMessage: 'Raw' }, - pages: { id: 'metrics.pages', defaultMessage: 'Pages' }, - views: { id: 'metrics.views', defaultMessage: 'View' }, -}); - export default function PagesTable({ websiteId, showFilters, ...props }) { const [filter, setFilter] = useState(FILTER_COMBINED); const { formatMessage } = useIntl(); const buttons = [ { - label: formatMessage(messages.combined), + label: formatMessage(labels.filterCombined), value: FILTER_COMBINED, }, { - label: formatMessage(messages.raw), + label: formatMessage(labels.filterRaw), value: FILTER_RAW, }, ]; @@ -38,9 +32,9 @@ export default function PagesTable({ websiteId, showFilters, ...props }) { <> {showFilters && } { return referrer ? ( ) : ( - `(${none})` + `(${formatMessage(labels.none)})` ); }; return ( <> - {showFilters && } + {showFilters && } )} - - + + diff --git a/components/metrics/WebsiteChart.module.css b/components/metrics/WebsiteChart.module.css index 92c58d6c..8c66b1b0 100644 --- a/components/metrics/WebsiteChart.module.css +++ b/components/metrics/WebsiteChart.module.css @@ -17,15 +17,12 @@ } .header { - min-height: 90px; - margin-bottom: 20px; -} - -.metrics { position: relative; display: flex; justify-content: space-between; align-items: center; + min-height: 90px; + margin-bottom: 20px; } .sticky { @@ -35,6 +32,7 @@ border-bottom: 1px solid var(--base300); z-index: 3; width: inherit; + padding-top: 20px; } .filter { diff --git a/components/pages/dashboard/DashboardSettingsButton.js b/components/pages/dashboard/DashboardSettingsButton.js index c7f902f8..cdbb771b 100644 --- a/components/pages/dashboard/DashboardSettingsButton.js +++ b/components/pages/dashboard/DashboardSettingsButton.js @@ -1,8 +1,8 @@ import { defineMessages, useIntl } from 'react-intl'; -import MenuButton from 'components/common/MenuButton'; -import Gear from 'assets/gear.svg'; +import { Menu, Icon, Text, PopupTrigger, Popup, Item, Button } from 'react-basics'; +import Icons from 'components/icons'; +import { labels } from 'components/messages'; import { saveDashboard } from 'store/dashboard'; -import { Icon } from 'react-basics'; const messages = defineMessages({ toggleCharts: { id: 'message.toggle-charts', defaultMessage: 'Toggle charts' }, @@ -33,10 +33,18 @@ export default function DashboardSettingsButton() { } return ( - - - - - + + + + + {({ label, value }) => {label}} + + + ); } diff --git a/components/pages/websites/WebsiteMenuView.js b/components/pages/websites/WebsiteMenuView.js index f9717688..49e42436 100644 --- a/components/pages/websites/WebsiteMenuView.js +++ b/components/pages/websites/WebsiteMenuView.js @@ -1,4 +1,5 @@ import { Row, Column, Menu, Item, Icon, Button } from 'react-basics'; +import { useIntl } from 'react-intl'; import Link from 'next/link'; import BrowsersTable from 'components/metrics/BrowsersTable'; import CountriesTable from 'components/metrics/CountriesTable'; @@ -13,7 +14,7 @@ import EventsTable from 'components/metrics/EventsTable'; import usePageQuery from 'hooks/usePageQuery'; import Icons from 'components/icons'; import { labels } from 'components/messages'; -import { useIntl } from 'react-intl'; +import styles from './WebsiteMenuView.module.css'; const views = { url: PagesTable, @@ -81,8 +82,8 @@ export default function WebsiteMenuView({ websiteId, websiteDomain }) { const DetailsComponent = views[view]; return ( - - + + {({ value, label }) => ( - - - {label} - - + + + {label} + + )} - + { + const element = scrollElementId ? document.getElementById(scrollElementId) : window; + const handleScroll = () => { setIsSticky(element.scrollTop > initialTop.current); }; if (initialTop.current === null) { - initialTop.current = ref.current.offsetTop; + initialTop.current = ref?.current?.offsetTop; } element.addEventListener('scroll', handleScroll); @@ -22,7 +21,7 @@ export default function useSticky( return () => { element.removeEventListener('scroll', handleScroll); }; - }, [setIsSticky]); + }, [ref, setIsSticky]); return { ref, isSticky }; } diff --git a/lib/constants.ts b/lib/constants.ts index 57746404..819fdff8 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -23,6 +23,8 @@ export const DEFAULT_WEBSITE_LIMIT = 10; export const REALTIME_RANGE = 30; export const REALTIME_INTERVAL = 3000; +export const UI_LAYOUT_BODY = 'ui-layout-body'; + export const EVENT_TYPE = { pageView: 1, customEvent: 2,