From 7f598fa84da3d65beddb3c1de10c62f69845b664 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Thu, 17 Sep 2020 00:17:11 -0700 Subject: [PATCH] Updated profile settings. Refactored locale saving. --- components/common/LanguageButton.js | 9 +++--- components/metrics/WebsiteChart.js | 2 ++ components/settings/ProfileSettings.js | 32 ++++++++++++++++++- .../settings/ProfileSettings.module.css | 3 ++ hooks/useDateRange.js | 12 ++++++- lib/web.js | 15 +++++++-- pages/_app.js | 11 ++----- redux/actions/app.js | 3 +- styles/index.css | 25 ++++++++------- 9 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 components/settings/ProfileSettings.module.css 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; }