diff --git a/.dockerignore b/.dockerignore index 40d5f5bb..74fa836a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,4 @@ Dockerfile .gitignore .DS_Store node_modules +.idea \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 99c7e132..7a824ff6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -46,6 +46,7 @@ "react/react-in-jsx-scope": "off", "react/prop-types": "off", "import/no-anonymous-default-export": "off", + "import/no-named-as-default": "off", "@next/next/no-img-element": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off", diff --git a/.github/workflows/cd-manual.yml b/.github/workflows/cd-manual.yml index f62f3e45..1afc6e93 100644 --- a/.github/workflows/cd-manual.yml +++ b/.github/workflows/cd-manual.yml @@ -18,7 +18,7 @@ jobs: db-type: [postgresql, mysql] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: mr-smithers-excellent/docker-build-push@v6 name: Build & push Docker image for ${{ matrix.db-type }} diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 824001ef..6fda05a6 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -3,7 +3,6 @@ name: Create docker images on: [create] jobs: - build: name: Build, push, and deploy if: ${{ startsWith(github.ref, 'refs/tags/v') }} @@ -14,7 +13,7 @@ jobs: db-type: [postgresql, mysql] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set env run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV diff --git a/.gitignore b/.gitignore index 84ac5e60..7066fb28 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ node_modules /build /public/script.js /geo +/dist # misc .DS_Store diff --git a/.prettierignore b/.prettierignore index 15ce475e..08076d40 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1 @@ -/public/ \ No newline at end of file +/public/script.js \ No newline at end of file diff --git a/components/common/EmptyPlaceholder.js b/components/common/EmptyPlaceholder.js index fa773a01..8834a1db 100644 --- a/components/common/EmptyPlaceholder.js +++ b/components/common/EmptyPlaceholder.js @@ -1,7 +1,7 @@ import { Icon, Text, Flexbox } from 'react-basics'; import Logo from 'assets/logo.svg'; -function EmptyPlaceholder({ message, children }) { +export function EmptyPlaceholder({ message, children }) { return ( diff --git a/components/common/ErrorMessage.js b/components/common/ErrorMessage.js index b5d44bb4..e2b22747 100644 --- a/components/common/ErrorMessage.js +++ b/components/common/ErrorMessage.js @@ -2,7 +2,7 @@ import { Icon, Icons, Text } from 'react-basics'; import styles from './ErrorMessage.module.css'; import useMessages from 'hooks/useMessages'; -export default function ErrorMessage() { +export function ErrorMessage() { const { formatMessage, messages } = useMessages(); return ( @@ -14,3 +14,5 @@ export default function ErrorMessage() { ); } + +export default ErrorMessage; diff --git a/components/common/Favicon.js b/components/common/Favicon.js index 2127d482..55059cc0 100644 --- a/components/common/Favicon.js +++ b/components/common/Favicon.js @@ -5,7 +5,7 @@ function getHostName(url) { return match && match.length > 1 ? match[1] : null; } -function Favicon({ domain, ...props }) { +export function Favicon({ domain, ...props }) { const hostName = domain ? getHostName(domain) : null; return hostName ? ( diff --git a/components/common/Favicon.module.css b/components/common/Favicon.module.css index 82c85c42..f8972ad1 100644 --- a/components/common/Favicon.module.css +++ b/components/common/Favicon.module.css @@ -1,3 +1,3 @@ .favicon { - margin-right: 8px; + margin-inline-end: 8px; } diff --git a/components/common/FilterButtons.js b/components/common/FilterButtons.js index 4d08a132..f5a54fb6 100644 --- a/components/common/FilterButtons.js +++ b/components/common/FilterButtons.js @@ -1,6 +1,6 @@ import { ButtonGroup, Button, Flexbox } from 'react-basics'; -export default function FilterButtons({ items, selectedKey, onSelect }) { +export function FilterButtons({ items, selectedKey, onSelect }) { return ( @@ -9,3 +9,5 @@ export default function FilterButtons({ items, selectedKey, onSelect }) { ); } + +export default FilterButtons; diff --git a/components/common/FilterLink.js b/components/common/FilterLink.js index 322b5499..0fed3cd6 100644 --- a/components/common/FilterLink.js +++ b/components/common/FilterLink.js @@ -6,7 +6,7 @@ import usePageQuery from 'hooks/usePageQuery'; import useMessages from 'hooks/useMessages'; import styles from './FilterLink.module.css'; -export default function FilterLink({ id, value, label, externalUrl }) { +export function FilterLink({ id, value, label, externalUrl }) { const { formatMessage, labels } = useMessages(); const { resolveUrl, query } = usePageQuery(); const active = query[id] !== undefined; @@ -37,3 +37,5 @@ export default function FilterLink({ id, value, label, externalUrl }) { ); } + +export default FilterLink; diff --git a/components/common/FilterLink.module.css b/components/common/FilterLink.module.css index ce3ffa5f..055b7772 100644 --- a/components/common/FilterLink.module.css +++ b/components/common/FilterLink.module.css @@ -14,7 +14,7 @@ .row .link { display: none; - margin-left: 20px; + margin-inline-start: 20px; } .row .label { diff --git a/components/common/HamburgerButton.js b/components/common/HamburgerButton.js index b3e0b54f..f4b12859 100644 --- a/components/common/HamburgerButton.js +++ b/components/common/HamburgerButton.js @@ -5,7 +5,7 @@ import Icons from 'components/icons'; import useMessages from 'hooks/useMessages'; import useConfig from 'hooks/useConfig'; -export default function HamburgerButton() { +export function HamburgerButton() { const { formatMessage, labels } = useMessages(); const [active, setActive] = useState(false); const { cloudMode } = useConfig(); @@ -57,3 +57,5 @@ export default function HamburgerButton() { ); } + +export default HamburgerButton; diff --git a/components/common/HoverTooltip.js b/components/common/HoverTooltip.js index 3b885b1d..2a98ab84 100644 --- a/components/common/HoverTooltip.js +++ b/components/common/HoverTooltip.js @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { Tooltip } from 'react-basics'; import styles from './HoverTooltip.module.css'; -export default function HoverTooltip({ tooltip }) { +export function HoverTooltip({ tooltip }) { const [position, setPosition] = useState({ x: -1000, y: -1000 }); useEffect(() => { @@ -23,3 +23,5 @@ export default function HoverTooltip({ tooltip }) { ); } + +export default HoverTooltip; diff --git a/components/common/MobileMenu.js b/components/common/MobileMenu.js index 44c8da84..2228a3e9 100644 --- a/components/common/MobileMenu.js +++ b/components/common/MobileMenu.js @@ -3,7 +3,7 @@ import { useRouter } from 'next/router'; import Link from 'next/link'; import styles from './MobileMenu.module.css'; -export default function MobileMenu({ items = [], onClose }) { +export function MobileMenu({ items = [], onClose }) { const { pathname } = useRouter(); const Items = ({ items, className }) => ( @@ -34,3 +34,5 @@ export default function MobileMenu({ items = [], onClose }) { ); } + +export default MobileMenu; diff --git a/components/common/NoData.js b/components/common/NoData.js index e278b6f3..e9c95754 100644 --- a/components/common/NoData.js +++ b/components/common/NoData.js @@ -2,7 +2,7 @@ import classNames from 'classnames'; import styles from './NoData.module.css'; import useMessages from 'hooks/useMessages'; -function NoData({ className }) { +export function NoData({ className }) { const { formatMessage, messages } = useMessages(); return ( diff --git a/components/common/SettingsTable.js b/components/common/SettingsTable.js index ac29d54e..8f039858 100644 --- a/components/common/SettingsTable.js +++ b/components/common/SettingsTable.js @@ -1,7 +1,7 @@ import { Table, TableHeader, TableBody, TableRow, TableCell, TableColumn } from 'react-basics'; import styles from './SettingsTable.module.css'; -export default function SettingsTable({ columns = [], data = [], children, cellRender }) { +export function SettingsTable({ columns = [], data = [], children, cellRender }) { return ( @@ -34,3 +34,5 @@ export default function SettingsTable({ columns = [], data = [], children, cellR
); } + +export default SettingsTable; diff --git a/components/common/UpdateNotice.js b/components/common/UpdateNotice.js index c30ab8fb..161a5a67 100644 --- a/components/common/UpdateNotice.js +++ b/components/common/UpdateNotice.js @@ -6,7 +6,7 @@ import { REPO_URL, VERSION_CHECK } from 'lib/constants'; import styles from './UpdateNotice.module.css'; import useMessages from 'hooks/useMessages'; -export default function UpdateNotice() { +export function UpdateNotice() { const { formatMessage, labels, messages } = useMessages(); const { latest, checked, hasUpdate, releaseUrl } = useStore(); const [dismissed, setDismissed] = useState(false); @@ -50,3 +50,5 @@ export default function UpdateNotice() { ); } + +export default UpdateNotice; diff --git a/components/common/WorldMap.js b/components/common/WorldMap.js index c6aa91ab..55a13f0b 100644 --- a/components/common/WorldMap.js +++ b/components/common/WorldMap.js @@ -3,16 +3,16 @@ import { useRouter } from 'next/router'; import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps'; import classNames from 'classnames'; import { colord } from 'colord'; -import useTheme from 'hooks/useTheme'; +import HoverTooltip from 'components/common/HoverTooltip'; import { ISO_COUNTRIES, THEME_COLORS, MAP_FILE } from 'lib/constants'; -import styles from './WorldMap.module.css'; +import useTheme from 'hooks/useTheme'; import useCountryNames from 'hooks/useCountryNames'; import useLocale from 'hooks/useLocale'; -import HoverTooltip from './HoverTooltip'; import { formatLongNumber } from 'lib/format'; import { percentFilter } from 'lib/filters'; +import styles from './WorldMap.module.css'; -function WorldMap({ data, className }) { +export function WorldMap({ data, className }) { const { basePath } = useRouter(); const [tooltip, setTooltip] = useState(); const [theme] = useTheme(); diff --git a/components/input/DateFilter.js b/components/input/DateFilter.js index e0881bd8..68dcd417 100644 --- a/components/input/DateFilter.js +++ b/components/input/DateFilter.js @@ -9,7 +9,7 @@ import useApi from 'hooks/useApi'; import useDateRange from 'hooks/useDateRange'; import useMessages from 'hooks/useMessages'; -function DateFilter({ websiteId, value, className }) { +export function DateFilter({ websiteId, value, className }) { const { formatMessage, labels } = useMessages(); const { get } = useApi(); const [dateRange, setDateRange] = useDateRange(websiteId); diff --git a/components/input/LanguageButton.js b/components/input/LanguageButton.js index e6da5991..1297d6c2 100644 --- a/components/input/LanguageButton.js +++ b/components/input/LanguageButton.js @@ -5,8 +5,8 @@ import useLocale from 'hooks/useLocale'; import Icons from 'components/icons'; import styles from './LanguageButton.module.css'; -export default function LanguageButton() { - const { locale, saveLocale } = useLocale(); +export function LanguageButton() { + const { locale, saveLocale, dir } = useLocale(); const items = Object.keys(languages).map(key => ({ ...languages[key], value: key })); function handleSelect(value) { @@ -20,7 +20,7 @@ export default function LanguageButton() {
- +
{items.map(({ value, label }) => { return ( @@ -43,3 +43,5 @@ export default function LanguageButton() { ); } + +export default LanguageButton; diff --git a/components/input/LogoutButton.js b/components/input/LogoutButton.js index 4dfe7bed..3314956e 100644 --- a/components/input/LogoutButton.js +++ b/components/input/LogoutButton.js @@ -2,7 +2,7 @@ import { Button, Icon, Icons, Tooltip } from 'react-basics'; import Link from 'next/link'; import useMessages from 'hooks/useMessages'; -export default function LogoutButton({ tooltipPosition = 'top' }) { +export function LogoutButton({ tooltipPosition = 'top' }) { const { formatMessage, labels } = useMessages(); return ( @@ -16,3 +16,5 @@ export default function LogoutButton({ tooltipPosition = 'top' }) { ); } + +export default LogoutButton; diff --git a/components/input/ProfileButton.js b/components/input/ProfileButton.js index 547054e0..bbd84af5 100644 --- a/components/input/ProfileButton.js +++ b/components/input/ProfileButton.js @@ -5,12 +5,14 @@ import useMessages from 'hooks/useMessages'; import useUser from 'hooks/useUser'; import useConfig from 'hooks/useConfig'; import styles from './ProfileButton.module.css'; +import useLocale from 'hooks/useLocale'; -export default function ProfileButton() { +export function ProfileButton() { const { formatMessage, labels } = useMessages(); const { user } = useUser(); const { cloudMode } = useConfig(); const router = useRouter(); + const { dir } = useLocale(); const handleSelect = key => { if (key === 'profile') { @@ -31,7 +33,7 @@ export default function ProfileButton() { - + {user.username} @@ -55,3 +57,5 @@ export default function ProfileButton() { ); } + +export default ProfileButton; diff --git a/components/input/RefreshButton.js b/components/input/RefreshButton.js index 458b469b..b3e2b815 100644 --- a/components/input/RefreshButton.js +++ b/components/input/RefreshButton.js @@ -4,7 +4,7 @@ import useDateRange from 'hooks/useDateRange'; import Icons from 'components/icons'; import useMessages from 'hooks/useMessages'; -function RefreshButton({ websiteId, isLoading }) { +export function RefreshButton({ websiteId, isLoading }) { const { formatMessage, labels } = useMessages(); const [dateRange] = useDateRange(websiteId); diff --git a/components/input/SettingsButton.js b/components/input/SettingsButton.js index 84a5d675..6f2012d4 100644 --- a/components/input/SettingsButton.js +++ b/components/input/SettingsButton.js @@ -5,7 +5,7 @@ import Icons from 'components/icons'; import useMessages from 'hooks/useMessages'; import styles from './SettingsButton.module.css'; -export default function SettingsButton() { +export function SettingsButton() { const { formatMessage, labels } = useMessages(); return ( @@ -33,3 +33,5 @@ export default function SettingsButton() { ); } + +export default SettingsButton; diff --git a/components/input/ThemeButton.js b/components/input/ThemeButton.js index 0e5706d7..b945ab7d 100644 --- a/components/input/ThemeButton.js +++ b/components/input/ThemeButton.js @@ -4,7 +4,7 @@ import useTheme from 'hooks/useTheme'; import Icons from 'components/icons'; import styles from './ThemeButton.module.css'; -export default function ThemeButton() { +export function ThemeButton() { const [theme, setTheme] = useTheme(); const transitions = useTransition(theme, { @@ -34,3 +34,5 @@ export default function ThemeButton() { ); } + +export default ThemeButton; diff --git a/components/input/WebsiteSelect.js b/components/input/WebsiteSelect.js index 62fc1435..a0ac38e4 100644 --- a/components/input/WebsiteSelect.js +++ b/components/input/WebsiteSelect.js @@ -2,7 +2,7 @@ import { Dropdown, Item } from 'react-basics'; import useApi from 'hooks/useApi'; import useMessages from 'hooks/useMessages'; -export default function WebsiteSelect({ websiteId, onSelect }) { +export function WebsiteSelect({ websiteId, onSelect }) { const { formatMessage, labels } = useMessages(); const { get, useQuery } = useApi(); const { data } = useQuery(['websites:me'], () => get('/me/websites')); @@ -25,3 +25,5 @@ export default function WebsiteSelect({ websiteId, onSelect }) { ); } + +export default WebsiteSelect; diff --git a/components/layout/AppLayout.js b/components/layout/AppLayout.js index 3a70685a..45ba7e23 100644 --- a/components/layout/AppLayout.js +++ b/components/layout/AppLayout.js @@ -5,9 +5,10 @@ import NavBar from 'components/layout/NavBar'; import UpdateNotice from 'components/common/UpdateNotice'; import useRequireLogin from 'hooks/useRequireLogin'; import useConfig from 'hooks/useConfig'; +import { CURRENT_VERSION } from 'lib/constants'; import styles from './AppLayout.module.css'; -export default function AppLayout({ title, children }) { +export function AppLayout({ title, children }) { const { user } = useRequireLogin(); const config = useConfig(); const { pathname } = useRouter(); @@ -19,7 +20,7 @@ export default function AppLayout({ title, children }) { const allowUpdate = user?.isAdmin && !config?.updatesDisabled && !pathname.includes('/share/'); return ( -
+
{allowUpdate && } {title ? `${title} | umami` : 'umami'} @@ -33,3 +34,5 @@ export default function AppLayout({ title, children }) {
); } + +export default AppLayout; diff --git a/components/layout/Footer.js b/components/layout/Footer.js index 64812b8e..7cc5d3de 100644 --- a/components/layout/Footer.js +++ b/components/layout/Footer.js @@ -4,7 +4,7 @@ import { CURRENT_VERSION, HOMEPAGE_URL, REPO_URL } from 'lib/constants'; import { labels } from 'components/messages'; import styles from './Footer.module.css'; -export default function Footer() { +export function Footer() { return (
@@ -29,3 +29,5 @@ export default function Footer() {
); } + +export default Footer; diff --git a/components/layout/Grid.module.css b/components/layout/Grid.module.css index 20df43c9..655e4ea2 100644 --- a/components/layout/Grid.module.css +++ b/components/layout/Grid.module.css @@ -10,16 +10,16 @@ } .row > .col { - border-left: 1px solid var(--base300); + border-inline-start: 1px solid var(--base300); } .row > .col:first-child { - border-left: 0; - padding-left: 0; + border-inline-start: 0; + padding-inline-start: 0; } .row > .col:last-child { - padding-right: 0; + padding-inline-end: 0; } @media only screen and (max-width: 992px) { @@ -29,7 +29,7 @@ .row > .col { border-top: 1px solid var(--base300); - border-left: 0; + border-inline-end: 0; padding: 20px 0; } } diff --git a/components/layout/Header.js b/components/layout/Header.js index 10451998..2007b1d9 100644 --- a/components/layout/Header.js +++ b/components/layout/Header.js @@ -6,7 +6,7 @@ import SettingsButton from 'components/input/SettingsButton'; import Icons from 'components/icons'; import styles from './Header.module.css'; -export default function Header() { +export function Header() { return (
@@ -27,3 +27,5 @@ export default function Header() {
); } + +export default Header; diff --git a/components/layout/NavBar.js b/components/layout/NavBar.js index 46eabc9e..5a6c877e 100644 --- a/components/layout/NavBar.js +++ b/components/layout/NavBar.js @@ -1,4 +1,3 @@ -import { useState } from 'react'; import { Icon, Text, Row, Column } from 'react-basics'; import Link from 'next/link'; import classNames from 'classnames'; @@ -12,7 +11,7 @@ import useMessages from 'hooks/useMessages'; import { useRouter } from 'next/router'; import HamburgerButton from '../common/HamburgerButton'; -export default function NavBar() { +export function NavBar() { const { pathname } = useRouter(); const { cloudMode } = useConfig(); const { formatMessage, labels } = useMessages(); @@ -61,3 +60,5 @@ export default function NavBar() {
); } + +export default NavBar; diff --git a/components/layout/NavGroup.js b/components/layout/NavGroup.js index 5d4f6ccc..b9e7155d 100644 --- a/components/layout/NavGroup.js +++ b/components/layout/NavGroup.js @@ -6,7 +6,7 @@ import Link from 'next/link'; import Icons from 'components/icons'; import styles from './NavGroup.module.css'; -export default function NavGroup({ +export function NavGroup({ title, items, defaultExpanded = true, @@ -54,3 +54,5 @@ export default function NavGroup({
); } + +export default NavGroup; diff --git a/components/layout/Page.js b/components/layout/Page.js index d06e0d06..30abde50 100644 --- a/components/layout/Page.js +++ b/components/layout/Page.js @@ -3,7 +3,7 @@ import { Banner, Loading } from 'react-basics'; import useMessages from 'hooks/useMessages'; import styles from './Page.module.css'; -export default function Page({ className, error, loading, children }) { +export function Page({ className, error, loading, children }) { const { formatMessage, messages } = useMessages(); if (error) { @@ -16,3 +16,5 @@ export default function Page({ className, error, loading, children }) { return
{children}
; } + +export default Page; diff --git a/components/layout/PageHeader.js b/components/layout/PageHeader.js index 05c87f73..bf243c21 100644 --- a/components/layout/PageHeader.js +++ b/components/layout/PageHeader.js @@ -1,7 +1,7 @@ import React from 'react'; import styles from './PageHeader.module.css'; -export default function PageHeader({ title, children }) { +export function PageHeader({ title, children }) { return (
{title}
@@ -9,3 +9,5 @@ export default function PageHeader({ title, children }) {
); } + +export default PageHeader; diff --git a/components/layout/SettingsLayout.js b/components/layout/SettingsLayout.js index ea0456e0..c79f0909 100644 --- a/components/layout/SettingsLayout.js +++ b/components/layout/SettingsLayout.js @@ -1,5 +1,4 @@ import { Row, Column } from 'react-basics'; -import classNames from 'classnames'; import { useRouter } from 'next/router'; import SideNav from './SideNav'; import useUser from 'hooks/useUser'; @@ -7,7 +6,7 @@ import useMessages from 'hooks/useMessages'; import useConfig from 'hooks/useConfig'; import styles from './SettingsLayout.module.css'; -export default function SettingsLayout({ children }) { +export function SettingsLayout({ children }) { const { user } = useUser(); const { pathname } = useRouter(); const { formatMessage, labels } = useMessages(); @@ -35,3 +34,5 @@ export default function SettingsLayout({ children }) { ); } + +export default SettingsLayout; diff --git a/components/layout/ShareLayout.js b/components/layout/ShareLayout.js index 9f19fda8..c634e1b6 100644 --- a/components/layout/ShareLayout.js +++ b/components/layout/ShareLayout.js @@ -2,7 +2,7 @@ import { Container } from 'react-basics'; import Header from './Header'; import Footer from './Footer'; -export default function ShareLayout({ children }) { +export function ShareLayout({ children }) { return (
@@ -11,3 +11,5 @@ export default function ShareLayout({ children }) { ); } + +export default ShareLayout; diff --git a/components/layout/SideNav.js b/components/layout/SideNav.js index 2b93c3f2..e7e96b7d 100644 --- a/components/layout/SideNav.js +++ b/components/layout/SideNav.js @@ -4,7 +4,7 @@ import { useRouter } from 'next/router'; import Link from 'next/link'; import styles from './SideNav.module.css'; -export default function SideNav({ selectedKey, items, shallow, onSelect = () => {} }) { +export function SideNav({ selectedKey, items, shallow, onSelect = () => {} }) { const { asPath } = useRouter(); return ( @@ -21,3 +21,5 @@ export default function SideNav({ selectedKey, items, shallow, onSelect = () => ); } + +export default SideNav; diff --git a/components/messages.js b/components/messages.js index 3cdac3be..aa268225 100644 --- a/components/messages.js +++ b/components/messages.js @@ -62,6 +62,7 @@ export const labels = defineMessages({ queries: { id: 'label.queries', defaultMessage: 'Queries' }, teams: { id: 'label.teams', defaultMessage: 'Teams' }, analytics: { id: 'label.analytics', defaultMessage: 'Analytics' }, + login: { id: 'label.login', defaultMessage: 'Login' }, logout: { id: 'label.logout', defaultMessage: 'Logout' }, singleDay: { id: 'label.single-day', defaultMessage: 'Single day' }, dateRange: { id: 'label.date-range', defaultMessage: 'Date range' }, @@ -94,12 +95,12 @@ export const labels = defineMessages({ thisMonth: { id: 'label.this-month', defaultMessage: 'This month' }, thisYear: { id: 'label.this-year', defaultMessage: 'This year' }, allTime: { id: 'label.all-time', defaultMessage: 'All time' }, - customRange: { id: 'label.custom-range', defaultMessage: 'Custom-range' }, + customRange: { id: 'label.custom-range', defaultMessage: 'Custom range' }, selectWebsite: { id: 'label.select-website', defaultMessage: 'Select website' }, all: { id: 'label.all', defaultMessage: 'All' }, sessions: { id: 'label.sessions', defaultMessage: 'Sessions' }, pageNotFound: { id: 'message.page-not-found', defaultMessage: 'Page not found' }, - logs: { id: 'label.activity-log', defaultMessage: 'Activity log' }, + activityLog: { id: 'label.activity-log', defaultMessage: 'Activity log' }, dismiss: { id: 'label.dismiss', defaultMessage: 'Dismiss' }, poweredBy: { id: 'label.powered-by', defaultMessage: 'Powered by {name}' }, pageViews: { id: 'label.page-views', defaultMessage: 'Page views' }, diff --git a/components/metrics/ActiveUsers.js b/components/metrics/ActiveUsers.js index 96b67df3..e79b977d 100644 --- a/components/metrics/ActiveUsers.js +++ b/components/metrics/ActiveUsers.js @@ -4,7 +4,7 @@ import useApi from 'hooks/useApi'; import useMessages from 'hooks/useMessages'; import styles from './ActiveUsers.module.css'; -export default function ActiveUsers({ websiteId, value, refetchInterval = 60000 }) { +export function ActiveUsers({ websiteId, value, refetchInterval = 60000 }) { const { formatMessage, messages } = useMessages(); const { get, useQuery } = useApi(); const { data } = useQuery( @@ -34,3 +34,5 @@ export default function ActiveUsers({ websiteId, value, refetchInterval = 60000 ); } + +export default ActiveUsers; diff --git a/components/metrics/BarChart.js b/components/metrics/BarChart.js index 95f25a5e..cd7070e8 100644 --- a/components/metrics/BarChart.js +++ b/components/metrics/BarChart.js @@ -11,7 +11,7 @@ import useTheme from 'hooks/useTheme'; import { DEFAULT_ANIMATION_DURATION, THEME_COLORS } from 'lib/constants'; import styles from './BarChart.module.css'; -export default function BarChart({ +export function BarChart({ datasets, unit, animationDuration = DEFAULT_ANIMATION_DURATION, @@ -45,7 +45,7 @@ export default function BarChart({ switch (unit) { case 'minute': - return dateFormat(d, 'H:mm', locale); + return dateFormat(d, 'h:mm', locale); case 'hour': return dateFormat(d, 'p', locale); case 'day': @@ -177,15 +177,16 @@ export default function BarChart({ const updateChart = () => { setTooltip(null); + datasets.forEach((dataset, index) => { + chart.current.data.datasets[index].data = dataset.data; + chart.current.data.datasets[index].label = dataset.label; + }); + chart.current.options = getOptions(); - if (datasets.length) { - chart.current.data.datasets = datasets; - } + onUpdate(chart.current); chart.current.update(); - - onUpdate(chart.current); }; useEffect(() => { @@ -209,3 +210,5 @@ export default function BarChart({ ); } + +export default BarChart; diff --git a/components/metrics/BrowsersTable.js b/components/metrics/BrowsersTable.js index c205ca99..a8dd34ea 100644 --- a/components/metrics/BrowsersTable.js +++ b/components/metrics/BrowsersTable.js @@ -3,7 +3,7 @@ import MetricsTable from 'components/metrics/MetricsTable'; import { BROWSERS } from 'lib/constants'; import useMessages from 'hooks/useMessages'; -export default function BrowsersTable({ websiteId, ...props }) { +export function BrowsersTable({ websiteId, ...props }) { const { formatMessage, labels } = useMessages(); function renderLink({ x: browser }) { @@ -21,3 +21,5 @@ export default function BrowsersTable({ websiteId, ...props }) { /> ); } + +export default BrowsersTable; diff --git a/components/metrics/CitiesTable.js b/components/metrics/CitiesTable.js index 4aa61334..2e74780d 100644 --- a/components/metrics/CitiesTable.js +++ b/components/metrics/CitiesTable.js @@ -4,7 +4,7 @@ import FilterLink from 'components/common/FilterLink'; import useLocale from 'hooks/useLocale'; import useMessages from 'hooks/useMessages'; -export default function CitiesTable({ websiteId, ...props }) { +export function CitiesTable({ websiteId, ...props }) { const { locale } = useLocale(); const { formatMessage, labels } = useMessages(); @@ -28,3 +28,5 @@ export default function CitiesTable({ websiteId, ...props }) { /> ); } + +export default CitiesTable; diff --git a/components/metrics/CountriesTable.js b/components/metrics/CountriesTable.js index dcebe5e0..129512f8 100644 --- a/components/metrics/CountriesTable.js +++ b/components/metrics/CountriesTable.js @@ -4,7 +4,7 @@ import useCountryNames from 'hooks/useCountryNames'; import useLocale from 'hooks/useLocale'; import useMessages from 'hooks/useMessages'; -export default function CountriesTable({ websiteId, ...props }) { +export function CountriesTable({ websiteId, ...props }) { const { locale } = useLocale(); const countryNames = useCountryNames(locale); const { formatMessage, labels } = useMessages(); @@ -28,3 +28,5 @@ export default function CountriesTable({ websiteId, ...props }) { /> ); } + +export default CountriesTable; diff --git a/components/metrics/DataTable.js b/components/metrics/DataTable.js index 4a132780..086f98ae 100644 --- a/components/metrics/DataTable.js +++ b/components/metrics/DataTable.js @@ -3,13 +3,12 @@ import useMeasure from 'react-use-measure'; import { FixedSizeList } from 'react-window'; import { useSpring, animated, config } from 'react-spring'; import classNames from 'classnames'; -import { FormattedMessage } from 'react-intl'; import NoData from 'components/common/NoData'; import { formatNumber, formatLongNumber } from 'lib/format'; import styles from './DataTable.module.css'; import useMessages from '../../hooks/useMessages'; -export default function DataTable({ +export function DataTable({ data = [], title, metric, @@ -102,3 +101,5 @@ const AnimatedRow = ({ ); }; + +export default DataTable; diff --git a/components/metrics/DataTable.module.css b/components/metrics/DataTable.module.css index 070dca1f..c5b2bd7c 100644 --- a/components/metrics/DataTable.module.css +++ b/components/metrics/DataTable.module.css @@ -68,8 +68,8 @@ .value { width: 50px; - text-align: right; - margin-right: 10px; + text-align: end; + margin-inline-end: 10px; font-weight: 600; cursor: pointer; } @@ -79,7 +79,7 @@ width: 50px; color: var(--base600); border-left: 1px solid var(--base600); - padding-left: 10px; + padding-inline-start: 10px; z-index: 1; } diff --git a/components/metrics/DatePickerForm.js b/components/metrics/DatePickerForm.js index 1a6265b7..96730591 100644 --- a/components/metrics/DatePickerForm.js +++ b/components/metrics/DatePickerForm.js @@ -8,7 +8,7 @@ import { FILTER_DAY, FILTER_RANGE } from 'lib/constants'; import useMessages from 'hooks/useMessages'; import styles from './DatePickerForm.module.css'; -export default function DatePickerForm({ +export function DatePickerForm({ startDate: defaultStartDate, endDate: defaultEndDate, minDate, @@ -78,3 +78,5 @@ export default function DatePickerForm({ ); } + +export default DatePickerForm; diff --git a/components/metrics/DevicesTable.js b/components/metrics/DevicesTable.js index c877ab58..1bc3ac04 100644 --- a/components/metrics/DevicesTable.js +++ b/components/metrics/DevicesTable.js @@ -2,7 +2,7 @@ import MetricsTable from './MetricsTable'; import FilterLink from 'components/common/FilterLink'; import useMessages from 'hooks/useMessages'; -export default function DevicesTable({ websiteId, ...props }) { +export function DevicesTable({ websiteId, ...props }) { const { formatMessage, labels } = useMessages(); function renderLink({ x: device }) { @@ -26,3 +26,5 @@ export default function DevicesTable({ websiteId, ...props }) { /> ); } + +export default DevicesTable; diff --git a/components/metrics/EventsChart.js b/components/metrics/EventsChart.js index 1fc461bb..eb397cc9 100644 --- a/components/metrics/EventsChart.js +++ b/components/metrics/EventsChart.js @@ -9,7 +9,7 @@ import useTimezone from 'hooks/useTimezone'; import usePageQuery from 'hooks/usePageQuery'; import { EVENT_COLORS } from 'lib/constants'; -export default function EventsChart({ websiteId, className, token }) { +export function EventsChart({ websiteId, className, token }) { const { get, useQuery } = useApi(); const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId); const [timezone] = useTimezone(); @@ -76,3 +76,5 @@ export default function EventsChart({ websiteId, className, token }) { /> ); } + +export default EventsChart; diff --git a/components/metrics/EventsTable.js b/components/metrics/EventsTable.js index 3e09a856..eb23a281 100644 --- a/components/metrics/EventsTable.js +++ b/components/metrics/EventsTable.js @@ -1,7 +1,7 @@ import MetricsTable from './MetricsTable'; import useMessages from 'hooks/useMessages'; -export default function EventsTable({ websiteId, ...props }) { +export function EventsTable({ websiteId, ...props }) { const { formatMessage, labels } = useMessages(); function handleDataLoad(data) { @@ -19,3 +19,5 @@ export default function EventsTable({ websiteId, ...props }) { /> ); } + +export default EventsTable; diff --git a/components/metrics/FilterTags.js b/components/metrics/FilterTags.js index 96c00983..ad3ff60b 100644 --- a/components/metrics/FilterTags.js +++ b/components/metrics/FilterTags.js @@ -4,7 +4,7 @@ import usePageQuery from 'hooks/usePageQuery'; import styles from './FilterTags.module.css'; import useMessages from 'hooks/useMessages'; -export default function FilterTags({ params }) { +export function FilterTags({ params }) { const { formatMessage, labels } = useMessages(); const { router, @@ -50,3 +50,5 @@ export default function FilterTags({ params }) { ); } + +export default FilterTags; diff --git a/components/metrics/LanguagesTable.js b/components/metrics/LanguagesTable.js index b32fe2c8..e90a3425 100644 --- a/components/metrics/LanguagesTable.js +++ b/components/metrics/LanguagesTable.js @@ -4,7 +4,7 @@ import useLanguageNames from 'hooks/useLanguageNames'; import useLocale from 'hooks/useLocale'; import useMessages from 'hooks/useMessages'; -export default function LanguagesTable({ websiteId, onDataLoad, ...props }) { +export function LanguagesTable({ websiteId, onDataLoad, ...props }) { const { formatMessage, labels } = useMessages(); const { locale } = useLocale(); const languageNames = useLanguageNames(locale); @@ -25,3 +25,5 @@ export default function LanguagesTable({ websiteId, onDataLoad, ...props }) { /> ); } + +export default LanguagesTable; diff --git a/components/metrics/Legend.js b/components/metrics/Legend.js index 10848066..91135acb 100644 --- a/components/metrics/Legend.js +++ b/components/metrics/Legend.js @@ -6,7 +6,7 @@ import useLocale from 'hooks/useLocale'; import useForceUpdate from 'hooks/useForceUpdate'; import styles from './Legend.module.css'; -export default function Legend({ chart }) { +export function Legend({ chart }) { const { locale } = useLocale(); const forceUpdate = useForceUpdate(); @@ -48,3 +48,5 @@ export default function Legend({ chart }) { ); } + +export default Legend; diff --git a/components/metrics/Legend.module.css b/components/metrics/Legend.module.css index 5a005db2..dea515f3 100644 --- a/components/metrics/Legend.module.css +++ b/components/metrics/Legend.module.css @@ -13,7 +13,7 @@ } .label + .label { - margin-left: 20px; + margin-inline-start: 20px; } .hidden { diff --git a/components/metrics/MetricCard.js b/components/metrics/MetricCard.js index a49aeefc..8a1806c9 100644 --- a/components/metrics/MetricCard.js +++ b/components/metrics/MetricCard.js @@ -3,7 +3,7 @@ import { useSpring, animated } from 'react-spring'; import { formatNumber } from 'lib/format'; import styles from './MetricCard.module.css'; -const MetricCard = ({ +export const MetricCard = ({ value = 0, change = 0, label, diff --git a/components/metrics/MetricsBar.js b/components/metrics/MetricsBar.js index 1f218ba8..25b93115 100644 --- a/components/metrics/MetricsBar.js +++ b/components/metrics/MetricsBar.js @@ -9,7 +9,7 @@ import MetricCard from './MetricCard'; import useMessages from 'hooks/useMessages'; import styles from './MetricsBar.module.css'; -export default function MetricsBar({ websiteId }) { +export function MetricsBar({ websiteId }) { const { formatMessage, labels } = useMessages(); const { get, useQuery } = useApi(); const [dateRange] = useDateRange(websiteId); @@ -111,3 +111,5 @@ export default function MetricsBar({ websiteId }) { ); } + +export default MetricsBar; diff --git a/components/metrics/MetricsTable.js b/components/metrics/MetricsTable.js index 0d83fc22..97deb39d 100644 --- a/components/metrics/MetricsTable.js +++ b/components/metrics/MetricsTable.js @@ -13,8 +13,9 @@ import { DEFAULT_ANIMATION_DURATION } from 'lib/constants'; import Icons from 'components/icons'; import useMessages from 'hooks/useMessages'; import styles from './MetricsTable.module.css'; +import useLocale from 'hooks/useLocale'; -export default function MetricsTable({ +export function MetricsTable({ websiteId, type, className, @@ -69,6 +70,7 @@ export default function MetricsTable({ } return []; }, [data, error, dataFilter, filterOptions]); + const { dir } = useLocale(); return (
@@ -80,7 +82,7 @@ export default function MetricsTable({ @@ -90,3 +92,5 @@ export default function MetricsTable({
); } + +export default MetricsTable; diff --git a/components/metrics/OSTable.js b/components/metrics/OSTable.js index 6269a94b..a638038b 100644 --- a/components/metrics/OSTable.js +++ b/components/metrics/OSTable.js @@ -2,7 +2,7 @@ import MetricsTable from './MetricsTable'; import FilterLink from 'components/common/FilterLink'; import useMessages from 'hooks/useMessages'; -export default function OSTable({ websiteId, ...props }) { +export function OSTable({ websiteId, ...props }) { const { formatMessage, labels } = useMessages(); function renderLink({ x: os }) { @@ -20,3 +20,5 @@ export default function OSTable({ websiteId, ...props }) { /> ); } + +export default OSTable; diff --git a/components/metrics/PagesTable.js b/components/metrics/PagesTable.js index 525bbc6e..47e70318 100644 --- a/components/metrics/PagesTable.js +++ b/components/metrics/PagesTable.js @@ -5,7 +5,7 @@ import useMessages from 'hooks/useMessages'; import usePageQuery from 'hooks/usePageQuery'; import { emptyFilter } from 'lib/filters'; -export default function PagesTable({ websiteId, showFilters, ...props }) { +export function PagesTable({ websiteId, showFilters, ...props }) { const { router, resolveUrl, @@ -47,3 +47,5 @@ export default function PagesTable({ websiteId, showFilters, ...props }) { ); } + +export default PagesTable; diff --git a/components/metrics/PageviewsChart.js b/components/metrics/PageviewsChart.js index 7370e5f9..6ea16226 100644 --- a/components/metrics/PageviewsChart.js +++ b/components/metrics/PageviewsChart.js @@ -6,15 +6,7 @@ import useTheme from 'hooks/useTheme'; import useMessages from 'hooks/useMessages'; import useLocale from 'hooks/useLocale'; -export default function PageviewsChart({ - websiteId, - data, - unit, - records, - className, - loading, - ...props -}) { +export function PageviewsChart({ websiteId, data, unit, records, className, loading, ...props }) { const { formatMessage, labels } = useMessages(); const [theme] = useTheme(); const { locale } = useLocale(); @@ -68,3 +60,5 @@ export default function PageviewsChart({ /> ); } + +export default PageviewsChart; diff --git a/components/metrics/QueryParametersTable.js b/components/metrics/QueryParametersTable.js index 9d4c1d2d..c5f573e3 100644 --- a/components/metrics/QueryParametersTable.js +++ b/components/metrics/QueryParametersTable.js @@ -12,7 +12,7 @@ const filters = { [FILTER_COMBINED]: paramFilter, }; -export default function QueryParametersTable({ websiteId, showFilters, ...props }) { +export function QueryParametersTable({ websiteId, showFilters, ...props }) { const [filter, setFilter] = useState(FILTER_COMBINED); const { formatMessage, labels } = useMessages(); @@ -49,3 +49,5 @@ export default function QueryParametersTable({ websiteId, showFilters, ...props ); } + +export default QueryParametersTable; diff --git a/components/metrics/RealtimeChart.js b/components/metrics/RealtimeChart.js index 05da3cec..07d73a7f 100644 --- a/components/metrics/RealtimeChart.js +++ b/components/metrics/RealtimeChart.js @@ -23,7 +23,7 @@ function mapData(data) { return arr; } -export default function RealtimeChart({ data, unit, ...props }) { +export function RealtimeChart({ data, unit, ...props }) { const endDate = startOfMinute(new Date()); const startDate = subMinutes(endDate, REALTIME_RANGE); const prevEndDate = useRef(endDate); @@ -58,3 +58,5 @@ export default function RealtimeChart({ data, unit, ...props }) { /> ); } + +export default RealtimeChart; diff --git a/components/metrics/ReferrersTable.js b/components/metrics/ReferrersTable.js index 810541b4..3cdcb02f 100644 --- a/components/metrics/ReferrersTable.js +++ b/components/metrics/ReferrersTable.js @@ -2,7 +2,7 @@ import MetricsTable from './MetricsTable'; import FilterLink from 'components/common/FilterLink'; import useMessages from 'hooks/useMessages'; -export default function ReferrersTable({ websiteId, ...props }) { +export function ReferrersTable({ websiteId, ...props }) { const { formatMessage, labels } = useMessages(); const renderLink = ({ x: referrer }) => { @@ -29,3 +29,5 @@ export default function ReferrersTable({ websiteId, ...props }) { ); } + +export default ReferrersTable; diff --git a/components/metrics/RegionsTable.js b/components/metrics/RegionsTable.js index 87a15b40..fe4d5b91 100644 --- a/components/metrics/RegionsTable.js +++ b/components/metrics/RegionsTable.js @@ -3,19 +3,25 @@ import { emptyFilter } from 'lib/filters'; import FilterLink from 'components/common/FilterLink'; import useLocale from 'hooks/useLocale'; import useMessages from 'hooks/useMessages'; +import useCountryNames from 'hooks/useCountryNames'; import regions from 'public/iso-3166-2.json'; -export default function RegionsTable({ websiteId, ...props }) { +export function RegionsTable({ websiteId, ...props }) { const { locale } = useLocale(); const { formatMessage, labels } = useMessages(); + const countryNames = useCountryNames(locale); - function renderLink({ x }) { + const renderLabel = x => { + return regions[x] ? `${regions[x]}, ${countryNames[x.split('-')[0]]}` : x; + }; + + const renderLink = ({ x }) => { return (
- +
); - } + }; return ( ); } + +export default RegionsTable; diff --git a/components/metrics/ScreenTable.js b/components/metrics/ScreenTable.js index 35fe42d2..f8ef5f2e 100644 --- a/components/metrics/ScreenTable.js +++ b/components/metrics/ScreenTable.js @@ -1,7 +1,7 @@ import MetricsTable from './MetricsTable'; import useMessages from 'hooks/useMessages'; -export default function ScreenTable({ websiteId, ...props }) { +export function ScreenTable({ websiteId, ...props }) { const { formatMessage, labels } = useMessages(); return ( @@ -14,3 +14,5 @@ export default function ScreenTable({ websiteId, ...props }) { /> ); } + +export default ScreenTable; diff --git a/components/metrics/WebsiteChart.js b/components/metrics/WebsiteChart.js index cc27ac25..6614d40f 100644 --- a/components/metrics/WebsiteChart.js +++ b/components/metrics/WebsiteChart.js @@ -18,8 +18,9 @@ import Icons from 'components/icons'; import useSticky from 'hooks/useSticky'; import useMessages from 'hooks/useMessages'; import styles from './WebsiteChart.module.css'; +import useLocale from 'hooks/useLocale'; -export default function WebsiteChart({ +export function WebsiteChart({ websiteId, name, domain, @@ -72,6 +73,7 @@ export default function WebsiteChart({ return { pageviews: [], sessions: [] }; }, [data, modified]); + const { dir } = useLocale(); return ( <> @@ -80,7 +82,9 @@ export default function WebsiteChart({ @@ -124,3 +128,5 @@ export default function WebsiteChart({ ); } + +export default WebsiteChart; diff --git a/components/metrics/WebsiteHeader.js b/components/metrics/WebsiteHeader.js index 491068d6..de21c0c7 100644 --- a/components/metrics/WebsiteHeader.js +++ b/components/metrics/WebsiteHeader.js @@ -3,7 +3,7 @@ import Favicon from 'components/common/Favicon'; import ActiveUsers from './ActiveUsers'; import styles from './WebsiteHeader.module.css'; -export default function WebsiteHeader({ websiteId, name, domain, children }) { +export function WebsiteHeader({ websiteId, name, domain, children }) { return ( @@ -17,3 +17,5 @@ export default function WebsiteHeader({ websiteId, name, domain, children }) { ); } + +export default WebsiteHeader; diff --git a/components/pages/console/TestConsole.js b/components/pages/console/TestConsole.js index 685f5458..745bf94c 100644 --- a/components/pages/console/TestConsole.js +++ b/components/pages/console/TestConsole.js @@ -11,7 +11,7 @@ import Script from 'next/script'; import { Button, Column, Row } from 'react-basics'; import styles from './TestConsole.module.css'; -export default function TestConsole() { +export function TestConsole() { const { get, useQuery } = useApi(); const { data, isLoading, error } = useQuery(['websites:me'], () => get('/me/websites')); const router = useRouter(); @@ -132,3 +132,5 @@ export default function TestConsole() { ); } + +export default TestConsole; diff --git a/components/pages/dashboard/Dashboard.js b/components/pages/dashboard/Dashboard.js index 6497aba4..07921dae 100644 --- a/components/pages/dashboard/Dashboard.js +++ b/components/pages/dashboard/Dashboard.js @@ -10,8 +10,9 @@ import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import useApi from 'hooks/useApi'; import useDashboard from 'store/dashboard'; import useMessages from 'hooks/useMessages'; +import useLocale from 'hooks/useLocale'; -export default function Dashboard({ userId }) { +export function Dashboard({ userId }) { const { formatMessage, labels, messages } = useMessages(); const dashboard = useDashboard(); const { showCharts, limit, editing } = dashboard; @@ -19,6 +20,7 @@ export default function Dashboard({ userId }) { const { get, useQuery } = useApi(); const { data, isLoading, error } = useQuery(['websites'], () => get('/websites', { userId })); const hasData = data && data.length !== 0; + const { dir } = useLocale(); function handleMore() { setMax(max + limit); @@ -33,7 +35,7 @@ export default function Dashboard({ userId }) {