mirror of
https://github.com/umami-software/umami.git
synced 2025-12-06 01:18:00 +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 { Button, Icon } from '@umami/react-zen';
|
||||
import { useTheme } from '@/components/hooks';
|
||||
import { Button, Icon, useTheme } from '@umami/react-zen';
|
||||
import { Icons } from '@/components/icons';
|
||||
import styles from './ThemeSetting.module.css';
|
||||
|
||||
export function ThemeSetting() {
|
||||
const { theme, saveTheme } = useTheme();
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
return (
|
||||
<div className={styles.buttons}>
|
||||
<Button
|
||||
className={classNames({ [styles.active]: theme === 'light' })}
|
||||
onPress={() => saveTheme('light')}
|
||||
onPress={() => setTheme('light')}
|
||||
>
|
||||
<Icon>
|
||||
<Icons.Sun />
|
||||
|
|
@ -19,7 +18,7 @@ export function ThemeSetting() {
|
|||
</Button>
|
||||
<Button
|
||||
className={classNames({ [styles.active]: theme === 'dark' })}
|
||||
onPress={() => saveTheme('dark')}
|
||||
onPress={() => setTheme('dark')}
|
||||
>
|
||||
<Icon>
|
||||
<Icons.Moon />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
import { useTheme } from '@umami/react-zen';
|
||||
import { BarChartTooltip } from '@/components/charts/BarChartTooltip';
|
||||
import { Chart, ChartProps } from '@/components/charts/Chart';
|
||||
import { useTheme } from '@/components/hooks';
|
||||
import { renderNumberLabels } from '@/lib/charts';
|
||||
import { getThemeColors } from '@/lib/colors';
|
||||
|
||||
export interface BarChartProps extends ChartProps {
|
||||
unit: string;
|
||||
|
|
@ -19,7 +20,8 @@ export interface BarChartProps extends ChartProps {
|
|||
|
||||
export function BarChart(props: BarChartProps) {
|
||||
const [tooltip, setTooltip] = useState(null);
|
||||
const { colors } = useTheme();
|
||||
const { theme } = useTheme();
|
||||
const { colors } = getThemeColors(theme);
|
||||
const {
|
||||
renderXLabel,
|
||||
renderYLabel,
|
||||
|
|
|
|||
|
|
@ -2,15 +2,5 @@ import { Box } from '@umami/react-zen';
|
|||
import type { BoxProps } from '@umami/react-zen/Box';
|
||||
|
||||
export function Panel(props: BoxProps) {
|
||||
return (
|
||||
<Box
|
||||
padding="6"
|
||||
border
|
||||
borderRadius="3"
|
||||
backgroundColor
|
||||
shadow="4"
|
||||
position="relative"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
return <Box padding="6" border borderRadius="3" backgroundColor position="relative" {...props} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,5 +44,4 @@ export * from './useRegionNames';
|
|||
export * from './useReport';
|
||||
export * from './useSticky';
|
||||
export * from './useNavigation';
|
||||
export * from './useTheme';
|
||||
export * from './useTimezone';
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ export function useLoginQuery(): {
|
|||
user: any;
|
||||
setUser: (data: any) => void;
|
||||
} & UseQueryResult {
|
||||
const { get, useQuery } = useApi();
|
||||
const { post, useQuery } = useApi();
|
||||
const user = useApp(selector);
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: ['login'],
|
||||
queryFn: async () => {
|
||||
const data = await get('/auth/verify');
|
||||
const data = await post('/auth/verify');
|
||||
|
||||
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 { useTheme } from '@umami/react-zen';
|
||||
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 { getThemeColors } from '@/lib/colors';
|
||||
|
||||
export interface PageviewsChartProps extends BarChartProps {
|
||||
data: {
|
||||
|
|
@ -25,7 +27,8 @@ export function PageviewsChart({
|
|||
...props
|
||||
}: PageviewsChartProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { colors } = useTheme();
|
||||
const { theme } = useTheme();
|
||||
const { colors } = getThemeColors(theme);
|
||||
const { locale } = useLocale();
|
||||
|
||||
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 { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';
|
||||
import classNames from 'classnames';
|
||||
|
|
@ -6,7 +6,6 @@ import { colord } from 'colord';
|
|||
import { ISO_COUNTRIES, MAP_FILE } from '@/lib/constants';
|
||||
import {
|
||||
useDateRange,
|
||||
useTheme,
|
||||
useWebsiteMetricsQuery,
|
||||
useCountryNames,
|
||||
useLocale,
|
||||
|
|
@ -15,6 +14,7 @@ import {
|
|||
import { formatLongNumber } from '@/lib/format';
|
||||
import { percentFilter } from '@/lib/filters';
|
||||
import styles from './WorldMap.module.css';
|
||||
import { getThemeColors } from '@/lib/colors';
|
||||
|
||||
export function WorldMap({
|
||||
websiteId,
|
||||
|
|
@ -27,7 +27,8 @@ export function WorldMap({
|
|||
className?: string;
|
||||
} & HTMLAttributes<HTMLDivElement>) {
|
||||
const [tooltip, setTooltipPopup] = useState();
|
||||
const { theme, colors } = useTheme();
|
||||
const { theme } = useTheme();
|
||||
const { colors } = getThemeColors(theme);
|
||||
const { locale } = useLocale();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { countryNames } = useCountryNames(locale);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import md5 from 'md5';
|
||||
import { THEME_COLORS } from '@/lib/constants';
|
||||
import { colord } from 'colord';
|
||||
|
||||
export const pick = (num: number, arr: any[]) => {
|
||||
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);
|
||||
}
|
||||
|
||||
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 }));
|
||||
|
||||
export function setTheme(theme: string) {
|
||||
store.setState({ theme });
|
||||
}
|
||||
|
||||
export function setTimezone(timezone: string) {
|
||||
store.setState({ timezone });
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue