From 9b850c0e21077e207a5d375a41d03d6b9c71b553 Mon Sep 17 00:00:00 2001 From: 0xflotus <0xflotus@gmail.com> Date: Thu, 17 Feb 2022 11:45:05 +0100 Subject: [PATCH 01/31] chore: changed value in de_DE.json For unified naming purposes, I changed the value from 'Website' to 'Webseite'. This term was used multiple times before. --- lang/de-DE.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/de-DE.json b/lang/de-DE.json index 2cad633a..f6f645a7 100644 --- a/lang/de-DE.json +++ b/lang/de-DE.json @@ -76,7 +76,7 @@ "message.no-websites-configured": "Es ist keine Webseite vorhanden.", "message.page-not-found": "Seite nicht gefunden.", "message.powered-by": "Betrieben durch {name}", - "message.reset-warning": "Alle Daten für diese Website werden gelöscht, jedoch bleibt der tracking code bestehen.", + "message.reset-warning": "Alle Daten für diese Webseite werden gelöscht, jedoch bleibt der Tracking Code bestehen.", "message.save-success": "Erfolgreich gespeichert.", "message.share-url": "Dies ist die öffentliche URL zum Teilen für {target}.", "message.toggle-charts": "Schaubilder umschalten", From dec3d49ab1c360fdf6178c7ca6b1431e627ec0c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Feb 2022 02:39:57 +0000 Subject: [PATCH 02/31] build(deps): bump next from 12.0.10 to 12.1.0 Bumps [next](https://github.com/vercel/next.js) from 12.0.10 to 12.1.0. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v12.0.10...v12.1.0) --- updated-dependencies: - dependency-name: next dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 151 ++++++++++++++++++++++----------------------------- 2 files changed, 67 insertions(+), 86 deletions(-) diff --git a/package.json b/package.json index 47f45047..8a05870d 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "jose": "2.0.5", "maxmind": "^4.3.2", "moment-timezone": "^0.5.33", - "next": "12.0.10", + "next": "12.1.0", "prompts": "2.4.2", "prop-types": "^15.7.2", "react": "^17.0.2", diff --git a/yarn.lock b/yarn.lock index 0d6921e2..720bdd8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1480,10 +1480,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== -"@next/env@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/env/-/env-12.0.10.tgz#561640fd62279218ccd2798ae907bae8d94a7730" - integrity sha512-mQVj0K6wQ5WEk/sL9SZ+mJXJUaG7el8CpZ6io1uFe9GgNTSC7EgUyNGqM6IQovIFc5ukF4O/hqsdh3S/DCgT2g== +"@next/env@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" + integrity sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ== "@next/eslint-plugin-next@12.0.1": version "12.0.1" @@ -1492,60 +1492,60 @@ dependencies: glob "7.1.7" -"@next/swc-android-arm64@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.0.10.tgz#fd9d716433cc9d361021b0052f8b002bcaff948d" - integrity sha512-xYwXGkNhzZZsM5MD7KRwF5ZNiC8OLPtVMUiagpPnwENg8Hb0GSQo/NbYWXM8YrawEwp9LaZ7OXiuRKPh2JyBdA== +"@next/swc-android-arm64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz#865ba3a9afc204ff2bdeea49dd64d58705007a39" + integrity sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA== -"@next/swc-darwin-arm64@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.0.10.tgz#34b2d0dc62eb89efb9176af111e3820a11fdb3f0" - integrity sha512-f2zngulkpIJKWHckhRi7X8GZ+J/tNgFF7lYIh7Qx15JH0OTBsjkqxORlkzy+VZyHJ5sWTCaI6HYYd3ow6qkEEg== +"@next/swc-darwin-arm64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz#08e8b411b8accd095009ed12efbc2f1d4d547135" + integrity sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg== -"@next/swc-darwin-x64@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.0.10.tgz#a4306795159293c7d4d58a2c88ce1710ff0a8baa" - integrity sha512-Qykcu/gVC5oTvOQoRBhyuS5GYm5SbcgrFTsaLFkGBmEkg9eMQRiaCswk4IafpDXVzITkVFurzSM28q3tLW2qUw== +"@next/swc-darwin-x64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz#fcd684497a76e8feaca88db3c394480ff0b007cd" + integrity sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug== -"@next/swc-linux-arm-gnueabihf@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.0.10.tgz#1ad15af3d5fca2fef57894d61e16f73aee61ec2e" - integrity sha512-EhqrTFsIXAXN9B/fiiW/QKUK/lSLCXRsLalkUp58KDfMqVLLlj1ORbESAcswiNQOChLuHQSldGEEtOBPQZcd9A== +"@next/swc-linux-arm-gnueabihf@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz#9ec6380a27938a5799aaa6035c205b3c478468a7" + integrity sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog== -"@next/swc-linux-arm64-gnu@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.0.10.tgz#a84a92d0e1a179c4346c9ed8f22e26f708101ad6" - integrity sha512-kqGtC72g3+JYXZbY2ca6digXR5U6AQ6Dzv4eAxYluMePLHjI/Xye1mf9dwVsgmeXfrD/IRDp5K/3A6UNvBm4oQ== +"@next/swc-linux-arm64-gnu@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz#7f4196dff1049cea479607c75b81033ae2dbd093" + integrity sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q== -"@next/swc-linux-arm64-musl@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.0.10.tgz#973ec96c77f845bd0a6eecbf1892caa1ee4defaf" - integrity sha512-bG9zTSNwnSgc1Un/7oz1ZVN4UeXsTWrsQhAGWU78lLLCn4Zj9HQoUCRCGLt0OVs2DBZ+WC8CzzFliQ1SKipVbg== +"@next/swc-linux-arm64-musl@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz#b445f767569cdc2dddee785ca495e1a88c025566" + integrity sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA== -"@next/swc-linux-x64-gnu@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.0.10.tgz#efcc7f8252ea8225834760eaf09350f1bead73f7" - integrity sha512-c79PcfWtyThiYRa1+3KVfDq0zXaI8o1d6dQWNVqDrtLz5HKM/rbjLdvoNuxDwUeZhxI/d9CtyH6GbuKPw5l/5A== +"@next/swc-linux-x64-gnu@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz#67610e9be4fbc987de7535f1bcb17e45fe12f90e" + integrity sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A== -"@next/swc-linux-x64-musl@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.0.10.tgz#c2a73d939dfd310acc1892a0a132762500dd5757" - integrity sha512-g/scgn+21/MLfizOCZOZt+MxNj2/8Tdlwjvy+QZcSUPZRUI2Y5o3HwBvI1f/bSci+NGRU+bUAO0NFtRJ9MzH5w== +"@next/swc-linux-x64-musl@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz#ea19a23db08a9f2e34ac30401f774cf7d1669d31" + integrity sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw== -"@next/swc-win32-arm64-msvc@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.0.10.tgz#2316af5f612cde1691abdf2571ff40ec32ea3429" - integrity sha512-gl6B/ravwMeY5Nv4Il2/ARYJQ6u+KPRwGMjS1ZrNudIKlNn4YBeXh5A4cIVm+dHaff6/O/lGOa5/SUYDMZpkww== +"@next/swc-win32-arm64-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz#eadf054fc412085659b98e145435bbba200b5283" + integrity sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw== -"@next/swc-win32-ia32-msvc@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.0.10.tgz#98a4f74d164871cfaccb0df6efddf2b7bcbaa54b" - integrity sha512-7RVpZ3tSThC6j+iZB0CUYmFiA3kXmN+pE7QcfyAxFaflKlaZoWNMKHIEZDuxSJc6YmQ6kyxsjqxVay2F5+/YCg== +"@next/swc-win32-ia32-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz#68faeae10c89f698bf9d28759172b74c9c21bda1" + integrity sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q== -"@next/swc-win32-x64-msvc@12.0.10": - version "12.0.10" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.0.10.tgz#5c0ba98b695c4be44d8793aff42971a0dac65c2d" - integrity sha512-oUIWRKd24jFLRWUYO1CZmML5+32BcpVfqhimGaaZIXcOkfQW+iqiAzdqsv688zaGtyKGeB9ZtiK3NDf+Q0v+Vw== +"@next/swc-win32-x64-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz#d27e7e76c87a460a4da99c5bfdb1618dcd6cd064" + integrity sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -2468,12 +2468,7 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001280: - version "1.0.30001282" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz#38c781ee0a90ccfe1fe7fefd00e43f5ffdcb96fd" - integrity sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg== - -caniuse-lite@^1.0.30001283: +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001280, caniuse-lite@^1.0.30001283: version "1.0.30001301" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz#ebc9086026534cab0dab99425d9c3b4425e5f450" integrity sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA== @@ -5003,28 +4998,28 @@ next-tick@~1.0.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= -next@12.0.10: - version "12.0.10" - resolved "https://registry.yarnpkg.com/next/-/next-12.0.10.tgz#fcc4584177418bd777ce157f3165b7ba5e7708f7" - integrity sha512-1y3PpGzpb/EZzz1jgne+JfZXKAVJUjYXwxzrADf/LWN+8yi9o79vMLXpW3mevvCHkEF2sBnIdjzNn16TJrINUw== +next@12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/next/-/next-12.1.0.tgz#c33d753b644be92fc58e06e5a214f143da61dd5d" + integrity sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q== dependencies: - "@next/env" "12.0.10" + "@next/env" "12.1.0" caniuse-lite "^1.0.30001283" postcss "8.4.5" styled-jsx "5.0.0" use-subscription "1.5.1" optionalDependencies: - "@next/swc-android-arm64" "12.0.10" - "@next/swc-darwin-arm64" "12.0.10" - "@next/swc-darwin-x64" "12.0.10" - "@next/swc-linux-arm-gnueabihf" "12.0.10" - "@next/swc-linux-arm64-gnu" "12.0.10" - "@next/swc-linux-arm64-musl" "12.0.10" - "@next/swc-linux-x64-gnu" "12.0.10" - "@next/swc-linux-x64-musl" "12.0.10" - "@next/swc-win32-arm64-msvc" "12.0.10" - "@next/swc-win32-ia32-msvc" "12.0.10" - "@next/swc-win32-x64-msvc" "12.0.10" + "@next/swc-android-arm64" "12.1.0" + "@next/swc-darwin-arm64" "12.1.0" + "@next/swc-darwin-x64" "12.1.0" + "@next/swc-linux-arm-gnueabihf" "12.1.0" + "@next/swc-linux-arm64-gnu" "12.1.0" + "@next/swc-linux-arm64-musl" "12.1.0" + "@next/swc-linux-x64-gnu" "12.1.0" + "@next/swc-linux-x64-musl" "12.1.0" + "@next/swc-win32-arm64-msvc" "12.1.0" + "@next/swc-win32-ia32-msvc" "12.1.0" + "@next/swc-win32-x64-msvc" "12.1.0" nice-try@^1.0.4: version "1.0.5" @@ -5783,7 +5778,7 @@ postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: indexes-of "^1.0.1" uniq "^1.0.1" -postcss@8.4.5: +postcss@8.4.5, postcss@^8.1.10, postcss@^8.2.15, postcss@^8.2.4: version "8.4.5" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== @@ -5800,15 +5795,6 @@ postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0. picocolors "^0.2.1" source-map "^0.6.1" -postcss@^8.1.10, postcss@^8.2.15, postcss@^8.2.4: - version "8.3.11" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858" - integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA== - dependencies: - nanoid "^3.1.30" - picocolors "^1.0.0" - source-map-js "^0.6.2" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -6497,11 +6483,6 @@ sort-keys@^4.0.0: dependencies: is-plain-obj "^2.0.0" -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - source-map-js@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" From 460762bf3d11b6e3938fa1270e807bc43a8f75a4 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Fri, 18 Feb 2022 20:00:21 -0800 Subject: [PATCH 03/31] Use rewrites for tracker script name, closes #972 --- Dockerfile | 7 +++++-- next.config.js | 17 ++++++++++++----- rollup.tracker.config.js | 4 +--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index e66ec5d5..ee931167 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,9 +2,12 @@ FROM node:12.22-alpine AS build ARG BASE_PATH ARG DATABASE_TYPE +ARG TRACKER_SCRIPT_NAME + ENV BASE_PATH=$BASE_PATH -ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami" \ - DATABASE_TYPE=$DATABASE_TYPE +ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami" +ENV DATABASE_TYPE=$DATABASE_TYPE +ENV TRACKER_SCRIPT_NAME=$TRACKER_SCRIPT_NAME WORKDIR /build RUN yarn config set --home enableTelemetry 0 diff --git a/next.config.js b/next.config.js index dd8bfba0..8387e9ac 100644 --- a/next.config.js +++ b/next.config.js @@ -1,14 +1,16 @@ require('dotenv').config(); const pkg = require('./package.json'); +const { BASE_PATH, FORCE_SSL, DISABLE_LOGIN, TRACKER_SCRIPT_NAME } = process.env; + module.exports = { env: { VERSION: pkg.version, - FORCE_SSL: !!process.env.FORCE_SSL, - DISABLE_LOGIN: !!process.env.DISABLE_LOGIN, - TRACKER_SCRIPT_NAME: process.env.TRACKER_SCRIPT_NAME, + FORCE_SSL: Boolean(FORCE_SSL), + DISABLE_LOGIN: Boolean(DISABLE_LOGIN), + TRACKER_SCRIPT_NAME, }, - basePath: process.env.BASE_PATH, + basePath: BASE_PATH, eslint: { ignoreDuringBuilds: true, }, @@ -21,10 +23,15 @@ module.exports = { return config; }, + async rewrites() { + return TRACKER_SCRIPT_NAME + ? [{ source: `/${TRACKER_SCRIPT_NAME}.js`, destination: '/umami.js' }] + : []; + }, async headers() { return [ { - source: '/umami.js', + source: `/${TRACKER_SCRIPT_NAME || 'umami'}.js`, headers: [ { key: 'Cache-Control', diff --git a/rollup.tracker.config.js b/rollup.tracker.config.js index 169f71fd..5d2938ee 100644 --- a/rollup.tracker.config.js +++ b/rollup.tracker.config.js @@ -3,12 +3,10 @@ import buble from '@rollup/plugin-buble'; import resolve from '@rollup/plugin-node-resolve'; import { terser } from 'rollup-plugin-terser'; -const scriptName = process.env.TRACKER_SCRIPT_NAME || 'umami'; - export default { input: 'tracker/index.js', output: { - file: `public/${scriptName}.js`, + file: 'public/umami.js', format: 'iife', }, plugins: [resolve(), buble({ objectAssign: true }), terser({ compress: { evaluate: false } })], From 736347d37cd1c6cd63ded6a1daafa3b6431ebee2 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Fri, 18 Feb 2022 21:30:41 -0800 Subject: [PATCH 04/31] Don't destructure process.env. --- next.config.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/next.config.js b/next.config.js index 8387e9ac..71cb9b20 100644 --- a/next.config.js +++ b/next.config.js @@ -1,16 +1,16 @@ require('dotenv').config(); const pkg = require('./package.json'); -const { BASE_PATH, FORCE_SSL, DISABLE_LOGIN, TRACKER_SCRIPT_NAME } = process.env; +const scriptName = process.env.TRACKER_SCRIPT_NAME; module.exports = { env: { VERSION: pkg.version, - FORCE_SSL: Boolean(FORCE_SSL), - DISABLE_LOGIN: Boolean(DISABLE_LOGIN), - TRACKER_SCRIPT_NAME, + FORCE_SSL: Boolean(process.env.FORCE_SSL), + DISABLE_LOGIN: Boolean(process.env.DISABLE_LOGIN), + TRACKER_SCRIPT_NAME: scriptName, }, - basePath: BASE_PATH, + basePath: process.env.BASE_PATH, eslint: { ignoreDuringBuilds: true, }, @@ -24,14 +24,12 @@ module.exports = { return config; }, async rewrites() { - return TRACKER_SCRIPT_NAME - ? [{ source: `/${TRACKER_SCRIPT_NAME}.js`, destination: '/umami.js' }] - : []; + return scriptName ? [{ source: `/${scriptName}.js`, destination: '/umami.js' }] : []; }, async headers() { return [ { - source: `/${TRACKER_SCRIPT_NAME || 'umami'}.js`, + source: `/${scriptName || 'umami'}.js`, headers: [ { key: 'Cache-Control', From f18491a818904fb22969dca8bf9637297dac0b7a Mon Sep 17 00:00:00 2001 From: "sur.la.route" Date: Sat, 19 Feb 2022 17:15:44 -0600 Subject: [PATCH 05/31] add netlify.toml for part of #731 Netlify next functions plugin is no longer copying in the build files. This adds the db file from the build into the functions. --- netlify.toml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 netlify.toml diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 00000000..c7168738 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,2 @@ +[functions] +included_files = ["public/geo/*.mmdb"] From 07e782ca393503b56edbd8ac55a5a43ee6dbaf4f Mon Sep 17 00:00:00 2001 From: Sophia Willows <20146550+sophiabits@users.noreply.github.com> Date: Sun, 20 Feb 2022 14:08:43 +1300 Subject: [PATCH 06/31] Truncate text in domain & name columns of website settings table when text content doesn't fit within the cell. --- components/common/OverflowText.js | 66 +++++++++++++++++++ components/common/OverflowText.module.css | 6 ++ components/settings/WebsiteSettings.js | 15 ++++- .../settings/WebsiteSettings.module.css | 4 ++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 components/common/OverflowText.js create mode 100644 components/common/OverflowText.module.css diff --git a/components/common/OverflowText.js b/components/common/OverflowText.js new file mode 100644 index 00000000..d67c4923 --- /dev/null +++ b/components/common/OverflowText.js @@ -0,0 +1,66 @@ +import PropTypes from 'prop-types'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import ReactTooltip from 'react-tooltip'; + +import styles from './OverflowText.module.css'; + +const OverflowText = ({ children, tooltipId }) => { + const measureEl = useRef(); + const [isOverflown, setIsOverflown] = useState(false); + + const measure = useCallback( + el => { + if (!el) return; + setIsOverflown(el.scrollWidth > el.clientWidth); + }, + [setIsOverflown], + ); + + // Do one measure on mount + useEffect(() => { + measure(measureEl.current); + }, [measure]); + + // Set up resize listener for subsequent measures + useEffect(() => { + if (!measureEl.current) return; + + // Destructure ref in case it changes out from under us + const el = measureEl.current; + + if ('ResizeObserver' in global) { + // Ideally, we have access to ResizeObservers + const observer = new ResizeObserver(() => { + measure(el); + }); + observer.observe(el); + return () => observer.unobserve(el); + } else { + // Otherwise, fall back to measuring on window resizes + const handler = () => measure(el); + + window.addEventListener('resize', handler, { passive: true }); + return () => window.removeEventListener('resize', handler, { passive: true }); + } + }); + + return ( + + {children} + {isOverflown && {children}} + + ); +}; + +OverflowText.propTypes = { + children: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, + tooltipId: PropTypes.string.isRequired, +}; + +export default OverflowText; diff --git a/components/common/OverflowText.module.css b/components/common/OverflowText.module.css new file mode 100644 index 00000000..c2066631 --- /dev/null +++ b/components/common/OverflowText.module.css @@ -0,0 +1,6 @@ +.root { + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/components/settings/WebsiteSettings.js b/components/settings/WebsiteSettings.js index 998df40e..8d61f8ae 100644 --- a/components/settings/WebsiteSettings.js +++ b/components/settings/WebsiteSettings.js @@ -5,6 +5,7 @@ import classNames from 'classnames'; import Link from 'components/common/Link'; import Table from 'components/common/Table'; import Button from 'components/common/Button'; +import OverflowText from 'components/common/OverflowText'; import PageHeader from 'components/layout/PageHeader'; import Modal from 'components/common/Modal'; import WebsiteEditForm from 'components/forms/WebsiteEditForm'; @@ -84,12 +85,20 @@ export default function WebsiteSettings() { ); const DetailsLink = ({ website_id, name, domain }) => ( - + - {name} + {name} ); + const Domain = ({ domain, website_id }) => ( + {domain} + ); + const adminColumns = [ { key: 'name', @@ -101,6 +110,7 @@ export default function WebsiteSettings() { key: 'domain', label: , className: 'col-4 col-xl-3', + render: Domain, }, { key: 'account', @@ -125,6 +135,7 @@ export default function WebsiteSettings() { key: 'domain', label: , className: 'col-6 col-xl-4', + render: Domain, }, { key: 'action', diff --git a/components/settings/WebsiteSettings.module.css b/components/settings/WebsiteSettings.module.css index 444235b3..6ecb34c7 100644 --- a/components/settings/WebsiteSettings.module.css +++ b/components/settings/WebsiteSettings.module.css @@ -5,3 +5,7 @@ .buttons { justify-content: flex-end; } + +.detailLink { + width: 100%; +} From ef3f08788f54a6d6bf9da70c1fe0044790d5a98f Mon Sep 17 00:00:00 2001 From: Sophia Willows <20146550+sophiabits@users.noreply.github.com> Date: Sun, 20 Feb 2022 14:25:33 +1300 Subject: [PATCH 07/31] Don't show metric change indicator when metric delta is 0 --- components/metrics/MetricCard.js | 1 - 1 file changed, 1 deletion(-) diff --git a/components/metrics/MetricCard.js b/components/metrics/MetricCard.js index 9b407f37..429a37d6 100644 --- a/components/metrics/MetricCard.js +++ b/components/metrics/MetricCard.js @@ -19,7 +19,6 @@ const MetricCard = ({ {props.x.interpolate(x => format(x))}
{label} - {~~change === 0 && !hideComparison && {format(0)}} {~~change !== 0 && !hideComparison && ( Date: Sun, 20 Feb 2022 14:32:54 +1300 Subject: [PATCH 08/31] Truncate website title on website list & website details pages --- components/metrics/WebsiteHeader.js | 15 ++++++++++----- components/metrics/WebsiteHeader.module.css | 8 ++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/components/metrics/WebsiteHeader.js b/components/metrics/WebsiteHeader.js index db68cd54..a4fb7df0 100644 --- a/components/metrics/WebsiteHeader.js +++ b/components/metrics/WebsiteHeader.js @@ -1,6 +1,7 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; import Link from 'components/common/Link'; +import OverflowText from 'components/common/OverflowText'; import PageHeader from 'components/layout/PageHeader'; import RefreshButton from 'components/common/RefreshButton'; import ButtonLayout from 'components/layout/ButtonLayout'; @@ -13,15 +14,19 @@ export default function WebsiteHeader({ websiteId, title, domain, showLink = fal const header = showLink ? ( <> - - {title} + + {title} ) : ( -
+ <> - {title} -
+ {title} + ); return ( diff --git a/components/metrics/WebsiteHeader.module.css b/components/metrics/WebsiteHeader.module.css index 5b5876c6..4c9670fa 100644 --- a/components/metrics/WebsiteHeader.module.css +++ b/components/metrics/WebsiteHeader.module.css @@ -2,6 +2,14 @@ color: var(--gray900); font-size: var(--font-size-large); line-height: var(--font-size-large); + align-items: center; + display: flex; + max-width: 100%; + overflow: hidden; +} + +.titleLink { + max-width: 100%; } .link { From 7270d9524004ca58854ec7b0eccbb5e30e2af5de Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Sun, 20 Feb 2022 23:27:50 -0800 Subject: [PATCH 09/31] Move environment variables to middleware. Closes #972. --- Dockerfile | 3 +- components/forms/TrackingCodeForm.js | 4 +-- hooks/useForceSSL.js | 14 --------- next.config.js | 10 +------ pages/_app.js | 2 -- pages/_middleware.js | 44 ++++++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 30 deletions(-) delete mode 100644 hooks/useForceSSL.js create mode 100644 pages/_middleware.js diff --git a/Dockerfile b/Dockerfile index ee931167..16dd9872 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,12 +2,11 @@ FROM node:12.22-alpine AS build ARG BASE_PATH ARG DATABASE_TYPE -ARG TRACKER_SCRIPT_NAME ENV BASE_PATH=$BASE_PATH ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami" ENV DATABASE_TYPE=$DATABASE_TYPE -ENV TRACKER_SCRIPT_NAME=$TRACKER_SCRIPT_NAME + WORKDIR /build RUN yarn config set --home enableTelemetry 0 diff --git a/components/forms/TrackingCodeForm.js b/components/forms/TrackingCodeForm.js index bfc6940d..fd679ab2 100644 --- a/components/forms/TrackingCodeForm.js +++ b/components/forms/TrackingCodeForm.js @@ -5,8 +5,6 @@ import Button from 'components/common/Button'; import FormLayout, { FormButtons, FormRow } from 'components/layout/FormLayout'; import CopyButton from 'components/common/CopyButton'; -const scriptName = process.env.TRACKER_SCRIPT_NAME || 'umami'; - export default function TrackingCodeForm({ values, onClose }) { const ref = useRef(); const { basePath } = useRouter(); @@ -26,7 +24,7 @@ export default function TrackingCodeForm({ values, onClose }) { rows={3} cols={60} spellCheck={false} - defaultValue={``} + defaultValue={``} readOnly /> diff --git a/hooks/useForceSSL.js b/hooks/useForceSSL.js deleted file mode 100644 index b9d95e19..00000000 --- a/hooks/useForceSSL.js +++ /dev/null @@ -1,14 +0,0 @@ -import { useEffect } from 'react'; -import { useRouter } from 'next/router'; - -export default function useForceSSL(enabled) { - const router = useRouter(); - - useEffect(() => { - if (enabled && typeof window !== 'undefined' && /^http:\/\//.test(location.href)) { - router.push(location.href.replace(/^http:\/\//, 'https://')); - } - }, [enabled]); - - return null; -} diff --git a/next.config.js b/next.config.js index 71cb9b20..3ee8e699 100644 --- a/next.config.js +++ b/next.config.js @@ -1,14 +1,9 @@ require('dotenv').config(); const pkg = require('./package.json'); -const scriptName = process.env.TRACKER_SCRIPT_NAME; - module.exports = { env: { VERSION: pkg.version, - FORCE_SSL: Boolean(process.env.FORCE_SSL), - DISABLE_LOGIN: Boolean(process.env.DISABLE_LOGIN), - TRACKER_SCRIPT_NAME: scriptName, }, basePath: process.env.BASE_PATH, eslint: { @@ -23,13 +18,10 @@ module.exports = { return config; }, - async rewrites() { - return scriptName ? [{ source: `/${scriptName}.js`, destination: '/umami.js' }] : []; - }, async headers() { return [ { - source: `/${scriptName || 'umami'}.js`, + source: `/umami.js`, headers: [ { key: 'Cache-Control', diff --git a/pages/_app.js b/pages/_app.js index a4c4776c..72364786 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -5,7 +5,6 @@ import { IntlProvider } from 'react-intl'; import { Provider } from 'react-redux'; import { useStore } from 'redux/store'; import useLocale from 'hooks/useLocale'; -import useForceSSL from 'hooks/useForceSSL'; import 'styles/variables.css'; import 'styles/bootstrap-grid.css'; import 'styles/index.css'; @@ -25,7 +24,6 @@ const Intl = ({ children }) => { }; export default function App({ Component, pageProps }) { - useForceSSL(process.env.FORCE_SSL); const store = useStore(); const { basePath } = useRouter(); diff --git a/pages/_middleware.js b/pages/_middleware.js new file mode 100644 index 00000000..94d88360 --- /dev/null +++ b/pages/_middleware.js @@ -0,0 +1,44 @@ +import { NextResponse } from 'next/server'; + +function redirectHTTPS(req) { + if ( + process.env.FORCE_SSL && + !req.headers.get('host').includes('localhost') && + req.nextUrl.protocol !== 'https' + ) { + return NextResponse.redirect(`https://${req.headers.get('host')}${req.nextUrl.pathname}`, 301); + } +} + +function customScriptName(req) { + const scriptName = process.env.TRACKER_SCRIPT_NAME; + + if (scriptName) { + const url = req.nextUrl.clone(); + const { pathname } = url; + + if (pathname.endsWith(`/${scriptName}.js`)) { + url.pathname = '/umami.js'; + return NextResponse.rewrite(url); + } + } +} + +function disableLogin(req) { + if (process.env.DISABLE_LOGIN && req.nextUrl.pathname.endsWith('/login')) { + return new Response('403 Forbidden', { status: 403 }); + } +} + +export function middleware(req) { + const fns = [redirectHTTPS, customScriptName, disableLogin]; + + for (const fn of fns) { + const res = fn(req); + if (res) { + return res; + } + } + + return NextResponse.next(); +} From 7071f5fba52f410f365ab9d25055e6467246c390 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Tue, 22 Feb 2022 13:31:37 -0800 Subject: [PATCH 10/31] Updated messages. --- components/messages.js | 5 ++--- components/metrics/DevicesTable.js | 2 +- components/metrics/RealtimeLog.js | 11 +++-------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/components/messages.js b/components/messages.js index f6b589eb..1151752a 100644 --- a/components/messages.js +++ b/components/messages.js @@ -1,5 +1,4 @@ -import React from 'react'; -import { defineMessages, FormattedMessage } from 'react-intl'; +import { defineMessages } from 'react-intl'; export const labels = defineMessages({ unknown: { id: 'label.unknown', defaultMessage: 'Unknown' }, @@ -13,5 +12,5 @@ export const devices = defineMessages({ }); export function getDeviceMessage(device) { - return ; + return devices[device] || labels.unknown; } diff --git a/components/metrics/DevicesTable.js b/components/metrics/DevicesTable.js index 3073cf8b..d09774b9 100644 --- a/components/metrics/DevicesTable.js +++ b/components/metrics/DevicesTable.js @@ -11,7 +11,7 @@ export default function DevicesTable({ websiteId, ...props }) { type="device" metric={} websiteId={websiteId} - renderLabel={({ x }) => getDeviceMessage(x)} + renderLabel={({ x }) => } /> ); } diff --git a/components/metrics/RealtimeLog.js b/components/metrics/RealtimeLog.js index 01a2f972..f4e87834 100644 --- a/components/metrics/RealtimeLog.js +++ b/components/metrics/RealtimeLog.js @@ -7,7 +7,7 @@ import Tag from 'components/common/Tag'; import Dot from 'components/common/Dot'; import FilterButtons from 'components/common/FilterButtons'; import NoData from 'components/common/NoData'; -import { getDeviceMessage } from 'components/messages'; +import { getDeviceMessage, labels } from 'components/messages'; import useLocale from 'hooks/useLocale'; import useCountryNames from 'hooks/useCountryNames'; import { BROWSERS } from 'lib/constants'; @@ -129,15 +129,10 @@ export default function RealtimeLog({ data, websites, websiteId }) { id="message.log.visitor" defaultMessage="Visitor from {country} using {browser} on {os} {device}" values={{ - country: ( - - {countryNames[country] || - intl.formatMessage({ id: 'label.unknown', defaultMessage: 'Unknown' })} - - ), + country: {countryNames[country] || intl.formatMessage(labels.unknown)}, browser: {BROWSERS[browser]}, os: {os}, - device: {getDeviceMessage(device)}, + device: {intl.formatMessage(getDeviceMessage(device))}, }} /> ); From 9937caa5694428c72ace4212e56878e0750182f1 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Tue, 22 Feb 2022 22:47:59 -0800 Subject: [PATCH 11/31] Replaced redux with zustand. Fixed login issue, closes #980. --- components/common/RefreshButton.js | 12 ++-- components/forms/LoginForm.js | 9 ++- components/layout/Header.js | 4 +- components/pages/Settings.js | 12 ++-- components/pages/TestConsole.js | 4 +- components/settings/DateRangeSetting.js | 10 ++- components/settings/ProfileSettings.js | 13 ++-- components/settings/UserButton.js | 4 +- components/settings/WebsiteSettings.js | 4 +- hooks/useDateRange.js | 17 +++-- hooks/useFetch.js | 6 +- hooks/useLocale.js | 10 +-- hooks/useRequireLogin.js | 12 ++-- hooks/useShareToken.js | 10 +-- hooks/useTheme.js | 12 ++-- hooks/useUser.js | 9 +++ hooks/useVersion.js | 8 +-- lib/web.js | 10 ++- package.json | 5 +- pages/_app.js | 11 +--- pages/api/auth/login.js | 5 +- pages/logout.js | 14 ++-- redux/actions/app.js | 87 ------------------------- redux/actions/queries.js | 17 ----- redux/actions/user.js | 16 ----- redux/actions/websites.js | 29 --------- redux/reducers.js | 7 -- redux/store.js | 40 ------------ store/app.js | 30 +++++++++ store/queries.js | 9 +++ store/version.js | 54 +++++++++++++++ store/websites.js | 20 ++++++ yarn.lock | 10 +++ 33 files changed, 234 insertions(+), 286 deletions(-) create mode 100644 hooks/useUser.js delete mode 100644 redux/actions/app.js delete mode 100644 redux/actions/queries.js delete mode 100644 redux/actions/user.js delete mode 100644 redux/actions/websites.js delete mode 100644 redux/reducers.js delete mode 100644 redux/store.js create mode 100644 store/app.js create mode 100644 store/queries.js create mode 100644 store/version.js create mode 100644 store/websites.js diff --git a/components/common/RefreshButton.js b/components/common/RefreshButton.js index 1e3dd9e7..7f000a20 100644 --- a/components/common/RefreshButton.js +++ b/components/common/RefreshButton.js @@ -1,23 +1,23 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; -import { useDispatch, useSelector } from 'react-redux'; import { FormattedMessage } from 'react-intl'; -import { setDateRange } from 'redux/actions/websites'; +import useStore from 'store/queries'; +import { setDateRange } from 'store/websites'; import Button from './Button'; import Refresh from 'assets/redo.svg'; import Dots from 'assets/ellipsis-h.svg'; import useDateRange from 'hooks/useDateRange'; function RefreshButton({ websiteId }) { - const dispatch = useDispatch(); const [dateRange] = useDateRange(websiteId); const [loading, setLoading] = useState(false); - const completed = useSelector(state => state.queries[`/api/website/${websiteId}/stats`]); + const selector = useCallback(state => state[`/api/website/${websiteId}/stats`], [websiteId]); + const completed = useStore(selector); function handleClick() { if (dateRange) { setLoading(true); - dispatch(setDateRange(websiteId, dateRange)); + setDateRange(websiteId, dateRange); } } diff --git a/components/forms/LoginForm.js b/components/forms/LoginForm.js index 68c2775c..276a7a4e 100644 --- a/components/forms/LoginForm.js +++ b/components/forms/LoginForm.js @@ -10,11 +10,12 @@ import FormLayout, { FormRow, } from 'components/layout/FormLayout'; import Icon from 'components/common/Icon'; -import Logo from 'assets/logo.svg'; -import styles from './LoginForm.module.css'; import usePost from 'hooks/usePost'; import { setItem } from 'lib/web'; -import { AUTH_TOKEN } from '../../lib/constants'; +import { AUTH_TOKEN } from 'lib/constants'; +import { setUser } from 'store/app'; +import Logo from 'assets/logo.svg'; +import styles from './LoginForm.module.css'; const validate = ({ username, password }) => { const errors = {}; @@ -43,6 +44,8 @@ export default function LoginForm() { if (ok) { setItem(AUTH_TOKEN, data.token); + setUser(data.user); + return router.push('/'); } else { setMessage( diff --git a/components/layout/Header.js b/components/layout/Header.js index 65abc47a..0baaaed7 100644 --- a/components/layout/Header.js +++ b/components/layout/Header.js @@ -1,6 +1,5 @@ import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; -import { useSelector } from 'react-redux'; import classNames from 'classnames'; import Link from 'components/common/Link'; import Icon from 'components/common/Icon'; @@ -14,9 +13,10 @@ import styles from './Header.module.css'; import useLocale from 'hooks/useLocale'; import XMark from 'assets/xmark.svg'; import Bars from 'assets/bars.svg'; +import useUser from 'hooks/useUser'; export default function Header() { - const user = useSelector(state => state.user); + const { user } = useUser(); const [active, setActive] = useState(false); const { dir } = useLocale(); diff --git a/components/pages/Settings.js b/components/pages/Settings.js index 35d039df..d38be07d 100644 --- a/components/pages/Settings.js +++ b/components/pages/Settings.js @@ -1,19 +1,19 @@ import React, { useState } from 'react'; +import { FormattedMessage } from 'react-intl'; import { useRouter } from 'next/router'; import Page from 'components/layout/Page'; import MenuLayout from 'components/layout/MenuLayout'; -import WebsiteSettings from '../settings/WebsiteSettings'; -import AccountSettings from '../settings/AccountSettings'; -import ProfileSettings from '../settings/ProfileSettings'; -import { useSelector } from 'react-redux'; -import { FormattedMessage } from 'react-intl'; +import WebsiteSettings from 'components/settings/WebsiteSettings'; +import AccountSettings from 'components/settings/AccountSettings'; +import ProfileSettings from 'components/settings/ProfileSettings'; +import useUser from 'hooks/useUser'; const WEBSITES = '/settings'; const ACCOUNTS = '/settings/accounts'; const PROFILE = '/settings/profile'; export default function Settings() { - const user = useSelector(state => state.user); + const { user } = useUser(); const [option, setOption] = useState(WEBSITES); const router = useRouter(); const { pathname } = router; diff --git a/components/pages/TestConsole.js b/components/pages/TestConsole.js index 8c0d29b9..fff60516 100644 --- a/components/pages/TestConsole.js +++ b/components/pages/TestConsole.js @@ -1,5 +1,4 @@ import React, { useState } from 'react'; -import { useSelector } from 'react-redux'; import classNames from 'classnames'; import Head from 'next/head'; import Link from 'next/link'; @@ -13,11 +12,12 @@ import Button from 'components/common/Button'; import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import Icon from 'components/common/Icon'; import useFetch from 'hooks/useFetch'; +import useUser from 'hooks/useUser'; import ChevronDown from 'assets/chevron-down.svg'; import styles from './TestConsole.module.css'; export default function TestConsole() { - const user = useSelector(state => state.user); + const { user } = useUser(); const [website, setWebsite] = useState(); const [show, setShow] = useState(true); const { basePath } = useRouter(); diff --git a/components/settings/DateRangeSetting.js b/components/settings/DateRangeSetting.js index 53dfe983..092e2427 100644 --- a/components/settings/DateRangeSetting.js +++ b/components/settings/DateRangeSetting.js @@ -14,6 +14,14 @@ export default function DateRangeSetting() { const { startDate, endDate, value } = dateRange; const options = filterOptions.filter(e => e.value !== 'all'); + function handleChange(value) { + if (typeof value === 'string') { + setDateRange(getDateRange(value, locale)); + } else { + setDateRange(value); + } + } + function handleReset() { setDateRange(getDateRange(DEFAULT_DATE_RANGE, locale)); } @@ -25,7 +33,7 @@ export default function DateRangeSetting() { value={value} startDate={startDate} endDate={endDate} - onChange={setDateRange} + onChange={handleChange} />
+
+ {items.map(({ label, value }) => ( + + {label} + + ))} +
+ + ); +} diff --git a/components/common/MobileMenu.module.css b/components/common/MobileMenu.module.css new file mode 100644 index 00000000..5bc2a377 --- /dev/null +++ b/components/common/MobileMenu.module.css @@ -0,0 +1,40 @@ +.menu { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; + z-index: 100; + display: flex; + flex-direction: column; + background-color: var(--gray50); + overflow: auto; +} + +.items { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.item { + font-size: var(--font-size-large); +} + +.item + .item { + margin-top: 20px; +} + +.button { + margin-right: 15px; +} + +.header { + display: flex; + justify-content: flex-end; + align-items: center; + height: 100px; +} diff --git a/components/layout/Footer.js b/components/layout/Footer.js index 33eda5e2..603b9369 100644 --- a/components/layout/Footer.js +++ b/components/layout/Footer.js @@ -4,32 +4,29 @@ import { FormattedMessage } from 'react-intl'; import Link from 'components/common/Link'; import styles from './Footer.module.css'; import useVersion from 'hooks/useVersion'; -import useLocale from 'hooks/useLocale'; +import { HOMEPAGE_URL, VERSION_URL } from 'lib/constants'; export default function Footer() { const { current } = useVersion(); - const { dir } = useLocale(); return ( -