Feat: Bind event to the theme Switch #3221 (#4067)

### What problem does this PR solve?

Feat: Bind event to  the theme Switch #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2024-12-17 16:32:17 +08:00 committed by GitHub
parent 000cd6d615
commit e8b4e8b3d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 73 additions and 98 deletions

View File

@ -1,6 +1,6 @@
import React, { createContext, useContext, useEffect, useState } from 'react'; import React, { createContext, useContext, useEffect, useState } from 'react';
type Theme = 'dark' | 'light'; type Theme = 'dark' | 'light' | 'system';
type ThemeProviderProps = { type ThemeProviderProps = {
children: React.ReactNode; children: React.ReactNode;

View File

@ -17,5 +17,14 @@ export const useNavigatePage = () => {
navigate(Routes.Home); navigate(Routes.Home);
}, [navigate]); }, [navigate]);
return { navigateToDatasetList, navigateToDataset, navigateToHome }; const navigateToProfile = useCallback(() => {
navigate(Routes.ProfileSetting);
}, [navigate]);
return {
navigateToDatasetList,
navigateToDataset,
navigateToHome,
navigateToProfile,
};
}; };

View File

@ -25,8 +25,7 @@ export function Header() {
const { t } = useTranslate('header'); const { t } = useTranslate('header');
const { pathname } = useLocation(); const { pathname } = useLocation();
const navigate = useNavigateWithFromState(); const navigate = useNavigateWithFromState();
// const [currentPath, setCurrentPath] = useState(Routes.Home); const { navigateToHome, navigateToProfile } = useNavigatePage();
const { navigateToHome } = useNavigatePage();
const tagsData = useMemo( const tagsData = useMemo(
() => [ () => [
@ -65,7 +64,6 @@ export function Header() {
const handleChange = (path: SegmentedValue) => { const handleChange = (path: SegmentedValue) => {
navigate(path as Routes); navigate(path as Routes);
// setCurrentPath(path as Routes);
}; };
const handleLogoClick = useCallback(() => { const handleLogoClick = useCallback(() => {
@ -121,7 +119,10 @@ export function Header() {
</Button> </Button>
</Container> </Container>
<Container className="px-3 py-2 bg-colors-background-inverse-standard"> <Container className="px-3 py-2 bg-colors-background-inverse-standard">
<Avatar className="w-[30px] h-[30px]"> <Avatar
className="w-[30px] h-[30px] cursor-pointer"
onClick={navigateToProfile}
>
<AvatarImage src="https://github.com/shadcn.png" /> <AvatarImage src="https://github.com/shadcn.png" />
<AvatarFallback>CN</AvatarFallback> <AvatarFallback>CN</AvatarFallback>
</Avatar> </Avatar>

View File

@ -1,49 +0,0 @@
import { useTheme } from '@/components/theme-provider';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Moon, Sun } from 'lucide-react';
export function ModeToggle() {
const { setTheme } = useTheme();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
const Demo = () => {
return (
<div>
<div>
<ModeToggle></ModeToggle>
</div>
<Button>Destructive</Button>
</div>
);
};
export default Demo;

View File

@ -1,14 +1,17 @@
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { ArrowLeft } from 'lucide-react'; import { ArrowLeft } from 'lucide-react';
import { Outlet } from 'umi'; import { Outlet } from 'umi';
import { SideBar } from './sidebar'; import { SideBar } from './sidebar';
export default function ProfileSetting() { export default function ProfileSetting() {
const { navigateToHome } = useNavigatePage();
return ( return (
<div className="flex flex-col w-full h-screen bg-background text-foreground"> <div className="flex flex-col w-full h-screen bg-background text-foreground">
<header className="flex items-center border-b"> <header className="flex items-center border-b">
<div className="flex items-center border-r p-1.5"> <div className="flex items-center border-r p-1.5">
<Button variant="ghost" size="icon"> <Button variant="ghost" size="icon" onClick={navigateToHome}>
<ArrowLeft className="w-5 h-5" /> <ArrowLeft className="w-5 h-5" />
</Button> </Button>
</div> </div>

View File

@ -1,3 +1,4 @@
import { useTheme } from '@/components/theme-provider';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
@ -13,6 +14,7 @@ import {
LogOut, LogOut,
User, User,
} from 'lucide-react'; } from 'lucide-react';
import { useCallback } from 'react';
import { useHandleMenuClick } from './hooks'; import { useHandleMenuClick } from './hooks';
const menuItems = [ const menuItems = [
@ -49,35 +51,45 @@ const menuItems = [
export function SideBar() { export function SideBar() {
const pathName = useSecondPathName(); const pathName = useSecondPathName();
const { handleMenuClick } = useHandleMenuClick(); const { handleMenuClick } = useHandleMenuClick();
const { setTheme } = useTheme();
const handleThemeChange = useCallback(
(checked: boolean) => {
setTheme(checked ? 'dark' : 'light');
},
[setTheme],
);
return ( return (
<aside className="w-[303px] bg-background border-r"> <aside className="w-[303px] bg-background border-r flex flex-col">
{menuItems.map((section, idx) => ( <div className="flex-1 overflow-auto">
<div key={idx}> {menuItems.map((section, idx) => (
<h2 className="p-6 text-sm font-semibold">{section.section}</h2> <div key={idx}>
{section.items.map((item, itemIdx) => { <h2 className="p-6 text-sm font-semibold">{section.section}</h2>
const active = pathName === item.key; {section.items.map((item, itemIdx) => {
return ( const active = pathName === item.key;
<Button return (
key={itemIdx} <Button
variant={active ? 'secondary' : 'ghost'} key={itemIdx}
className={cn('w-full justify-start gap-2.5 p-6 relative')} variant={active ? 'secondary' : 'ghost'}
onClick={handleMenuClick(item.key)} className={cn('w-full justify-start gap-2.5 p-6 relative')}
> onClick={handleMenuClick(item.key)}
<item.icon className="w-6 h-6" /> >
<span>{item.label}</span> <item.icon className="w-6 h-6" />
{active && ( <span>{item.label}</span>
<div className="absolute right-0 w-[5px] h-[66px] bg-primary rounded-l-xl shadow-[0_0_5.94px_#7561ff,0_0_11.88px_#7561ff,0_0_41.58px_#7561ff,0_0_83.16px_#7561ff,0_0_142.56px_#7561ff,0_0_249.48px_#7561ff]" /> {active && (
)} <div className="absolute right-0 w-[5px] h-[66px] bg-primary rounded-l-xl shadow-[0_0_5.94px_#7561ff,0_0_11.88px_#7561ff,0_0_41.58px_#7561ff,0_0_83.16px_#7561ff,0_0_142.56px_#7561ff,0_0_249.48px_#7561ff]" />
</Button> )}
); </Button>
})} );
</div> })}
))} </div>
))}
</div>
<div className="p-6 mt-auto border-t"> <div className="p-6 mt-auto border-t">
<div className="flex items-center gap-2 mb-6"> <div className="flex items-center gap-2 mb-6">
<Switch id="dark-mode" /> <Switch id="dark-mode" onCheckedChange={handleThemeChange} />
<Label htmlFor="dark-mode" className="text-sm"> <Label htmlFor="dark-mode" className="text-sm">
Dark Dark
</Label> </Label>

View File

@ -7,6 +7,7 @@ export enum Routes {
Agent = '/agent', Agent = '/agent',
Search = '/next-search', Search = '/next-search',
Chat = '/next-chat', Chat = '/next-chat',
ProfileSetting = '/profile-setting',
} }
const routes = [ const routes = [
@ -136,11 +137,6 @@ const routes = [
component: '@/pages/404', component: '@/pages/404',
layout: false, layout: false,
}, },
{
path: '/demo',
component: '@/pages/demo',
layout: false,
},
{ {
path: Routes.Home, path: Routes.Home,
layout: false, layout: false,
@ -223,30 +219,33 @@ const routes = [
], ],
}, },
{ {
path: '/profile-setting', path: Routes.ProfileSetting,
layout: false, layout: false,
component: '@/pages/profile-setting', component: `@/pages${Routes.ProfileSetting}`,
routes: [ routes: [
{ path: '/profile-setting', redirect: '/profile-setting/profile' },
{ {
path: '/profile-setting/profile', path: Routes.ProfileSetting,
component: '@/pages/profile-setting/profile', redirect: `${Routes.ProfileSetting}/profile`,
}, },
{ {
path: '/profile-setting/team', path: `${Routes.ProfileSetting}/profile`,
component: '@/pages/profile-setting/team', component: `@/pages${Routes.ProfileSetting}/profile`,
}, },
{ {
path: '/profile-setting/plan', path: `${Routes.ProfileSetting}/team`,
component: '@/pages/profile-setting/plan', component: `@/pages${Routes.ProfileSetting}/team`,
}, },
{ {
path: '/profile-setting/model', path: `${Routes.ProfileSetting}/plan`,
component: '@/pages/profile-setting/model', component: `@/pages${Routes.ProfileSetting}/plan`,
}, },
{ {
path: '/profile-setting/prompt', path: `${Routes.ProfileSetting}/model`,
component: '@/pages/profile-setting/prompt', component: `@/pages${Routes.ProfileSetting}/model`,
},
{
path: `${Routes.ProfileSetting}/prompt`,
component: `@/pages${Routes.ProfileSetting}/prompt`,
}, },
], ],
}, },