mirror of
https://github.com/umami-software/umami.git
synced 2025-12-08 05:12:36 +01:00
Updated theme handling.
This commit is contained in:
parent
c71e9b5707
commit
34a8fa100c
10 changed files with 57 additions and 93 deletions
|
|
@ -1,17 +1,16 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Button, Icon } from '@umami/react-zen';
|
import { Button, Icon, useTheme } from '@umami/react-zen';
|
||||||
import { useTheme } from '@/components/hooks';
|
|
||||||
import { Icons } from '@/components/icons';
|
import { Icons } from '@/components/icons';
|
||||||
import styles from './ThemeSetting.module.css';
|
import styles from './ThemeSetting.module.css';
|
||||||
|
|
||||||
export function ThemeSetting() {
|
export function ThemeSetting() {
|
||||||
const { theme, saveTheme } = useTheme();
|
const { theme, setTheme } = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.buttons}>
|
<div className={styles.buttons}>
|
||||||
<Button
|
<Button
|
||||||
className={classNames({ [styles.active]: theme === 'light' })}
|
className={classNames({ [styles.active]: theme === 'light' })}
|
||||||
onPress={() => saveTheme('light')}
|
onPress={() => setTheme('light')}
|
||||||
>
|
>
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Sun />
|
<Icons.Sun />
|
||||||
|
|
@ -19,7 +18,7 @@ export function ThemeSetting() {
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className={classNames({ [styles.active]: theme === 'dark' })}
|
className={classNames({ [styles.active]: theme === 'dark' })}
|
||||||
onPress={() => saveTheme('dark')}
|
onPress={() => setTheme('dark')}
|
||||||
>
|
>
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Moon />
|
<Icons.Moon />
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
|
import { useTheme } from '@umami/react-zen';
|
||||||
import { BarChartTooltip } from '@/components/charts/BarChartTooltip';
|
import { BarChartTooltip } from '@/components/charts/BarChartTooltip';
|
||||||
import { Chart, ChartProps } from '@/components/charts/Chart';
|
import { Chart, ChartProps } from '@/components/charts/Chart';
|
||||||
import { useTheme } from '@/components/hooks';
|
|
||||||
import { renderNumberLabels } from '@/lib/charts';
|
import { renderNumberLabels } from '@/lib/charts';
|
||||||
|
import { getThemeColors } from '@/lib/colors';
|
||||||
|
|
||||||
export interface BarChartProps extends ChartProps {
|
export interface BarChartProps extends ChartProps {
|
||||||
unit: string;
|
unit: string;
|
||||||
|
|
@ -19,7 +20,8 @@ export interface BarChartProps extends ChartProps {
|
||||||
|
|
||||||
export function BarChart(props: BarChartProps) {
|
export function BarChart(props: BarChartProps) {
|
||||||
const [tooltip, setTooltip] = useState(null);
|
const [tooltip, setTooltip] = useState(null);
|
||||||
const { colors } = useTheme();
|
const { theme } = useTheme();
|
||||||
|
const { colors } = getThemeColors(theme);
|
||||||
const {
|
const {
|
||||||
renderXLabel,
|
renderXLabel,
|
||||||
renderYLabel,
|
renderYLabel,
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,5 @@ import { Box } from '@umami/react-zen';
|
||||||
import type { BoxProps } from '@umami/react-zen/Box';
|
import type { BoxProps } from '@umami/react-zen/Box';
|
||||||
|
|
||||||
export function Panel(props: BoxProps) {
|
export function Panel(props: BoxProps) {
|
||||||
return (
|
return <Box padding="6" border borderRadius="3" backgroundColor position="relative" {...props} />;
|
||||||
<Box
|
|
||||||
padding="6"
|
|
||||||
border
|
|
||||||
borderRadius="3"
|
|
||||||
backgroundColor
|
|
||||||
shadow="4"
|
|
||||||
position="relative"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,5 +44,4 @@ export * from './useRegionNames';
|
||||||
export * from './useReport';
|
export * from './useReport';
|
||||||
export * from './useSticky';
|
export * from './useSticky';
|
||||||
export * from './useNavigation';
|
export * from './useNavigation';
|
||||||
export * from './useTheme';
|
|
||||||
export * from './useTimezone';
|
export * from './useTimezone';
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ export function useLoginQuery(): {
|
||||||
user: any;
|
user: any;
|
||||||
setUser: (data: any) => void;
|
setUser: (data: any) => void;
|
||||||
} & UseQueryResult {
|
} & UseQueryResult {
|
||||||
const { get, useQuery } = useApi();
|
const { post, useQuery } = useApi();
|
||||||
const user = useApp(selector);
|
const user = useApp(selector);
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ['login'],
|
queryKey: ['login'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const data = await get('/auth/verify');
|
const data = await post('/auth/verify');
|
||||||
|
|
||||||
setUser(data);
|
setUser(data);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
import { useEffect, useMemo } from 'react';
|
|
||||||
import { useApp, setTheme } from '@/store/app';
|
|
||||||
import { getItem, setItem } from '@/lib/storage';
|
|
||||||
import { DEFAULT_THEME, THEME_COLORS, THEME_CONFIG } from '@/lib/constants';
|
|
||||||
import { colord } from 'colord';
|
|
||||||
|
|
||||||
const selector = (state: { theme: string }) => state.theme;
|
|
||||||
|
|
||||||
export function useTheme() {
|
|
||||||
const theme = useApp(selector) || getItem(THEME_CONFIG) || DEFAULT_THEME;
|
|
||||||
const { primary, text, line, fill } = THEME_COLORS[theme];
|
|
||||||
const primaryColor = colord(THEME_COLORS[theme].primary);
|
|
||||||
|
|
||||||
const colors = useMemo(() => {
|
|
||||||
return {
|
|
||||||
theme: {
|
|
||||||
...THEME_COLORS[theme],
|
|
||||||
},
|
|
||||||
chart: {
|
|
||||||
text,
|
|
||||||
line,
|
|
||||||
views: {
|
|
||||||
hoverBackgroundColor: primaryColor.alpha(0.7).toRgbString(),
|
|
||||||
backgroundColor: primaryColor.alpha(0.4).toRgbString(),
|
|
||||||
borderColor: primaryColor.alpha(0.7).toRgbString(),
|
|
||||||
hoverBorderColor: primaryColor.toRgbString(),
|
|
||||||
},
|
|
||||||
visitors: {
|
|
||||||
hoverBackgroundColor: primaryColor.alpha(0.9).toRgbString(),
|
|
||||||
backgroundColor: primaryColor.alpha(0.6).toRgbString(),
|
|
||||||
borderColor: primaryColor.alpha(0.9).toRgbString(),
|
|
||||||
hoverBorderColor: primaryColor.toRgbString(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
map: {
|
|
||||||
baseColor: primary,
|
|
||||||
fillColor: fill,
|
|
||||||
strokeColor: primary,
|
|
||||||
hoverColor: primary,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}, [theme]);
|
|
||||||
|
|
||||||
const saveTheme = (value: string) => {
|
|
||||||
setItem(THEME_CONFIG, value);
|
|
||||||
setTheme(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
document.body.setAttribute('data-theme', theme);
|
|
||||||
}, [theme]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const url = new URL(window?.location?.href);
|
|
||||||
const theme = url.searchParams.get('theme');
|
|
||||||
|
|
||||||
if (['light', 'dark'].includes(theme)) {
|
|
||||||
saveTheme(theme);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return { theme, saveTheme, colors };
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { useTheme } from '@umami/react-zen';
|
||||||
import { BarChart, BarChartProps } from '@/components/charts/BarChart';
|
import { BarChart, BarChartProps } from '@/components/charts/BarChart';
|
||||||
import { useLocale, useTheme, useMessages } from '@/components/hooks';
|
import { useLocale, useMessages } from '@/components/hooks';
|
||||||
import { renderDateLabels } from '@/lib/charts';
|
import { renderDateLabels } from '@/lib/charts';
|
||||||
|
import { getThemeColors } from '@/lib/colors';
|
||||||
|
|
||||||
export interface PageviewsChartProps extends BarChartProps {
|
export interface PageviewsChartProps extends BarChartProps {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -25,7 +27,8 @@ export function PageviewsChart({
|
||||||
...props
|
...props
|
||||||
}: PageviewsChartProps) {
|
}: PageviewsChartProps) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { colors } = useTheme();
|
const { theme } = useTheme();
|
||||||
|
const { colors } = getThemeColors(theme);
|
||||||
const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
|
|
||||||
const chartData = useMemo(() => {
|
const chartData = useMemo(() => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { FloatingTooltip, Column } from '@umami/react-zen';
|
import { FloatingTooltip, Column, useTheme } from '@umami/react-zen';
|
||||||
import { useState, useMemo, HTMLAttributes } from 'react';
|
import { useState, useMemo, HTMLAttributes } from 'react';
|
||||||
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';
|
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
@ -6,7 +6,6 @@ import { colord } from 'colord';
|
||||||
import { ISO_COUNTRIES, MAP_FILE } from '@/lib/constants';
|
import { ISO_COUNTRIES, MAP_FILE } from '@/lib/constants';
|
||||||
import {
|
import {
|
||||||
useDateRange,
|
useDateRange,
|
||||||
useTheme,
|
|
||||||
useWebsiteMetricsQuery,
|
useWebsiteMetricsQuery,
|
||||||
useCountryNames,
|
useCountryNames,
|
||||||
useLocale,
|
useLocale,
|
||||||
|
|
@ -15,6 +14,7 @@ import {
|
||||||
import { formatLongNumber } from '@/lib/format';
|
import { formatLongNumber } from '@/lib/format';
|
||||||
import { percentFilter } from '@/lib/filters';
|
import { percentFilter } from '@/lib/filters';
|
||||||
import styles from './WorldMap.module.css';
|
import styles from './WorldMap.module.css';
|
||||||
|
import { getThemeColors } from '@/lib/colors';
|
||||||
|
|
||||||
export function WorldMap({
|
export function WorldMap({
|
||||||
websiteId,
|
websiteId,
|
||||||
|
|
@ -27,7 +27,8 @@ export function WorldMap({
|
||||||
className?: string;
|
className?: string;
|
||||||
} & HTMLAttributes<HTMLDivElement>) {
|
} & HTMLAttributes<HTMLDivElement>) {
|
||||||
const [tooltip, setTooltipPopup] = useState();
|
const [tooltip, setTooltipPopup] = useState();
|
||||||
const { theme, colors } = useTheme();
|
const { theme } = useTheme();
|
||||||
|
const { colors } = getThemeColors(theme);
|
||||||
const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { countryNames } = useCountryNames(locale);
|
const { countryNames } = useCountryNames(locale);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import md5 from 'md5';
|
import md5 from 'md5';
|
||||||
|
import { THEME_COLORS } from '@/lib/constants';
|
||||||
|
import { colord } from 'colord';
|
||||||
|
|
||||||
export const pick = (num: number, arr: any[]) => {
|
export const pick = (num: number, arr: any[]) => {
|
||||||
return arr[num % arr.length];
|
return arr[num % arr.length];
|
||||||
|
|
@ -43,3 +45,38 @@ export function getColor(seed: string, min: number = 0, max: number = 255) {
|
||||||
|
|
||||||
return rgb2Hex(r, g, b);
|
return rgb2Hex(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getThemeColors(theme: string) {
|
||||||
|
const { primary, text, line, fill } = THEME_COLORS[theme];
|
||||||
|
const primaryColor = colord(THEME_COLORS[theme].primary);
|
||||||
|
|
||||||
|
return {
|
||||||
|
colors: {
|
||||||
|
theme: {
|
||||||
|
...THEME_COLORS[theme],
|
||||||
|
},
|
||||||
|
chart: {
|
||||||
|
text,
|
||||||
|
line,
|
||||||
|
views: {
|
||||||
|
hoverBackgroundColor: primaryColor.alpha(0.7).toRgbString(),
|
||||||
|
backgroundColor: primaryColor.alpha(0.4).toRgbString(),
|
||||||
|
borderColor: primaryColor.alpha(0.7).toRgbString(),
|
||||||
|
hoverBorderColor: primaryColor.toRgbString(),
|
||||||
|
},
|
||||||
|
visitors: {
|
||||||
|
hoverBackgroundColor: primaryColor.alpha(0.9).toRgbString(),
|
||||||
|
backgroundColor: primaryColor.alpha(0.6).toRgbString(),
|
||||||
|
borderColor: primaryColor.alpha(0.9).toRgbString(),
|
||||||
|
hoverBorderColor: primaryColor.toRgbString(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
map: {
|
||||||
|
baseColor: primary,
|
||||||
|
fillColor: fill,
|
||||||
|
strokeColor: primary,
|
||||||
|
hoverColor: primary,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,6 @@ const initialState = {
|
||||||
|
|
||||||
const store = create(() => ({ ...initialState }));
|
const store = create(() => ({ ...initialState }));
|
||||||
|
|
||||||
export function setTheme(theme: string) {
|
|
||||||
store.setState({ theme });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setTimezone(timezone: string) {
|
export function setTimezone(timezone: string) {
|
||||||
store.setState({ timezone });
|
store.setState({ timezone });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue