balibabu commited on
Commit
7099111
·
1 Parent(s): afeb6cb

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

Browse files

### 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)

web/src/components/theme-provider.tsx CHANGED
@@ -1,6 +1,6 @@
1
  import React, { createContext, useContext, useEffect, useState } from 'react';
2
 
3
- type Theme = 'dark' | 'light';
4
 
5
  type ThemeProviderProps = {
6
  children: React.ReactNode;
 
1
  import React, { createContext, useContext, useEffect, useState } from 'react';
2
 
3
+ type Theme = 'dark' | 'light' | 'system';
4
 
5
  type ThemeProviderProps = {
6
  children: React.ReactNode;
web/src/hooks/logic-hooks/navigate-hooks.ts CHANGED
@@ -17,5 +17,14 @@ export const useNavigatePage = () => {
17
  navigate(Routes.Home);
18
  }, [navigate]);
19
 
20
- return { navigateToDatasetList, navigateToDataset, navigateToHome };
 
 
 
 
 
 
 
 
 
21
  };
 
17
  navigate(Routes.Home);
18
  }, [navigate]);
19
 
20
+ const navigateToProfile = useCallback(() => {
21
+ navigate(Routes.ProfileSetting);
22
+ }, [navigate]);
23
+
24
+ return {
25
+ navigateToDatasetList,
26
+ navigateToDataset,
27
+ navigateToHome,
28
+ navigateToProfile,
29
+ };
30
  };
