242 lines
7.0 KiB
TypeScript

import { ReactNode } from 'react';
import {
Box,
Button,
Drawer,
DrawerBody,
DrawerContent,
DrawerHeader,
DrawerRoot,
Flex,
HStack,
IconButton,
Text,
useDisclosure,
} from '@chakra-ui/react';
import {
LuAlignJustify,
LuArrowBigLeft,
LuLogIn,
LuLogOut,
LuMoon,
LuSettings,
LuSun,
} from 'react-icons/lu';
import { useNavigate } from 'react-router-dom';
import { useServiceContext } from '@/service/ServiceContext';
import { SessionState } from '@/service/SessionState';
import { colors } from '@/theme/foundations/colors';
import { requestSignIn, requestSignOut, requestSignUp } from '@/utils/sso';
import { useThemeMode } from '@/utils/theme-tools';
import { useSessionService } from '@/service/session';
import { MdHelp, MdHome, MdMore, MdOutlinePlaylistPlay, MdOutlineUploadFile, MdSupervisedUserCircle } from 'react-icons/md';
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '../ui/menu';
export const TOP_BAR_HEIGHT = '50px';
export const BUTTON_TOP_BAR_PROPERTY = {
colorPalette: '@menu',
height: TOP_BAR_HEIGHT,
};
export type TopBarProps = {
children?: ReactNode;
title?: string;
};
export const TopBar = ({ title, children }: TopBarProps) => {
const { mode, colorMode, toggleColorMode } = useThemeMode();
const { clearToken } = useSessionService();
const { session } = useServiceContext();
const backColor = mode('back.100', 'back.800');
const drawerDisclose = useDisclosure();
const onChangeTheme = () => {
drawerDisclose.onOpen();
};
const navigate = useNavigate();
const onSignIn = (): void => {
clearToken();
requestSignIn();
};
const onSignUp = (): void => {
clearToken();
requestSignUp();
};
const onSignOut = (): void => {
clearToken();
requestSignOut();
};
const onSelectAdd = () => {
navigate('/add');
};
const onSelectHome = () => {
navigate('/');
};
const onSelectOnAir = () => {
navigate('/on-air');
};
const onHelp = () => {
navigate('/help');
};
const onSettings = () => {
navigate('/settings');
};
return (
<Flex
position="absolute"
top={0}
left={0}
right={0}
height={TOP_BAR_HEIGHT}
alignItems="center"
justifyContent="space-between"
backgroundColor={backColor}
gap="2"
px="2"
boxShadow={'0px 2px 4px ' + colors.back[900]}
zIndex={200}
>
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onChangeTheme}>
<LuAlignJustify />
<Text paddingLeft="3px" fontWeight="bold">
Karusic
</Text>
</Button>
{title && (
<Text
fontSize="20px"
fontWeight="bold"
textTransform="uppercase"
marginRight="auto"
userSelect="none"
>
{title}
</Text>
)}
{children}
<Flex right="0">
{session?.state !== SessionState.CONNECTED && (
<>
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onSignIn}>
<LuLogIn />
<Text paddingLeft="3px" fontWeight="bold">
Sign-in
</Text>
</Button>
<Button
{...BUTTON_TOP_BAR_PROPERTY}
onClick={onSignUp}
disabled={true}
>
<MdMore />
<Text paddingLeft="3px" fontWeight="bold">
Sign-up
</Text>
</Button>
</>
)}
{session?.state === SessionState.CONNECTED && (
<MenuRoot>
<MenuTrigger asChild>
<IconButton
as={IconButton}
aria-label="Options"
{...BUTTON_TOP_BAR_PROPERTY}
width={TOP_BAR_HEIGHT}
><MdSupervisedUserCircle /></IconButton>
</MenuTrigger>
<MenuContent>
<MenuItem value="user" valueText="user" _hover={{}} color={mode('brand.800', 'brand.200')}>
<MdSupervisedUserCircle />
<Box flex="1">Sign in as {session?.login ?? 'Fail'}</Box>
</MenuItem>
<MenuItem value="Settings" valueText="Settings" onClick={onSettings}><LuSettings />Settings</MenuItem>
<MenuItem value="Help" valueText="Help" onClick={onHelp}><MdHelp /> Help</MenuItem>
<MenuItem value="Sign-out" valueText="Sign-out" onClick={onSignOut}>
<LuLogOut /> Sign-out
</MenuItem>
{colorMode === 'light' ? (
<MenuItem value="set-dark" valueText="set-dark" onClick={toggleColorMode}>
<LuMoon /> Set dark mode
</MenuItem>
) : (
<MenuItem value="set-light" valueText="set-light" onClick={toggleColorMode}>
<LuSun /> Set light mode
</MenuItem>
)}
</MenuContent>
</MenuRoot>
)}
</Flex>
<Drawer.Root
placement="start"
onOpenChange={drawerDisclose.onClose}
open={drawerDisclose.open}
data-testid="top-bar_drawer-root"
>
<Drawer.Positioner>
<Drawer.Content
data-testid="top-bar_drawer-content">
<Drawer.Header
paddingY="auto"
as="button"
onClick={drawerDisclose.onClose}
boxShadow={'0px 2px 4px ' + colors.back[900]}
backgroundColor={backColor}
color={mode('brand.900', 'brand.50')}
textTransform="uppercase"
>
<HStack height={TOP_BAR_HEIGHT}>
<LuArrowBigLeft />
<Text as="span" paddingLeft="3px">
Karusic
</Text>
</HStack>
</Drawer.Header>
<Drawer.Body paddingX="0px">
<Button
background="#00000000"
borderRadius="0px"
onClick={onSelectHome}
width="full"
>
<MdHome />
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
Home
</Text>
</Button>
<hr />
<Button
background="#00000000"
borderRadius="0px"
onClick={onSelectOnAir}
width="full"
>
<MdOutlinePlaylistPlay />
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
On air
</Text>
</Button>
<hr />
<Button
background="#00000000"
borderRadius="0px"
onClick={onSelectAdd}
width="full"
>
<MdOutlineUploadFile />
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
Add Media
</Text>
</Button>
</Drawer.Body>
</Drawer.Content>
</Drawer.Positioner>
</Drawer.Root>
</Flex>
);
};