From 2c54a46eb074c64c4cdc111097fa38304abfad94 Mon Sep 17 00:00:00 2001 From: Aliwoto Date: Fri, 23 Aug 2024 03:18:09 +0330 Subject: [PATCH] Add new stuff. Signed-off-by: Aliwoto --- public/passwordreset.gif | Bin 0 -> 93759 bytes src/App.tsx | 78 +- src/api/api.ts | 4020 +++++++++++++++++++++++++--- src/apiClient.ts | 48 + src/components/menus/sideMenu.tsx | 286 +- src/pages/createTopicPage.tsx | 59 + src/pages/createUserPage.tsx | 4 +- src/pages/searchTopicPage.tsx | 146 + src/translations/appTranslation.ts | 11 + src/translations/faTranslation.ts | 13 + 10 files changed, 4143 insertions(+), 522 deletions(-) create mode 100644 public/passwordreset.gif create mode 100644 src/pages/createTopicPage.tsx create mode 100644 src/pages/searchTopicPage.tsx diff --git a/public/passwordreset.gif b/public/passwordreset.gif new file mode 100644 index 0000000000000000000000000000000000000000..31b7d79865e8345516cf257a7987f4052f2f4ad5 GIT binary patch literal 93759 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 literal 0 HcmV?d00001 diff --git a/src/App.tsx b/src/App.tsx index b3c2941..2665bd7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,8 @@ import Dashboard from './pages/dashboardPage'; import SearchUserPage from './pages/searchUserPage'; import UserInfoPage from './pages/userInfoPage'; import { Box, CircularProgress, Typography } from '@mui/material'; +import CreateTopicPage from './pages/createTopicPage'; +import SearchTopicPage from './pages/searchTopicPage'; const App: React.FC = () => { const [isLoggedIn, setIsLoggedIn] = useState(apiClient.isLoggedIn()); @@ -33,52 +35,60 @@ const App: React.FC = () => { }, []); if (isLoading) { - return ( - - - - {CurrentAppTranslation.LoadingText} - - - Please wait while we load the content for you. - - - ); + return ( + + + + {CurrentAppTranslation.LoadingText} + + + Please wait while we load the content for you. + + + ); } return ( - : } + : } /> : } /> - : } + : } + /> + : } + /> + : } /> - : } + : } /> - : } + : } /> } /> diff --git a/src/api/api.ts b/src/api/api.ts index 3e242bf..9093bc2 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -72,12 +72,145 @@ export const APIErrorCode = { ErrCodeQueryParameterNotProvided: 2139, ErrCodeTooManyPasswordChangeAttempts: 2140, ErrCodeRequestExpired: 2141, - ErrCodeInvalidEmail: 2142 + ErrCodeInvalidEmail: 2142, + ErrCodeCourseAlreadyExists: 2143, + ErrCodeCourseNotFound: 2144, + ErrCodeExamNotFound: 2145, + ErrCodeNotParticipatedInExam: 2146, + ErrCodeExamNotStarted: 2147, + ErrCodeExamFinished: 2148, + ErrCodeExamQuestionNotFound: 2149, + ErrCodeInvalidAnswerOption: 2150, + ErrCodeGivenExamNotFound: 2151 } as const; export type APIErrorCode = typeof APIErrorCode[keyof typeof APIErrorCode]; +/** + * + * @export + * @interface AnswerExamQuestionV1200Response + */ +export interface AnswerExamQuestionV1200Response { + /** + * + * @type {EndpointError} + * @memberof AnswerExamQuestionV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {AnswerQuestionResult} + * @memberof AnswerExamQuestionV1200Response + */ + 'result'?: AnswerQuestionResult; + /** + * + * @type {boolean} + * @memberof AnswerExamQuestionV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface AnswerQuestionData + */ +export interface AnswerQuestionData { + /** + * + * @type {string} + * @memberof AnswerQuestionData + */ + 'answer_text'?: string; + /** + * + * @type {string} + * @memberof AnswerQuestionData + */ + 'chosen_option'?: string; + /** + * + * @type {number} + * @memberof AnswerQuestionData + */ + 'exam_id'?: number; + /** + * + * @type {number} + * @memberof AnswerQuestionData + */ + 'question_id'?: number; + /** + * + * @type {number} + * @memberof AnswerQuestionData + */ + 'seconds_taken'?: number; +} +/** + * + * @export + * @interface AnswerQuestionResult + */ +export interface AnswerQuestionResult { + /** + * + * @type {string} + * @memberof AnswerQuestionResult + */ + 'answered_at'?: string; + /** + * + * @type {string} + * @memberof AnswerQuestionResult + */ + 'answered_by'?: string; + /** + * + * @type {number} + * @memberof AnswerQuestionResult + */ + 'exam_id'?: number; + /** + * + * @type {number} + * @memberof AnswerQuestionResult + */ + 'question_id'?: number; +} +/** + * + * @export + * @interface AnsweredQuestionInfo + */ +export interface AnsweredQuestionInfo { + /** + * + * @type {string} + * @memberof AnsweredQuestionInfo + */ + 'answer'?: string; + /** + * + * @type {string} + * @memberof AnsweredQuestionInfo + */ + 'chosen_option'?: string; + /** + * + * @type {number} + * @memberof AnsweredQuestionInfo + */ + 'question_id'?: number; + /** + * + * @type {number} + * @memberof AnsweredQuestionInfo + */ + 'seconds_taken'?: number; +} /** * * @export @@ -246,6 +379,31 @@ export interface ChangePasswordData { */ 'user_id'?: string; } +/** + * + * @export + * @interface ChangePasswordResult + */ +export interface ChangePasswordResult { + /** + * + * @type {boolean} + * @memberof ChangePasswordResult + */ + 'email_sent'?: boolean; + /** + * + * @type {string} + * @memberof ChangePasswordResult + */ + 'lang'?: string; + /** + * + * @type {boolean} + * @memberof ChangePasswordResult + */ + 'password_changed'?: boolean; +} /** * * @export @@ -260,10 +418,10 @@ export interface ChangePasswordV1200Response { 'error'?: EndpointError; /** * - * @type {boolean} + * @type {ChangePasswordResult} * @memberof ChangePasswordV1200Response */ - 'result'?: boolean; + 'result'?: ChangePasswordResult; /** * * @type {boolean} @@ -274,568 +432,566 @@ export interface ChangePasswordV1200Response { /** * * @export - * @interface ConfirmChangePasswordData + * @interface ConfirmAccountData */ -export interface ConfirmChangePasswordData { +export interface ConfirmAccountData { /** * * @type {string} - * @memberof ConfirmChangePasswordData + * @memberof ConfirmAccountData */ - 'new_password'?: string; + 'confirm_token'?: string; /** * * @type {string} - * @memberof ConfirmChangePasswordData + * @memberof ConfirmAccountData */ - 'rq_id'?: string; + 'lt_token'?: string; /** * * @type {string} - * @memberof ConfirmChangePasswordData + * @memberof ConfirmAccountData */ - 'rt_hash'?: string; + 'raw_password'?: string; /** * * @type {string} - * @memberof ConfirmChangePasswordData + * @memberof ConfirmAccountData */ - 'rt_param'?: string; + 'rl_token'?: string; /** * * @type {string} - * @memberof ConfirmChangePasswordData + * @memberof ConfirmAccountData */ - 'rt_verifier'?: string; + 'user_id'?: string; } /** * * @export - * @interface CreateNewTopicData + * @interface ConfirmAccountV1200Response */ -export interface CreateNewTopicData { +export interface ConfirmAccountV1200Response { /** * - * @type {string} - * @memberof CreateNewTopicData + * @type {EndpointError} + * @memberof ConfirmAccountV1200Response */ - 'topicName'?: string; -} -/** - * - * @export - * @interface CreateNewTopicResult - */ -export interface CreateNewTopicResult { + 'error'?: EndpointError; /** * - * @type {number} - * @memberof CreateNewTopicResult + * @type {boolean} + * @memberof ConfirmAccountV1200Response */ - 'topicID'?: number; + 'result'?: boolean; /** * - * @type {string} - * @memberof CreateNewTopicResult + * @type {boolean} + * @memberof ConfirmAccountV1200Response */ - 'topicName'?: string; + 'success'?: boolean; } /** * * @export - * @interface CreateUserData + * @interface ConfirmChangePasswordData */ -export interface CreateUserData { +export interface ConfirmChangePasswordData { /** * * @type {string} - * @memberof CreateUserData + * @memberof ConfirmChangePasswordData */ - 'email'?: string; + 'new_password'?: string; /** * * @type {string} - * @memberof CreateUserData + * @memberof ConfirmChangePasswordData */ - 'full_name'?: string; + 'rq_id'?: string; /** * * @type {string} - * @memberof CreateUserData + * @memberof ConfirmChangePasswordData */ - 'password'?: string; + 'rt_hash'?: string; /** * * @type {string} - * @memberof CreateUserData + * @memberof ConfirmChangePasswordData */ - 'phone_number'?: string; + 'rt_param'?: string; /** * - * @type {UserRole} - * @memberof CreateUserData + * @type {string} + * @memberof ConfirmChangePasswordData */ - 'role'?: UserRole; + 'rt_verifier'?: string; +} +/** + * + * @export + * @interface CourseParticipantInfo + */ +export interface CourseParticipantInfo { /** * - * @type {boolean} - * @memberof CreateUserData + * @type {string} + * @memberof CourseParticipantInfo */ - 'setup_completed'?: boolean; + 'full_name'?: string; /** * * @type {string} - * @memberof CreateUserData + * @memberof CourseParticipantInfo */ - 'user_address'?: string; + 'user_id'?: string; +} +/** + * + * @export + * @interface CreateCourseData + */ +export interface CreateCourseData { /** * * @type {string} - * @memberof CreateUserData + * @memberof CreateCourseData */ - 'user_id'?: string; + 'course_description'?: string; + /** + * + * @type {string} + * @memberof CreateCourseData + */ + 'course_name'?: string; } - - /** * * @export - * @interface CreateUserResult + * @interface CreateCourseResult */ -export interface CreateUserResult { +export interface CreateCourseResult { /** * * @type {string} - * @memberof CreateUserResult + * @memberof CreateCourseResult */ - 'email'?: string; + 'added_by'?: string; /** * * @type {string} - * @memberof CreateUserResult + * @memberof CreateCourseResult */ - 'full_name'?: string; + 'course_description'?: string; /** * - * @type {string} - * @memberof CreateUserResult + * @type {number} + * @memberof CreateCourseResult */ - 'role'?: string; + 'course_id'?: number; /** * * @type {string} - * @memberof CreateUserResult + * @memberof CreateCourseResult */ - 'user_id'?: string; + 'course_name'?: string; } /** * * @export - * @interface CreateUserV1200Response + * @interface CreateCourseV1200Response */ -export interface CreateUserV1200Response { +export interface CreateCourseV1200Response { /** * * @type {EndpointError} - * @memberof CreateUserV1200Response + * @memberof CreateCourseV1200Response */ 'error'?: EndpointError; /** * - * @type {CreateUserResult} - * @memberof CreateUserV1200Response + * @type {CreateCourseResult} + * @memberof CreateCourseV1200Response */ - 'result'?: CreateUserResult; + 'result'?: CreateCourseResult; /** * * @type {boolean} - * @memberof CreateUserV1200Response + * @memberof CreateCourseV1200Response */ 'success'?: boolean; } /** * * @export - * @interface EditUserData + * @interface CreateExamData */ -export interface EditUserData { +export interface CreateExamData { /** * - * @type {string} - * @memberof EditUserData + * @type {number} + * @memberof CreateExamData */ - 'email'?: string; + 'course_id'?: number; /** * - * @type {string} - * @memberof EditUserData + * @type {number} + * @memberof CreateExamData */ - 'full_name'?: string; + 'duration'?: number; + /** + * + * @type {number} + * @memberof CreateExamData + */ + 'exam_date'?: number; /** * * @type {string} - * @memberof EditUserData + * @memberof CreateExamData */ - 'phone_number'?: string; + 'exam_description'?: string; /** * * @type {string} - * @memberof EditUserData + * @memberof CreateExamData */ - 'user_address'?: string; + 'exam_title'?: string; + /** + * + * @type {boolean} + * @memberof CreateExamData + */ + 'is_public'?: boolean; /** * * @type {string} - * @memberof EditUserData + * @memberof CreateExamData */ - 'user_id'?: string; + 'price'?: string; } /** * * @export - * @interface EditUserResult + * @interface CreateExamResult */ -export interface EditUserResult { +export interface CreateExamResult { + /** + * + * @type {number} + * @memberof CreateExamResult + */ + 'course_id'?: number; /** * * @type {string} - * @memberof EditUserResult + * @memberof CreateExamResult */ - 'email'?: string; + 'created_at'?: string; /** * * @type {string} - * @memberof EditUserResult + * @memberof CreateExamResult */ - 'full_name'?: string; + 'created_by'?: string; /** * - * @type {UserRole} - * @memberof EditUserResult + * @type {number} + * @memberof CreateExamResult */ - 'role'?: UserRole; + 'duration'?: number; /** * * @type {string} - * @memberof EditUserResult + * @memberof CreateExamResult */ - 'user_id'?: string; -} - - -/** - * - * @export - * @interface EditUserV1200Response - */ -export interface EditUserV1200Response { + 'exam_date'?: string; /** * - * @type {EndpointError} - * @memberof EditUserV1200Response + * @type {number} + * @memberof CreateExamResult */ - 'error'?: EndpointError; + 'exam_id'?: number; /** * - * @type {EditUserResult} - * @memberof EditUserV1200Response + * @type {boolean} + * @memberof CreateExamResult */ - 'result'?: EditUserResult; + 'is_public'?: boolean; /** * - * @type {boolean} - * @memberof EditUserV1200Response + * @type {string} + * @memberof CreateExamResult */ - 'success'?: boolean; + 'price'?: string; } /** * * @export - * @interface EndpointError + * @interface CreateExamV1200Response */ -export interface EndpointError { +export interface CreateExamV1200Response { /** * - * @type {APIErrorCode} - * @memberof EndpointError + * @type {EndpointError} + * @memberof CreateExamV1200Response */ - 'code'?: APIErrorCode; + 'error'?: EndpointError; /** * - * @type {string} - * @memberof EndpointError + * @type {CreateExamResult} + * @memberof CreateExamV1200Response */ - 'date'?: string; + 'result'?: CreateExamResult; /** * - * @type {string} - * @memberof EndpointError + * @type {boolean} + * @memberof CreateExamV1200Response */ - 'message'?: string; + 'success'?: boolean; +} +/** + * + * @export + * @interface CreateNewTopicData + */ +export interface CreateNewTopicData { /** * * @type {string} - * @memberof EndpointError + * @memberof CreateNewTopicData */ - 'origin'?: string; + 'topic_name'?: string; } - - /** * * @export - * @interface EndpointResponse + * @interface CreateNewTopicResult */ -export interface EndpointResponse { - /** - * - * @type {EndpointError} - * @memberof EndpointResponse - */ - 'error'?: EndpointError; +export interface CreateNewTopicResult { /** * - * @type {object} - * @memberof EndpointResponse + * @type {number} + * @memberof CreateNewTopicResult */ - 'result'?: object; + 'topic_id'?: number; /** * - * @type {boolean} - * @memberof EndpointResponse + * @type {string} + * @memberof CreateNewTopicResult */ - 'success'?: boolean; + 'topic_name'?: string; } /** * * @export - * @interface GenerateCaptchaV1200Response + * @interface CreateTopicV1200Response */ -export interface GenerateCaptchaV1200Response { +export interface CreateTopicV1200Response { /** * * @type {EndpointError} - * @memberof GenerateCaptchaV1200Response + * @memberof CreateTopicV1200Response */ 'error'?: EndpointError; /** * - * @type {CaptchaHandlersGetCaptchaResult} - * @memberof GenerateCaptchaV1200Response + * @type {CreateNewTopicResult} + * @memberof CreateTopicV1200Response */ - 'result'?: CaptchaHandlersGetCaptchaResult; + 'result'?: CreateNewTopicResult; /** * * @type {boolean} - * @memberof GenerateCaptchaV1200Response + * @memberof CreateTopicV1200Response */ 'success'?: boolean; } /** * * @export - * @interface GetMeResult + * @interface CreateUserData */ -export interface GetMeResult { +export interface CreateUserData { /** * * @type {string} - * @memberof GetMeResult + * @memberof CreateUserData + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof CreateUserData */ 'full_name'?: string; /** * - * @type {UserRole} - * @memberof GetMeResult + * @type {string} + * @memberof CreateUserData */ - 'role'?: UserRole; + 'password'?: string; /** * * @type {string} - * @memberof GetMeResult + * @memberof CreateUserData */ - 'user_id'?: string; -} - - -/** - * - * @export - * @interface GetMeV1200Response - */ -export interface GetMeV1200Response { + 'phone_number'?: string; /** * - * @type {EndpointError} - * @memberof GetMeV1200Response + * @type {string} + * @memberof CreateUserData */ - 'error'?: EndpointError; + 'primary_language'?: string; /** * - * @type {GetMeResult} - * @memberof GetMeV1200Response + * @type {UserRole} + * @memberof CreateUserData */ - 'result'?: GetMeResult; + 'role'?: UserRole; /** * * @type {boolean} - * @memberof GetMeV1200Response + * @memberof CreateUserData */ - 'success'?: boolean; -} -/** - * - * @export - * @interface GetUserInfoResult - */ -export interface GetUserInfoResult { + 'setup_completed'?: boolean; /** * * @type {string} - * @memberof GetUserInfoResult + * @memberof CreateUserData */ - 'ban_reason'?: string; + 'user_address'?: string; /** * * @type {string} - * @memberof GetUserInfoResult + * @memberof CreateUserData */ - 'created_at'?: string; + 'user_id'?: string; +} + + +/** + * + * @export + * @interface CreateUserResult + */ +export interface CreateUserResult { /** * * @type {string} - * @memberof GetUserInfoResult + * @memberof CreateUserResult */ 'email'?: string; /** * * @type {string} - * @memberof GetUserInfoResult + * @memberof CreateUserResult */ 'full_name'?: string; /** * - * @type {boolean} - * @memberof GetUserInfoResult - */ - 'is_banned'?: boolean; - /** - * - * @type {UserRole} - * @memberof GetUserInfoResult + * @type {string} + * @memberof CreateUserResult */ - 'role'?: UserRole; + 'role'?: string; /** * * @type {string} - * @memberof GetUserInfoResult + * @memberof CreateUserResult */ 'user_id'?: string; } - - /** * * @export - * @interface GetUserInfoV1200Response + * @interface CreateUserV1200Response */ -export interface GetUserInfoV1200Response { +export interface CreateUserV1200Response { /** * * @type {EndpointError} - * @memberof GetUserInfoV1200Response + * @memberof CreateUserV1200Response */ 'error'?: EndpointError; /** * - * @type {GetUserInfoResult} - * @memberof GetUserInfoV1200Response + * @type {CreateUserResult} + * @memberof CreateUserV1200Response */ - 'result'?: GetUserInfoResult; + 'result'?: CreateUserResult; /** * * @type {boolean} - * @memberof GetUserInfoV1200Response + * @memberof CreateUserV1200Response */ 'success'?: boolean; } /** * * @export - * @interface LoginData + * @interface EditUserData */ -export interface LoginData { +export interface EditUserData { /** * * @type {string} - * @memberof LoginData + * @memberof EditUserData */ - 'captcha_answer'?: string; + 'email'?: string; /** * * @type {string} - * @memberof LoginData + * @memberof EditUserData */ - 'captcha_id'?: string; + 'full_name'?: string; /** * * @type {string} - * @memberof LoginData + * @memberof EditUserData */ - 'client_rid'?: string; + 'phone_number'?: string; /** * * @type {string} - * @memberof LoginData + * @memberof EditUserData */ - 'password'?: string; + 'user_address'?: string; /** * * @type {string} - * @memberof LoginData + * @memberof EditUserData */ 'user_id'?: string; } /** * * @export - * @interface LoginResult + * @interface EditUserResult */ -export interface LoginResult { +export interface EditUserResult { /** * * @type {string} - * @memberof LoginResult - */ - 'access_token'?: string; - /** - * - * @type {number} - * @memberof LoginResult + * @memberof EditUserResult */ - 'expiration'?: number; + 'email'?: string; /** * * @type {string} - * @memberof LoginResult + * @memberof EditUserResult */ 'full_name'?: string; - /** - * - * @type {string} - * @memberof LoginResult - */ - 'refresh_token'?: string; /** * * @type {UserRole} - * @memberof LoginResult + * @memberof EditUserResult */ 'role'?: UserRole; /** * * @type {string} - * @memberof LoginResult + * @memberof EditUserResult */ 'user_id'?: string; } @@ -844,184 +1000,3277 @@ export interface LoginResult { /** * * @export - * @interface LoginV1200Response + * @interface EditUserV1200Response */ -export interface LoginV1200Response { +export interface EditUserV1200Response { /** * * @type {EndpointError} - * @memberof LoginV1200Response + * @memberof EditUserV1200Response */ 'error'?: EndpointError; /** * - * @type {LoginResult} - * @memberof LoginV1200Response + * @type {EditUserResult} + * @memberof EditUserV1200Response */ - 'result'?: LoginResult; + 'result'?: EditUserResult; /** * * @type {boolean} - * @memberof LoginV1200Response + * @memberof EditUserV1200Response */ 'success'?: boolean; } /** * * @export - * @interface ReAuthV1200Response + * @interface EndpointError */ -export interface ReAuthV1200Response { +export interface EndpointError { /** * - * @type {EndpointError} - * @memberof ReAuthV1200Response + * @type {APIErrorCode} + * @memberof EndpointError */ - 'error'?: EndpointError; + 'code'?: APIErrorCode; /** * - * @type {AuthResult} - * @memberof ReAuthV1200Response + * @type {string} + * @memberof EndpointError */ - 'result'?: AuthResult; + 'date'?: string; /** * - * @type {boolean} - * @memberof ReAuthV1200Response + * @type {string} + * @memberof EndpointError + */ + 'message'?: string; + /** + * + * @type {string} + * @memberof EndpointError + */ + 'origin'?: string; +} + + +/** + * + * @export + * @interface EndpointResponse + */ +export interface EndpointResponse { + /** + * + * @type {EndpointError} + * @memberof EndpointResponse + */ + 'error'?: EndpointError; + /** + * + * @type {object} + * @memberof EndpointResponse + */ + 'result'?: object; + /** + * + * @type {boolean} + * @memberof EndpointResponse */ 'success'?: boolean; } /** * * @export - * @interface SearchUserData + * @interface ExamQuestionInfo */ -export interface SearchUserData { +export interface ExamQuestionInfo { + /** + * + * @type {string} + * @memberof ExamQuestionInfo + */ + 'created_at'?: string; + /** + * + * @type {string} + * @memberof ExamQuestionInfo + */ + 'description'?: string; + /** + * + * @type {string} + * @memberof ExamQuestionInfo + */ + 'option1'?: string; + /** + * + * @type {string} + * @memberof ExamQuestionInfo + */ + 'option2'?: string; + /** + * + * @type {string} + * @memberof ExamQuestionInfo + */ + 'option3'?: string; + /** + * + * @type {string} + * @memberof ExamQuestionInfo + */ + 'option4'?: string; /** * * @type {number} - * @memberof SearchUserData + * @memberof ExamQuestionInfo */ - 'limit'?: number; + 'question_id'?: number; + /** + * + * @type {string} + * @memberof ExamQuestionInfo + */ + 'question_title'?: string; + /** + * + * @type {AnsweredQuestionInfo} + * @memberof ExamQuestionInfo + */ + 'user_answer'?: AnsweredQuestionInfo; +} +/** + * + * @export + * @interface GenerateCaptchaV1200Response + */ +export interface GenerateCaptchaV1200Response { + /** + * + * @type {EndpointError} + * @memberof GenerateCaptchaV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {CaptchaHandlersGetCaptchaResult} + * @memberof GenerateCaptchaV1200Response + */ + 'result'?: CaptchaHandlersGetCaptchaResult; + /** + * + * @type {boolean} + * @memberof GenerateCaptchaV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetAllUserTopicStatsResult + */ +export interface GetAllUserTopicStatsResult { + /** + * + * @type {Array} + * @memberof GetAllUserTopicStatsResult + */ + 'stats'?: Array; + /** + * + * @type {string} + * @memberof GetAllUserTopicStatsResult + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface GetAllUserTopicStatsV1200Response + */ +export interface GetAllUserTopicStatsV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetAllUserTopicStatsV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetAllUserTopicStatsResult} + * @memberof GetAllUserTopicStatsV1200Response + */ + 'result'?: GetAllUserTopicStatsResult; + /** + * + * @type {boolean} + * @memberof GetAllUserTopicStatsV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetCourseInfoResult + */ +export interface GetCourseInfoResult { + /** + * + * @type {string} + * @memberof GetCourseInfoResult + */ + 'added_by'?: string; + /** + * + * @type {string} + * @memberof GetCourseInfoResult + */ + 'course_description'?: string; /** * * @type {number} - * @memberof SearchUserData + * @memberof GetCourseInfoResult */ - 'offset'?: number; + 'course_id'?: number; /** * * @type {string} - * @memberof SearchUserData + * @memberof GetCourseInfoResult */ - 'query'?: string; + 'course_name'?: string; + /** + * + * @type {string} + * @memberof GetCourseInfoResult + */ + 'created_at'?: string; +} +/** + * + * @export + * @interface GetCourseInfoV1200Response + */ +export interface GetCourseInfoV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetCourseInfoV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetCourseInfoResult} + * @memberof GetCourseInfoV1200Response + */ + 'result'?: GetCourseInfoResult; + /** + * + * @type {boolean} + * @memberof GetCourseInfoV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetCourseParticipantsData + */ +export interface GetCourseParticipantsData { + /** + * + * @type {number} + * @memberof GetCourseParticipantsData + */ + 'course_id'?: number; +} +/** + * + * @export + * @interface GetCourseParticipantsResult + */ +export interface GetCourseParticipantsResult { + /** + * + * @type {Array} + * @memberof GetCourseParticipantsResult + */ + 'participants'?: Array; +} +/** + * + * @export + * @interface GetCourseParticipantsV1200Response + */ +export interface GetCourseParticipantsV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetCourseParticipantsV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetCourseParticipantsResult} + * @memberof GetCourseParticipantsV1200Response + */ + 'result'?: GetCourseParticipantsResult; + /** + * + * @type {boolean} + * @memberof GetCourseParticipantsV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetCreatedCoursesData + */ +export interface GetCreatedCoursesData { + /** + * + * @type {string} + * @memberof GetCreatedCoursesData + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface GetCreatedCoursesResult + */ +export interface GetCreatedCoursesResult { + /** + * + * @type {Array} + * @memberof GetCreatedCoursesResult + */ + 'courses'?: Array; +} +/** + * + * @export + * @interface GetCreatedCoursesV1200Response + */ +export interface GetCreatedCoursesV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetCreatedCoursesV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetCreatedCoursesResult} + * @memberof GetCreatedCoursesV1200Response + */ + 'result'?: GetCreatedCoursesResult; + /** + * + * @type {boolean} + * @memberof GetCreatedCoursesV1200Response + */ + 'success'?: boolean; } /** - * + * + * @export + * @interface GetExamInfoResult + */ +export interface GetExamInfoResult { + /** + * + * @type {number} + * @memberof GetExamInfoResult + */ + 'course_id'?: number; + /** + * + * @type {string} + * @memberof GetExamInfoResult + */ + 'created_at'?: string; + /** + * + * @type {string} + * @memberof GetExamInfoResult + */ + 'created_by'?: string; + /** + * + * @type {number} + * @memberof GetExamInfoResult + */ + 'duration'?: number; + /** + * + * @type {string} + * @memberof GetExamInfoResult + */ + 'exam_date'?: string; + /** + * + * @type {string} + * @memberof GetExamInfoResult + */ + 'exam_description'?: string; + /** + * + * @type {number} + * @memberof GetExamInfoResult + */ + 'exam_id'?: number; + /** + * + * @type {string} + * @memberof GetExamInfoResult + */ + 'exam_title'?: string; + /** + * + * @type {number} + * @memberof GetExamInfoResult + */ + 'finishes_in'?: number; + /** + * + * @type {boolean} + * @memberof GetExamInfoResult + */ + 'has_finished'?: boolean; + /** + * + * @type {boolean} + * @memberof GetExamInfoResult + */ + 'has_started'?: boolean; + /** + * + * @type {boolean} + * @memberof GetExamInfoResult + */ + 'is_public'?: boolean; + /** + * + * @type {string} + * @memberof GetExamInfoResult + */ + 'price'?: string; + /** + * + * @type {number} + * @memberof GetExamInfoResult + */ + 'question_count'?: number; + /** + * + * @type {number} + * @memberof GetExamInfoResult + */ + 'starts_in'?: number; +} +/** + * + * @export + * @interface GetExamInfoV1200Response + */ +export interface GetExamInfoV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetExamInfoV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetExamInfoResult} + * @memberof GetExamInfoV1200Response + */ + 'result'?: GetExamInfoResult; + /** + * + * @type {boolean} + * @memberof GetExamInfoV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetExamQuestionsData + */ +export interface GetExamQuestionsData { + /** + * + * @type {number} + * @memberof GetExamQuestionsData + */ + 'exam_id'?: number; +} +/** + * + * @export + * @interface GetExamQuestionsResult + */ +export interface GetExamQuestionsResult { + /** + * + * @type {number} + * @memberof GetExamQuestionsResult + */ + 'exam_id'?: number; + /** + * + * @type {Array} + * @memberof GetExamQuestionsResult + */ + 'questions'?: Array; +} +/** + * + * @export + * @interface GetExamQuestionsV1200Response + */ +export interface GetExamQuestionsV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetExamQuestionsV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetExamQuestionsResult} + * @memberof GetExamQuestionsV1200Response + */ + 'result'?: GetExamQuestionsResult; + /** + * + * @type {boolean} + * @memberof GetExamQuestionsV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetGivenExamData + */ +export interface GetGivenExamData { + /** + * + * @type {string} + * @memberof GetGivenExamData + */ + 'added_by'?: string; + /** + * + * @type {string} + * @memberof GetGivenExamData + */ + 'created_at'?: string; + /** + * + * @type {number} + * @memberof GetGivenExamData + */ + 'exam_id'?: number; + /** + * + * @type {string} + * @memberof GetGivenExamData + */ + 'final_score'?: string; + /** + * + * @type {string} + * @memberof GetGivenExamData + */ + 'price'?: string; + /** + * + * @type {string} + * @memberof GetGivenExamData + */ + 'scored_by'?: string; + /** + * + * @type {string} + * @memberof GetGivenExamData + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface GetGivenExamV1200Response + */ +export interface GetGivenExamV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetGivenExamV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetGivenExamData} + * @memberof GetGivenExamV1200Response + */ + 'result'?: GetGivenExamData; + /** + * + * @type {boolean} + * @memberof GetGivenExamV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetMeResult + */ +export interface GetMeResult { + /** + * + * @type {string} + * @memberof GetMeResult + */ + 'full_name'?: string; + /** + * + * @type {UserRole} + * @memberof GetMeResult + */ + 'role'?: UserRole; + /** + * + * @type {string} + * @memberof GetMeResult + */ + 'user_id'?: string; +} + + +/** + * + * @export + * @interface GetMeV1200Response + */ +export interface GetMeV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetMeV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetMeResult} + * @memberof GetMeV1200Response + */ + 'result'?: GetMeResult; + /** + * + * @type {boolean} + * @memberof GetMeV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetTopicInfoResult + */ +export interface GetTopicInfoResult { + /** + * + * @type {number} + * @memberof GetTopicInfoResult + */ + 'topic_id'?: number; + /** + * + * @type {string} + * @memberof GetTopicInfoResult + */ + 'topic_name'?: string; +} +/** + * + * @export + * @interface GetTopicInfoV1200Response + */ +export interface GetTopicInfoV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetTopicInfoV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetTopicInfoResult} + * @memberof GetTopicInfoV1200Response + */ + 'result'?: GetTopicInfoResult; + /** + * + * @type {boolean} + * @memberof GetTopicInfoV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetUserCoursesData + */ +export interface GetUserCoursesData { + /** + * + * @type {string} + * @memberof GetUserCoursesData + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface GetUserCoursesResult + */ +export interface GetUserCoursesResult { + /** + * + * @type {Array} + * @memberof GetUserCoursesResult + */ + 'courses'?: Array; +} +/** + * + * @export + * @interface GetUserCoursesV1200Response + */ +export interface GetUserCoursesV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetUserCoursesV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetUserCoursesResult} + * @memberof GetUserCoursesV1200Response + */ + 'result'?: GetUserCoursesResult; + /** + * + * @type {boolean} + * @memberof GetUserCoursesV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetUserExamsHistoryV1200Response + */ +export interface GetUserExamsHistoryV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetUserExamsHistoryV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetUsersExamHistoryResult} + * @memberof GetUserExamsHistoryV1200Response + */ + 'result'?: GetUsersExamHistoryResult; + /** + * + * @type {boolean} + * @memberof GetUserExamsHistoryV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetUserInfoResult + */ +export interface GetUserInfoResult { + /** + * + * @type {string} + * @memberof GetUserInfoResult + */ + 'ban_reason'?: string; + /** + * + * @type {string} + * @memberof GetUserInfoResult + */ + 'created_at'?: string; + /** + * + * @type {string} + * @memberof GetUserInfoResult + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof GetUserInfoResult + */ + 'full_name'?: string; + /** + * + * @type {boolean} + * @memberof GetUserInfoResult + */ + 'is_banned'?: boolean; + /** + * + * @type {UserRole} + * @memberof GetUserInfoResult + */ + 'role'?: UserRole; + /** + * + * @type {string} + * @memberof GetUserInfoResult + */ + 'user_id'?: string; +} + + +/** + * + * @export + * @interface GetUserInfoV1200Response + */ +export interface GetUserInfoV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetUserInfoV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetUserInfoResult} + * @memberof GetUserInfoV1200Response + */ + 'result'?: GetUserInfoResult; + /** + * + * @type {boolean} + * @memberof GetUserInfoV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetUserOngoingExamsResult + */ +export interface GetUserOngoingExamsResult { + /** + * + * @type {Array} + * @memberof GetUserOngoingExamsResult + */ + 'exams'?: Array; +} +/** + * + * @export + * @interface GetUserOngoingExamsV1200Response + */ +export interface GetUserOngoingExamsV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetUserOngoingExamsV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetUserOngoingExamsResult} + * @memberof GetUserOngoingExamsV1200Response + */ + 'result'?: GetUserOngoingExamsResult; + /** + * + * @type {boolean} + * @memberof GetUserOngoingExamsV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetUserTopicStatData + */ +export interface GetUserTopicStatData { + /** + * + * @type {number} + * @memberof GetUserTopicStatData + */ + 'topic_id'?: number; + /** + * + * @type {string} + * @memberof GetUserTopicStatData + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface GetUserTopicStatResult + */ +export interface GetUserTopicStatResult { + /** + * + * @type {UserTopicStatInfo} + * @memberof GetUserTopicStatResult + */ + 'stat'?: UserTopicStatInfo; +} +/** + * + * @export + * @interface GetUserTopicStatV1200Response + */ +export interface GetUserTopicStatV1200Response { + /** + * + * @type {EndpointError} + * @memberof GetUserTopicStatV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {GetUserTopicStatResult} + * @memberof GetUserTopicStatV1200Response + */ + 'result'?: GetUserTopicStatResult; + /** + * + * @type {boolean} + * @memberof GetUserTopicStatV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface GetUsersExamHistoryData + */ +export interface GetUsersExamHistoryData { + /** + * + * @type {number} + * @memberof GetUsersExamHistoryData + */ + 'limit'?: number; + /** + * + * @type {number} + * @memberof GetUsersExamHistoryData + */ + 'offset'?: number; + /** + * + * @type {string} + * @memberof GetUsersExamHistoryData + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface GetUsersExamHistoryResult + */ +export interface GetUsersExamHistoryResult { + /** + * + * @type {Array} + * @memberof GetUsersExamHistoryResult + */ + 'exams'?: Array; +} +/** + * + * @export + * @interface LoginData + */ +export interface LoginData { + /** + * + * @type {string} + * @memberof LoginData + */ + 'captcha_answer'?: string; + /** + * + * @type {string} + * @memberof LoginData + */ + 'captcha_id'?: string; + /** + * + * @type {string} + * @memberof LoginData + */ + 'client_rid'?: string; + /** + * + * @type {string} + * @memberof LoginData + */ + 'password'?: string; + /** + * + * @type {string} + * @memberof LoginData + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface LoginResult + */ +export interface LoginResult { + /** + * + * @type {string} + * @memberof LoginResult + */ + 'access_token'?: string; + /** + * + * @type {number} + * @memberof LoginResult + */ + 'expiration'?: number; + /** + * + * @type {string} + * @memberof LoginResult + */ + 'full_name'?: string; + /** + * + * @type {string} + * @memberof LoginResult + */ + 'refresh_token'?: string; + /** + * + * @type {UserRole} + * @memberof LoginResult + */ + 'role'?: UserRole; + /** + * + * @type {string} + * @memberof LoginResult + */ + 'user_id'?: string; +} + + +/** + * + * @export + * @interface LoginV1200Response + */ +export interface LoginV1200Response { + /** + * + * @type {EndpointError} + * @memberof LoginV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {LoginResult} + * @memberof LoginV1200Response + */ + 'result'?: LoginResult; + /** + * + * @type {boolean} + * @memberof LoginV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface ReAuthV1200Response + */ +export interface ReAuthV1200Response { + /** + * + * @type {EndpointError} + * @memberof ReAuthV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {AuthResult} + * @memberof ReAuthV1200Response + */ + 'result'?: AuthResult; + /** + * + * @type {boolean} + * @memberof ReAuthV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface SearchCourseData + */ +export interface SearchCourseData { + /** + * + * @type {string} + * @memberof SearchCourseData + */ + 'course_name'?: string; +} +/** + * + * @export + * @interface SearchCourseResult + */ +export interface SearchCourseResult { + /** + * + * @type {Array} + * @memberof SearchCourseResult + */ + 'courses'?: Array; +} +/** + * + * @export + * @interface SearchCourseV1200Response + */ +export interface SearchCourseV1200Response { + /** + * + * @type {EndpointError} + * @memberof SearchCourseV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {SearchCourseResult} + * @memberof SearchCourseV1200Response + */ + 'result'?: SearchCourseResult; + /** + * + * @type {boolean} + * @memberof SearchCourseV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface SearchTopicData + */ +export interface SearchTopicData { + /** + * + * @type {string} + * @memberof SearchTopicData + */ + 'topic_name'?: string; +} +/** + * + * @export + * @interface SearchTopicResult + */ +export interface SearchTopicResult { + /** + * + * @type {Array} + * @memberof SearchTopicResult + */ + 'topics'?: Array; +} +/** + * + * @export + * @interface SearchTopicV1200Response + */ +export interface SearchTopicV1200Response { + /** + * + * @type {EndpointError} + * @memberof SearchTopicV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {SearchTopicResult} + * @memberof SearchTopicV1200Response + */ + 'result'?: SearchTopicResult; + /** + * + * @type {boolean} + * @memberof SearchTopicV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface SearchUserData + */ +export interface SearchUserData { + /** + * + * @type {number} + * @memberof SearchUserData + */ + 'limit'?: number; + /** + * + * @type {number} + * @memberof SearchUserData + */ + 'offset'?: number; + /** + * + * @type {string} + * @memberof SearchUserData + */ + 'query'?: string; +} +/** + * + * @export + * @interface SearchUserResult + */ +export interface SearchUserResult { + /** + * + * @type {Array} + * @memberof SearchUserResult + */ + 'users'?: Array; +} +/** + * + * @export + * @interface SearchUserV1200Response + */ +export interface SearchUserV1200Response { + /** + * + * @type {EndpointError} + * @memberof SearchUserV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {SearchUserResult} + * @memberof SearchUserV1200Response + */ + 'result'?: SearchUserResult; + /** + * + * @type {boolean} + * @memberof SearchUserV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface SearchedCourseInfo + */ +export interface SearchedCourseInfo { + /** + * + * @type {string} + * @memberof SearchedCourseInfo + */ + 'added_by'?: string; + /** + * + * @type {string} + * @memberof SearchedCourseInfo + */ + 'course_description'?: string; + /** + * + * @type {number} + * @memberof SearchedCourseInfo + */ + 'course_id'?: number; + /** + * + * @type {string} + * @memberof SearchedCourseInfo + */ + 'course_name'?: string; + /** + * + * @type {string} + * @memberof SearchedCourseInfo + */ + 'created_at'?: string; +} +/** + * + * @export + * @interface SearchedTopicInfo + */ +export interface SearchedTopicInfo { + /** + * + * @type {number} + * @memberof SearchedTopicInfo + */ + 'topic_id'?: number; + /** + * + * @type {string} + * @memberof SearchedTopicInfo + */ + 'topic_name'?: string; +} +/** + * + * @export + * @interface SearchedUserInfo + */ +export interface SearchedUserInfo { + /** + * + * @type {string} + * @memberof SearchedUserInfo + */ + 'ban_reason'?: string; + /** + * + * @type {string} + * @memberof SearchedUserInfo + */ + 'created_at'?: string; + /** + * + * @type {string} + * @memberof SearchedUserInfo + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof SearchedUserInfo + */ + 'full_name'?: string; + /** + * + * @type {boolean} + * @memberof SearchedUserInfo + */ + 'is_banned'?: boolean; + /** + * + * @type {UserRole} + * @memberof SearchedUserInfo + */ + 'role'?: UserRole; + /** + * + * @type {string} + * @memberof SearchedUserInfo + */ + 'user_id'?: string; +} + + +/** + * + * @export + * @interface SetScoreData + */ +export interface SetScoreData { + /** + * ExamId is the exam we are trying to give this score to. + * @type {number} + * @memberof SetScoreData + */ + 'exam_id'?: number; + /** + * Score is the score we are trying to give to the user. + * @type {string} + * @memberof SetScoreData + */ + 'score'?: string; + /** + * UserId is the person we are trying to give this score to. + * @type {string} + * @memberof SetScoreData + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface SetScoreResult + */ +export interface SetScoreResult { + /** + * + * @type {number} + * @memberof SetScoreResult + */ + 'exam_id'?: number; + /** + * + * @type {string} + * @memberof SetScoreResult + */ + 'score'?: string; + /** + * + * @type {string} + * @memberof SetScoreResult + */ + 'scored_by'?: string; + /** + * + * @type {string} + * @memberof SetScoreResult + */ + 'user_id'?: string; +} +/** + * + * @export + * @interface SetScoreV1200Response + */ +export interface SetScoreV1200Response { + /** + * + * @type {EndpointError} + * @memberof SetScoreV1200Response + */ + 'error'?: EndpointError; + /** + * + * @type {SetScoreResult} + * @memberof SetScoreV1200Response + */ + 'result'?: SetScoreResult; + /** + * + * @type {boolean} + * @memberof SetScoreV1200Response + */ + 'success'?: boolean; +} +/** + * + * @export + * @interface UserExamHistoryInfo + */ +export interface UserExamHistoryInfo { + /** + * + * @type {number} + * @memberof UserExamHistoryInfo + */ + 'exam_id'?: number; + /** + * + * @type {string} + * @memberof UserExamHistoryInfo + */ + 'exam_title'?: string; + /** + * + * @type {string} + * @memberof UserExamHistoryInfo + */ + 'started_at'?: string; +} +/** + * + * @export + * @interface UserOngoingExamInfo + */ +export interface UserOngoingExamInfo { + /** + * + * @type {number} + * @memberof UserOngoingExamInfo + */ + 'course_id'?: number; + /** + * + * @type {number} + * @memberof UserOngoingExamInfo + */ + 'exam_id'?: number; + /** + * + * @type {string} + * @memberof UserOngoingExamInfo + */ + 'start_time'?: string; +} +/** + * + * @export + * @interface UserParticipatedCourse + */ +export interface UserParticipatedCourse { + /** + * + * @type {number} + * @memberof UserParticipatedCourse + */ + 'course_id'?: number; + /** + * + * @type {string} + * @memberof UserParticipatedCourse + */ + 'course_name'?: string; +} +/** + * UserRole is the role of the user. + * @export + * @enum {string} + */ + +export const UserRole = { + UserRoleOwner: 'owner', + UserRoleAdmin: 'admin', + UserRoleStudent: 'student', + UserRoleTeacher: 'teacher', + UserRoleUnknown: '' +} as const; + +export type UserRole = typeof UserRole[keyof typeof UserRole]; + + +/** + * + * @export + * @interface UserTopicStatInfo + */ +export interface UserTopicStatInfo { + /** + * + * @type {number} + * @memberof UserTopicStatInfo + */ + 'current_exp'?: number; + /** + * + * @type {number} + * @memberof UserTopicStatInfo + */ + 'current_level'?: number; + /** + * + * @type {string} + * @memberof UserTopicStatInfo + */ + 'last_visited'?: string; + /** + * + * @type {number} + * @memberof UserTopicStatInfo + */ + 'topic_id'?: number; + /** + * + * @type {number} + * @memberof UserTopicStatInfo + */ + 'total_exp'?: number; + /** + * + * @type {string} + * @memberof UserTopicStatInfo + */ + 'user_id'?: string; +} + +/** + * CourseApi - axios parameter creator + * @export + */ +export const CourseApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Allows a user to create a new course. + * @summary Create a new course + * @param {string} authorization Authorization token + * @param {CreateCourseData} data Data needed to create a new course + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createCourseV1: async (authorization: string, data: CreateCourseData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('createCourseV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('createCourseV1', 'data', data) + const localVarPath = `/api/v1/course/create`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows a user to get information about a course by its id. + * @summary Get course information + * @param {number} id Course ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCourseInfoV1: async (id: number, authorization: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getCourseInfoV1', 'id', id) + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getCourseInfoV1', 'authorization', authorization) + const localVarPath = `/api/v1/course/info`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (id !== undefined) { + localVarQueryParameter['id'] = id; + } + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows a user to get all participants of a course. + * @summary Get course participants + * @param {string} authorization Authorization token + * @param {GetCourseParticipantsData} data Data needed to get course participants + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCourseParticipantsV1: async (authorization: string, data: GetCourseParticipantsData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getCourseParticipantsV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('getCourseParticipantsV1', 'data', data) + const localVarPath = `/api/v1/course/courseParticipants`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows a user to get all courses created by a user. + * @summary Get created courses + * @param {string} authorization Authorization token + * @param {GetCreatedCoursesData} data Data needed to get created courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCreatedCoursesV1: async (authorization: string, data: GetCreatedCoursesData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getCreatedCoursesV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('getCreatedCoursesV1', 'data', data) + const localVarPath = `/api/v1/course/createdCourses`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows a user to get all courses participated by a user. + * @summary Get user courses + * @param {string} authorization Authorization token + * @param {GetUserCoursesData} data Data needed to get user courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserCoursesV1: async (authorization: string, data: GetUserCoursesData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getUserCoursesV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('getUserCoursesV1', 'data', data) + const localVarPath = `/api/v1/course/userCourses`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows a user to search for courses by their name. + * @summary Search for courses + * @param {string} authorization Authorization token + * @param {SearchCourseData} data Data needed to search for courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + searchCourseV1: async (authorization: string, data: SearchCourseData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('searchCourseV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('searchCourseV1', 'data', data) + const localVarPath = `/api/v1/course/search`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * CourseApi - functional programming interface + * @export + */ +export const CourseApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = CourseApiAxiosParamCreator(configuration) + return { + /** + * Allows a user to create a new course. + * @summary Create a new course + * @param {string} authorization Authorization token + * @param {CreateCourseData} data Data needed to create a new course + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createCourseV1(authorization: string, data: CreateCourseData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createCourseV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CourseApi.createCourseV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows a user to get information about a course by its id. + * @summary Get course information + * @param {number} id Course ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCourseInfoV1(id: number, authorization: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCourseInfoV1(id, authorization, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CourseApi.getCourseInfoV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows a user to get all participants of a course. + * @summary Get course participants + * @param {string} authorization Authorization token + * @param {GetCourseParticipantsData} data Data needed to get course participants + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCourseParticipantsV1(authorization: string, data: GetCourseParticipantsData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCourseParticipantsV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CourseApi.getCourseParticipantsV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows a user to get all courses created by a user. + * @summary Get created courses + * @param {string} authorization Authorization token + * @param {GetCreatedCoursesData} data Data needed to get created courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCreatedCoursesV1(authorization: string, data: GetCreatedCoursesData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCreatedCoursesV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CourseApi.getCreatedCoursesV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows a user to get all courses participated by a user. + * @summary Get user courses + * @param {string} authorization Authorization token + * @param {GetUserCoursesData} data Data needed to get user courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserCoursesV1(authorization: string, data: GetUserCoursesData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserCoursesV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CourseApi.getUserCoursesV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows a user to search for courses by their name. + * @summary Search for courses + * @param {string} authorization Authorization token + * @param {SearchCourseData} data Data needed to search for courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async searchCourseV1(authorization: string, data: SearchCourseData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.searchCourseV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CourseApi.searchCourseV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * CourseApi - factory interface + * @export + */ +export const CourseApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = CourseApiFp(configuration) + return { + /** + * Allows a user to create a new course. + * @summary Create a new course + * @param {string} authorization Authorization token + * @param {CreateCourseData} data Data needed to create a new course + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createCourseV1(authorization: string, data: CreateCourseData, options?: any): AxiosPromise { + return localVarFp.createCourseV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows a user to get information about a course by its id. + * @summary Get course information + * @param {number} id Course ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCourseInfoV1(id: number, authorization: string, options?: any): AxiosPromise { + return localVarFp.getCourseInfoV1(id, authorization, options).then((request) => request(axios, basePath)); + }, + /** + * Allows a user to get all participants of a course. + * @summary Get course participants + * @param {string} authorization Authorization token + * @param {GetCourseParticipantsData} data Data needed to get course participants + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCourseParticipantsV1(authorization: string, data: GetCourseParticipantsData, options?: any): AxiosPromise { + return localVarFp.getCourseParticipantsV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows a user to get all courses created by a user. + * @summary Get created courses + * @param {string} authorization Authorization token + * @param {GetCreatedCoursesData} data Data needed to get created courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCreatedCoursesV1(authorization: string, data: GetCreatedCoursesData, options?: any): AxiosPromise { + return localVarFp.getCreatedCoursesV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows a user to get all courses participated by a user. + * @summary Get user courses + * @param {string} authorization Authorization token + * @param {GetUserCoursesData} data Data needed to get user courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserCoursesV1(authorization: string, data: GetUserCoursesData, options?: any): AxiosPromise { + return localVarFp.getUserCoursesV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows a user to search for courses by their name. + * @summary Search for courses + * @param {string} authorization Authorization token + * @param {SearchCourseData} data Data needed to search for courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + searchCourseV1(authorization: string, data: SearchCourseData, options?: any): AxiosPromise { + return localVarFp.searchCourseV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * CourseApi - object-oriented interface + * @export + * @class CourseApi + * @extends {BaseAPI} + */ +export class CourseApi extends BaseAPI { + /** + * Allows a user to create a new course. + * @summary Create a new course + * @param {string} authorization Authorization token + * @param {CreateCourseData} data Data needed to create a new course + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CourseApi + */ + public createCourseV1(authorization: string, data: CreateCourseData, options?: RawAxiosRequestConfig) { + return CourseApiFp(this.configuration).createCourseV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows a user to get information about a course by its id. + * @summary Get course information + * @param {number} id Course ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CourseApi + */ + public getCourseInfoV1(id: number, authorization: string, options?: RawAxiosRequestConfig) { + return CourseApiFp(this.configuration).getCourseInfoV1(id, authorization, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows a user to get all participants of a course. + * @summary Get course participants + * @param {string} authorization Authorization token + * @param {GetCourseParticipantsData} data Data needed to get course participants + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CourseApi + */ + public getCourseParticipantsV1(authorization: string, data: GetCourseParticipantsData, options?: RawAxiosRequestConfig) { + return CourseApiFp(this.configuration).getCourseParticipantsV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows a user to get all courses created by a user. + * @summary Get created courses + * @param {string} authorization Authorization token + * @param {GetCreatedCoursesData} data Data needed to get created courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CourseApi + */ + public getCreatedCoursesV1(authorization: string, data: GetCreatedCoursesData, options?: RawAxiosRequestConfig) { + return CourseApiFp(this.configuration).getCreatedCoursesV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows a user to get all courses participated by a user. + * @summary Get user courses + * @param {string} authorization Authorization token + * @param {GetUserCoursesData} data Data needed to get user courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CourseApi + */ + public getUserCoursesV1(authorization: string, data: GetUserCoursesData, options?: RawAxiosRequestConfig) { + return CourseApiFp(this.configuration).getUserCoursesV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows a user to search for courses by their name. + * @summary Search for courses + * @param {string} authorization Authorization token + * @param {SearchCourseData} data Data needed to search for courses + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CourseApi + */ + public searchCourseV1(authorization: string, data: SearchCourseData, options?: RawAxiosRequestConfig) { + return CourseApiFp(this.configuration).searchCourseV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } +} + + + +/** + * ExamApi - axios parameter creator + * @export + */ +export const ExamApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Allows the user to answer a question of an exam. + * @summary Answer a question of an exam + * @param {string} authorization Authorization token + * @param {AnswerQuestionData} data Data needed to answer a question of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + answerExamQuestionV1: async (authorization: string, data: AnswerQuestionData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('answerExamQuestionV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('answerExamQuestionV1', 'data', data) + const localVarPath = `/api/v1/exam/answer`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows the user to create a new exam. + * @summary Create a new exam + * @param {string} authorization Authorization token + * @param {CreateExamData} data Data needed to create a new exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createExamV1: async (authorization: string, data: CreateExamData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('createExamV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('createExamV1', 'data', data) + const localVarPath = `/api/v1/exam/create`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows the user to get information about an exam. + * @summary Get information about an exam + * @param {number} id Exam ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getExamInfoV1: async (id: number, authorization: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getExamInfoV1', 'id', id) + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getExamInfoV1', 'authorization', authorization) + const localVarPath = `/api/v1/exam/info`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (id !== undefined) { + localVarQueryParameter['id'] = id; + } + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows the user to get questions of an exam. + * @summary Get questions of an exam + * @param {string} authorization Authorization token + * @param {GetExamQuestionsData} data Data needed to get questions of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getExamQuestionsV1: async (authorization: string, data: GetExamQuestionsData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getExamQuestionsV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('getExamQuestionsV1', 'data', data) + const localVarPath = `/api/v1/exam/questions`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows the user to get information about an exam that a user has participated in. + * @summary Get information about an exam that a user has participated in + * @param {string} authorization Authorization token + * @param {GetGivenExamData} data Data needed to get information about an exam that a user has participated in + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getGivenExamV1: async (authorization: string, data: GetGivenExamData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getGivenExamV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('getGivenExamV1', 'data', data) + const localVarPath = `/api/v1/exam/givenExam`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows the user to get history of exams of a user. + * @summary Get history of exams of a user + * @param {string} authorization Authorization token + * @param {GetUsersExamHistoryData} data Data needed to get history of exams of a user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserExamsHistoryV1: async (authorization: string, data: GetUsersExamHistoryData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getUserExamsHistoryV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('getUserExamsHistoryV1', 'data', data) + const localVarPath = `/api/v1/exam/userExamsHistory`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows the user to get ongoing exams of a user. + * @summary Get ongoing exams of a user + * @param {string} authorization Authorization token + * @param {string} [targetId] Target user id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserOngoingExamsV1: async (authorization: string, targetId?: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getUserOngoingExamsV1', 'authorization', authorization) + const localVarPath = `/api/v1/exam/userOngoingExams`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (targetId !== undefined) { + localVarQueryParameter['targetId'] = targetId; + } + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Allows the user to set score for a user in an exam. + * @summary Set score for a user in an exam + * @param {string} authorization Authorization token + * @param {SetScoreData} data Data needed to set score for a user in an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setScoreV1: async (authorization: string, data: SetScoreData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('setScoreV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('setScoreV1', 'data', data) + const localVarPath = `/api/v1/exam/setScore`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ExamApi - functional programming interface + * @export + */ +export const ExamApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ExamApiAxiosParamCreator(configuration) + return { + /** + * Allows the user to answer a question of an exam. + * @summary Answer a question of an exam + * @param {string} authorization Authorization token + * @param {AnswerQuestionData} data Data needed to answer a question of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async answerExamQuestionV1(authorization: string, data: AnswerQuestionData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.answerExamQuestionV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.answerExamQuestionV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows the user to create a new exam. + * @summary Create a new exam + * @param {string} authorization Authorization token + * @param {CreateExamData} data Data needed to create a new exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createExamV1(authorization: string, data: CreateExamData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createExamV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.createExamV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows the user to get information about an exam. + * @summary Get information about an exam + * @param {number} id Exam ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getExamInfoV1(id: number, authorization: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getExamInfoV1(id, authorization, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.getExamInfoV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows the user to get questions of an exam. + * @summary Get questions of an exam + * @param {string} authorization Authorization token + * @param {GetExamQuestionsData} data Data needed to get questions of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getExamQuestionsV1(authorization: string, data: GetExamQuestionsData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getExamQuestionsV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.getExamQuestionsV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows the user to get information about an exam that a user has participated in. + * @summary Get information about an exam that a user has participated in + * @param {string} authorization Authorization token + * @param {GetGivenExamData} data Data needed to get information about an exam that a user has participated in + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getGivenExamV1(authorization: string, data: GetGivenExamData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getGivenExamV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.getGivenExamV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows the user to get history of exams of a user. + * @summary Get history of exams of a user + * @param {string} authorization Authorization token + * @param {GetUsersExamHistoryData} data Data needed to get history of exams of a user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserExamsHistoryV1(authorization: string, data: GetUsersExamHistoryData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserExamsHistoryV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.getUserExamsHistoryV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows the user to get ongoing exams of a user. + * @summary Get ongoing exams of a user + * @param {string} authorization Authorization token + * @param {string} [targetId] Target user id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserOngoingExamsV1(authorization: string, targetId?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserOngoingExamsV1(authorization, targetId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.getUserOngoingExamsV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Allows the user to set score for a user in an exam. + * @summary Set score for a user in an exam + * @param {string} authorization Authorization token + * @param {SetScoreData} data Data needed to set score for a user in an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async setScoreV1(authorization: string, data: SetScoreData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.setScoreV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExamApi.setScoreV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * ExamApi - factory interface + * @export + */ +export const ExamApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ExamApiFp(configuration) + return { + /** + * Allows the user to answer a question of an exam. + * @summary Answer a question of an exam + * @param {string} authorization Authorization token + * @param {AnswerQuestionData} data Data needed to answer a question of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + answerExamQuestionV1(authorization: string, data: AnswerQuestionData, options?: any): AxiosPromise { + return localVarFp.answerExamQuestionV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows the user to create a new exam. + * @summary Create a new exam + * @param {string} authorization Authorization token + * @param {CreateExamData} data Data needed to create a new exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createExamV1(authorization: string, data: CreateExamData, options?: any): AxiosPromise { + return localVarFp.createExamV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows the user to get information about an exam. + * @summary Get information about an exam + * @param {number} id Exam ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getExamInfoV1(id: number, authorization: string, options?: any): AxiosPromise { + return localVarFp.getExamInfoV1(id, authorization, options).then((request) => request(axios, basePath)); + }, + /** + * Allows the user to get questions of an exam. + * @summary Get questions of an exam + * @param {string} authorization Authorization token + * @param {GetExamQuestionsData} data Data needed to get questions of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getExamQuestionsV1(authorization: string, data: GetExamQuestionsData, options?: any): AxiosPromise { + return localVarFp.getExamQuestionsV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows the user to get information about an exam that a user has participated in. + * @summary Get information about an exam that a user has participated in + * @param {string} authorization Authorization token + * @param {GetGivenExamData} data Data needed to get information about an exam that a user has participated in + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getGivenExamV1(authorization: string, data: GetGivenExamData, options?: any): AxiosPromise { + return localVarFp.getGivenExamV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows the user to get history of exams of a user. + * @summary Get history of exams of a user + * @param {string} authorization Authorization token + * @param {GetUsersExamHistoryData} data Data needed to get history of exams of a user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserExamsHistoryV1(authorization: string, data: GetUsersExamHistoryData, options?: any): AxiosPromise { + return localVarFp.getUserExamsHistoryV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Allows the user to get ongoing exams of a user. + * @summary Get ongoing exams of a user + * @param {string} authorization Authorization token + * @param {string} [targetId] Target user id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserOngoingExamsV1(authorization: string, targetId?: string, options?: any): AxiosPromise { + return localVarFp.getUserOngoingExamsV1(authorization, targetId, options).then((request) => request(axios, basePath)); + }, + /** + * Allows the user to set score for a user in an exam. + * @summary Set score for a user in an exam + * @param {string} authorization Authorization token + * @param {SetScoreData} data Data needed to set score for a user in an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setScoreV1(authorization: string, data: SetScoreData, options?: any): AxiosPromise { + return localVarFp.setScoreV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ExamApi - object-oriented interface + * @export + * @class ExamApi + * @extends {BaseAPI} + */ +export class ExamApi extends BaseAPI { + /** + * Allows the user to answer a question of an exam. + * @summary Answer a question of an exam + * @param {string} authorization Authorization token + * @param {AnswerQuestionData} data Data needed to answer a question of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public answerExamQuestionV1(authorization: string, data: AnswerQuestionData, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).answerExamQuestionV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows the user to create a new exam. + * @summary Create a new exam + * @param {string} authorization Authorization token + * @param {CreateExamData} data Data needed to create a new exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public createExamV1(authorization: string, data: CreateExamData, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).createExamV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows the user to get information about an exam. + * @summary Get information about an exam + * @param {number} id Exam ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public getExamInfoV1(id: number, authorization: string, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).getExamInfoV1(id, authorization, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows the user to get questions of an exam. + * @summary Get questions of an exam + * @param {string} authorization Authorization token + * @param {GetExamQuestionsData} data Data needed to get questions of an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public getExamQuestionsV1(authorization: string, data: GetExamQuestionsData, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).getExamQuestionsV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows the user to get information about an exam that a user has participated in. + * @summary Get information about an exam that a user has participated in + * @param {string} authorization Authorization token + * @param {GetGivenExamData} data Data needed to get information about an exam that a user has participated in + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public getGivenExamV1(authorization: string, data: GetGivenExamData, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).getGivenExamV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows the user to get history of exams of a user. + * @summary Get history of exams of a user + * @param {string} authorization Authorization token + * @param {GetUsersExamHistoryData} data Data needed to get history of exams of a user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public getUserExamsHistoryV1(authorization: string, data: GetUsersExamHistoryData, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).getUserExamsHistoryV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows the user to get ongoing exams of a user. + * @summary Get ongoing exams of a user + * @param {string} authorization Authorization token + * @param {string} [targetId] Target user id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public getUserOngoingExamsV1(authorization: string, targetId?: string, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).getUserOngoingExamsV1(authorization, targetId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Allows the user to set score for a user in an exam. + * @summary Set score for a user in an exam + * @param {string} authorization Authorization token + * @param {SetScoreData} data Data needed to set score for a user in an exam + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExamApi + */ + public setScoreV1(authorization: string, data: SetScoreData, options?: RawAxiosRequestConfig) { + return ExamApiFp(this.configuration).setScoreV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } +} + + + +/** + * TopicApi - axios parameter creator + * @export + */ +export const TopicApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Create a new topic + * @summary Create a new topic + * @param {string} authorization Authorization token + * @param {CreateNewTopicData} data Data needed to create a new topic + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTopicV1: async (authorization: string, data: CreateNewTopicData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('createTopicV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('createTopicV1', 'data', data) + const localVarPath = `/api/v1/topic/create`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Get all user topic stats + * @summary Get all user topic stats + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllUserTopicStatsV1: async (authorization: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getAllUserTopicStatsV1', 'authorization', authorization) + const localVarPath = `/api/v1/topic/allUserTopicStats`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Get topic info + * @summary Get topic info + * @param {number} id Topic ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTopicInfoV1: async (id: number, authorization: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getTopicInfoV1', 'id', id) + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getTopicInfoV1', 'authorization', authorization) + const localVarPath = `/api/v1/topic/info`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (id !== undefined) { + localVarQueryParameter['id'] = id; + } + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Get user topic stat + * @summary Get user topic stat + * @param {string} authorization Authorization token + * @param {GetUserTopicStatData} data Data needed to get user topic stat + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserTopicStatV1: async (authorization: string, data: GetUserTopicStatData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('getUserTopicStatV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('getUserTopicStatV1', 'data', data) + const localVarPath = `/api/v1/topic/userTopicStat`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Search for topics + * @summary Search for topics + * @param {string} authorization Authorization token + * @param {SearchTopicData} data Data needed to search for topics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + searchTopicV1: async (authorization: string, data: SearchTopicData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('searchTopicV1', 'authorization', authorization) + // verify required parameter 'data' is not null or undefined + assertParamExists('searchTopicV1', 'data', data) + const localVarPath = `/api/v1/topic/search`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (authorization != null) { + localVarHeaderParameter['Authorization'] = String(authorization); + } + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * TopicApi - functional programming interface * @export - * @interface SearchUserResult */ -export interface SearchUserResult { - /** - * - * @type {Array} - * @memberof SearchUserResult - */ - 'users'?: Array; -} +export const TopicApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = TopicApiAxiosParamCreator(configuration) + return { + /** + * Create a new topic + * @summary Create a new topic + * @param {string} authorization Authorization token + * @param {CreateNewTopicData} data Data needed to create a new topic + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createTopicV1(authorization: string, data: CreateNewTopicData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createTopicV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TopicApi.createTopicV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Get all user topic stats + * @summary Get all user topic stats + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAllUserTopicStatsV1(authorization: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAllUserTopicStatsV1(authorization, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TopicApi.getAllUserTopicStatsV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Get topic info + * @summary Get topic info + * @param {number} id Topic ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getTopicInfoV1(id: number, authorization: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getTopicInfoV1(id, authorization, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TopicApi.getTopicInfoV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Get user topic stat + * @summary Get user topic stat + * @param {string} authorization Authorization token + * @param {GetUserTopicStatData} data Data needed to get user topic stat + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserTopicStatV1(authorization: string, data: GetUserTopicStatData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserTopicStatV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TopicApi.getUserTopicStatV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Search for topics + * @summary Search for topics + * @param {string} authorization Authorization token + * @param {SearchTopicData} data Data needed to search for topics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async searchTopicV1(authorization: string, data: SearchTopicData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.searchTopicV1(authorization, data, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TopicApi.searchTopicV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + /** - * + * TopicApi - factory interface * @export - * @interface SearchUserV1200Response */ -export interface SearchUserV1200Response { - /** - * - * @type {EndpointError} - * @memberof SearchUserV1200Response - */ - 'error'?: EndpointError; - /** - * - * @type {SearchUserResult} - * @memberof SearchUserV1200Response - */ - 'result'?: SearchUserResult; - /** - * - * @type {boolean} - * @memberof SearchUserV1200Response - */ - 'success'?: boolean; -} +export const TopicApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = TopicApiFp(configuration) + return { + /** + * Create a new topic + * @summary Create a new topic + * @param {string} authorization Authorization token + * @param {CreateNewTopicData} data Data needed to create a new topic + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTopicV1(authorization: string, data: CreateNewTopicData, options?: any): AxiosPromise { + return localVarFp.createTopicV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Get all user topic stats + * @summary Get all user topic stats + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllUserTopicStatsV1(authorization: string, options?: any): AxiosPromise { + return localVarFp.getAllUserTopicStatsV1(authorization, options).then((request) => request(axios, basePath)); + }, + /** + * Get topic info + * @summary Get topic info + * @param {number} id Topic ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTopicInfoV1(id: number, authorization: string, options?: any): AxiosPromise { + return localVarFp.getTopicInfoV1(id, authorization, options).then((request) => request(axios, basePath)); + }, + /** + * Get user topic stat + * @summary Get user topic stat + * @param {string} authorization Authorization token + * @param {GetUserTopicStatData} data Data needed to get user topic stat + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserTopicStatV1(authorization: string, data: GetUserTopicStatData, options?: any): AxiosPromise { + return localVarFp.getUserTopicStatV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + /** + * Search for topics + * @summary Search for topics + * @param {string} authorization Authorization token + * @param {SearchTopicData} data Data needed to search for topics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + searchTopicV1(authorization: string, data: SearchTopicData, options?: any): AxiosPromise { + return localVarFp.searchTopicV1(authorization, data, options).then((request) => request(axios, basePath)); + }, + }; +}; + /** - * + * TopicApi - object-oriented interface * @export - * @interface SearchedUserInfo + * @class TopicApi + * @extends {BaseAPI} */ -export interface SearchedUserInfo { - /** - * - * @type {string} - * @memberof SearchedUserInfo - */ - 'ban_reason'?: string; - /** - * - * @type {string} - * @memberof SearchedUserInfo - */ - 'created_at'?: string; +export class TopicApi extends BaseAPI { /** - * - * @type {string} - * @memberof SearchedUserInfo + * Create a new topic + * @summary Create a new topic + * @param {string} authorization Authorization token + * @param {CreateNewTopicData} data Data needed to create a new topic + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TopicApi */ - 'email'?: string; + public createTopicV1(authorization: string, data: CreateNewTopicData, options?: RawAxiosRequestConfig) { + return TopicApiFp(this.configuration).createTopicV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + /** - * - * @type {string} - * @memberof SearchedUserInfo + * Get all user topic stats + * @summary Get all user topic stats + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TopicApi */ - 'full_name'?: string; + public getAllUserTopicStatsV1(authorization: string, options?: RawAxiosRequestConfig) { + return TopicApiFp(this.configuration).getAllUserTopicStatsV1(authorization, options).then((request) => request(this.axios, this.basePath)); + } + /** - * - * @type {boolean} - * @memberof SearchedUserInfo + * Get topic info + * @summary Get topic info + * @param {number} id Topic ID + * @param {string} authorization Authorization token + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TopicApi */ - 'is_banned'?: boolean; + public getTopicInfoV1(id: number, authorization: string, options?: RawAxiosRequestConfig) { + return TopicApiFp(this.configuration).getTopicInfoV1(id, authorization, options).then((request) => request(this.axios, this.basePath)); + } + /** - * - * @type {UserRole} - * @memberof SearchedUserInfo + * Get user topic stat + * @summary Get user topic stat + * @param {string} authorization Authorization token + * @param {GetUserTopicStatData} data Data needed to get user topic stat + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TopicApi */ - 'role'?: UserRole; + public getUserTopicStatV1(authorization: string, data: GetUserTopicStatData, options?: RawAxiosRequestConfig) { + return TopicApiFp(this.configuration).getUserTopicStatV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } + /** - * - * @type {string} - * @memberof SearchedUserInfo + * Search for topics + * @summary Search for topics + * @param {string} authorization Authorization token + * @param {SearchTopicData} data Data needed to search for topics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TopicApi */ - 'user_id'?: string; + public searchTopicV1(authorization: string, data: SearchTopicData, options?: RawAxiosRequestConfig) { + return TopicApiFp(this.configuration).searchTopicV1(authorization, data, options).then((request) => request(this.axios, this.basePath)); + } } -/** - * UserRole is the role of the user. - * @export - * @enum {string} - */ - -export const UserRole = { - UserRoleOwner: 'owner', - UserRoleAdmin: 'admin', - UserRoleStudent: 'student', - UserRoleTeacher: 'teacher', - UserRoleUnknown: '' -} as const; - -export type UserRole = typeof UserRole[keyof typeof UserRole]; - - /** * UserApi - axios parameter creator @@ -1115,6 +4364,42 @@ export const UserApiAxiosParamCreator = function (configuration?: Configuration) options: localVarRequestOptions, }; }, + /** + * Allows a user to confirm their account + * @summary Confirm account + * @param {ConfirmAccountData} confirmAccountData Confirm account data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + confirmAccountV1: async (confirmAccountData: ConfirmAccountData, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'confirmAccountData' is not null or undefined + assertParamExists('confirmAccountV1', 'confirmAccountData', confirmAccountData) + const localVarPath = `/api/v1/user/confirmAccount`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(confirmAccountData, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, /** * Allows a user to confirm changing their own\'s password (from redirected page) * @summary Confirm changing your own\'s password @@ -1509,6 +4794,19 @@ export const UserApiFp = function(configuration?: Configuration) { const localVarOperationServerBasePath = operationServerMap['UserApi.changePasswordV1']?.[localVarOperationServerIndex]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); }, + /** + * Allows a user to confirm their account + * @summary Confirm account + * @param {ConfirmAccountData} confirmAccountData Confirm account data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async confirmAccountV1(confirmAccountData: ConfirmAccountData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.confirmAccountV1(confirmAccountData, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UserApi.confirmAccountV1']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, /** * Allows a user to confirm changing their own\'s password (from redirected page) * @summary Confirm changing your own\'s password @@ -1516,7 +4814,7 @@ export const UserApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async confirmChangePasswordV1(confirmChangePasswordData: ConfirmChangePasswordData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async confirmChangePasswordV1(confirmChangePasswordData: ConfirmChangePasswordData, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.confirmChangePasswordV1(confirmChangePasswordData, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['UserApi.confirmChangePasswordV1']?.[localVarOperationServerIndex]?.url; @@ -1662,6 +4960,16 @@ export const UserApiFactory = function (configuration?: Configuration, basePath? changePasswordV1(authorization: string, changePasswordData: ChangePasswordData, options?: any): AxiosPromise { return localVarFp.changePasswordV1(authorization, changePasswordData, options).then((request) => request(axios, basePath)); }, + /** + * Allows a user to confirm their account + * @summary Confirm account + * @param {ConfirmAccountData} confirmAccountData Confirm account data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + confirmAccountV1(confirmAccountData: ConfirmAccountData, options?: any): AxiosPromise { + return localVarFp.confirmAccountV1(confirmAccountData, options).then((request) => request(axios, basePath)); + }, /** * Allows a user to confirm changing their own\'s password (from redirected page) * @summary Confirm changing your own\'s password @@ -1669,7 +4977,7 @@ export const UserApiFactory = function (configuration?: Configuration, basePath? * @param {*} [options] Override http request option. * @throws {RequiredError} */ - confirmChangePasswordV1(confirmChangePasswordData: ConfirmChangePasswordData, options?: any): AxiosPromise { + confirmChangePasswordV1(confirmChangePasswordData: ConfirmChangePasswordData, options?: any): AxiosPromise { return localVarFp.confirmChangePasswordV1(confirmChangePasswordData, options).then((request) => request(axios, basePath)); }, /** @@ -1792,6 +5100,18 @@ export class UserApi extends BaseAPI { return UserApiFp(this.configuration).changePasswordV1(authorization, changePasswordData, options).then((request) => request(this.axios, this.basePath)); } + /** + * Allows a user to confirm their account + * @summary Confirm account + * @param {ConfirmAccountData} confirmAccountData Confirm account data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public confirmAccountV1(confirmAccountData: ConfirmAccountData, options?: RawAxiosRequestConfig) { + return UserApiFp(this.configuration).confirmAccountV1(confirmAccountData, options).then((request) => request(this.axios, this.basePath)); + } + /** * Allows a user to confirm changing their own\'s password (from redirected page) * @summary Confirm changing your own\'s password diff --git a/src/apiClient.ts b/src/apiClient.ts index 86c8b3e..7522747 100644 --- a/src/apiClient.ts +++ b/src/apiClient.ts @@ -15,6 +15,11 @@ import { GetUserInfoResult, EditUserData, EditUserResult, + TopicApi, + CreateNewTopicData, + CreateNewTopicResult, + SearchTopicData, + SearchTopicResult, } from './api'; class ExamSphereAPIClient extends UserApi { @@ -35,11 +40,15 @@ class ExamSphereAPIClient extends UserApi { /** The currently logged-in user's role. */ public role?: UserRole; + private topicApi: TopicApi; + constructor() { super(); this.guessBasePath(); this.clientRId = this.generateClientRId(); this.readTokens(); + + this.topicApi = new TopicApi(this.configuration); } /** @@ -62,6 +71,7 @@ class ExamSphereAPIClient extends UserApi { public guessBasePath(): void { // try to find out the base path let correctBasePath = "https://aliwoto.is-a.dev:8080"; + // let correctBasePath = "http://localhost:8080"; const envBasePath = process.env.EXAM_SPHERE_API_URL; if (envBasePath) { correctBasePath = envBasePath; @@ -264,6 +274,36 @@ class ExamSphereAPIClient extends UserApi { return searchUserResult; } + public async createNewTopic(data: CreateNewTopicData): Promise { + if (!this.isLoggedIn()) { + throw new Error("Not logged in"); + } + + let createTopicResult = (await this.topicApi.createTopicV1(`Bearer ${this.accessToken}`, data))?.data.result; + if (!createTopicResult) { + // we shouldn't reach here, because if there is an error somewhere, + // it should have already been thrown by the API client + throw new Error("Failed to create topic"); + } + + return createTopicResult; + } + + public async searchTopic(data: SearchTopicData): Promise { + if (!this.isLoggedIn()) { + throw new Error("Not logged in"); + } + + let searchTopicResult = (await this.topicApi.searchTopicV1(`Bearer ${this.accessToken}`, data))?.data.result; + if (!searchTopicResult) { + // we shouldn't reach here, because if there is an error somewhere, + // it should have already been thrown by the API client + throw new Error("Failed to search topic"); + } + + return searchTopicResult; + } + /** * Returns true if we are considered as "logged in" by the API client, * This method only checks if the access token is present, it doesn't @@ -307,6 +347,14 @@ class ExamSphereAPIClient extends UserApi { return this.isOwner() || this.isAdmin(); } + public canCreateTopics(): boolean { + return this.isOwner() || this.isAdmin(); + } + + public canSearchTopics(): boolean { + return this.isLoggedIn(); + } + public canCreateTargetRole(targetRole: UserRole): boolean { if (targetRole === UserRole.UserRoleOwner || UserRole.UserRoleUnknown) { diff --git a/src/components/menus/sideMenu.tsx b/src/components/menus/sideMenu.tsx index 138fcf3..50c9338 100644 --- a/src/components/menus/sideMenu.tsx +++ b/src/components/menus/sideMenu.tsx @@ -21,150 +21,164 @@ const SideMenuContainer = styled.div<{ $isOpen: boolean }>` `; interface SideMenuProps { - isOpen: boolean; - toggleMenu: () => void; + isOpen: boolean; + toggleMenu: () => void; - children?: React.ReactNode; + children?: React.ReactNode; } -const SideMenu: React.FC = ({...props}) => { - if (apiClient.isOwner()) { - return ( - - - - - - - - - - - - - - - - - - - - { - apiClient.logout(); - window.location.href = '/'; - }} - > - - ); - } +const RenderProfileMenu = () => { + return ( + + + + + ) +}; + +const RenderManageUserMenu = () => { + return ( + + + + + + + + + ) +} + +const RenderManageTopicsMenu = () => { + return ( + + + + + + ) +}; - if (apiClient.isAdmin()) { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - { - apiClient.logout(); - window.location.href = '/'; - }} - > - - ); - } +const RenderManageCoursesMenu = () => { + return ( + + + + + + ) +}; - if (apiClient.isTeacher()) { - return ( - - - - - - - - - - - - - { - apiClient.logout(); - window.location.href = '/'; - }} - > - - ); - } - - if (apiClient.isStudent()) { - return ( - - - - - - - - - - - - - { - apiClient.logout(); - window.location.href = '/'; - }} - > - - ); - } +const RenderManageExamsMenu = () => { + return ( + + + + + ) +}; +const RenderCommonMenus = () => { + return ( + <> + + + { + apiClient.logout(); + window.location.href = '/'; + }} + > + + ); +}; + +const SideMenu: React.FC = ({ ...props }) => { + if (apiClient.isOwner()) { return ( - - - + + + {RenderProfileMenu()} + {RenderManageUserMenu()} + {RenderManageTopicsMenu()} + {RenderManageCoursesMenu()} + {RenderManageExamsMenu()} + {RenderCommonMenus()} + ); + } + + if (apiClient.isAdmin()) { + return ( + + + {RenderProfileMenu()} + {RenderManageUserMenu()} + {RenderManageTopicsMenu()} + {RenderManageCoursesMenu()} + {RenderManageExamsMenu()} + {RenderCommonMenus()} + + ); + } + + if (apiClient.isTeacher()) { + return ( + + + {RenderProfileMenu()} + {RenderManageUserMenu()} + {RenderManageCoursesMenu()} + {RenderManageExamsMenu()} + {RenderCommonMenus()} + + ); + } + + if (apiClient.isStudent()) { + return ( + + + {RenderProfileMenu()} + {RenderManageUserMenu()} + {RenderManageExamsMenu()} + {RenderCommonMenus()} + + ); + } + + return ( + + + + ); }; export default SideMenu; diff --git a/src/pages/createTopicPage.tsx b/src/pages/createTopicPage.tsx new file mode 100644 index 0000000..9b7aaf8 --- /dev/null +++ b/src/pages/createTopicPage.tsx @@ -0,0 +1,59 @@ +import React, { useState } from 'react'; +import SubmitButton from '../components/buttons/submitButton'; +import DashboardContainer from '../components/containers/dashboardContainer'; +import TitleLabel from '../components/labels/titleLabel'; +import CreateUserForm from '../components/forms/createUserForm'; +import CreateUserContainer from '../components/containers/createUserContainer'; +import apiClient from '../apiClient'; +import { CreateNewTopicData } from '../api'; +import { CurrentAppTranslation } from '../translations/appTranslation'; +import { TextField } from '@mui/material'; +import useAppSnackbar from '../components/snackbars/useAppSnackbars'; +import { extractErrorDetails } from '../utils/errorUtils'; + +const CreateTopicPage: React.FC = () => { + const [createTopicData, setUserInfo] = useState({ + topic_name: '', + }); + const snackbar = useAppSnackbar(); + + const handleInputChange = (e: React.ChangeEvent) => { + setUserInfo({ ...createTopicData, [e.target.name]: e.target.value }); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + try { + await apiClient.createNewTopic(createTopicData); + snackbar.success(CurrentAppTranslation.TopicCreatedSuccessfullyText); + } catch (error: any) { + const [errCode, errMessage] = extractErrorDetails(error); + snackbar.error(`Failed (${errCode}): ${errMessage}`); + } + }; + + return ( + + + + {CurrentAppTranslation.CreateNewUserText} + { handleInputChange(e as any) }} + required /> + {CurrentAppTranslation.CreateUserButtonText} + + + + ); +}; + +export default CreateTopicPage; \ No newline at end of file diff --git a/src/pages/createUserPage.tsx b/src/pages/createUserPage.tsx index 6886044..731a956 100644 --- a/src/pages/createUserPage.tsx +++ b/src/pages/createUserPage.tsx @@ -113,9 +113,9 @@ const CreateUserPage: React.FC = () => { onChange={(e) => { handleInputChange(e as any) }} required={false} /> apiClient.canCreateTargetRole(role))} diff --git a/src/pages/searchTopicPage.tsx b/src/pages/searchTopicPage.tsx new file mode 100644 index 0000000..f8d025e --- /dev/null +++ b/src/pages/searchTopicPage.tsx @@ -0,0 +1,146 @@ +import { useEffect, useState } from 'react'; +import { + TextField, + List, + ListItem, + CircularProgress, + Paper, + Grid, + Typography, +} from '@mui/material'; +import { Box } from '@mui/material'; +import SearchIcon from '@mui/icons-material/Search'; +import IconButton from '@mui/material/IconButton'; +import { SearchedTopicInfo } from '../api'; +import apiClient from '../apiClient'; +import DashboardContainer from '../components/containers/dashboardContainer'; +import { CurrentAppTranslation } from '../translations/appTranslation'; + +const RenderTopicsList = (topics: SearchedTopicInfo[] | undefined, forEdit: boolean = false) => { + if (!topics || topics.length === 0) { + return ( + + {forEdit ? CurrentAppTranslation.EnterSearchForEdit : + CurrentAppTranslation.NoResultsFoundText} + + ); + } + + return ( + + {topics.map((topic) => ( + + { + // Redirect to user info page, make sure to query encode it + window.location.href = `/topicInfo?topicId=${encodeURIComponent(topic.topic_id!)}`; + } + }> + + + + {`${CurrentAppTranslation.topic_id}: ${topic.topic_id}`} + + + {`${CurrentAppTranslation.topic_name}: ${topic.topic_name}`} + + + + + + ))} + + ) +} + +const SearchTopicPage = () => { + const urlSearch = new URLSearchParams(window.location.search); + const providedQuery = urlSearch.get('query'); + const forEdit = (urlSearch.get('edit') ?? "false") === "true"; + + const [query, setQuery] = useState(providedQuery ?? ''); + const [topics, setTopics] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + const handleSearch = async () => { + window.history.pushState( + `searchTopic_query_${query}`, + "Search Topic", + `/searchTopic?query=${encodeURIComponent(query)}`, + ); + + if (query === '') { + return; + } + + setIsLoading(true); + const results = await apiClient.searchTopic({ + topic_name: query, + }) + + if (!results || !results.topics) { + setIsLoading(false); + return; + } + + setTopics(results.topics); + setIsLoading(false); + }; + + useEffect(() => { + // if at first the query is not null (e.g. the providedQuery exists), + // do the search. + if (query) { + handleSearch(); + } + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + return ( + + + + setQuery(e.target.value)} + label={CurrentAppTranslation.SearchTopicsText} + onKeyDown={(e) => e.key === 'Enter' && handleSearch()} + InputProps={{ + endAdornment: ( + handleSearch()} disabled={isLoading}> + + + ), + }} + /> + {isLoading ? ( + + + + ) : RenderTopicsList(topics, forEdit)} + + + + + + ); +}; + +export default SearchTopicPage; \ No newline at end of file diff --git a/src/translations/appTranslation.ts b/src/translations/appTranslation.ts index 214a67c..29e60b5 100644 --- a/src/translations/appTranslation.ts +++ b/src/translations/appTranslation.ts @@ -8,6 +8,7 @@ export class AppTranslationBase { LoginText: string = "Login"; LoadingText: string = "Loading..."; ProfileText: string = "Profile"; + DashboardText: string = "Dashboard"; EditProfileText: string = "Edit Profile"; ChangePasswordText: string = "Change Password"; ManageUsersText: string = "Manage Users"; @@ -15,6 +16,10 @@ export class AppTranslationBase { SearchUsersText: string = "Search Users"; EditUserInfoText: string = "Edit User Info"; ChangeUserPasswordText: string = "Change User Password"; + ManageTopicsText: string = "Manage Topics"; + AddTopicText: string = "Add Topic"; + SearchTopicsText: string = "Search Topics"; + EditTopicsText: string = "Edit Topic"; ManageCoursesText: string = "Manage Courses"; AddCourseText: string = "Add Course"; SearchCoursesText: string = "Search Courses"; @@ -26,12 +31,16 @@ export class AppTranslationBase { HelpText: string = "Help"; LogoutText: string = "Logout"; CreateUserButtonText: string = "Create User"; + CreateTopicButtonText: string = "Create Topic"; SaveText: string = "Save"; EditText: string = "Edit"; UserInformationText: string = "User Information"; + + // System messages UserNotFoundText: string = "This user doesn't seem to exist..."; CreateNewUserText: string = "Create New User"; UserCreatedSuccessfullyText: string = "User created successfully"; + TopicCreatedSuccessfullyText: string = "Topic created successfully"; NoResultsFoundText: string = "No results found, try changing your search query"; EnterSearchForEdit: string = "Enter search query to edit the user"; @@ -40,6 +49,8 @@ export class AppTranslationBase { //#region API response fields translations + topic_name: string = "Topic Name"; + topic_id: string = "Topic ID"; user_id: string = "User ID"; full_name: string = "Full Name"; email: string = "Email"; diff --git a/src/translations/faTranslation.ts b/src/translations/faTranslation.ts index 9c14519..86658c2 100644 --- a/src/translations/faTranslation.ts +++ b/src/translations/faTranslation.ts @@ -10,12 +10,17 @@ class FaTranslation extends AppTranslationBase { LoginText: string = "ورود"; LoadingText: string = "در حال بارگذاری..."; ProfileText: string = "پروفایل"; + DashboardText: string = "داشبورد"; EditProfileText: string = "ویرایش پروفایل"; ChangePasswordText: string = "تغییر رمز عبور"; ManageUsersText: string = "مدیریت کاربران"; AddUserText: string = "افزودن کاربر"; EditUserInfoText: string = "ویرایش اطلاعات کاربر"; ChangeUserPasswordText: string = "تغییر رمز عبور کاربر"; + ManageTopicsText: string = "مدیریت موضوعات"; + AddTopicText: string = "افزودن موضوع"; + SearchTopicsText: string = "جستجوی موضوعات"; + EditTopicsText: string = "ویرایش موضوع"; ManageCoursesText: string = "مدیریت دوره ها"; AddCourseText: string = "افزودن دوره"; SearchCoursesText: string = "جستجوی دوره ها"; @@ -27,12 +32,18 @@ class FaTranslation extends AppTranslationBase { HelpText: string = "راهنما"; LogoutText: string = "خروج از حساب کاربری"; CreateUserButtonText: string = "ایجاد کاربر"; + CreateTopicButtonText: string = "ایجاد موضوع"; SaveText: string = "ذخیره"; EditText: string = "ویرایش"; UserInformationText: string = "اطلاعات کاربر"; + + + // System messages + UserNotFoundText: string = "این کاربر وجود ندارد..."; CreateNewUserText: string = "ایجاد کاربر جدید"; UserCreatedSuccessfullyText: string = "کاربر با موفقیت ایجاد شد"; + TopicCreatedSuccessfullyText: string = "موضوع با موفقیت ایجاد شد"; NoResultsFoundText: string = "نتیجه ای یافت نشد، تلاش کنید تا جستجوی خود را تغییر دهید"; EnterSearchForEdit: string = "برای ویرایش کاربر جستجو کنید"; @@ -41,6 +52,8 @@ class FaTranslation extends AppTranslationBase { //#region API response fields translations + topic_name: string = "نام موضوع"; + topic_id: string = "شناسه موضوع"; user_id: string = "شناسه کاربری"; full_name: string = "نام کامل"; email: string = "ایمیل";