web/src/layouts/next-header.tsx CHANGED
@@ -25,8 +25,7 @@ export function Header() {
25
  const { t } = useTranslate('header');
26
  const { pathname } = useLocation();
27
  const navigate = useNavigateWithFromState();
28
- // const [currentPath, setCurrentPath] = useState(Routes.Home);
29
- const { navigateToHome } = useNavigatePage();
30
 
31
  const tagsData = useMemo(
32
  () => [
@@ -65,7 +64,6 @@ export function Header() {
65
 
66
  const handleChange = (path: SegmentedValue) => {
67
  navigate(path as Routes);
68
- // setCurrentPath(path as Routes);
69
  };
70
 
71
  const handleLogoClick = useCallback(() => {
@@ -121,7 +119,10 @@ export function Header() {
121
  </Button>
122
  </Container>
123
  <Container className="px-3 py-2 bg-colors-background-inverse-standard">
124
- <Avatar className="w-[30px] h-[30px]">
 
 
 
125
  <AvatarImage src="https://github.com/shadcn.png" />
126
  <AvatarFallback>CN</AvatarFallback>
127
  </Avatar>
 
25
  const { t } = useTranslate('header');
26
  const { pathname } = useLocation();
27
  const navigate = useNavigateWithFromState();
28
+ const { navigateToHome, navigateToProfile } = useNavigatePage();
 
29
 
30
  const tagsData = useMemo(
31
  () => [
 
64
 
65
  const handleChange = (path: SegmentedValue) => {
66
  navigate(path as Routes);
 
67
  };
68
 
69
  const handleLogoClick = useCallback(() => {
 
119
  </Button>
120
  </Container>
121
  <Container className="px-3 py-2 bg-colors-background-inverse-standard">
122
+ <Avatar
123
+ className="w-[30px] h-[30px] cursor-pointer"
124
+ onClick={navigateToProfile}
125
+ >
126
  <AvatarImage src="https://github.com/shadcn.png" />
127
  <AvatarFallback>CN</AvatarFallback>
128
  </Avatar>
web/src/pages/demo.tsx DELETED
@@ -1,49 +0,0 @@
1
- import { useTheme } from '@/components/theme-provider';
2
- import { Button } from '@/components/ui/button';
3
- import {
4
- DropdownMenu,
5
- DropdownMenuContent,
6
- DropdownMenuItem,
7
- DropdownMenuTrigger,
8
- } from '@/components/ui/dropdown-menu';
9
- import { Moon, Sun } from 'lucide-react';
10
-
11
- export function ModeToggle() {
12
- const { setTheme } = useTheme();
13
-
14
- return (
15
- <DropdownMenu>
16
- <DropdownMenuTrigger asChild>
17
- <Button variant="outline" size="icon">
18
- <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
19
- <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
20
- <span className="sr-only">Toggle theme</span>
21
- </Button>
22
- </DropdownMenuTrigger>
23
- <DropdownMenuContent align="end">
24
- <DropdownMenuItem onClick={() => setTheme('light')}>
25
- Light
26
- </DropdownMenuItem>
27
- <DropdownMenuItem onClick={() => setTheme('dark')}>
28
- Dark
29
- </DropdownMenuItem>
30
- <DropdownMenuItem onClick={() => setTheme('system')}>
31
- System
32
- </DropdownMenuItem>
33
- </DropdownMenuContent>
34
- </DropdownMenu>
35
- );
36
- }
37
-
38
- const Demo = () => {
39
- return (
40
- <div>
41
- <div>
42
- <ModeToggle></ModeToggle>
43
- </div>
44
- <Button>Destructive</Button>
45
- </div>
46
- );
47
- };
48
-
49
- export default Demo;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
web/src/pages/profile-setting/index.tsx CHANGED
@@ -1,14 +1,17 @@
1
  import { Button } from '@/components/ui/button';
 
2
  import { ArrowLeft } from 'lucide-react';
3
  import { Outlet } from 'umi';
4
  import { SideBar } from './sidebar';
5
 
6
  export default function ProfileSetting() {
 
 
7
  return (
8
  <div className="flex flex-col w-full h-screen bg-background text-foreground">
9
  <header className="flex items-center border-b">
10
  <div className="flex items-center border-r p-1.5">
11
- <Button variant="ghost" size="icon">
12
  <ArrowLeft className="w-5 h-5" />
13
  </Button>
14
  </div>
 
1
  import { Button } from '@/components/ui/button';
2
+ import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
3
  import { ArrowLeft } from 'lucide-react';
4
  import { Outlet } from 'umi';
5
  import { SideBar } from './sidebar';
6
 
7
  export default function ProfileSetting() {
8
+ const { navigateToHome } = useNavigatePage();
9
+
10
  return (
11
  <div className="flex flex-col w-full h-screen bg-background text-foreground">
12
  <header className="flex items-center border-b">
13
  <div className="flex items-center border-r p-1.5">
14
+ <Button variant="ghost" size="icon" onClick={navigateToHome}>
15
  <ArrowLeft className="w-5 h-5" />
16
  </Button>
17
  </div>
web/src/pages/profile-setting/sidebar/index.tsx CHANGED
@@ -1,3 +1,4 @@
 
1
  import { Button } from '@/components/ui/button';
2
  import { Label } from '@/components/ui/label';
3
  import { Switch } from '@/components/ui/switch';
@@ -13,6 +14,7 @@ import {
13
  LogOut,
14
  User,
15
  } from 'lucide-react';
 
16
  import { useHandleMenuClick } from './hooks';
17
 
18
  const menuItems = [
@@ -49,35 +51,45 @@ const menuItems = [
49
  export function SideBar() {
50
  const pathName = useSecondPathName();
51
  const { handleMenuClick } = useHandleMenuClick();
 
 
 
 
 
 
 
 
52
 
53
  return (
54
- <aside className="w-[303px] bg-background border-r">
55
- {menuItems.map((section, idx) => (
56
- <div key={idx}>
57
- <h2 className="p-6 text-sm font-semibold">{section.section}</h2>
58
- {section.items.map((item, itemIdx) => {
59
- const active = pathName === item.key;
60
- return (
61
- <Button
62
- key={itemIdx}
63
- variant={active ? 'secondary' : 'ghost'}
64
- className={cn('w-full justify-start gap-2.5 p-6 relative')}
65
- onClick={handleMenuClick(item.key)}
66
- >
67
- <item.icon className="w-6 h-6" />
68
- <span>{item.label}</span>
69
- {active && (
70
- <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]" />
71
- )}
72
- </Button>
73
- );
74
- })}
75
- </div>
76
- ))}
 
 
77
 
78
  <div className="p-6 mt-auto border-t">
79
  <div className="flex items-center gap-2 mb-6">
80
- <Switch id="dark-mode" />
81
  <Label htmlFor="dark-mode" className="text-sm">
82
  Dark
83
  </Label>
 
1
+ import { useTheme } from '@/components/theme-provider';
2
  import { Button } from '@/components/ui/button';
3
  import { Label } from '@/components/ui/label';
4
  import { Switch } from '@/components/ui/switch';
 
14
  LogOut,
15
  User,
16
  } from 'lucide-react';
17
+ import { useCallback } from 'react';
18
  import { useHandleMenuClick } from './hooks';
19
 
20
  const menuItems = [
 
51
  export function SideBar() {
52
  const pathName = useSecondPathName();
53
  const { handleMenuClick } = useHandleMenuClick();
54
+ const { setTheme } = useTheme();
55
+
56
+ const handleThemeChange = useCallback(
57
+ (checked: boolean) => {
58
+ setTheme(checked ? 'dark' : 'light');
59
+ },
60
+ [setTheme],
61
+ );
62
 
63
  return (
64
+ <aside className="w-[303px] bg-background border-r flex flex-col">
65
+ <div className="flex-1 overflow-auto">
66
+ {menuItems.map((section, idx) => (
67
+ <div key={idx}>
68
+ <h2 className="p-6 text-sm font-semibold">{section.section}</h2>
69
+ {section.items.map((item, itemIdx) => {
70
+ const active = pathName === item.key;
71
+ return (
72
+ <Button
73
+ key={itemIdx}
74
+ variant={active ? 'secondary' : 'ghost'}
75
+ className={cn('w-full justify-start gap-2.5 p-6 relative')}
76
+ onClick={handleMenuClick(item.key)}
77
+ >
78
+ <item.icon className="w-6 h-6" />
79
+ <span>{item.label}</span>
80
+ {active && (
81
+ <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]" />
82
+ )}
83
+ </Button>
84
+ );
85
+ })}
86
+ </div>
87
+ ))}
88
+ </div>
89
 
90
  <div className="p-6 mt-auto border-t">
91
  <div className="flex items-center gap-2 mb-6">
92
+ <Switch id="dark-mode" onCheckedChange={handleThemeChange} />
93
  <Label htmlFor="dark-mode" className="text-sm">
94
  Dark
95
  </Label>
web/src/routes.ts CHANGED
@@ -7,6 +7,7 @@ export enum Routes {
7
  Agent = '/agent',
8
  Search = '/next-search',
9
  Chat = '/next-chat',
 
10
  }
11
 
12
  const routes = [
@@ -136,11 +137,6 @@ const routes = [
136
  component: '@/pages/404',
137
  layout: false,
138
  },
139
- {
140
- path: '/demo',
141
- component: '@/pages/demo',
142
- layout: false,
143
- },
144
  {
145
  path: Routes.Home,
146
  layout: false,
@@ -223,30 +219,33 @@ const routes = [
223
  ],
224
  },
225
  {
226
- path: '/profile-setting',
227
  layout: false,
228
- component: '@/pages/profile-setting',
229
  routes: [
230
- { path: '/profile-setting', redirect: '/profile-setting/profile' },
231
  {
232
- path: '/profile-setting/profile',
233
- component: '@/pages/profile-setting/profile',
 
 
 
 
234
  },
235
  {
236
- path: '/profile-setting/team',
237
- component: '@/pages/profile-setting/team',
238
  },
239
  {
240
- path: '/profile-setting/plan',
241
- component: '@/pages/profile-setting/plan',
242
  },
243
  {
244
- path: '/profile-setting/model',
245
- component: '@/pages/profile-setting/model',
246
  },
247
  {
248
- path: '/profile-setting/prompt',
249
- component: '@/pages/profile-setting/prompt',
250
  },
251
  ],
252
  },
 
7
  Agent = '/agent',
8
  Search = '/next-search',
9
  Chat = '/next-chat',
10
+ ProfileSetting = '/profile-setting',
11
  }
12
 
13
  const routes = [
 
137
  component: '@/pages/404',
138
  layout: false,
139
  },
 
 
 
 
 
140
  {
141
  path: Routes.Home,
142
  layout: false,
 
219
  ],
220
  },
221
  {
222
+ path: Routes.ProfileSetting,
223
  layout: false,
224
+ component: `@/pages${Routes.ProfileSetting}`,
225
  routes: [
 
226
  {
227
+ path: Routes.ProfileSetting,
228
+ redirect: `${Routes.ProfileSetting}/profile`,
229
+ },
230
+ {
231
+ path: `${Routes.ProfileSetting}/profile`,
232
+ component: `@/pages${Routes.ProfileSetting}/profile`,
233
  },
234
  {
235
+ path: `${Routes.ProfileSetting}/team`,
236
+ component: `@/pages${Routes.ProfileSetting}/team`,
237
  },
238
  {
239
+ path: `${Routes.ProfileSetting}/plan`,
240
+ component: `@/pages${Routes.ProfileSetting}/plan`,
241
  },
242
  {
243
+ path: `${Routes.ProfileSetting}/model`,
244
+ component: `@/pages${Routes.ProfileSetting}/model`,
245
  },
246
  {
247
+ path: `${Routes.ProfileSetting}/prompt`,
248
+ component: `@/pages${Routes.ProfileSetting}/prompt`,
249
  },
250
  ],
251
  },