committed by
GitHub
29 changed files with 2081 additions and 1376 deletions
@ -1,42 +1,76 @@ |
|||||
import React from 'react'; |
import React from 'react' |
||||
|
import { |
||||
import { Button, Menu, MenuButton, MenuItem, MenuList, useDisclosure } from '@chakra-ui/react'; |
Button, |
||||
import { BsThreeDotsVertical } from 'react-icons/bs'; |
Menu, |
||||
import { FiEdit, FiTrash } from 'react-icons/fi'; |
MenuButton, |
||||
|
MenuItem, |
||||
import EditUser from '../Admin/EditUser'; |
MenuList, |
||||
import EditItem from '../Items/EditItem'; |
useDisclosure, |
||||
import Delete from './DeleteAlert'; |
} from '@chakra-ui/react' |
||||
import { ItemOut, UserOut } from '../../client'; |
import { BsThreeDotsVertical } from 'react-icons/bs' |
||||
|
import { FiEdit, FiTrash } from 'react-icons/fi' |
||||
|
|
||||
|
import EditUser from '../Admin/EditUser' |
||||
|
import EditItem from '../Items/EditItem' |
||||
|
import Delete from './DeleteAlert' |
||||
|
import { ItemOut, UserOut } from '../../client' |
||||
|
|
||||
interface ActionsMenuProps { |
interface ActionsMenuProps { |
||||
type: string; |
type: string |
||||
value: ItemOut | UserOut; |
value: ItemOut | UserOut |
||||
disabled?: boolean; |
disabled?: boolean |
||||
} |
} |
||||
|
|
||||
const ActionsMenu: React.FC<ActionsMenuProps> = ({ type, value, disabled }) => { |
const ActionsMenu: React.FC<ActionsMenuProps> = ({ type, value, disabled }) => { |
||||
const editUserModal = useDisclosure(); |
const editUserModal = useDisclosure() |
||||
const deleteModal = useDisclosure(); |
const deleteModal = useDisclosure() |
||||
|
|
||||
return ( |
return ( |
||||
<> |
<> |
||||
<Menu> |
<Menu> |
||||
<MenuButton isDisabled={disabled} as={Button} rightIcon={<BsThreeDotsVertical />} variant='unstyled'> |
<MenuButton |
||||
</MenuButton> |
isDisabled={disabled} |
||||
|
as={Button} |
||||
|
rightIcon={<BsThreeDotsVertical />} |
||||
|
variant="unstyled" |
||||
|
></MenuButton> |
||||
<MenuList> |
<MenuList> |
||||
<MenuItem onClick={editUserModal.onOpen} icon={<FiEdit fontSize='16px' />}>Edit {type}</MenuItem> |
<MenuItem |
||||
<MenuItem onClick={deleteModal.onOpen} icon={<FiTrash fontSize='16px' />} color='ui.danger'>Delete {type}</MenuItem> |
onClick={editUserModal.onOpen} |
||||
|
icon={<FiEdit fontSize="16px" />} |
||||
|
> |
||||
|
Edit {type} |
||||
|
</MenuItem> |
||||
|
<MenuItem |
||||
|
onClick={deleteModal.onOpen} |
||||
|
icon={<FiTrash fontSize="16px" />} |
||||
|
color="ui.danger" |
||||
|
> |
||||
|
Delete {type} |
||||
|
</MenuItem> |
||||
</MenuList> |
</MenuList> |
||||
{ |
{type === 'User' ? ( |
||||
type === 'User' ? <EditUser user={value as UserOut} isOpen={editUserModal.isOpen} onClose={editUserModal.onClose} /> |
<EditUser |
||||
: <EditItem item={value as ItemOut} isOpen={editUserModal.isOpen} onClose={editUserModal.onClose} /> |
user={value as UserOut} |
||||
} |
isOpen={editUserModal.isOpen} |
||||
<Delete type={type} id={value.id} isOpen={deleteModal.isOpen} onClose={deleteModal.onClose} /> |
onClose={editUserModal.onClose} |
||||
|
/> |
||||
|
) : ( |
||||
|
<EditItem |
||||
|
item={value as ItemOut} |
||||
|
isOpen={editUserModal.isOpen} |
||||
|
onClose={editUserModal.onClose} |
||||
|
/> |
||||
|
)} |
||||
|
<Delete |
||||
|
type={type} |
||||
|
id={value.id} |
||||
|
isOpen={deleteModal.isOpen} |
||||
|
onClose={deleteModal.onClose} |
||||
|
/> |
||||
</Menu> |
</Menu> |
||||
</> |
</> |
||||
); |
) |
||||
}; |
} |
||||
|
|
||||
export default ActionsMenu; |
export default ActionsMenu |
||||
|
@ -1,22 +1,42 @@ |
|||||
import { Button, Container, Text } from '@chakra-ui/react'; |
import React from 'react' |
||||
import { Link } from '@tanstack/react-router'; |
import { Button, Container, Text } from '@chakra-ui/react' |
||||
|
import { Link } from '@tanstack/react-router' |
||||
|
|
||||
const NotFound: React.FC = () => { |
const NotFound: React.FC = () => { |
||||
|
|
||||
return ( |
return ( |
||||
<> |
<> |
||||
<Container h='100vh' |
<Container |
||||
alignItems='stretch' |
h="100vh" |
||||
justifyContent='center' textAlign='center' maxW='sm' centerContent> |
alignItems="stretch" |
||||
<Text fontSize='8xl' color='ui.main' fontWeight='bold' lineHeight='1' mb={4}>404</Text> |
justifyContent="center" |
||||
<Text fontSize='md'>Oops!</Text> |
textAlign="center" |
||||
<Text fontSize='md'>Page not found.</Text> |
maxW="sm" |
||||
<Button as={Link} to='/' color='ui.main' borderColor='ui.main' variant='outline' mt={4}>Go back</Button> |
centerContent |
||||
|
> |
||||
|
<Text |
||||
|
fontSize="8xl" |
||||
|
color="ui.main" |
||||
|
fontWeight="bold" |
||||
|
lineHeight="1" |
||||
|
mb={4} |
||||
|
> |
||||
|
404 |
||||
|
</Text> |
||||
|
<Text fontSize="md">Oops!</Text> |
||||
|
<Text fontSize="md">Page not found.</Text> |
||||
|
<Button |
||||
|
as={Link} |
||||
|
to="/" |
||||
|
color="ui.main" |
||||
|
borderColor="ui.main" |
||||
|
variant="outline" |
||||
|
mt={4} |
||||
|
> |
||||
|
Go back |
||||
|
</Button> |
||||
</Container> |
</Container> |
||||
</> |
</> |
||||
); |
) |
||||
} |
} |
||||
|
|
||||
export default NotFound; |
export default NotFound |
||||
|
|
||||
|
|
||||
|
@ -1,70 +1,117 @@ |
|||||
import React from 'react'; |
import React from 'react' |
||||
|
import { |
||||
|
Box, |
||||
|
Drawer, |
||||
|
DrawerBody, |
||||
|
DrawerCloseButton, |
||||
|
DrawerContent, |
||||
|
DrawerOverlay, |
||||
|
Flex, |
||||
|
IconButton, |
||||
|
Image, |
||||
|
Text, |
||||
|
useColorModeValue, |
||||
|
useDisclosure, |
||||
|
} from '@chakra-ui/react' |
||||
|
import { FiLogOut, FiMenu } from 'react-icons/fi' |
||||
|
import { useQueryClient } from 'react-query' |
||||
|
|
||||
import { Box, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerOverlay, Flex, IconButton, Image, Text, useColorModeValue, useDisclosure } from '@chakra-ui/react'; |
import Logo from '../../assets/images/fastapi-logo.svg' |
||||
import { FiLogOut, FiMenu } from 'react-icons/fi'; |
import { UserOut } from '../../client' |
||||
import { useQueryClient } from 'react-query'; |
import useAuth from '../../hooks/useAuth' |
||||
|
import SidebarItems from './SidebarItems' |
||||
import Logo from '../../assets/images/fastapi-logo.svg'; |
|
||||
import { UserOut } from '../../client'; |
|
||||
import useAuth from '../../hooks/useAuth'; |
|
||||
import SidebarItems from './SidebarItems'; |
|
||||
|
|
||||
const Sidebar: React.FC = () => { |
const Sidebar: React.FC = () => { |
||||
const queryClient = useQueryClient(); |
const queryClient = useQueryClient() |
||||
const bgColor = useColorModeValue('white', '#1a202c'); |
const bgColor = useColorModeValue('white', '#1a202c') |
||||
const textColor = useColorModeValue('gray', 'white'); |
const textColor = useColorModeValue('gray', 'white') |
||||
const secBgColor = useColorModeValue('ui.secondary', '#252d3d'); |
const secBgColor = useColorModeValue('ui.secondary', '#252d3d') |
||||
const currentUser = queryClient.getQueryData<UserOut>('currentUser'); |
const currentUser = queryClient.getQueryData<UserOut>('currentUser') |
||||
const { isOpen, onOpen, onClose } = useDisclosure(); |
const { isOpen, onOpen, onClose } = useDisclosure() |
||||
const { logout } = useAuth(); |
const { logout } = useAuth() |
||||
|
|
||||
const handleLogout = async () => { |
const handleLogout = async () => { |
||||
logout() |
logout() |
||||
}; |
} |
||||
|
|
||||
|
|
||||
return ( |
return ( |
||||
<> |
<> |
||||
{/* Mobile */} |
{/* Mobile */} |
||||
<IconButton onClick={onOpen} display={{ base: 'flex', md: 'none' }} aria-label='Open Menu' position='absolute' fontSize='20px' m={4} icon={<FiMenu />} /> |
<IconButton |
||||
<Drawer isOpen={isOpen} placement='left' onClose={onClose}> |
onClick={onOpen} |
||||
|
display={{ base: 'flex', md: 'none' }} |
||||
|
aria-label="Open Menu" |
||||
|
position="absolute" |
||||
|
fontSize="20px" |
||||
|
m={4} |
||||
|
icon={<FiMenu />} |
||||
|
/> |
||||
|
<Drawer isOpen={isOpen} placement="left" onClose={onClose}> |
||||
<DrawerOverlay /> |
<DrawerOverlay /> |
||||
<DrawerContent maxW='250px'> |
<DrawerContent maxW="250px"> |
||||
<DrawerCloseButton /> |
<DrawerCloseButton /> |
||||
<DrawerBody py={8}> |
<DrawerBody py={8}> |
||||
<Flex flexDir='column' justify='space-between'> |
<Flex flexDir="column" justify="space-between"> |
||||
<Box> |
<Box> |
||||
<Image src={Logo} alt='logo' p={6} /> |
<Image src={Logo} alt="logo" p={6} /> |
||||
<SidebarItems onClose={onClose} /> |
<SidebarItems onClose={onClose} /> |
||||
<Flex as='button' onClick={handleLogout} p={2} color='ui.danger' fontWeight='bold' alignItems='center'> |
<Flex |
||||
|
as="button" |
||||
|
onClick={handleLogout} |
||||
|
p={2} |
||||
|
color="ui.danger" |
||||
|
fontWeight="bold" |
||||
|
alignItems="center" |
||||
|
> |
||||
<FiLogOut /> |
<FiLogOut /> |
||||
<Text ml={2}>Log out</Text> |
<Text ml={2}>Log out</Text> |
||||
</Flex> |
</Flex> |
||||
</Box> |
</Box> |
||||
{ |
{currentUser?.email && ( |
||||
currentUser?.email && |
<Text color={textColor} noOfLines={2} fontSize="sm" p={2}> |
||||
<Text color={textColor} noOfLines={2} fontSize='sm' p={2}>Logged in as: {currentUser.email}</Text> |
Logged in as: {currentUser.email} |
||||
} |
</Text> |
||||
|
)} |
||||
</Flex> |
</Flex> |
||||
</DrawerBody> |
</DrawerBody> |
||||
</DrawerContent> |
</DrawerContent> |
||||
</Drawer> |
</Drawer> |
||||
|
|
||||
{/* Desktop */} |
{/* Desktop */} |
||||
<Box bg={bgColor} p={3} h='100vh' position='sticky' top='0' display={{ base: 'none', md: 'flex' }}> |
<Box |
||||
<Flex flexDir='column' justify='space-between' bg={secBgColor} p={4} borderRadius={12}> |
bg={bgColor} |
||||
|
p={3} |
||||
|
h="100vh" |
||||
|
position="sticky" |
||||
|
top="0" |
||||
|
display={{ base: 'none', md: 'flex' }} |
||||
|
> |
||||
|
<Flex |
||||
|
flexDir="column" |
||||
|
justify="space-between" |
||||
|
bg={secBgColor} |
||||
|
p={4} |
||||
|
borderRadius={12} |
||||
|
> |
||||
<Box> |
<Box> |
||||
<Image src={Logo} alt='Logo' w='180px' maxW='2xs' p={6} /> |
<Image src={Logo} alt="Logo" w="180px" maxW="2xs" p={6} /> |
||||
<SidebarItems /> |
<SidebarItems /> |
||||
</Box> |
</Box> |
||||
{ |
{currentUser?.email && ( |
||||
currentUser?.email && |
<Text |
||||
<Text color={textColor} noOfLines={2} fontSize='sm' p={2} maxW='180px'>Logged in as: {currentUser.email}</Text> |
color={textColor} |
||||
} |
noOfLines={2} |
||||
|
fontSize="sm" |
||||
|
p={2} |
||||
|
maxW="180px" |
||||
|
> |
||||
|
Logged in as: {currentUser.email} |
||||
|
</Text> |
||||
|
)} |
||||
</Flex> |
</Flex> |
||||
</Box> |
</Box> |
||||
</> |
</> |
||||
); |
) |
||||
} |
} |
||||
|
|
||||
export default Sidebar; |
export default Sidebar |
||||
|
@ -1,43 +1,59 @@ |
|||||
import React from 'react'; |
import React from 'react' |
||||
|
import { |
||||
|
Box, |
||||
|
IconButton, |
||||
|
Menu, |
||||
|
MenuButton, |
||||
|
MenuItem, |
||||
|
MenuList, |
||||
|
} from '@chakra-ui/react' |
||||
|
import { FaUserAstronaut } from 'react-icons/fa' |
||||
|
import { FiLogOut, FiUser } from 'react-icons/fi' |
||||
|
|
||||
import { Box, IconButton, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react'; |
import useAuth from '../../hooks/useAuth' |
||||
import { FaUserAstronaut } from 'react-icons/fa'; |
import { Link } from '@tanstack/react-router' |
||||
import { FiLogOut, FiUser } from 'react-icons/fi'; |
|
||||
|
|
||||
import useAuth from '../../hooks/useAuth'; |
|
||||
import { Link } from '@tanstack/react-router'; |
|
||||
|
|
||||
const UserMenu: React.FC = () => { |
const UserMenu: React.FC = () => { |
||||
const { logout } = useAuth(); |
const { logout } = useAuth() |
||||
|
|
||||
const handleLogout = async () => { |
const handleLogout = async () => { |
||||
logout() |
logout() |
||||
}; |
} |
||||
|
|
||||
return ( |
return ( |
||||
<> |
<> |
||||
{/* Desktop */} |
{/* Desktop */} |
||||
<Box display={{ base: 'none', md: 'block' }} position='fixed' top={4} right={4}> |
<Box |
||||
|
display={{ base: 'none', md: 'block' }} |
||||
|
position="fixed" |
||||
|
top={4} |
||||
|
right={4} |
||||
|
> |
||||
<Menu> |
<Menu> |
||||
<MenuButton |
<MenuButton |
||||
as={IconButton} |
as={IconButton} |
||||
aria-label='Options' |
aria-label="Options" |
||||
icon={<FaUserAstronaut color='white' fontSize='18px' />} |
icon={<FaUserAstronaut color="white" fontSize="18px" />} |
||||
bg='ui.main' |
bg="ui.main" |
||||
isRound |
isRound |
||||
/> |
/> |
||||
<MenuList> |
<MenuList> |
||||
<MenuItem icon={<FiUser fontSize='18px' />} as={Link} to='settings'> |
<MenuItem icon={<FiUser fontSize="18px" />} as={Link} to="settings"> |
||||
My profile |
My profile |
||||
</MenuItem> |
</MenuItem> |
||||
<MenuItem icon={<FiLogOut fontSize='18px' />} onClick={handleLogout} color='ui.danger' fontWeight='bold'> |
<MenuItem |
||||
|
icon={<FiLogOut fontSize="18px" />} |
||||
|
onClick={handleLogout} |
||||
|
color="ui.danger" |
||||
|
fontWeight="bold" |
||||
|
> |
||||
Log out |
Log out |
||||
</MenuItem> |
</MenuItem> |
||||
</MenuList> |
</MenuList> |
||||
</Menu> |
</Menu> |
||||
</Box> |
</Box> |
||||
</> |
</> |
||||
); |
) |
||||
}; |
} |
||||
|
|
||||
export default UserMenu; |
export default UserMenu |
||||
|
@ -1,29 +1,39 @@ |
|||||
import React from 'react'; |
import React from 'react' |
||||
|
import { |
||||
import { Badge, Container, Heading, Radio, RadioGroup, Stack, useColorMode } from '@chakra-ui/react'; |
Badge, |
||||
|
Container, |
||||
|
Heading, |
||||
|
Radio, |
||||
|
RadioGroup, |
||||
|
Stack, |
||||
|
useColorMode, |
||||
|
} from '@chakra-ui/react' |
||||
|
|
||||
const Appearance: React.FC = () => { |
const Appearance: React.FC = () => { |
||||
const { colorMode, toggleColorMode } = useColorMode(); |
const { colorMode, toggleColorMode } = useColorMode() |
||||
|
|
||||
return ( |
return ( |
||||
<> |
<> |
||||
<Container maxW='full'> |
<Container maxW="full"> |
||||
<Heading size='sm' py={4}> |
<Heading size="sm" py={4}> |
||||
Appearance |
Appearance |
||||
</Heading> |
</Heading> |
||||
<RadioGroup onChange={toggleColorMode} value={colorMode}> |
<RadioGroup onChange={toggleColorMode} value={colorMode}> |
||||
<Stack> |
<Stack> |
||||
{/* TODO: Add system default option */} |
{/* TODO: Add system default option */} |
||||
<Radio value='light' colorScheme='teal'> |
<Radio value="light" colorScheme="teal"> |
||||
Light mode<Badge ml='1' colorScheme='teal'>Default</Badge> |
Light mode |
||||
|
<Badge ml="1" colorScheme="teal"> |
||||
|
Default |
||||
|
</Badge> |
||||
</Radio> |
</Radio> |
||||
<Radio value='dark' colorScheme='teal'> |
<Radio value="dark" colorScheme="teal"> |
||||
Dark mode |
Dark mode |
||||
</Radio> |
</Radio> |
||||
</Stack> |
</Stack> |
||||
</RadioGroup> |
</RadioGroup> |
||||
</Container> |
</Container> |
||||
</> |
</> |
||||
); |
) |
||||
} |
} |
||||
export default Appearance; |
export default Appearance |
||||
|
@ -1,27 +1,42 @@ |
|||||
import React from 'react'; |
import React from 'react' |
||||
|
import { |
||||
|
Button, |
||||
|
Container, |
||||
|
Heading, |
||||
|
Text, |
||||
|
useDisclosure, |
||||
|
} from '@chakra-ui/react' |
||||
|
|
||||
import { Button, Container, Heading, Text, useDisclosure } from '@chakra-ui/react'; |
import DeleteConfirmation from './DeleteConfirmation' |
||||
|
|
||||
import DeleteConfirmation from './DeleteConfirmation'; |
|
||||
|
|
||||
const DeleteAccount: React.FC = () => { |
const DeleteAccount: React.FC = () => { |
||||
const confirmationModal = useDisclosure(); |
const confirmationModal = useDisclosure() |
||||
|
|
||||
return ( |
return ( |
||||
<> |
<> |
||||
<Container maxW='full'> |
<Container maxW="full"> |
||||
<Heading size='sm' py={4}> |
<Heading size="sm" py={4}> |
||||
Delete Account |
Delete Account |
||||
</Heading> |
</Heading> |
||||
<Text> |
<Text> |
||||
Are you sure you want to delete your account? This action cannot be undone. |
Are you sure you want to delete your account? This action cannot be |
||||
|
undone. |
||||
</Text> |
</Text> |
||||
<Button bg='ui.danger' color='white' _hover={{ opacity: 0.8 }} mt={4} onClick={confirmationModal.onOpen}> |
<Button |
||||
|
bg="ui.danger" |
||||
|
color="white" |
||||
|
_hover={{ opacity: 0.8 }} |
||||
|
mt={4} |
||||
|
onClick={confirmationModal.onOpen} |
||||
|
> |
||||
Delete |
Delete |
||||
</Button> |
</Button> |
||||
<DeleteConfirmation isOpen={confirmationModal.isOpen} onClose={confirmationModal.onClose} /> |
<DeleteConfirmation |
||||
|
isOpen={confirmationModal.isOpen} |
||||
|
onClose={confirmationModal.onClose} |
||||
|
/> |
||||
</Container> |
</Container> |
||||
</> |
</> |
||||
); |
) |
||||
} |
} |
||||
export default DeleteAccount; |
export default DeleteAccount |
||||
|
@ -1,33 +1,42 @@ |
|||||
import { useQuery } from 'react-query'; |
import { useQuery } from 'react-query' |
||||
import { useNavigate } from '@tanstack/react-router'; |
import { useNavigate } from '@tanstack/react-router' |
||||
|
|
||||
import { Body_login_login_access_token as AccessToken, LoginService, UserOut, UsersService } from '../client'; |
import { |
||||
|
Body_login_login_access_token as AccessToken, |
||||
|
LoginService, |
||||
|
UserOut, |
||||
|
UsersService, |
||||
|
} from '../client' |
||||
|
|
||||
const isLoggedIn = () => { |
const isLoggedIn = () => { |
||||
return localStorage.getItem('access_token') !== null; |
return localStorage.getItem('access_token') !== null |
||||
}; |
} |
||||
|
|
||||
const useAuth = () => { |
const useAuth = () => { |
||||
const navigate = useNavigate(); |
const navigate = useNavigate() |
||||
const { data: user, isLoading } = useQuery<UserOut | null, Error>('currentUser', UsersService.readUserMe, { |
const { data: user, isLoading } = useQuery<UserOut | null, Error>( |
||||
|
'currentUser', |
||||
|
UsersService.readUserMe, |
||||
|
{ |
||||
enabled: isLoggedIn(), |
enabled: isLoggedIn(), |
||||
}); |
}, |
||||
|
) |
||||
|
|
||||
const login = async (data: AccessToken) => { |
const login = async (data: AccessToken) => { |
||||
const response = await LoginService.loginAccessToken({ |
const response = await LoginService.loginAccessToken({ |
||||
formData: data, |
formData: data, |
||||
}); |
}) |
||||
localStorage.setItem('access_token', response.access_token); |
localStorage.setItem('access_token', response.access_token) |
||||
navigate({ to: '/' }); |
navigate({ to: '/' }) |
||||
}; |
} |
||||
|
|
||||
const logout = () => { |
const logout = () => { |
||||
localStorage.removeItem('access_token'); |
localStorage.removeItem('access_token') |
||||
navigate({ to: '/login' }); |
navigate({ to: '/login' }) |
||||
}; |
} |
||||
|
|
||||
return { login, logout, user, isLoading }; |
return { login, logout, user, isLoading } |
||||
} |
} |
||||
|
|
||||
export { isLoggedIn }; |
export { isLoggedIn } |
||||
export default useAuth; |
export default useAuth |
||||
|
@ -1,21 +1,23 @@ |
|||||
import { useCallback } from 'react'; |
import { useCallback } from 'react' |
||||
|
import { useToast } from '@chakra-ui/react' |
||||
import { useToast } from '@chakra-ui/react'; |
|
||||
|
|
||||
const useCustomToast = () => { |
const useCustomToast = () => { |
||||
const toast = useToast(); |
const toast = useToast() |
||||
|
|
||||
const showToast = useCallback((title: string, description: string, status: 'success' | 'error') => { |
const showToast = useCallback( |
||||
|
(title: string, description: string, status: 'success' | 'error') => { |
||||
toast({ |
toast({ |
||||
title, |
title, |
||||
description, |
description, |
||||
status, |
status, |
||||
isClosable: true, |
isClosable: true, |
||||
position: 'bottom-right' |
position: 'bottom-right', |
||||
}); |
}) |
||||
}, [toast]); |
}, |
||||
|
[toast], |
||||
|
) |
||||
|
|
||||
return showToast; |
return showToast |
||||
}; |
} |
||||
|
|
||||
export default useCustomToast; |
export default useCustomToast |
||||
|
@ -1,27 +1,28 @@ |
|||||
|
import { Container, Text } from '@chakra-ui/react' |
||||
|
import { useQueryClient } from 'react-query' |
||||
|
import { createFileRoute } from '@tanstack/react-router' |
||||
|
|
||||
import { Container, Text } from '@chakra-ui/react'; |
import { UserOut } from '../../client' |
||||
import { useQueryClient } from 'react-query'; |
|
||||
import { createFileRoute } from '@tanstack/react-router'; |
|
||||
|
|
||||
import { UserOut } from '../../client'; |
|
||||
|
|
||||
export const Route = createFileRoute('/_layout/')({ |
export const Route = createFileRoute('/_layout/')({ |
||||
component: Dashboard, |
component: Dashboard, |
||||
}) |
}) |
||||
|
|
||||
function Dashboard() { |
function Dashboard() { |
||||
const queryClient = useQueryClient(); |
const queryClient = useQueryClient() |
||||
|
|
||||
const currentUser = queryClient.getQueryData<UserOut>('currentUser'); |
const currentUser = queryClient.getQueryData<UserOut>('currentUser') |
||||
|
|
||||
return ( |
return ( |
||||
<> |
<> |
||||
<Container maxW='full' pt={12}> |
<Container maxW="full" pt={12}> |
||||
<Text fontSize='2xl'>Hi, {currentUser?.full_name || currentUser?.email} 👋🏼</Text> |
<Text fontSize="2xl"> |
||||
|
Hi, {currentUser?.full_name || currentUser?.email} 👋🏼 |
||||
|
</Text> |
||||
<Text>Welcome back, nice to see you again!</Text> |
<Text>Welcome back, nice to see you again!</Text> |
||||
</Container> |
</Container> |
||||
</> |
</> |
||||
) |
) |
||||
} |
} |
||||
|
|
||||
export default Dashboard; |
export default Dashboard |
||||
|
Loading…
Reference in new issue