diff --git a/components/common/LanguageButton.js b/components/common/LanguageButton.js
index 5565b45e..6fe7eb83 100644
--- a/components/common/LanguageButton.js
+++ b/components/common/LanguageButton.js
@@ -1,12 +1,13 @@
import React, { useState, useRef } from 'react';
import Head from 'next/head';
-import Globe from 'assets/globe.svg';
-import useDocumentClick from 'hooks/useDocumentClick';
import Menu from './Menu';
import Button from './Button';
import { menuOptions } from 'lib/lang';
+import { setItem } from 'lib/web';
+import useLocale from 'hooks/useLocale';
+import useDocumentClick from 'hooks/useDocumentClick';
+import Globe from 'assets/globe.svg';
import styles from './LanguageButton.module.css';
-import useLocale from '../../hooks/useLocale';
export default function LanguageButton({ menuPosition = 'bottom', menuAlign = 'left' }) {
const [showMenu, setShowMenu] = useState(false);
@@ -16,7 +17,7 @@ export default function LanguageButton({ menuPosition = 'bottom', menuAlign = 'l
function handleSelect(value) {
setLocale(value);
- window.localStorage.setItem('locale', value);
+ setItem('umami.locale', value);
setShowMenu(false);
}
diff --git a/components/metrics/WebsiteChart.js b/components/metrics/WebsiteChart.js
index 8cf01a5a..37c13f9f 100644
--- a/components/metrics/WebsiteChart.js
+++ b/components/metrics/WebsiteChart.js
@@ -23,6 +23,8 @@ export default function WebsiteChart({
const dateRange = useDateRange(websiteId);
const { startDate, endDate, unit, value, modified } = dateRange;
+ console.log({ websiteId, dateRange });
+
const { data } = useFetch(
`/api/website/${websiteId}/pageviews`,
{
diff --git a/components/settings/ProfileSettings.js b/components/settings/ProfileSettings.js
index 7c5444a7..4e82f192 100644
--- a/components/settings/ProfileSettings.js
+++ b/components/settings/ProfileSettings.js
@@ -1,24 +1,39 @@
import React, { useState } from 'react';
import { FormattedMessage } from 'react-intl';
-import { useSelector } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import PageHeader from 'components/layout/PageHeader';
import Button from 'components/common/Button';
import Modal from 'components/common/Modal';
import Toast from 'components/common/Toast';
import ChangePasswordForm from 'components/forms/ChangePasswordForm';
+import DateFilter from 'components/common/DateFilter';
import Dots from 'assets/ellipsis-h.svg';
+import { getTimezone } from 'lib/date';
+import { setItem } from 'lib/web';
+import { useDateRange } from 'hooks/useDateRange';
+import { setDateRange } from 'redux/actions/websites';
+import styles from './ProfileSettings.module.css';
export default function ProfileSettings() {
+ const dispatch = useDispatch();
const user = useSelector(state => state.user);
const [changePassword, setChangePassword] = useState(false);
const [message, setMessage] = useState();
const { user_id } = user;
+ const timezone = getTimezone();
+ const dateRange = useDateRange(0);
+ const { startDate, endDate, value } = dateRange;
function handleSave() {
setChangePassword(false);
setMessage();
}
+ function handleDateChange(values) {
+ setItem(`umami.date-range`, values);
+ dispatch(setDateRange(0, values));
+ }
+
return (
<>
@@ -36,6 +51,21 @@ export default function ProfileSettings() {
{user.username}
+
+
+
+ {timezone}
+
+
+
+
+
+
{changePassword && (
state.websites[websiteId]?.dateRange || getDateRange(defaultDateRange),
+ state =>
+ state.websites[websiteId]?.dateRange || globalDefault || getDateRange(defaultDateRange),
);
}
diff --git a/lib/web.js b/lib/web.js
index 4a8578f1..4081b3ab 100644
--- a/lib/web.js
+++ b/lib/web.js
@@ -19,7 +19,7 @@ export const apiRequest = (method, url, body) =>
return null;
});
-function parseQuery(url, params = {}) {
+const parseQuery = (url, params = {}) => {
const query = Object.keys(params).reduce((values, key) => {
if (params[key] !== undefined) {
return values.concat(`${key}=${encodeURIComponent(params[key])}`);
@@ -27,7 +27,7 @@ function parseQuery(url, params = {}) {
return values;
}, []);
return query.length ? `${url}?${query.join('&')}` : url;
-}
+};
export const get = (url, params) => apiRequest('get', parseQuery(url, params));
@@ -62,3 +62,14 @@ export const doNotTrack = () => {
return dnt === true || dnt === 1 || dnt === 'yes' || dnt === '1';
};
+
+export const setItem = (key, data, session) => {
+ if (typeof window !== 'undefined') {
+ (session ? sessionStorage : localStorage).setItem(key, JSON.stringify(data));
+ }
+};
+
+export const getItem = (key, session) =>
+ typeof window !== 'undefined'
+ ? JSON.parse((session ? sessionStorage : localStorage).getItem(key))
+ : null;
diff --git a/pages/_app.js b/pages/_app.js
index 694049d4..9aad4339 100644
--- a/pages/_app.js
+++ b/pages/_app.js
@@ -1,4 +1,4 @@
-import React, { useEffect } from 'react';
+import React from 'react';
import { IntlProvider } from 'react-intl';
import { Provider } from 'react-redux';
import { useStore } from 'redux/store';
@@ -9,17 +9,10 @@ import 'styles/bootstrap-grid.css';
import 'styles/index.css';
const Intl = ({ children }) => {
- const [locale, setLocale] = useLocale();
+ const [locale] = useLocale();
const Wrapper = ({ children }) => {children};
- useEffect(() => {
- const saved = localStorage.getItem('locale');
- if (saved) {
- setLocale(saved);
- }
- });
-
return (
{children}
diff --git a/redux/actions/app.js b/redux/actions/app.js
index a74272a5..72636a74 100644
--- a/redux/actions/app.js
+++ b/redux/actions/app.js
@@ -1,8 +1,9 @@
import { createSlice } from '@reduxjs/toolkit';
+import { getItem } from 'lib/web';
const app = createSlice({
name: 'app',
- initialState: { locale: 'en-US' },
+ initialState: { locale: getItem('umami.locale') || 'en-US' },
reducers: {
updateApp(state, action) {
state = action.payload;
diff --git a/styles/index.css b/styles/index.css
index 5435364f..c305f70f 100644
--- a/styles/index.css
+++ b/styles/index.css
@@ -36,17 +36,6 @@ h6 {
font-weight: 400;
}
-#__next {
- display: flex;
- flex-direction: column;
- width: 100%;
- height: 100%;
-}
-
-#__modals {
- z-index: 10;
-}
-
button,
input,
select {
@@ -87,16 +76,28 @@ label:empty {
dt {
font-weight: 600;
+ margin: 0 0 5px 0;
}
dd {
- margin: 0 0 10px 0;
+ margin: 0 0 30px 0;
}
main {
flex: 1;
}
+#__next {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ height: 100%;
+}
+
+#__modals {
+ z-index: 10;
+}
+
.container {
padding: 0;
}