theme switcher
This commit is contained in:
parent
945db959b7
commit
2900cab17a
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,8 @@
|
||||
node_modules/
|
||||
*/node_modules/
|
||||
*/build/
|
||||
|
||||
**/node_modules/
|
||||
**/build/
|
||||
.DS_Store
|
||||
.env
|
||||
File diff suppressed because one or more lines are too long
1
frontend/json/runtimeError.json
Normal file
1
frontend/json/runtimeError.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
@ -6,6 +6,8 @@ import NavBarItemPlain from './NavBarItemPlain';
|
||||
import NavBarMenuList from './NavBarMenuList';
|
||||
import { MenuNavBarItem } from '../interfaces';
|
||||
import { useAppSelector } from '../stores/hooks';
|
||||
import { ThemeSwitcher } from './ThemeSwitcher';
|
||||
|
||||
|
||||
type Props = {
|
||||
menu: MenuNavBarItem[];
|
||||
@ -42,6 +44,10 @@ export default function NavBar({ menu, className = '', children }: Props) {
|
||||
isScrolled && `border-b border-pavitra-400 dark:border-dark-700`
|
||||
}`}
|
||||
>
|
||||
<div className="hidden lg:flex items-center px-4 h-14">
|
||||
<ThemeSwitcher />
|
||||
</div>
|
||||
|
||||
<div className='flex flex-1 items-stretch h-14'>{children}</div>
|
||||
<div className='flex-none items-stretch flex h-14 lg:hidden'>
|
||||
<NavBarItemPlain onClick={handleMenuNavBarToggleClick}>
|
||||
|
||||
52
frontend/src/components/ThemeSwitcher.tsx
Normal file
52
frontend/src/components/ThemeSwitcher.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useAppDispatch } from '../stores/hooks';
|
||||
import { setStyle } from '../stores/styleSlice';
|
||||
import { StyleKey } from '../interfaces';
|
||||
import { localStorageStyleKey } from '../config';
|
||||
|
||||
const availableThemes: { key: StyleKey; label: string }[] = [
|
||||
{ key: 'white', label: 'White' },
|
||||
{ key: 'basic', label: 'Basic' },
|
||||
{ key: 'minimized', label: 'Min.' },
|
||||
{ key: 'facebook', label: 'FB' },
|
||||
];
|
||||
|
||||
export const ThemeSwitcher = (): JSX.Element => {
|
||||
const dispatch = useAppDispatch();
|
||||
const [theme, setThemeState] = useState<StyleKey>('minimized');
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
const saved = (localStorage.getItem(localStorageStyleKey) as StyleKey) || 'minimized';
|
||||
setThemeState(saved);
|
||||
dispatch(setStyle(saved));
|
||||
}
|
||||
}, [dispatch]);
|
||||
|
||||
const handleSelect = (key: StyleKey) => {
|
||||
setThemeState(key);
|
||||
localStorage.setItem(localStorageStyleKey, key);
|
||||
dispatch(setStyle(key));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<div className="bg-white dark:bg-dark-700 rounded-full shadow px-1 py-1 flex space-x-1">
|
||||
{availableThemes.map(({ key, label }) => (
|
||||
<button
|
||||
key={key}
|
||||
onClick={() => handleSelect(key)}
|
||||
className={`rounded-full px-3 py-1 text-xs font-medium transition-colors focus:outline-none
|
||||
${
|
||||
theme === key
|
||||
? 'bg-blue-500 text-white'
|
||||
: 'bg-transparent text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-dark-600'
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -114,7 +114,7 @@ export interface User {
|
||||
notes: any[];
|
||||
}
|
||||
|
||||
export type StyleKey = 'white' | 'basic';
|
||||
export type StyleKey = 'white' | 'basic' | 'minimized' | 'facebook';
|
||||
|
||||
export type UserForm = {
|
||||
name: string;
|
||||
|
||||
@ -15,8 +15,8 @@ import { hasPermission } from '../helpers/userPermissions';
|
||||
import { fetchWidgets } from '../stores/roles/rolesSlice';
|
||||
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator';
|
||||
import { SmartWidget } from '../components/SmartWidget/SmartWidget';
|
||||
|
||||
import { useAppDispatch, useAppSelector } from '../stores/hooks';
|
||||
|
||||
const Dashboard = () => {
|
||||
const { t } = useTranslation('common');
|
||||
const dispatch = useAppDispatch();
|
||||
@ -24,11 +24,17 @@ const Dashboard = () => {
|
||||
const corners = useAppSelector((state) => state.style.corners);
|
||||
const cardsStyle = useAppSelector((state) => state.style.cardsStyle);
|
||||
|
||||
const loadingMessage = t('pages.dashboard.loading', {
|
||||
defaultValue: 'Loading...',
|
||||
});
|
||||
{/* Theme switcher relocated to NavBar */}
|
||||
<div className='mb-4 flex items-center'>
|
||||
<h2 className='text-xl font-semibold text-gray-800 dark:text-gray-200 flex-1'>
|
||||
{t('Your workspaces')}
|
||||
</h2>
|
||||
{/* <ThemeSwitcher /> */}
|
||||
</div>
|
||||
|
||||
const loadingMessage: number | string | null = null;
|
||||
const [users, setUsers] = React.useState<number | string | null>(loadingMessage);
|
||||
|
||||
const [users, setUsers] = React.useState(loadingMessage);
|
||||
const [demo_requests, setDemo_requests] = React.useState(loadingMessage);
|
||||
const [notifications, setNotifications] = React.useState(loadingMessage);
|
||||
const [reports, setReports] = React.useState(loadingMessage);
|
||||
|
||||
@ -31,30 +31,30 @@ interface StyleState {
|
||||
}
|
||||
|
||||
const initialState: StyleState = {
|
||||
asideStyle: styles.white.aside,
|
||||
asideScrollbarsStyle: styles.white.asideScrollbars,
|
||||
asideBrandStyle: styles.white.asideBrand,
|
||||
asideMenuItemStyle: styles.white.asideMenuItem,
|
||||
asideMenuItemActiveStyle: styles.white.asideMenuItemActive,
|
||||
asideMenuDropdownStyle: styles.white.asideMenuDropdown,
|
||||
navBarItemLabelStyle: styles.white.navBarItemLabel,
|
||||
navBarItemLabelHoverStyle: styles.white.navBarItemLabelHover,
|
||||
navBarItemLabelActiveColorStyle: styles.white.navBarItemLabelActiveColor,
|
||||
overlayStyle: styles.white.overlay,
|
||||
asideStyle: styles.minimized.aside,
|
||||
asideScrollbarsStyle: styles.minimized.asideScrollbars,
|
||||
asideBrandStyle: styles.minimized.asideBrand,
|
||||
asideMenuItemStyle: styles.minimized.asideMenuItem,
|
||||
asideMenuItemActiveStyle: styles.minimized.asideMenuItemActive,
|
||||
asideMenuDropdownStyle: styles.minimized.asideMenuDropdown,
|
||||
navBarItemLabelStyle: styles.minimized.navBarItemLabel,
|
||||
navBarItemLabelHoverStyle: styles.minimized.navBarItemLabelHover,
|
||||
navBarItemLabelActiveColorStyle: styles.minimized.navBarItemLabelActiveColor,
|
||||
overlayStyle: styles.minimized.overlay,
|
||||
darkMode: false,
|
||||
bgLayoutColor: styles.white.bgLayoutColor,
|
||||
iconsColor: styles.white.iconsColor,
|
||||
activeLinkColor: styles.white.activeLinkColor,
|
||||
cardsColor: styles.white.cardsColor,
|
||||
focusRingColor: styles.white.focusRingColor,
|
||||
corners: styles.white.corners,
|
||||
cardsStyle: styles.white.cardsStyle,
|
||||
linkColor: styles.white.linkColor,
|
||||
websiteHeder: styles.white.websiteHeder,
|
||||
borders: styles.white.borders,
|
||||
shadow: styles.white.shadow,
|
||||
websiteSectionStyle: styles.white.websiteSectionStyle,
|
||||
textSecondary: styles.white.textSecondary,
|
||||
bgLayoutColor: styles.minimized.bgLayoutColor,
|
||||
iconsColor: styles.minimized.iconsColor,
|
||||
activeLinkColor: styles.minimized.activeLinkColor,
|
||||
cardsColor: styles.minimized.cardsColor,
|
||||
focusRingColor: styles.minimized.focusRingColor,
|
||||
corners: styles.minimized.corners,
|
||||
cardsStyle: styles.minimized.cardsStyle,
|
||||
linkColor: styles.minimized.linkColor,
|
||||
websiteHeder: styles.minimized.websiteHeder,
|
||||
borders: styles.minimized.borders,
|
||||
shadow: styles.minimized.shadow,
|
||||
websiteSectionStyle: styles.minimized.websiteSectionStyle,
|
||||
textSecondary: styles.minimized.textSecondary,
|
||||
};
|
||||
|
||||
export const styleSlice = createSlice({
|
||||
|
||||
@ -104,3 +104,55 @@ export const basic: StyleObject = {
|
||||
websiteSectionStyle: '',
|
||||
textSecondary: '',
|
||||
};
|
||||
export const minimized: StyleObject = {
|
||||
aside: 'bg-gray-50 dark:bg-gray-900 dark:text-gray-400 p-1',
|
||||
asideScrollbars: 'aside-scrollbars-light',
|
||||
asideBrand: '',
|
||||
asideMenuItem: 'text-gray-600 dark:text-gray-400 p-0.5 hover:bg-gray-100 dark:hover:bg-dark-800',
|
||||
asideMenuItemActive: 'font-medium text-gray-800 dark:text-gray-100',
|
||||
asideMenuDropdown: 'bg-gray-100/50',
|
||||
navBarItemLabel: 'text-gray-600 text-xs',
|
||||
navBarItemLabelHover: 'hover:text-gray-700',
|
||||
navBarItemLabelActiveColor: 'text-gray-900',
|
||||
overlay: '',
|
||||
activeLinkColor: 'bg-gray-50/20',
|
||||
bgLayoutColor: 'bg-gray-50',
|
||||
iconsColor: 'text-gray-700',
|
||||
cardsColor: 'bg-gray-50',
|
||||
focusRingColor: 'focus:outline-none focus:ring-1 focus:ring-gray-500',
|
||||
corners: 'rounded-sm',
|
||||
cardsStyle: 'bg-gray-50 border border-gray-200 !p-2',
|
||||
linkColor: 'text-gray-700',
|
||||
websiteHeder: 'border-b border-gray-100',
|
||||
borders: 'border-gray-100',
|
||||
shadow: '',
|
||||
websiteSectionStyle: '',
|
||||
textSecondary: 'text-gray-600 text-xs',
|
||||
};
|
||||
|
||||
export const facebook: StyleObject = {
|
||||
aside: 'bg-[#F0F2F5] text-[#050505]',
|
||||
asideScrollbars: 'aside-scrollbars-light',
|
||||
asideBrand: '',
|
||||
asideMenuItem: 'text-[#050505] hover:bg-[#e4e6eb]',
|
||||
asideMenuItemActive: 'font-bold text-[#1877F2]',
|
||||
asideMenuDropdown: 'bg-[#e4e6eb]',
|
||||
navBarItemLabel: 'text-[#1877F2]',
|
||||
navBarItemLabelHover: 'hover:text-[#155DB2]',
|
||||
navBarItemLabelActiveColor: 'text-[#155DB2]',
|
||||
overlay: '',
|
||||
activeLinkColor: 'bg-[#e4e6eb]',
|
||||
bgLayoutColor: 'bg-[#F0F2F5]',
|
||||
iconsColor: 'text-[#1877F2]',
|
||||
cardsColor: 'bg-white',
|
||||
focusRingColor: 'focus:ring focus:ring-[#1877F2] focus:border-[#1877F2]',
|
||||
corners: 'rounded',
|
||||
cardsStyle: 'bg-white border border-[#e4e6eb]',
|
||||
linkColor: 'text-[#1877F2]',
|
||||
websiteHeder: 'border-b border-[#e4e6eb]',
|
||||
borders: 'border-[#e4e6eb]',
|
||||
shadow: '',
|
||||
websiteSectionStyle: '',
|
||||
textSecondary: 'text-[#65676B]',
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user