mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: added eslint & fixed errors
This commit is contained in:
parent
5c0599fe0a
commit
ef07c9c7be
20
.eslintrc.json
Normal file
20
.eslintrc.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended"],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"jsx": true
|
||||||
|
},
|
||||||
|
"ecmaVersion": "latest",
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"plugins": ["react", "@typescript-eslint"],
|
||||||
|
"rules": {
|
||||||
|
"react/display-name": "off",
|
||||||
|
"react/prop-types": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
1382
package-lock.json
generated
1382
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -44,7 +44,11 @@
|
|||||||
"@types/react-helmet": "^6.1.2",
|
"@types/react-helmet": "^6.1.2",
|
||||||
"@types/react-router-dom": "^5.1.8",
|
"@types/react-router-dom": "^5.1.8",
|
||||||
"@types/validator": "^13.6.3",
|
"@types/validator": "^13.6.3",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
||||||
|
"@typescript-eslint/parser": "^5.6.0",
|
||||||
"@vitejs/plugin-react": "^1.0.0",
|
"@vitejs/plugin-react": "^1.0.0",
|
||||||
|
"eslint": "^8.4.1",
|
||||||
|
"eslint-plugin-react": "^7.27.1",
|
||||||
"rollup-plugin-visualizer": "^5.5.2",
|
"rollup-plugin-visualizer": "^5.5.2",
|
||||||
"typescript": "^4.5.2",
|
"typescript": "^4.5.2",
|
||||||
"vite": "^2.6.4"
|
"vite": "^2.6.4"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogBody,
|
AlertDialogBody,
|
||||||
|
|||||||
@ -36,7 +36,7 @@ const DeleteCourseDialog: React.FC<DeleteCourseDialogPropsType> = ({ onClose, is
|
|||||||
if (isMountedRef.current && location.pathname !== '/courses') {
|
if (isMountedRef.current && location.pathname !== '/courses') {
|
||||||
history.push('/courses');
|
history.push('/courses');
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const DeleteLessonDialog: React.FC<DeleteLessonDialogPropsType> = ({ lesson, isO
|
|||||||
if (isConfirmed) {
|
if (isConfirmed) {
|
||||||
try {
|
try {
|
||||||
await deleteLesson(lesson.id);
|
await deleteLesson(lesson.id);
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ const DeleteUserDialog: React.FC<DeleteUserDialogPropsType> = ({ isOpen, onClose
|
|||||||
role: searchingRole,
|
role: searchingRole,
|
||||||
search,
|
search,
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
|
import axios, { AxiosError } from 'axios';
|
||||||
import { Redirect } from 'react-router';
|
import { Redirect } from 'react-router';
|
||||||
import { Icon, Box, Heading, Text } from '@chakra-ui/react';
|
import { Icon, Box, Heading, Text } from '@chakra-ui/react';
|
||||||
import { MdError } from 'react-icons/md';
|
import { MdError } from 'react-icons/md';
|
||||||
@ -11,7 +12,7 @@ import { useEffect } from 'react';
|
|||||||
import { useToast } from '@chakra-ui/toast';
|
import { useToast } from '@chakra-ui/toast';
|
||||||
import { useRootStore } from '@educt/hooks/useRootStore';
|
import { useRootStore } from '@educt/hooks/useRootStore';
|
||||||
|
|
||||||
const ErrorFallback: React.FC<{ error: any }> = props => {
|
const ErrorFallback: React.FC<{ error: Error | AxiosError }> = props => {
|
||||||
const { userStore, authStore } = useRootStore();
|
const { userStore, authStore } = useRootStore();
|
||||||
const { error } = props;
|
const { error } = props;
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
@ -20,6 +21,7 @@ const ErrorFallback: React.FC<{ error: any }> = props => {
|
|||||||
toast({ title: `${error.message}`, duration: 10000, isClosable: true, status: 'error' });
|
toast({ title: `${error.message}`, duration: 10000, isClosable: true, status: 'error' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (axios.isAxiosError(error)) {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
if (error.response.status === 401) {
|
if (error.response.status === 401) {
|
||||||
userStore.me = null;
|
userStore.me = null;
|
||||||
@ -27,6 +29,7 @@ const ErrorFallback: React.FC<{ error: any }> = props => {
|
|||||||
Cookies.remove('logged_in');
|
Cookies.remove('logged_in');
|
||||||
} else if (error.response.status === 404) return <Redirect to='/404' />;
|
} else if (error.response.status === 404) return <Redirect to='/404' />;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box textAlign='center' mt={40}>
|
<Box textAlign='center' mt={40}>
|
||||||
|
|||||||
@ -47,7 +47,9 @@ export const PasswordField = React.forwardRef<HTMLInputElement, PasswordFieldPro
|
|||||||
<FormLabel>Password</FormLabel>
|
<FormLabel>Password</FormLabel>
|
||||||
</Flex>
|
</Flex>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<InputLeftElement children={<Icon as={MdVpnKey} />} />
|
<InputLeftElement>
|
||||||
|
<Icon as={MdVpnKey} />
|
||||||
|
</InputLeftElement>
|
||||||
<InputRightElement>
|
<InputRightElement>
|
||||||
<IconButton
|
<IconButton
|
||||||
bg='transparent !important'
|
bg='transparent !important'
|
||||||
@ -74,3 +76,5 @@ export const PasswordField = React.forwardRef<HTMLInputElement, PasswordFieldPro
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PasswordField.displayName = 'PasswordField';
|
||||||
|
|||||||
@ -19,7 +19,6 @@ import FileSelect from '@educt/components/FileSelect';
|
|||||||
/**
|
/**
|
||||||
* Hooks
|
* Hooks
|
||||||
*/
|
*/
|
||||||
import { useToast } from '@chakra-ui/toast';
|
|
||||||
import { useErrorHandler } from 'react-error-boundary';
|
import { useErrorHandler } from 'react-error-boundary';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +50,6 @@ const CourseForm: React.FC<CourseFormPropsType> = ({ onSubmit, buttonLabel, isLo
|
|||||||
} = reactHookForm;
|
} = reactHookForm;
|
||||||
|
|
||||||
const handleError = useErrorHandler();
|
const handleError = useErrorHandler();
|
||||||
const toast = useToast();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load users into select field
|
* Load users into select field
|
||||||
@ -64,13 +62,9 @@ const CourseForm: React.FC<CourseFormPropsType> = ({ onSubmit, buttonLabel, isLo
|
|||||||
label: user.fullname,
|
label: user.fullname,
|
||||||
value: user.id,
|
value: user.id,
|
||||||
}));
|
}));
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
if (error.response) {
|
|
||||||
toast({ title: 'Error' });
|
|
||||||
} else {
|
|
||||||
handleError(error);
|
handleError(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,13 +77,9 @@ const CourseForm: React.FC<CourseFormPropsType> = ({ onSubmit, buttonLabel, isLo
|
|||||||
label: category.title,
|
label: category.title,
|
||||||
value: category.id,
|
value: category.id,
|
||||||
}));
|
}));
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
if (error.response) {
|
|
||||||
toast({ title: 'Error' });
|
|
||||||
} else {
|
|
||||||
handleError(error);
|
handleError(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const watchTitle = watch('title');
|
const watchTitle = watch('title');
|
||||||
@ -102,14 +92,11 @@ const CourseForm: React.FC<CourseFormPropsType> = ({ onSubmit, buttonLabel, isLo
|
|||||||
<FormLabel>Name</FormLabel>
|
<FormLabel>Name</FormLabel>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<Input pr='60px' size='md' placeholder='Course name' type='text' {...register('title')} />
|
<Input pr='60px' size='md' placeholder='Course name' type='text' {...register('title')} />
|
||||||
<InputRightElement
|
<InputRightElement mr='2'>
|
||||||
mr='2'
|
|
||||||
children={
|
|
||||||
<Text as='small' color={!!errors.title || watchTitle?.length > 90 ? 'red.500' : 'gray.500'}>
|
<Text as='small' color={!!errors.title || watchTitle?.length > 90 ? 'red.500' : 'gray.500'}>
|
||||||
{watchTitle?.length || 0}/90
|
{watchTitle?.length || 0}/90
|
||||||
</Text>
|
</Text>
|
||||||
}
|
</InputRightElement>
|
||||||
/>
|
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<FormHelperText>e.g Web Development in Javascript</FormHelperText>
|
<FormHelperText>e.g Web Development in Javascript</FormHelperText>
|
||||||
<Text as='small' color='red.500'>
|
<Text as='small' color='red.500'>
|
||||||
|
|||||||
@ -26,9 +26,7 @@ import { useCreateCourse } from '@educt/hooks/queries';
|
|||||||
*/
|
*/
|
||||||
import CourseFormSchema from './CourseForm.validator';
|
import CourseFormSchema from './CourseForm.validator';
|
||||||
|
|
||||||
type CreateFormCoursePropsType = {};
|
const CreateFormCourse: React.FC = () => {
|
||||||
|
|
||||||
const CreateFormCourse: React.FC<CreateFormCoursePropsType> = () => {
|
|
||||||
const form = useForm<InputFields>({ resolver: yupResolver(CourseFormSchema) });
|
const form = useForm<InputFields>({ resolver: yupResolver(CourseFormSchema) });
|
||||||
const { createCourse, isLoading } = useCreateCourse();
|
const { createCourse, isLoading } = useCreateCourse();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|||||||
@ -29,10 +29,10 @@ const AddStudentsModal: React.FC<AddStudentsModalPropsType> = ({ isOpen, onClose
|
|||||||
const ids = students.map(s => s.id);
|
const ids = students.map(s => s.id);
|
||||||
await CourseServiceInstance.attachStudentsList(courseId, ids);
|
await CourseServiceInstance.attachStudentsList(courseId, ids);
|
||||||
|
|
||||||
toast({ title: 'Students successfully attached.', status: 'success' });
|
toast({ title: 'Students successfully added.', status: 'success' });
|
||||||
onClose();
|
onClose();
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
throw error;
|
console.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
if (isMountedRef.current) setIsLoading(false);
|
if (isMountedRef.current) setIsLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ const SelectUsersInput: React.FC<SelectUsersInputPropsType> = ({ placeholder, se
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const { data } = await UserServiceInstance.fetchAll({ search, ...params });
|
const { data } = await UserServiceInstance.fetchAll({ search, ...params });
|
||||||
setUsers(data);
|
setUsers(data);
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@ -58,6 +58,7 @@ const SelectUsersInput: React.FC<SelectUsersInputPropsType> = ({ placeholder, se
|
|||||||
return updated;
|
return updated;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveSelected = (id: IUser['id']) => () => {
|
const handleRemoveSelected = (id: IUser['id']) => () => {
|
||||||
setSelected(prev => {
|
setSelected(prev => {
|
||||||
const updated = prev.filter(u => u.id !== id);
|
const updated = prev.filter(u => u.id !== id);
|
||||||
@ -91,7 +92,9 @@ const SelectUsersInput: React.FC<SelectUsersInputPropsType> = ({ placeholder, se
|
|||||||
type='text'
|
type='text'
|
||||||
placeholder={placeholder || 'Search for users...'}
|
placeholder={placeholder || 'Search for users...'}
|
||||||
/>
|
/>
|
||||||
<InputRightElement pointerEvents='none' children={<SearchIcon color='gray.300' />} />
|
<InputRightElement pointerEvents='none'>
|
||||||
|
<SearchIcon color='gray.300' />
|
||||||
|
</InputRightElement>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { BadgeProps, Badge, Box } from '@chakra-ui/react';
|
import { BadgeProps, Badge } from '@chakra-ui/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { UserRoleEnum } from '@educt/enums';
|
import { UserRoleEnum } from '@educt/enums';
|
||||||
import { IUserRole } from '@educt/interfaces';
|
import { IUserRole } from '@educt/interfaces';
|
||||||
|
|||||||
@ -6,23 +6,23 @@ export const StoreContext = createContext<RootStore | undefined>(undefined);
|
|||||||
|
|
||||||
export const ChangeEmailPageContext = createContext<ChangeEmailPageContextType>({
|
export const ChangeEmailPageContext = createContext<ChangeEmailPageContextType>({
|
||||||
isCodeSent: false,
|
isCodeSent: false,
|
||||||
setIsCodeSent: () => {},
|
setIsCodeSent: () => null,
|
||||||
confirmEmailData: undefined,
|
confirmEmailData: undefined,
|
||||||
setConfirmEmailData: () => {},
|
setConfirmEmailData: () => null,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const UsersPageContext = createContext<UsersPageContextType>({
|
export const UsersPageContext = createContext<UsersPageContextType>({
|
||||||
searchingRole: undefined,
|
searchingRole: undefined,
|
||||||
setSearchingRole: () => {},
|
setSearchingRole: () => null,
|
||||||
searchingPage: 1,
|
searchingPage: 1,
|
||||||
setSearchingPage: () => {},
|
setSearchingPage: () => null,
|
||||||
search: undefined,
|
search: undefined,
|
||||||
setSearch: () => {},
|
setSearch: () => null,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const CoursesPageContext = createContext<CoursesPageContextType>({
|
export const CoursesPageContext = createContext<CoursesPageContextType>({
|
||||||
selectedCategory: undefined,
|
selectedCategory: undefined,
|
||||||
setSelectedCategory: () => {},
|
setSelectedCategory: () => null,
|
||||||
courseStatus: undefined,
|
courseStatus: undefined,
|
||||||
setCourseStatus: () => {},
|
setCourseStatus: () => null,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useRootStore } from '../../useRootStore';
|
|||||||
import { useErrorHandler } from 'react-error-boundary';
|
import { useErrorHandler } from 'react-error-boundary';
|
||||||
import useAsync from '../../useAsync';
|
import useAsync from '../../useAsync';
|
||||||
|
|
||||||
type LogoutResultDataType = {};
|
type LogoutResultDataType = Record<string, never>;
|
||||||
|
|
||||||
const useLogout = () => {
|
const useLogout = () => {
|
||||||
const { authStore } = useRootStore();
|
const { authStore } = useRootStore();
|
||||||
@ -18,7 +18,7 @@ const useLogout = () => {
|
|||||||
history.push('/auth');
|
history.push('/auth');
|
||||||
toast({ title: 'You are logged out.', isClosable: true, status: 'info' });
|
toast({ title: 'You are logged out.', isClosable: true, status: 'info' });
|
||||||
return result.data;
|
return result.data;
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import useAsync from '../../useAsync';
|
|||||||
import { useRootStore } from '../../useRootStore';
|
import { useRootStore } from '../../useRootStore';
|
||||||
import { useToast } from '@chakra-ui/toast';
|
import { useToast } from '@chakra-ui/toast';
|
||||||
|
|
||||||
type SetCourseStatusResultDataType = {};
|
type SetCourseStatusResultDataType = Record<string, never>;
|
||||||
export type SetCourseStatusFnType = (id: string, newStatus: CourseStatusEnum) => Promise<SetCourseStatusResultDataType>;
|
export type SetCourseStatusFnType = (id: string, newStatus: CourseStatusEnum) => Promise<SetCourseStatusResultDataType>;
|
||||||
|
|
||||||
const useSetCourseStatus = () => {
|
const useSetCourseStatus = () => {
|
||||||
|
|||||||
@ -9,9 +9,8 @@ import {
|
|||||||
Icon,
|
Icon,
|
||||||
Text,
|
Text,
|
||||||
Stack,
|
Stack,
|
||||||
Box,
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { MdAccountCircle, MdVpnKey } from 'react-icons/md';
|
import { MdAccountCircle } from 'react-icons/md';
|
||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +57,9 @@ const AuthForm: React.FC = () => {
|
|||||||
<FormControl id='login'>
|
<FormControl id='login'>
|
||||||
<FormLabel>Login</FormLabel>
|
<FormLabel>Login</FormLabel>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<InputLeftElement children={<Icon as={MdAccountCircle} />} />
|
<InputLeftElement>
|
||||||
|
<Icon as={MdAccountCircle} />
|
||||||
|
</InputLeftElement>
|
||||||
<Input type='text' placeholder='Login' {...register('login')} isInvalid={!!errors.login} />
|
<Input type='text' placeholder='Login' {...register('login')} isInvalid={!!errors.login} />
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<Text as='small' color='red.500'>
|
<Text as='small' color='red.500'>
|
||||||
|
|||||||
@ -74,13 +74,9 @@ const LessonList: React.FC<LessonListPropsType> = ({ course }) => {
|
|||||||
try {
|
try {
|
||||||
const data = await LessonServiceInstance.saveOrder(ids);
|
const data = await LessonServiceInstance.saveOrder(ids);
|
||||||
return data;
|
return data;
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
if (error.response) {
|
|
||||||
console.error(error);
|
|
||||||
} else {
|
|
||||||
handleError(error);
|
handleError(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragEnd = (result: DropResult) => {
|
const handleDragEnd = (result: DropResult) => {
|
||||||
|
|||||||
@ -19,8 +19,8 @@ const BulkActionsMenu: React.FC<BulkActionsMenuPropsType> = ({ selected, rows, s
|
|||||||
);
|
);
|
||||||
setRows(rows.filter(r => selected.every(s => s.id !== r.id)));
|
setRows(rows.filter(r => selected.every(s => s.id !== r.id)));
|
||||||
};
|
};
|
||||||
const handleDelete = async () => {};
|
const handleDelete = async () => undefined;
|
||||||
const handleExport = async () => {};
|
const handleExport = async () => undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu isLazy>
|
<Menu isLazy>
|
||||||
|
|||||||
@ -93,7 +93,9 @@ const StudentTableList: React.FC<StudentTableListPropsType> = props => {
|
|||||||
<Flex justifyContent='space-between' flexDir={{ base: 'column', lg: 'row' }}>
|
<Flex justifyContent='space-between' flexDir={{ base: 'column', lg: 'row' }}>
|
||||||
<Flex mb='2'>
|
<Flex mb='2'>
|
||||||
<InputGroup mr='2' borderRadius='lg'>
|
<InputGroup mr='2' borderRadius='lg'>
|
||||||
<InputLeftElement pointerEvents='none' children={<MdSearch color='gray.300' />} />
|
<InputLeftElement pointerEvents='none'>
|
||||||
|
<MdSearch color='gray.300' />
|
||||||
|
</InputLeftElement>
|
||||||
<Input value={search} size='sm' onChange={handleSearch} type='text' placeholder='Search for student...' />
|
<Input value={search} size='sm' onChange={handleSearch} type='text' placeholder='Search for student...' />
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@ -52,8 +52,6 @@ import { UsersPageContext } from '@educt/contexts';
|
|||||||
import CreateUserSchema from './CreateUserForm.validator';
|
import CreateUserSchema from './CreateUserForm.validator';
|
||||||
import { CreateButton } from '@educt/components/Buttons';
|
import { CreateButton } from '@educt/components/Buttons';
|
||||||
|
|
||||||
type CreateUserFormPropsType = {};
|
|
||||||
|
|
||||||
type CreateUserInputType = {
|
type CreateUserInputType = {
|
||||||
first_name: string;
|
first_name: string;
|
||||||
last_name: string;
|
last_name: string;
|
||||||
@ -63,7 +61,7 @@ type CreateUserInputType = {
|
|||||||
password: string;
|
password: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CreateUserModal: React.FC<CreateUserFormPropsType> = () => {
|
const CreateUserModal: React.FC = () => {
|
||||||
const { userStore } = useRootStore();
|
const { userStore } = useRootStore();
|
||||||
const { searchingRole, search } = useContext(UsersPageContext);
|
const { searchingRole, search } = useContext(UsersPageContext);
|
||||||
const { createUser, isLoading } = useCreateUser();
|
const { createUser, isLoading } = useCreateUser();
|
||||||
|
|||||||
@ -50,7 +50,9 @@ const UserSearch: React.FC = () => {
|
|||||||
<option value={UserRoleEnum.STUDENT}>Student</option>
|
<option value={UserRoleEnum.STUDENT}>Student</option>
|
||||||
</Select>
|
</Select>
|
||||||
<InputGroup maxW='400px' w='full' size='sm'>
|
<InputGroup maxW='400px' w='full' size='sm'>
|
||||||
<InputLeftElement pointerEvents='none' children={<SearchIcon color='gray.300' />} />
|
<InputLeftElement pointerEvents='none'>
|
||||||
|
<SearchIcon color='gray.300' />
|
||||||
|
</InputLeftElement>
|
||||||
<Input placeholder='Search for a user...' value={search || ''} onChange={onSearch} />
|
<Input placeholder='Search for a user...' value={search || ''} onChange={onSearch} />
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export interface AuthServiceImpl {
|
|||||||
/**
|
/**
|
||||||
* Logout user
|
* Logout user
|
||||||
*/
|
*/
|
||||||
requestLogout(): Promise<IApiRespose<{}>>;
|
requestLogout(): Promise<IApiRespose<Record<string, never>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuthService implements AuthServiceImpl {
|
class AuthService implements AuthServiceImpl {
|
||||||
@ -41,7 +41,7 @@ class AuthService implements AuthServiceImpl {
|
|||||||
*
|
*
|
||||||
* @returns Empty obj
|
* @returns Empty obj
|
||||||
*/
|
*/
|
||||||
public async requestLogout(): Promise<IApiRespose<{}>> {
|
public async requestLogout(): Promise<IApiRespose<Record<string, never>>> {
|
||||||
const result = await this.api.post('v1/auth/logout');
|
const result = await this.api.post('v1/auth/logout');
|
||||||
return result.data;
|
return result.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,7 +49,7 @@ class CourseService {
|
|||||||
* @param status Course status
|
* @param status Course status
|
||||||
* @returns Empty data
|
* @returns Empty data
|
||||||
*/
|
*/
|
||||||
public async setStatus(id: string, status: CourseStatusEnum): Promise<IApiRespose<{}>> {
|
public async setStatus(id: string, status: CourseStatusEnum): Promise<IApiRespose<Record<string, never>>> {
|
||||||
const result = await this.api.post(`/v1/courses/${id}/set-status`, {
|
const result = await this.api.post(`/v1/courses/${id}/set-status`, {
|
||||||
status,
|
status,
|
||||||
});
|
});
|
||||||
@ -97,7 +97,7 @@ class CourseService {
|
|||||||
return result.data;
|
return result.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async attachStudentsList(courseId: string, ids: Array<string>): Promise<IApiRespose<{}>> {
|
public async attachStudentsList(courseId: string, ids: Array<string>): Promise<IApiRespose<Record<string, never>>> {
|
||||||
const result = await this.api.post(
|
const result = await this.api.post(
|
||||||
`/v1/courses/${courseId}/attach-student-list`,
|
`/v1/courses/${courseId}/attach-student-list`,
|
||||||
helpers.transformToFormData({ students: ids })
|
helpers.transformToFormData({ students: ids })
|
||||||
|
|||||||
@ -99,7 +99,7 @@ class UserService {
|
|||||||
* @param newPassword New password
|
* @param newPassword New password
|
||||||
* @returns Empty object
|
* @returns Empty object
|
||||||
*/
|
*/
|
||||||
public async updatePassword(oldPassword: string, newPassword: string): Promise<IApiRespose<{}>> {
|
public async updatePassword(oldPassword: string, newPassword: string): Promise<IApiRespose<Record<string, never>>> {
|
||||||
const result = await this.api.patch('v1/me/password', {
|
const result = await this.api.patch('v1/me/password', {
|
||||||
oldPassword,
|
oldPassword,
|
||||||
newPassword,
|
newPassword,
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import RootStore from './RootStore';
|
|||||||
export default class AuthStore {
|
export default class AuthStore {
|
||||||
public root: RootStore;
|
public root: RootStore;
|
||||||
|
|
||||||
public isLoggedIn: boolean = !!Cookies.get('logged_in');
|
public isLoggedIn = !!Cookies.get('logged_in');
|
||||||
|
|
||||||
constructor(root: RootStore) {
|
constructor(root: RootStore) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@ -26,28 +26,20 @@ export default class AuthStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async login(login: string, password: string) {
|
public async login(login: string, password: string) {
|
||||||
try {
|
|
||||||
const result = await AuthServiceInstance.requestLogin(login, password);
|
const result = await AuthServiceInstance.requestLogin(login, password);
|
||||||
|
|
||||||
this.setIsLoggedIn(true);
|
this.setIsLoggedIn(true);
|
||||||
Cookies.set('logged_in', 'true');
|
Cookies.set('logged_in', 'true');
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async logout() {
|
public async logout() {
|
||||||
try {
|
|
||||||
const result = await AuthServiceInstance.requestLogout();
|
const result = await AuthServiceInstance.requestLogout();
|
||||||
|
|
||||||
this.setIsLoggedIn(false);
|
this.setIsLoggedIn(false);
|
||||||
this.root.userStore.reset();
|
this.root.userStore.reset();
|
||||||
Cookies.remove('logged_in');
|
Cookies.remove('logged_in');
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export default class CategoryStore {
|
|||||||
|
|
||||||
public categories: ICategory[] | null = null;
|
public categories: ICategory[] | null = null;
|
||||||
|
|
||||||
public isLoading: boolean = false;
|
public isLoading = false;
|
||||||
|
|
||||||
constructor(root: RootStore) {
|
constructor(root: RootStore) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@ -41,8 +41,6 @@ export default class CategoryStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
} finally {
|
} finally {
|
||||||
this.setLoading(false);
|
this.setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export default class CourseStore {
|
|||||||
|
|
||||||
public courses: Omit<ICourse, 'teacher' | 'students' | 'lessons'>[] | null = null;
|
public courses: Omit<ICourse, 'teacher' | 'students' | 'lessons'>[] | null = null;
|
||||||
|
|
||||||
public isLoading: boolean = false;
|
public isLoading = false;
|
||||||
|
|
||||||
constructor(root: RootStore) {
|
constructor(root: RootStore) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@ -46,15 +46,12 @@ export default class CourseStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
} finally {
|
} finally {
|
||||||
this.setLoading(false);
|
this.setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deleteCourse(id: string) {
|
public async deleteCourse(id: string) {
|
||||||
try {
|
|
||||||
const result = await CourseServiceInstance.delete(id);
|
const result = await CourseServiceInstance.delete(id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,9 +64,6 @@ export default class CourseStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setCourseStatus(id: string, status: CourseStatusEnum) {
|
public async setCourseStatus(id: string, status: CourseStatusEnum) {
|
||||||
@ -95,7 +89,7 @@ export default class CourseStore {
|
|||||||
*/
|
*/
|
||||||
const result = await CourseServiceInstance.setStatus(id, status);
|
const result = await CourseServiceInstance.setStatus(id, status);
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
/**
|
/**
|
||||||
* Resume status if there was an error on request
|
* Resume status if there was an error on request
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export default class UserStore {
|
|||||||
|
|
||||||
public pagination: IPaginationMeta | undefined;
|
public pagination: IPaginationMeta | undefined;
|
||||||
|
|
||||||
public isLoading: boolean = false;
|
public isLoading = false;
|
||||||
|
|
||||||
constructor(root: RootStore) {
|
constructor(root: RootStore) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@ -49,15 +49,12 @@ export default class UserStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
} finally {
|
} finally {
|
||||||
this.setLoading(false);
|
this.setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadCurrentUserData() {
|
public async loadCurrentUserData() {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.fetchMe();
|
const result = await UserServiceInstance.fetchMe();
|
||||||
const {
|
const {
|
||||||
data: { id, first_name, last_name, fullname, email, roles, contacts, courses, created_at, updated_at },
|
data: { id, first_name, last_name, fullname, email, roles, contacts, courses, created_at, updated_at },
|
||||||
@ -82,13 +79,9 @@ export default class UserStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createUser(data: CreateUserParamsType, paramsContext?: FetchUsersParamsType) {
|
public async createUser(data: CreateUserParamsType, paramsContext?: FetchUsersParamsType) {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.create(data);
|
const result = await UserServiceInstance.create(data);
|
||||||
|
|
||||||
if (this.users !== null) {
|
if (this.users !== null) {
|
||||||
@ -99,13 +92,9 @@ export default class UserStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateUser(id: string, params: UpdateUserParamsType) {
|
public async updateUser(id: string, params: UpdateUserParamsType) {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.update(id, params);
|
const result = await UserServiceInstance.update(id, params);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -119,9 +108,6 @@ export default class UserStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,7 +117,6 @@ export default class UserStore {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public async deleteUser(id: string, paramsContext?: FetchUsersParamsType) {
|
public async deleteUser(id: string, paramsContext?: FetchUsersParamsType) {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.delete(id);
|
const result = await UserServiceInstance.delete(id);
|
||||||
|
|
||||||
if (this.users !== null) {
|
if (this.users !== null) {
|
||||||
@ -142,9 +127,6 @@ export default class UserStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,7 +136,6 @@ export default class UserStore {
|
|||||||
* @returns Updated user contacts
|
* @returns Updated user contacts
|
||||||
*/
|
*/
|
||||||
public async updateCurrentUserContacts(data: IUserContacts) {
|
public async updateCurrentUserContacts(data: IUserContacts) {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.updateContacts(data);
|
const result = await UserServiceInstance.updateContacts(data);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -164,9 +145,6 @@ export default class UserStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,12 +155,8 @@ export default class UserStore {
|
|||||||
* @returns Data result status
|
* @returns Data result status
|
||||||
*/
|
*/
|
||||||
public async updateCurrentUserPassword(oldPassword: string, newPassword: string) {
|
public async updateCurrentUserPassword(oldPassword: string, newPassword: string) {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.updatePassword(oldPassword, newPassword);
|
const result = await UserServiceInstance.updatePassword(oldPassword, newPassword);
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,12 +166,8 @@ export default class UserStore {
|
|||||||
* @returns Expires at code in seconds
|
* @returns Expires at code in seconds
|
||||||
*/
|
*/
|
||||||
public async updateCurrentUserEmail(email: string) {
|
public async updateCurrentUserEmail(email: string) {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.updateEmail(email);
|
const result = await UserServiceInstance.updateEmail(email);
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +178,6 @@ export default class UserStore {
|
|||||||
* @returns Updated user email
|
* @returns Updated user email
|
||||||
*/
|
*/
|
||||||
public async updateCurrentUserEmailConfirm(email: string, confirmationCode: string) {
|
public async updateCurrentUserEmailConfirm(email: string, confirmationCode: string) {
|
||||||
try {
|
|
||||||
const result = await UserServiceInstance.updateEmailConfirm(email, confirmationCode);
|
const result = await UserServiceInstance.updateEmailConfirm(email, confirmationCode);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
if (this.me) {
|
if (this.me) {
|
||||||
@ -216,9 +185,6 @@ export default class UserStore {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public reset(): void {
|
public reset(): void {
|
||||||
|
|||||||
@ -23,7 +23,6 @@ export default class EditCourseStore {
|
|||||||
* @returns Course response
|
* @returns Course response
|
||||||
*/
|
*/
|
||||||
public async loadCourseById(id: string) {
|
public async loadCourseById(id: string) {
|
||||||
try {
|
|
||||||
const result = await CourseServiceInstance.fetchById(id);
|
const result = await CourseServiceInstance.fetchById(id);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -31,9 +30,6 @@ export default class EditCourseStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +39,6 @@ export default class EditCourseStore {
|
|||||||
* @returns Deleted lesson response
|
* @returns Deleted lesson response
|
||||||
*/
|
*/
|
||||||
public async deleteLessonById(id: string) {
|
public async deleteLessonById(id: string) {
|
||||||
try {
|
|
||||||
const result = await LessonServiceInstance.deleteLesson(id);
|
const result = await LessonServiceInstance.deleteLesson(id);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -53,9 +48,6 @@ export default class EditCourseStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CourseStatusEnum, UserRoleEnum } from '@educt/enums';
|
import { CourseStatusEnum, UserRoleEnum } from '@educt/enums';
|
||||||
import { ICategory, ICourse, IUser } from '@educt/interfaces';
|
import { ICategory } from '@educt/interfaces';
|
||||||
import { IconType } from 'react-icons/lib';
|
import { IconType } from 'react-icons/lib';
|
||||||
|
|
||||||
export type LinkType = {
|
export type LinkType = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user