Merge pull request #126 from chamikaJ/chore/improved-dark-mode-toggle
feat(settings): add appearance settings with dark mode toggle and tra…
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"title": "Appearance",
|
||||||
|
"darkMode": "Dark Mode",
|
||||||
|
"darkModeDescription": "Switch between light and dark mode to customize your viewing experience."
|
||||||
|
}
|
||||||
@@ -10,5 +10,6 @@
|
|||||||
"team-members": "Team Members",
|
"team-members": "Team Members",
|
||||||
"teams": "Teams",
|
"teams": "Teams",
|
||||||
"change-password": "Change Password",
|
"change-password": "Change Password",
|
||||||
"language-and-region": "Language and Region"
|
"language-and-region": "Language and Region",
|
||||||
|
"appearance": "Appearance"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"title": "Apariencia",
|
||||||
|
"darkMode": "Modo Oscuro",
|
||||||
|
"darkModeDescription": "Cambia entre el modo claro y oscuro para personalizar tu experiencia visual."
|
||||||
|
}
|
||||||
@@ -10,5 +10,6 @@
|
|||||||
"team-members": "Miembros del equipo",
|
"team-members": "Miembros del equipo",
|
||||||
"teams": "Equipos",
|
"teams": "Equipos",
|
||||||
"change-password": "Cambiar contraseña",
|
"change-password": "Cambiar contraseña",
|
||||||
"language-and-region": "Idioma y región"
|
"language-and-region": "Idioma y región",
|
||||||
|
"appearance": "Apariencia"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"title": "Aparência",
|
||||||
|
"darkMode": "Modo Escuro",
|
||||||
|
"darkModeDescription": "Alterne entre o modo claro e escuro para personalizar sua experiência de visualização."
|
||||||
|
}
|
||||||
@@ -10,5 +10,6 @@
|
|||||||
"team-members": "Membros da Equipe",
|
"team-members": "Membros da Equipe",
|
||||||
"teams": "Equipes",
|
"teams": "Equipes",
|
||||||
"change-password": "Alterar Senha",
|
"change-password": "Alterar Senha",
|
||||||
"language-and-region": "Idioma e Região"
|
"language-and-region": "Idioma e Região",
|
||||||
|
"appearance": "Aparência"
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,6 @@ const App: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|||||||
<Suspense fallback={<SuspenseFallback />}>
|
<Suspense fallback={<SuspenseFallback />}>
|
||||||
<ThemeWrapper>
|
<ThemeWrapper>
|
||||||
<RouterProvider router={router} future={{ v7_startTransition: true }} />
|
<RouterProvider router={router} future={{ v7_startTransition: true }} />
|
||||||
<PreferenceSelector />
|
|
||||||
</ThemeWrapper>
|
</ThemeWrapper>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FloatButton, Space, Tooltip } from 'antd';
|
import { FloatButton, Space, Tooltip } from 'antd';
|
||||||
import { FormatPainterOutlined } from '@ant-design/icons';
|
import { FormatPainterOutlined } from '@ant-design/icons';
|
||||||
import LanguageSelector from '../features/i18n/language-selector';
|
// import LanguageSelector from '../features/i18n/language-selector';
|
||||||
import ThemeSelector from '../features/theme/ThemeSelector';
|
// import ThemeSelector from '../features/theme/ThemeSelector';
|
||||||
|
|
||||||
const PreferenceSelector = () => {
|
const PreferenceSelector = () => {
|
||||||
return (
|
return (
|
||||||
@@ -17,7 +17,7 @@ const PreferenceSelector = () => {
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ThemeSelector />
|
{/* <ThemeSelector /> */}
|
||||||
</Space>
|
</Space>
|
||||||
</FloatButton.Group>
|
</FloatButton.Group>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
// ThemeSelector.tsx
|
|
||||||
import { Button } from 'antd';
|
|
||||||
import React from 'react';
|
|
||||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
|
||||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
|
||||||
import { toggleTheme } from './themeSlice';
|
|
||||||
import { MoonOutlined, SunOutlined } from '@ant-design/icons';
|
|
||||||
|
|
||||||
const ThemeSelector = () => {
|
|
||||||
const themeMode = useAppSelector(state => state.themeReducer.mode);
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
const handleDarkModeToggle = () => {
|
|
||||||
dispatch(toggleTheme());
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
type={themeMode === 'dark' ? 'primary' : 'default'}
|
|
||||||
icon={themeMode === 'dark' ? <SunOutlined /> : <MoonOutlined />}
|
|
||||||
shape="circle"
|
|
||||||
onClick={handleDarkModeToggle}
|
|
||||||
className="transition-all duration-300" // Optional: add smooth transition
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ThemeSelector;
|
|
||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
TeamOutlined,
|
TeamOutlined,
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
UserSwitchOutlined,
|
UserSwitchOutlined,
|
||||||
|
BulbOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import React, { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
import ProfileSettings from '../../pages/settings/profile/profile-settings';
|
import ProfileSettings from '../../pages/settings/profile/profile-settings';
|
||||||
@@ -25,6 +26,7 @@ import TeamMembersSettings from '@/pages/settings/team-members/team-members-sett
|
|||||||
import TeamsSettings from '../../pages/settings/teams/teams-settings';
|
import TeamsSettings from '../../pages/settings/teams/teams-settings';
|
||||||
import ChangePassword from '@/pages/settings/change-password/change-password';
|
import ChangePassword from '@/pages/settings/change-password/change-password';
|
||||||
import LanguageAndRegionSettings from '@/pages/settings/language-and-region/language-and-region-settings';
|
import LanguageAndRegionSettings from '@/pages/settings/language-and-region/language-and-region-settings';
|
||||||
|
import AppearanceSettings from '@/pages/settings/appearance/appearance-settings';
|
||||||
|
|
||||||
// type of menu item in settings sidebar
|
// type of menu item in settings sidebar
|
||||||
type SettingMenuItems = {
|
type SettingMenuItems = {
|
||||||
@@ -52,6 +54,13 @@ export const settingsItems: SettingMenuItems[] = [
|
|||||||
icon: React.createElement(NotificationOutlined),
|
icon: React.createElement(NotificationOutlined),
|
||||||
element: React.createElement(NotificationsSettings),
|
element: React.createElement(NotificationsSettings),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'appearance',
|
||||||
|
name: 'appearance',
|
||||||
|
endpoint: 'appearance',
|
||||||
|
icon: React.createElement(BulbOutlined),
|
||||||
|
element: React.createElement(AppearanceSettings),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'change-password',
|
key: 'change-password',
|
||||||
name: 'change-password',
|
name: 'change-password',
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { Card, Divider, Flex, Switch, Typography } from 'antd';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||||
|
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||||
|
import { toggleTheme } from '@/features/theme/themeSlice';
|
||||||
|
import { useDocumentTitle } from '@/hooks/useDoumentTItle';
|
||||||
|
import { MoonOutlined, SunOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
|
const AppearanceSettings = () => {
|
||||||
|
const { t } = useTranslation('settings/appearance');
|
||||||
|
const themeMode = useAppSelector(state => state.themeReducer.mode);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
useDocumentTitle(t('title'));
|
||||||
|
|
||||||
|
const handleThemeToggle = () => {
|
||||||
|
dispatch(toggleTheme());
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card style={{ width: '100%' }}>
|
||||||
|
<Flex vertical gap={4}>
|
||||||
|
<Flex gap={8} align="center">
|
||||||
|
<Switch
|
||||||
|
checked={themeMode === 'dark'}
|
||||||
|
onChange={handleThemeToggle}
|
||||||
|
checkedChildren={<MoonOutlined />}
|
||||||
|
unCheckedChildren={<SunOutlined />}
|
||||||
|
/>
|
||||||
|
<Typography.Title level={4} style={{ marginBlockEnd: 0 }}>
|
||||||
|
{t('darkMode')}
|
||||||
|
</Typography.Title>
|
||||||
|
</Flex>
|
||||||
|
<Typography.Text
|
||||||
|
style={{ fontSize: 14, color: themeMode === 'dark' ? '#9CA3AF' : '#00000073' }}
|
||||||
|
>
|
||||||
|
{t('darkModeDescription')}
|
||||||
|
</Typography.Text>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppearanceSettings;
|
||||||
Reference in New Issue
Block a user