ConceptPortal-public/rsconcept/frontend/src/app/navigation/user-dropdown.tsx

145 lines
4.5 KiB
TypeScript
Raw Normal View History

2025-02-26 00:16:41 +03:00
import { useAuthSuspense } from '@/features/auth';
2025-03-12 11:55:43 +03:00
import { useLogout } from '@/features/auth/backend/use-logout';
2025-02-12 21:36:25 +03:00
2025-03-12 12:04:50 +03:00
import { Dropdown, DropdownButton } from '@/components/dropdown';
2024-05-02 17:04:18 +03:00
import {
IconAdmin,
IconAdminOff,
IconDarkTheme,
IconDatabase,
2024-07-28 13:07:22 +03:00
IconDBStructure,
2024-05-02 17:04:18 +03:00
IconHelp,
IconHelpOff,
2024-07-26 21:09:16 +03:00
IconImage,
2024-05-02 17:04:18 +03:00
IconLightTheme,
IconLogout,
2024-07-28 13:07:22 +03:00
IconRESTapi,
2024-05-02 17:04:18 +03:00
IconUser
2025-03-12 12:04:50 +03:00
} from '@/components/icons';
import { usePreferencesStore } from '@/stores/preferences';
import { globalIDs } from '@/utils/constants';
2023-07-15 17:46:19 +03:00
import { urls } from '../urls';
2025-02-12 21:36:25 +03:00
2025-03-12 11:55:43 +03:00
import { useConceptNavigation } from './navigation-context';
2023-07-15 17:46:19 +03:00
interface UserDropdownProps {
2023-12-28 14:04:44 +03:00
isOpen: boolean;
hideDropdown: () => void;
2023-07-15 17:46:19 +03:00
}
2025-02-19 23:30:35 +03:00
export function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) {
const router = useConceptNavigation();
const { user } = useAuthSuspense();
const { logout } = useLogout();
2023-07-15 17:46:19 +03:00
const darkMode = usePreferencesStore(state => state.darkMode);
const toggleDarkMode = usePreferencesStore(state => state.toggleDarkMode);
const showHelp = usePreferencesStore(state => state.showHelp);
const toggleShowHelp = usePreferencesStore(state => state.toggleShowHelp);
const adminMode = usePreferencesStore(state => state.adminMode);
const toggleAdminMode = usePreferencesStore(state => state.toggleAdminMode);
2025-02-22 14:04:01 +03:00
function navigateProfile(event: React.MouseEvent<Element>) {
2023-08-27 16:35:17 +03:00
hideDropdown();
router.push({ path: urls.profile, newTab: event.ctrlKey || event.metaKey });
2024-04-01 19:07:20 +03:00
}
2023-07-15 17:46:19 +03:00
2024-04-01 19:07:20 +03:00
function logoutAndRedirect() {
2023-07-25 20:27:29 +03:00
hideDropdown();
void logout().then(() => router.push({ path: urls.login, force: true }));
2024-04-01 19:07:20 +03:00
}
function gotoAdmin() {
hideDropdown();
void logout().then(() => router.push({ path: urls.admin, force: true, newTab: true }));
}
2025-02-22 14:04:01 +03:00
function gotoIcons(event: React.MouseEvent<Element>) {
2024-07-26 21:09:16 +03:00
hideDropdown();
router.push({ path: urls.icons, newTab: event.ctrlKey || event.metaKey });
2024-07-26 21:09:16 +03:00
}
2024-07-28 13:07:22 +03:00
function gotoRestApi() {
hideDropdown();
router.push({ path: urls.rest_api, newTab: true });
2024-07-28 13:07:22 +03:00
}
2025-02-22 14:04:01 +03:00
function gotoDatabaseSchema(event: React.MouseEvent<Element>) {
2024-07-28 13:07:22 +03:00
hideDropdown();
router.push({ path: urls.database_schema, newTab: event.ctrlKey || event.metaKey });
2024-07-28 13:07:22 +03:00
}
2024-04-01 19:07:20 +03:00
function handleToggleDarkMode() {
toggleDarkMode();
hideDropdown();
2024-04-01 19:07:20 +03:00
}
2023-07-16 22:53:22 +03:00
2023-07-15 17:46:19 +03:00
return (
2025-03-09 21:59:21 +03:00
<Dropdown id={globalIDs.user_dropdown} className='min-w-[18ch] max-w-48' stretchLeft isOpen={isOpen}>
2024-04-01 19:07:20 +03:00
<DropdownButton
text={user.username}
2024-04-01 19:07:20 +03:00
title='Профиль пользователя'
icon={<IconUser size='1rem' />}
2024-04-01 19:07:20 +03:00
onClick={navigateProfile}
/>
2023-12-28 14:04:44 +03:00
<DropdownButton
2024-04-01 19:07:20 +03:00
text={darkMode ? 'Тема: Темная' : 'Тема: Светлая'}
2024-05-02 17:04:18 +03:00
icon={darkMode ? <IconDarkTheme size='1rem' /> : <IconLightTheme size='1rem' />}
2023-12-28 14:04:44 +03:00
title='Переключение темы оформления'
2024-04-01 19:07:20 +03:00
onClick={handleToggleDarkMode}
/>
<DropdownButton
text={showHelp ? 'Помощь: Вкл' : 'Помощь: Выкл'}
icon={showHelp ? <IconHelp size='1rem' /> : <IconHelpOff size='1rem' />}
2024-04-01 19:07:20 +03:00
title='Отображение иконок подсказок'
onClick={toggleShowHelp}
/>
{user.is_staff ? (
<DropdownButton
text={adminMode ? 'Админ: Вкл' : 'Админ: Выкл'}
icon={adminMode ? <IconAdmin size='1rem' /> : <IconAdminOff size='1rem' />}
title='Работа в режиме администратора'
onClick={toggleAdminMode}
/>
) : null}
{user.is_staff ? (
2024-07-28 13:07:22 +03:00
<DropdownButton
2025-03-09 21:59:21 +03:00
text='REST API' //
2024-07-28 13:07:22 +03:00
icon={<IconRESTapi size='1rem' />}
className='border-t'
onClick={gotoRestApi}
/>
) : null}
{user.is_staff ? (
2024-07-26 21:09:16 +03:00
<DropdownButton
2025-03-09 21:59:21 +03:00
text='База данных' //
2024-07-26 21:09:16 +03:00
icon={<IconDatabase size='1rem' />}
onClick={gotoAdmin}
/>
) : null}
{user?.is_staff ? (
<DropdownButton
2025-03-09 21:59:21 +03:00
text='Иконки' //
2024-07-26 21:09:16 +03:00
icon={<IconImage size='1rem' />}
onClick={gotoIcons}
/>
) : null}
{user.is_staff ? (
2024-07-28 13:07:22 +03:00
<DropdownButton
2025-03-09 21:59:21 +03:00
text='Структура БД' //
2024-07-28 13:07:22 +03:00
icon={<IconDBStructure size='1rem' />}
onClick={gotoDatabaseSchema}
className='border-b'
/>
) : null}
2024-04-01 19:07:20 +03:00
<DropdownButton
text='Выйти...'
className='font-semibold'
icon={<IconLogout size='1rem' />}
2024-04-01 19:07:20 +03:00
onClick={logoutAndRedirect}
2023-12-28 14:04:44 +03:00
/>
</Dropdown>
);
2023-07-15 17:46:19 +03:00
}