mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: added layout
This commit is contained in:
parent
8999a36eaf
commit
5ad94b7b25
45
src/components/Stat/index.tsx
Normal file
45
src/components/Stat/index.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import {
|
||||||
|
Stat as ChakraStat,
|
||||||
|
StatProps,
|
||||||
|
useColorModeValue,
|
||||||
|
StatLabel as ChakraStatLabel,
|
||||||
|
StatLabel as ChakraStatNumber,
|
||||||
|
StatLabelProps,
|
||||||
|
Icon,
|
||||||
|
FlexProps,
|
||||||
|
Flex,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { IconType } from 'react-icons';
|
||||||
|
|
||||||
|
export const Stat: React.FC = (props: StatProps) => (
|
||||||
|
<ChakraStat
|
||||||
|
px={{ base: 4, sm: 6 }}
|
||||||
|
py='5'
|
||||||
|
bg={useColorModeValue('white', 'gray.700')}
|
||||||
|
shadow='base'
|
||||||
|
rounded='lg'
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const StatLabel: React.FC = (props: StatLabelProps) => (
|
||||||
|
<ChakraStatLabel fontWeight='medium' isTruncated color={useColorModeValue('gray.500', 'gray.400')} {...props} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const StatNumber: React.FC = (props: StatLabelProps) => (
|
||||||
|
<ChakraStatNumber mt='2' fontWeight='medium' fontSize={'5xl'} isTruncated {...props} />
|
||||||
|
);
|
||||||
|
|
||||||
|
type StatIconPropsType = {
|
||||||
|
icon: IconType;
|
||||||
|
};
|
||||||
|
export const StatIcon: React.FC<StatIconPropsType> = props => (
|
||||||
|
<Icon as={props.icon} color={useColorModeValue('gray.700', 'gray.300')} width={10} height={10} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const StatContent: React.FC<FlexProps> = props => (
|
||||||
|
<Flex justifyContent={'space-between'} alignItems={'flex-end'}>
|
||||||
|
{props.children}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
@ -13,6 +13,7 @@ const useUpdateCategory = () => {
|
|||||||
const update = async (id: string, data: UpdateCategoryParamsType) => {
|
const update = async (id: string, data: UpdateCategoryParamsType) => {
|
||||||
try {
|
try {
|
||||||
const result = await CategoryServiceInstance.update(id, data);
|
const result = await CategoryServiceInstance.update(id, data);
|
||||||
|
toast({ title: 'Category updated.', status: 'info' });
|
||||||
return result.data;
|
return result.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (axios.isAxiosError(error)) {
|
if (axios.isAxiosError(error)) {
|
||||||
|
|||||||
94
src/pages/main/components/index.tsx
Normal file
94
src/pages/main/components/index.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
BoxProps,
|
||||||
|
TextProps,
|
||||||
|
Text,
|
||||||
|
FlexProps,
|
||||||
|
Flex,
|
||||||
|
Tag,
|
||||||
|
TagLabel,
|
||||||
|
Icon,
|
||||||
|
Button,
|
||||||
|
useColorModeValue,
|
||||||
|
SimpleGrid,
|
||||||
|
SimpleGridProps,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { Card } from '@educt/components/Card';
|
||||||
|
import { MdOutlineVideoLibrary, MdOutlineGroup, MdOutlineThumbUpOffAlt, MdOutlinePlayCircle } from 'react-icons/md';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
|
export const CourseCardList: React.FC<SimpleGridProps> = props => (
|
||||||
|
<SimpleGrid
|
||||||
|
mt='4'
|
||||||
|
templateColumns={{
|
||||||
|
base: '1fr',
|
||||||
|
md: 'repeat(auto-fill, minmax(320px, 1fr))',
|
||||||
|
}}
|
||||||
|
spacing={'6'}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
export const CourseCard: React.FC<BoxProps> = props => <Card py='5' px='6' {...props} />;
|
||||||
|
export const CourseCardHeading: React.FC<BoxProps> = props => (
|
||||||
|
<Box borderLeftWidth={'5px'} borderColor={'blue.500'} pl='2' {...props} />
|
||||||
|
);
|
||||||
|
export const CourseCardTitle: React.FC<TextProps> = props => <Text fontSize={'2xl'} fontWeight={'bold'} {...props} />;
|
||||||
|
export const CourseCardCategory: React.FC = props => (
|
||||||
|
<Flex mt='2'>
|
||||||
|
<Tag size='sm' borderRadius='full' variant={'solid'}>
|
||||||
|
<TagLabel>{props.children}</TagLabel>
|
||||||
|
</Tag>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
export const CourseCardContent: React.FC<FlexProps> = props => <Flex mt='5' alignItems={'center'} {...props} />;
|
||||||
|
export const CourseCardCreated: React.FC<{ created: string }> = props => (
|
||||||
|
<Box lineHeight={'1.2rem'} mr='14'>
|
||||||
|
<Text fontWeight={'medium'} fontSize={'sm'} color={useColorModeValue('gray.500', 'gray.400')}>
|
||||||
|
Created
|
||||||
|
</Text>
|
||||||
|
<Box as='time' verticalAlign='middle' dateTime={props.created}>
|
||||||
|
{props.created}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
export const CourseCardLessons: React.FC<{ count: string | number }> = props => (
|
||||||
|
<Box>
|
||||||
|
<Flex alignItems={'center'}>
|
||||||
|
<Icon as={MdOutlineVideoLibrary} w={5} h={5} mr='3' />
|
||||||
|
<Box>
|
||||||
|
<Text fontWeight={'medium'} fontSize={'sm'} color={useColorModeValue('gray.500', 'gray.400')}>
|
||||||
|
Total lessons
|
||||||
|
</Text>
|
||||||
|
<Text>{props.count}</Text>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
export const CourseCardFooter: React.FC<FlexProps> = props => (
|
||||||
|
<Flex justifyContent={'space-between'} alignItems={'center'} mt='9' {...props} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const CourseCardStat: React.FC<{ students: string | number; likes: string | number }> = props => (
|
||||||
|
<Flex>
|
||||||
|
<Flex alignItems={'center'} mr='5'>
|
||||||
|
<Icon as={MdOutlineGroup} mr='2' w={4} h={4} />
|
||||||
|
<Text>{props.students}</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex alignItems={'center'}>
|
||||||
|
<Icon as={MdOutlineThumbUpOffAlt} mr='2' w={4} h={4} />
|
||||||
|
<Text>{props.likes}</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
export const CourseCardWatch: React.FC<{ id: string }> = props => {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Button onClick={() => history.push(`/courses/${props.id}`)} leftIcon={<MdOutlinePlayCircle />} size='sm'>
|
||||||
|
Watch
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -1,16 +1,102 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box, Heading } from '@chakra-ui/react';
|
import { Flex, Box, Text, Link, SimpleGrid, Divider } from '@chakra-ui/react';
|
||||||
|
import { Link as ReactRouterLink } from 'react-router-dom';
|
||||||
import { IPageProps } from '@educt/interfaces';
|
import { IPageProps } from '@educt/interfaces';
|
||||||
|
import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements';
|
||||||
|
import { Stat, StatContent, StatIcon, StatLabel, StatNumber } from '@educt/components/Stat';
|
||||||
|
import { MdOutlineCollectionsBookmark, MdOutlineGroup, MdOutlineMessage, MdOutlineVideoLibrary } from 'react-icons/md';
|
||||||
|
import { useRootStore } from '@educt/hooks/useRootStore';
|
||||||
|
import LoadingPage from '@educt/components/LoadingPage';
|
||||||
|
import {
|
||||||
|
CourseCard,
|
||||||
|
CourseCardCategory,
|
||||||
|
CourseCardCreated,
|
||||||
|
CourseCardHeading,
|
||||||
|
CourseCardContent,
|
||||||
|
CourseCardLessons,
|
||||||
|
CourseCardTitle,
|
||||||
|
CourseCardFooter,
|
||||||
|
CourseCardWatch,
|
||||||
|
CourseCardStat,
|
||||||
|
CourseCardList,
|
||||||
|
} from './components';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main page
|
* Main page
|
||||||
*/
|
*/
|
||||||
const MainPage: React.FC<IPageProps> = () => {
|
const MainPage: React.FC<IPageProps> = () => {
|
||||||
|
const {
|
||||||
|
userStore: { me },
|
||||||
|
} = useRootStore();
|
||||||
|
|
||||||
|
if (me === null) return <LoadingPage />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<PageWrapper>
|
||||||
<Heading as='h1'>Main page</Heading>
|
<PageHeading heading={`👋 Hello ${me.first_name},`} description="This what we've got today for you." />
|
||||||
</Box>
|
<PageContent>
|
||||||
|
<SimpleGrid columns={{ base: 1, md: 2, lg: 4 }} spacing='6'>
|
||||||
|
<Stat>
|
||||||
|
<StatLabel>Unread messages</StatLabel>
|
||||||
|
<StatContent>
|
||||||
|
<StatNumber>3</StatNumber>
|
||||||
|
<StatIcon icon={MdOutlineMessage} />
|
||||||
|
</StatContent>
|
||||||
|
</Stat>
|
||||||
|
|
||||||
|
<Stat>
|
||||||
|
<StatLabel>Registered students</StatLabel>
|
||||||
|
<StatContent>
|
||||||
|
<StatNumber>24</StatNumber>
|
||||||
|
<StatIcon icon={MdOutlineGroup} />
|
||||||
|
</StatContent>
|
||||||
|
</Stat>
|
||||||
|
|
||||||
|
<Stat>
|
||||||
|
<StatLabel>Courses</StatLabel>
|
||||||
|
<StatContent>
|
||||||
|
<StatNumber>7</StatNumber>
|
||||||
|
<StatIcon icon={MdOutlineCollectionsBookmark} />
|
||||||
|
</StatContent>
|
||||||
|
</Stat>
|
||||||
|
|
||||||
|
<Stat>
|
||||||
|
<StatLabel>Lessons</StatLabel>
|
||||||
|
<StatContent>
|
||||||
|
<StatNumber>42</StatNumber>
|
||||||
|
<StatIcon icon={MdOutlineVideoLibrary} />
|
||||||
|
</StatContent>
|
||||||
|
</Stat>
|
||||||
|
</SimpleGrid>
|
||||||
|
<Box my='8'>
|
||||||
|
<Flex justifyContent={'space-between'}>
|
||||||
|
<Text fontWeight={'medium'}>Recently added</Text>
|
||||||
|
<Link as={ReactRouterLink} fontWeight={'medium'} to='/courses'>
|
||||||
|
See all
|
||||||
|
</Link>
|
||||||
|
</Flex>
|
||||||
|
<CourseCardList>
|
||||||
|
<CourseCard>
|
||||||
|
<CourseCardHeading>
|
||||||
|
<CourseCardTitle>Javascript in a nutshell</CourseCardTitle>
|
||||||
|
<CourseCardCategory>Web Developing</CourseCardCategory>
|
||||||
|
</CourseCardHeading>
|
||||||
|
|
||||||
|
<CourseCardContent>
|
||||||
|
<CourseCardCreated created='29 Nov 2022' />
|
||||||
|
<CourseCardLessons count={26} />
|
||||||
|
</CourseCardContent>
|
||||||
|
|
||||||
|
<CourseCardFooter>
|
||||||
|
<CourseCardStat students={24} likes={14} />
|
||||||
|
<CourseCardWatch id='123' />
|
||||||
|
</CourseCardFooter>
|
||||||
|
</CourseCard>
|
||||||
|
</CourseCardList>
|
||||||
|
</Box>
|
||||||
|
<Divider />
|
||||||
|
</PageContent>
|
||||||
|
</PageWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@ export const ProfileDescription: React.FC<IProfileDescriptionProps> = props => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ProfileSignOutButton: React.FC<ButtonProps> = props => {
|
export const ProfileSignOutButton: React.FC<ButtonProps> = () => {
|
||||||
const { logout } = useLogout();
|
const { logout } = useLogout();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user