touchstudy-core 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/components/Chats/ChatContainer.d.ts +6 -0
  2. package/dist/components/Chats/ChatHeader.d.ts +1 -0
  3. package/dist/components/Chats/ChatItem.d.ts +2 -1
  4. package/dist/components/Chats/ChatList.d.ts +1 -1
  5. package/dist/components/Chats/configs/types.d.ts +2 -0
  6. package/dist/components/Chats/hooks/useChatContainer.d.ts +6 -1
  7. package/dist/components/Chats/hooks/useMessageList.d.ts +2 -1
  8. package/dist/components/Dialogs/ConfirmDialog.d.ts +1 -0
  9. package/dist/components/Selects/CustomAsyncSelect.d.ts +3 -0
  10. package/dist/components/Selects/CustomCreatable.d.ts +3 -0
  11. package/dist/components/Selects/CustomSelect.d.ts +1 -1
  12. package/dist/containers/Exams/components/ArticleGroupView.d.ts +19 -0
  13. package/dist/containers/Exams/components/QuestionView.d.ts +11 -0
  14. package/dist/containers/Exams/configs/constants.d.ts +8 -0
  15. package/dist/containers/Exams/configs/interfaces.d.ts +9 -0
  16. package/dist/containers/Exams/configs/types.d.ts +21 -0
  17. package/dist/containers/Exams/hooks/useExamDetailView.d.ts +23 -0
  18. package/dist/containers/Exams/views/ExamDetailView.d.ts +4 -0
  19. package/dist/containers/Login/configs/constants.d.ts +5 -0
  20. package/dist/containers/Login/views/Login.d.ts +2 -1
  21. package/dist/containers/Login/views/block/BlockLogin.d.ts +2 -1
  22. package/dist/index.css +40 -1
  23. package/dist/index.d.ts +11 -1
  24. package/dist/index.js +993 -112
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.modern.js +978 -113
  27. package/dist/index.modern.js.map +1 -1
  28. package/dist/utils/useLanguage.d.ts +10 -0
  29. package/package.json +3 -1
  30. package/dist/services/api.d.ts +0 -3
package/dist/index.js CHANGED
@@ -16,11 +16,16 @@ var gapiScript = require('gapi-script');
16
16
  var i18n = _interopDefault(require('i18next'));
17
17
  var reactI18next = require('react-i18next');
18
18
  var io5 = require('react-icons/io5');
19
- var Select = _interopDefault(require('react-select'));
19
+ var Select = require('react-select');
20
+ var Select__default = _interopDefault(Select);
21
+ var fa = require('react-icons/fa');
20
22
  var reactRouterDom = require('react-router-dom');
21
23
  var io = require('react-icons/io');
22
- var reactToastify = require('react-toastify');
23
24
  var Pusher = _interopDefault(require('pusher-js'));
25
+ var reactToastify = require('react-toastify');
26
+ var CreatableSelect = _interopDefault(require('react-select/creatable'));
27
+ var pi = require('react-icons/pi');
28
+ var _ = _interopDefault(require('lodash'));
24
29
 
25
30
  var setLoading = toolkit.createAction("common/setLoading");
26
31
  var setAlert = toolkit.createAction("common/setAlert");
@@ -150,6 +155,11 @@ var AuthenticationMessage;
150
155
  AuthenticationMessage["NotAllowedToRegister"] = "NotAllowedToRegister";
151
156
  AuthenticationMessage["InvalidGoogleToken"] = "InvalidGoogleToken";
152
157
  })(AuthenticationMessage || (AuthenticationMessage = {}));
158
+ (function (Role) {
159
+ Role["Student"] = "Student";
160
+ Role["Teacher"] = "Teacher";
161
+ Role["Admin"] = "Admin";
162
+ })(exports.Role || (exports.Role = {}));
153
163
 
154
164
  var useGoogleSignOut = function useGoogleSignOut(props) {
155
165
  var dispatch = reactRedux.useDispatch();
@@ -196,7 +206,8 @@ var schema = yup.object({
196
206
  var BlockLogin = function BlockLogin(_ref) {
197
207
  var defaultInfo = _ref.defaultInfo,
198
208
  onNavigate = _ref.onNavigate,
199
- isTeacher = _ref.isTeacher;
209
+ _ref$role = _ref.role,
210
+ role = _ref$role === void 0 ? exports.Role.Student : _ref$role;
200
211
  var dispatch = reactRedux.useDispatch();
201
212
  var _useGoogleSignOut = useGoogleSignOut({
202
213
  onNavigate: onNavigate
@@ -222,7 +233,6 @@ var BlockLogin = function BlockLogin(_ref) {
222
233
  token: accessToken,
223
234
  googleId: googleId
224
235
  };
225
- var role = isTeacher ? "Teacher" : "Student";
226
236
  dispatch(setLoading(true));
227
237
  var _temp = _catch(function () {
228
238
  return Promise.resolve(apiLoginGoogle(infoLogin, role)).then(function (res1) {
@@ -230,7 +240,7 @@ var BlockLogin = function BlockLogin(_ref) {
230
240
  var tokenJWT = res1.data.token;
231
241
  localStorage.setItem("USER_INFORMATION", JSON.stringify(infoLogin));
232
242
  localStorage.setItem(ACCESS_TOKEN, tokenJWT);
233
- if (!isTeacher && isFirstLogin) {
243
+ if (role === exports.Role.Student && isFirstLogin) {
234
244
  onNavigate("/register/info");
235
245
  } else {
236
246
  onNavigate("/");
@@ -349,7 +359,7 @@ var useLogin = function useLogin(onNavigate) {
349
359
 
350
360
  var Login = function Login(_ref) {
351
361
  var onNavigate = _ref.onNavigate,
352
- isTeacher = _ref.isTeacher;
362
+ role = _ref.role;
353
363
  var _useLogin = useLogin(onNavigate),
354
364
  defaultInfo = _useLogin.defaultInfo;
355
365
  return React__default.createElement("div", {
@@ -364,7 +374,7 @@ var Login = function Login(_ref) {
364
374
  }, React__default.createElement(BlockLogin, {
365
375
  defaultInfo: defaultInfo,
366
376
  onNavigate: onNavigate,
367
- isTeacher: isTeacher
377
+ role: role
368
378
  }))));
369
379
  };
370
380
 
@@ -604,11 +614,11 @@ var NotFound = function NotFound() {
604
614
  document.title = TITLE;
605
615
  });
606
616
  return React__default.createElement("div", {
607
- className: "not-found"
617
+ className: "not-found d-flex justify-content-center"
608
618
  }, React__default.createElement("div", {
609
- className: "clearfix"
619
+ className: "clearfix pt-5"
610
620
  }, React__default.createElement("h1", {
611
- className: "float-left display-3 mr-4"
621
+ className: "float-left display-3 fw-bold mr-4 text-center"
612
622
  }, "404"), React__default.createElement("div", {
613
623
  className: "float-left"
614
624
  }, React__default.createElement("h4", {
@@ -663,16 +673,13 @@ var LayoutContext = function LayoutContext(_ref) {
663
673
  var _state$common;
664
674
  return state === null || state === void 0 ? void 0 : (_state$common = state.common) === null || _state$common === void 0 ? void 0 : _state$common.user;
665
675
  });
676
+ var roles = (user === null || user === void 0 ? void 0 : user.roles) || [];
666
677
  var resetAuth = function resetAuth() {
667
678
  handleSignOut();
668
679
  };
669
680
  var checkRoleUser = React.useCallback(function () {
670
- var _user$roles, _user$roles2;
671
681
  if (!user) return;
672
- var isAdmin = (_user$roles = user.roles) === null || _user$roles === void 0 ? void 0 : _user$roles.includes("Admin");
673
- if (isAdmin && role !== "Teacher") alert(user.email + " not allow to register " + role);
674
- if (isAdmin) return;
675
- if (!((_user$roles2 = user.roles) !== null && _user$roles2 !== void 0 && _user$roles2.includes(role))) {
682
+ if (!roles.includes(role)) {
676
683
  alert(user.email + " not allow to register " + role);
677
684
  resetAuth();
678
685
  }
@@ -725,19 +732,47 @@ var ConfirmDialog = function ConfirmDialog(_ref) {
725
732
  _ref$title = _ref.title,
726
733
  title = _ref$title === void 0 ? "Confirmation" : _ref$title,
727
734
  toggle = _ref.toggle,
728
- onConfirm = _ref.onConfirm;
735
+ onConfirm = _ref.onConfirm,
736
+ confirmText = _ref.confirmText;
737
+ var _useState = React.useState(),
738
+ confirmTextValue = _useState[0],
739
+ setConfirmTextValue = _useState[1];
740
+ var handleConfirm = function handleConfirm() {
741
+ onConfirm();
742
+ };
743
+ var handleChangeConfirmText = function handleChangeConfirmText(e) {
744
+ setConfirmTextValue(e.target.value);
745
+ };
746
+ var handlePaste = function handlePaste(e) {
747
+ e.preventDefault();
748
+ };
749
+ React.useEffect(function () {
750
+ !open && setConfirmTextValue(undefined);
751
+ }, [open]);
752
+ var isValid = !!confirmText && !!confirmTextValue && confirmTextValue.trim() === confirmText.trim();
729
753
  return React__default.createElement(reactstrap.Modal, {
730
754
  isOpen: open,
731
755
  toggle: toggle,
732
- centered: true
756
+ centered: true,
757
+ zIndex: 1102
733
758
  }, React__default.createElement(reactstrap.ModalHeader, {
734
759
  toggle: toggle
735
- }, title), React__default.createElement(reactstrap.ModalBody, null, text), React__default.createElement(reactstrap.ModalFooter, null, React__default.createElement(reactstrap.Button, {
760
+ }, title), React__default.createElement(reactstrap.ModalBody, null, React__default.createElement("p", null, React__default.createElement("strong", null, text)), !!confirmText && React__default.createElement("div", null, React__default.createElement("p", null, "Enter \"", React__default.createElement("strong", null, confirmText), "\" to confirm delete"), React__default.createElement(reactstrap.Input, {
761
+ value: confirmTextValue,
762
+ onChange: handleChangeConfirmText,
763
+ placeholder: "Please enter...",
764
+ onPaste: handlePaste,
765
+ invalid: !isValid && confirmTextValue !== undefined,
766
+ valid: isValid
767
+ }))), React__default.createElement(reactstrap.ModalFooter, null, React__default.createElement(reactstrap.Button, {
736
768
  color: "secondary",
769
+ className: "px-3",
737
770
  onClick: toggle
738
771
  }, cancelText), React__default.createElement(reactstrap.Button, {
739
772
  color: isDelete ? "danger" : "primary",
740
- onClick: onConfirm
773
+ className: "px-3",
774
+ disabled: !!confirmText && (confirmTextValue === null || confirmTextValue === void 0 ? void 0 : confirmTextValue.trim()) !== confirmText.trim(),
775
+ onClick: handleConfirm
741
776
  }, okText)));
742
777
  };
743
778
 
@@ -755,7 +790,8 @@ var CommonDialog = function CommonDialog(_ref) {
755
790
  isOpen: open,
756
791
  toggle: onClose,
757
792
  centered: centered,
758
- size: size
793
+ size: size,
794
+ zIndex: 1102
759
795
  }, React__default.createElement(reactstrap.ModalHeader, {
760
796
  toggle: onClose
761
797
  }, title), children);
@@ -971,6 +1007,18 @@ var problem = "문제";
971
1007
  var problem_solving_time = "문제풀이 시간";
972
1008
  var minutes = "분";
973
1009
  var correct_rate = "정확한 비율";
1010
+ var title = "시험명";
1011
+ var duration = "시험 시간";
1012
+ var answer_count = "답변 수";
1013
+ var question_count = "문제 갯수";
1014
+ var category = "문항 카테고리";
1015
+ var save_and_exit = "저장 및 종료";
1016
+ var update_exam = "시험 업데이트";
1017
+ var create_exam = "새 시험 만들기";
1018
+ var enter_title = "시험 제목을 입력하세요";
1019
+ var select_placeholder = "선택하다...";
1020
+ var view_exam = "시험 보기";
1021
+ var back = "뒤쪽에";
974
1022
  var lang_ko = {
975
1023
  problem_solving: problem_solving,
976
1024
  my_story: my_story,
@@ -1028,7 +1076,19 @@ var lang_ko = {
1028
1076
  problem: problem,
1029
1077
  problem_solving_time: problem_solving_time,
1030
1078
  minutes: minutes,
1031
- correct_rate: correct_rate
1079
+ correct_rate: correct_rate,
1080
+ title: title,
1081
+ duration: duration,
1082
+ answer_count: answer_count,
1083
+ question_count: question_count,
1084
+ category: category,
1085
+ save_and_exit: save_and_exit,
1086
+ update_exam: update_exam,
1087
+ create_exam: create_exam,
1088
+ enter_title: enter_title,
1089
+ select_placeholder: select_placeholder,
1090
+ view_exam: view_exam,
1091
+ back: back
1032
1092
  };
1033
1093
 
1034
1094
  var problem_solving$1 = "Problem Solving";
@@ -1088,6 +1148,58 @@ var problem$1 = "Problem ";
1088
1148
  var problem_solving_time$1 = "Problem solving time";
1089
1149
  var minutes$1 = "m";
1090
1150
  var correct_rate$1 = "Correct rate";
1151
+ var difficult_level = "Difficult level";
1152
+ var difficulty_explain = "(The Difficulty Level provides an indication of the difficulty level of each test question)";
1153
+ var explain_your_answer = "Explain your answer";
1154
+ var hint = "Hint";
1155
+ var save_and_add_next_question = "Save and add next question";
1156
+ var save_and_exit$1 = "Save and exit";
1157
+ var question_text = "Question text";
1158
+ var title$1 = "Title";
1159
+ var create_question = "Create question";
1160
+ var parent_question = "Parent question";
1161
+ var edit_question = "Edit question";
1162
+ var easy = "Easy";
1163
+ var intermediate = "Intermediate";
1164
+ var difficult = "Difficult";
1165
+ var article = "Article";
1166
+ var correct_answer = "Correct answer";
1167
+ var mark = "Mark";
1168
+ var answer = "Answer";
1169
+ var add_new_row = "Add new row";
1170
+ var question_text_required = "Question text is required";
1171
+ var create_question_success = "Question is created successfully";
1172
+ var update_question_success = "Question is updated successfully";
1173
+ var number_of_answers = "Number of answers";
1174
+ var correct_answers = "Correct answers";
1175
+ var category$1 = "Category";
1176
+ var score = "Score";
1177
+ var enter_title$1 = "Enter title";
1178
+ var enter_score = "Enter score";
1179
+ var exam_title_required = "Exam title is required";
1180
+ var question_category_required = "Question category is required";
1181
+ var start_time = "Start time";
1182
+ var end_time = "End time";
1183
+ var enter_class_name = "Enter class name";
1184
+ var class_required = "Class name is required";
1185
+ var total_teachers = "Total teachers";
1186
+ var start_time_required = "Start time is required";
1187
+ var end_time_required = "End time is required";
1188
+ var full_name = "Full name";
1189
+ var email = "Email";
1190
+ var is_paid = "Is paid";
1191
+ var payment_time = "Payment time";
1192
+ var create_and_continue = "Create and continue";
1193
+ var payments = "Payments";
1194
+ var duration$1 = "Duration";
1195
+ var answer_count$1 = "Answer count";
1196
+ var question_count$1 = "Question count";
1197
+ var multi_choice = "Is multiple";
1198
+ var select_placeholder$1 = "Select...";
1199
+ var view_exam$1 = "View exam";
1200
+ var update_exam$1 = "Update exam";
1201
+ var create_exam$1 = "Create exam";
1202
+ var back$1 = "Back";
1091
1203
  var lang_en = {
1092
1204
  problem_solving: problem_solving$1,
1093
1205
  my_story: my_story$1,
@@ -1145,7 +1257,59 @@ var lang_en = {
1145
1257
  problem: problem$1,
1146
1258
  problem_solving_time: problem_solving_time$1,
1147
1259
  minutes: minutes$1,
1148
- correct_rate: correct_rate$1
1260
+ correct_rate: correct_rate$1,
1261
+ difficult_level: difficult_level,
1262
+ difficulty_explain: difficulty_explain,
1263
+ explain_your_answer: explain_your_answer,
1264
+ hint: hint,
1265
+ save_and_add_next_question: save_and_add_next_question,
1266
+ save_and_exit: save_and_exit$1,
1267
+ question_text: question_text,
1268
+ title: title$1,
1269
+ create_question: create_question,
1270
+ parent_question: parent_question,
1271
+ edit_question: edit_question,
1272
+ easy: easy,
1273
+ intermediate: intermediate,
1274
+ difficult: difficult,
1275
+ article: article,
1276
+ correct_answer: correct_answer,
1277
+ mark: mark,
1278
+ answer: answer,
1279
+ add_new_row: add_new_row,
1280
+ question_text_required: question_text_required,
1281
+ create_question_success: create_question_success,
1282
+ update_question_success: update_question_success,
1283
+ number_of_answers: number_of_answers,
1284
+ correct_answers: correct_answers,
1285
+ category: category$1,
1286
+ score: score,
1287
+ enter_title: enter_title$1,
1288
+ enter_score: enter_score,
1289
+ exam_title_required: exam_title_required,
1290
+ question_category_required: question_category_required,
1291
+ start_time: start_time,
1292
+ end_time: end_time,
1293
+ enter_class_name: enter_class_name,
1294
+ class_required: class_required,
1295
+ total_teachers: total_teachers,
1296
+ start_time_required: start_time_required,
1297
+ end_time_required: end_time_required,
1298
+ full_name: full_name,
1299
+ email: email,
1300
+ is_paid: is_paid,
1301
+ payment_time: payment_time,
1302
+ create_and_continue: create_and_continue,
1303
+ payments: payments,
1304
+ duration: duration$1,
1305
+ answer_count: answer_count$1,
1306
+ question_count: question_count$1,
1307
+ multi_choice: multi_choice,
1308
+ select_placeholder: select_placeholder$1,
1309
+ view_exam: view_exam$1,
1310
+ update_exam: update_exam$1,
1311
+ create_exam: create_exam$1,
1312
+ back: back$1
1149
1313
  };
1150
1314
 
1151
1315
  i18n.use(reactI18next.initReactI18next).init({
@@ -1184,7 +1348,7 @@ var SUPPORTED_LANGUAGES_CODE = LANGUAGES.map(function (i) {
1184
1348
  return i.code;
1185
1349
  });
1186
1350
 
1187
- var TheLanguageDropdown = function TheLanguageDropdown() {
1351
+ var useLanguage = function useLanguage() {
1188
1352
  var defaultLanguage = !!localStorage.getItem("language") ? localStorage.getItem("language") : navigator.language || DEFAULT_LANGUAGE_CODE;
1189
1353
  var dispatch = reactRedux.useDispatch();
1190
1354
  var _useTranslation = reactI18next.useTranslation(),
@@ -1207,19 +1371,32 @@ var TheLanguageDropdown = function TheLanguageDropdown() {
1207
1371
  setItemLanguage(lang);
1208
1372
  dispatch(setLanguage(lang));
1209
1373
  };
1374
+ React.useEffect(function () {
1375
+ changeLanguageApp(language);
1376
+ }, [language]);
1210
1377
  var currentLanguage = React.useMemo(function () {
1211
1378
  var currentLang = LANGUAGES.find(function (i) {
1212
1379
  return i.code === language;
1213
1380
  });
1214
1381
  if (!currentLang) return null;
1215
- return React__default.createElement(React__default.Fragment, null, React__default.createElement("img", {
1216
- className: "mr-2 " + styles['dropdown-menu-flag'],
1217
- src: currentLang.image
1218
- }), " ", currentLang.shortName);
1219
- }, [language]);
1220
- React.useEffect(function () {
1221
- changeLanguageApp(language);
1382
+ return currentLang;
1222
1383
  }, [language]);
1384
+ return {
1385
+ language: language,
1386
+ dropdownOpen: dropdownOpen,
1387
+ currentLanguage: currentLanguage,
1388
+ toggle: toggle,
1389
+ setItemLanguage: setItemLanguage
1390
+ };
1391
+ };
1392
+
1393
+ var TheLanguageDropdown = function TheLanguageDropdown() {
1394
+ var _useLanguage = useLanguage(),
1395
+ currentLanguage = _useLanguage.currentLanguage,
1396
+ language = _useLanguage.language,
1397
+ dropdownOpen = _useLanguage.dropdownOpen,
1398
+ toggle = _useLanguage.toggle,
1399
+ setItemLanguage = _useLanguage.setItemLanguage;
1223
1400
  return React__default.createElement(reactstrap.Dropdown, {
1224
1401
  isOpen: dropdownOpen,
1225
1402
  toggle: toggle,
@@ -1233,7 +1410,10 @@ var TheLanguageDropdown = function TheLanguageDropdown() {
1233
1410
  display: 'flex',
1234
1411
  alignItems: 'center'
1235
1412
  }
1236
- }, currentLanguage, React__default.createElement(io5.IoChevronDown, {
1413
+ }, !!currentLanguage && React__default.createElement("img", {
1414
+ className: "mr-2 " + styles['dropdown-menu-flag'],
1415
+ src: currentLanguage.image
1416
+ }), !!currentLanguage && currentLanguage.shortName, React__default.createElement(io5.IoChevronDown, {
1237
1417
  className: "ml-2",
1238
1418
  style: {
1239
1419
  fontSize: '15px',
@@ -1317,14 +1497,54 @@ function _objectWithoutPropertiesLoose(source, excluded) {
1317
1497
  return target;
1318
1498
  }
1319
1499
 
1320
- var _excluded = ["defaultValue", "options", "isDisabled", "scrollBottom", "value", "isMulti"];
1500
+ var _excluded = ["isDefault", "defaultValue", "options", "isDisabled", "scrollBottom", "value", "isMulti"];
1501
+ var DropdownIndicator = function DropdownIndicator(props) {
1502
+ return React__default.createElement(Select.components.DropdownIndicator, Object.assign({}, props), React__default.createElement(fa.FaCaretDown, {
1503
+ color: "#5458D5"
1504
+ }));
1505
+ };
1506
+ var CustomOption = function CustomOption(props) {
1507
+ return React__default.createElement(Select.components.Option, Object.assign({}, props), React__default.createElement("div", {
1508
+ style: {
1509
+ fontSize: "14px",
1510
+ fontWeight: 500
1511
+ }
1512
+ }, props.data.label));
1513
+ };
1514
+ var customStyles = {
1515
+ control: function control(baseStyles, state) {
1516
+ return _extends({}, baseStyles, {
1517
+ fontSize: "14px",
1518
+ fontWeight: 700,
1519
+ color: "#5458D5",
1520
+ borderColor: state.isFocused ? '#5458D5' : '#C3C5FE'
1521
+ });
1522
+ },
1523
+ input: function input(baseStyles, _) {
1524
+ return _extends({}, baseStyles, {
1525
+ fontSize: "14px",
1526
+ fontWeight: 700,
1527
+ color: "#5458D5"
1528
+ });
1529
+ },
1530
+ singleValue: function singleValue(baseStyles) {
1531
+ return _extends({}, baseStyles, {
1532
+ fontSize: "14px",
1533
+ fontWeight: 700,
1534
+ color: "#5458D5"
1535
+ });
1536
+ }
1537
+ };
1321
1538
  var CustomSelect = function CustomSelect(_ref) {
1322
- var options = _ref.options,
1539
+ var isDefault = _ref.isDefault,
1540
+ options = _ref.options,
1323
1541
  isDisabled = _ref.isDisabled,
1324
1542
  scrollBottom = _ref.scrollBottom,
1325
1543
  value = _ref.value,
1326
1544
  isMulti = _ref.isMulti,
1327
1545
  rest = _objectWithoutPropertiesLoose(_ref, _excluded);
1546
+ var _useTranslation = reactI18next.useTranslation(),
1547
+ t = _useTranslation.t;
1328
1548
  var initialValues = Array.isArray(value) ? options.filter(function (i) {
1329
1549
  return value.includes(i.value);
1330
1550
  }) : isMulti ? options.filter(function (i) {
@@ -1332,12 +1552,22 @@ var CustomSelect = function CustomSelect(_ref) {
1332
1552
  }) : options.find(function (i) {
1333
1553
  return i.value == value;
1334
1554
  });
1335
- return React__default.createElement(Select, Object.assign({
1555
+ return React__default.createElement(Select__default, Object.assign({
1336
1556
  isDisabled: isDisabled,
1337
1557
  options: options,
1338
- value: initialValues,
1558
+ value: !isDefault ? initialValues != null ? initialValues : null : undefined,
1559
+ defaultValue: isDefault ? initialValues : undefined,
1339
1560
  menuPlacement: scrollBottom ? "top" : "auto",
1340
- isMulti: isMulti
1561
+ isMulti: isMulti,
1562
+ components: {
1563
+ IndicatorSeparator: function IndicatorSeparator() {
1564
+ return null;
1565
+ },
1566
+ DropdownIndicator: DropdownIndicator,
1567
+ Option: CustomOption
1568
+ },
1569
+ styles: customStyles,
1570
+ placeholder: t("select_placeholder")
1341
1571
  }, rest));
1342
1572
  };
1343
1573
 
@@ -1381,11 +1611,10 @@ var MessageStatus;
1381
1611
  })(MessageStatus || (MessageStatus = {}));
1382
1612
 
1383
1613
  var ChatRightItem = function ChatRightItem(_ref) {
1384
- var content = _ref.content,
1614
+ var id = _ref.id,
1615
+ content = _ref.content,
1385
1616
  createdAt = _ref.createdAt,
1386
1617
  isRead = _ref.isRead,
1387
- _ref$type = _ref.type,
1388
- type = _ref$type === void 0 ? exports.ChatItemType.Default : _ref$type,
1389
1618
  examCode = _ref.examCode,
1390
1619
  isSystemLog = _ref.isSystemLog,
1391
1620
  parentId = _ref.parentId,
@@ -1399,8 +1628,11 @@ var ChatRightItem = function ChatRightItem(_ref) {
1399
1628
  examTitle = _ref.examTitle,
1400
1629
  parentContent = _ref.parentContent,
1401
1630
  status = _ref.status,
1631
+ selectedReplyMessageId = _ref.selectedReplyMessageId,
1632
+ selectedReplyItemRef = _ref.selectedReplyItemRef,
1402
1633
  onAddExamMessage = _ref.onAddExamMessage,
1403
- onReTrySendMessage = _ref.onReTrySendMessage;
1634
+ onReTrySendMessage = _ref.onReTrySendMessage,
1635
+ onGotoParentMessage = _ref.onGotoParentMessage;
1404
1636
  var _useState = React.useState(false),
1405
1637
  isShowTime = _useState[0],
1406
1638
  setShowTime = _useState[1];
@@ -1425,16 +1657,17 @@ var ChatRightItem = function ChatRightItem(_ref) {
1425
1657
  setShowTime(isSystemLog || !!isFirst);
1426
1658
  }, [isFirst, isSystemLog]);
1427
1659
  return React__default.createElement("li", {
1660
+ ref: selectedReplyMessageId === id ? selectedReplyItemRef : undefined,
1428
1661
  className: "px-3 " + (!isLast ? "pb-1" : "pb-3") + " " + (!!examCode ? "border border-top-0 border-info" : "") + " " + (!!examCode && isLast ? "border-bottom-1 mb-3" : "border-bottom-0")
1429
1662
  }, showExamHeader && isFirst && React__default.createElement("div", {
1430
1663
  className: "d-flex bg-info justify-content-between px-3 mb-3 py-1 " + styles$1["list__item__header"]
1431
1664
  }, React__default.createElement(reactRouterDom.Link, {
1432
1665
  to: "" + (actionLink || "/"),
1433
1666
  className: "text-black"
1434
- }, examTitle), !!examId && !!examTitle && React__default.createElement("span", {
1667
+ }, examTitle), !!examId && !!examTitle && !!examCode && React__default.createElement("span", {
1435
1668
  className: "pointer text-black",
1436
1669
  onClick: function onClick() {
1437
- return onAddExamMessage === null || onAddExamMessage === void 0 ? void 0 : onAddExamMessage(examId, examTitle);
1670
+ return onAddExamMessage === null || onAddExamMessage === void 0 ? void 0 : onAddExamMessage(examId, examTitle, examCode);
1438
1671
  }
1439
1672
  }, "Add message to exam")), isSystemLog || !!isFirst ? React__default.createElement("p", {
1440
1673
  className: "mb-0 py-1 px-3 fs-6 text-muted text-center"
@@ -1454,14 +1687,17 @@ var ChatRightItem = function ChatRightItem(_ref) {
1454
1687
  }, React__default.createElement("div", {
1455
1688
  className: "d-flex flex-column align-items-end"
1456
1689
  }, parentId && React__default.createElement("p", {
1457
- className: "opacity-50 mb-0 py-2 px-3 fw-medium pointer " + styles$1["list__item__message"] + " " + styles$1["list__item__message--reply-from-right"] + " text-end bg-primary text-white"
1690
+ className: "px-3 bg-light opacity-50 pointer " + styles$1["list__item__message"] + " " + styles$1["list__item__message--reply-from-right"] + " mb-0 fw-medium " + styles$1["reply-text"],
1691
+ onClick: function onClick() {
1692
+ return onGotoParentMessage === null || onGotoParentMessage === void 0 ? void 0 : onGotoParentMessage(parentId);
1693
+ }
1458
1694
  }, React__default.createElement("b", null, "Reply To:"), " ", parentContent), React__default.createElement("p", {
1459
1695
  className: "mb-0 py-2 px-3 fw-medium pointer " + styles$1["list__item__message"] + " " + (parentId ? styles$1["list__item__message--reply-right"] : "") + " text-end bg-primary text-white",
1460
1696
  onClick: handleShowInfo
1461
1697
  }, content), status !== MessageStatus.Default && React__default.createElement("p", {
1462
1698
  onClick: handleReTrySendMessage,
1463
1699
  className: "fs-6 mb-0 " + (status === MessageStatus.SentError ? "text-danger text-decoration-underline pointer" : "")
1464
- }, status), (type !== exports.ChatItemType.Exam || !examCode) && status === MessageStatus.Default && React__default.createElement(reactstrap.Collapse, {
1700
+ }, status), !isSystemLog && status === MessageStatus.Default && React__default.createElement(reactstrap.Collapse, {
1465
1701
  isOpen: isShowInfo
1466
1702
  }, React__default.createElement("p", {
1467
1703
  className: "mb-0 py-1 px-3 fs-6 text-muted text-end"
@@ -1489,7 +1725,8 @@ var ChatLeftItem = function ChatLeftItem(_ref) {
1489
1725
  onReply = _ref.onReply,
1490
1726
  selectedReplyMessageId = _ref.selectedReplyMessageId,
1491
1727
  onToggleReply = _ref.onToggleReply,
1492
- selectedReplyItemRef = _ref.selectedReplyItemRef;
1728
+ selectedReplyItemRef = _ref.selectedReplyItemRef,
1729
+ onGotoParentMessage = _ref.onGotoParentMessage;
1493
1730
  var _useState = React.useState(false),
1494
1731
  isShowTime = _useState[0],
1495
1732
  setShowTime = _useState[1];
@@ -1517,10 +1754,10 @@ var ChatLeftItem = function ChatLeftItem(_ref) {
1517
1754
  }, React__default.createElement(reactRouterDom.Link, {
1518
1755
  to: "" + (actionLink || "/"),
1519
1756
  className: "text-black"
1520
- }, examTitle), !!examId && !!examTitle && React__default.createElement("span", {
1757
+ }, examTitle), !!examId && !!examTitle && !!examCode && React__default.createElement("span", {
1521
1758
  className: "pointer text-black",
1522
1759
  onClick: function onClick() {
1523
- return onAddExamMessage === null || onAddExamMessage === void 0 ? void 0 : onAddExamMessage(examId, examTitle);
1760
+ return onAddExamMessage === null || onAddExamMessage === void 0 ? void 0 : onAddExamMessage(examId, examTitle, examCode);
1524
1761
  }
1525
1762
  }, "Add message to exam")), isSystemLog || !!isFirst ? React__default.createElement("p", {
1526
1763
  className: "mb-0 py-1 px-3 fs-6 text-muted text-center"
@@ -1545,7 +1782,10 @@ var ChatLeftItem = function ChatLeftItem(_ref) {
1545
1782
  })), React__default.createElement("div", {
1546
1783
  className: "d-flex flex-column"
1547
1784
  }, parentId && React__default.createElement("p", {
1548
- className: "opacity-50 mb-0 py-2 px-3 fw-medium pointer " + styles$1["list__item__message"] + " " + styles$1["list__item__message--reply-from"] + " text-start bg-light"
1785
+ className: "opacity-50 mb-0 px-3 fw-medium pointer " + styles$1["list__item__message"] + " " + styles$1["list__item__message--reply-from"] + " " + styles$1["reply-text"] + " text-start bg-light",
1786
+ onClick: function onClick() {
1787
+ return onGotoParentMessage === null || onGotoParentMessage === void 0 ? void 0 : onGotoParentMessage(parentId);
1788
+ }
1549
1789
  }, React__default.createElement("b", null, "Reply To:"), " ", parentContent), React__default.createElement("p", {
1550
1790
  className: "mb-0 py-2 px-3 fw-medium pointer " + styles$1["list__item__message"] + " " + (parentId ? styles$1["list__item__message--reply"] : "") + " text-start bg-light",
1551
1791
  onClick: handleShowInfo
@@ -1585,6 +1825,11 @@ var ChatList = function ChatList(_ref) {
1585
1825
  var handleToggleReply = function handleToggleReply(id) {
1586
1826
  setSelectedReplyMessageId(id === selectedReplyMessageId ? undefined : id);
1587
1827
  };
1828
+ var handleSelectParentMessage = function handleSelectParentMessage(id) {
1829
+ if (id === selectedReplyMessageId) selectedReplyItemRef.current && selectedReplyItemRef.current.scrollIntoView({
1830
+ behavior: "smooth"
1831
+ });else setSelectedReplyMessageId(id);
1832
+ };
1588
1833
  React.useEffect(function () {
1589
1834
  selectedReplyMessageId && selectedReplyItemRef.current && selectedReplyItemRef.current.scrollIntoView({
1590
1835
  behavior: "smooth"
@@ -1607,7 +1852,8 @@ var ChatList = function ChatList(_ref) {
1607
1852
  selectedReplyMessageId: selectedReplyMessageId,
1608
1853
  onToggleReply: handleToggleReply,
1609
1854
  selectedReplyItemRef: selectedReplyItemRef,
1610
- onReTrySendMessage: onReTrySendMessage
1855
+ onReTrySendMessage: onReTrySendMessage,
1856
+ onGotoParentMessage: handleSelectParentMessage
1611
1857
  }));
1612
1858
  }));
1613
1859
  };
@@ -1672,6 +1918,7 @@ var ChatHeader = function ChatHeader(_ref) {
1672
1918
  var name = _ref.name,
1673
1919
  avatar = _ref.avatar,
1674
1920
  options = _ref.options,
1921
+ selectedOption = _ref.selectedOption,
1675
1922
  onChangeOption = _ref.onChangeOption;
1676
1923
  var wrapperRef = React.useRef(null);
1677
1924
  var actionRef = React.useRef(null);
@@ -1710,6 +1957,7 @@ var ChatHeader = function ChatHeader(_ref) {
1710
1957
  }, selectOptions !== undefined && React__default.createElement("div", {
1711
1958
  className: styles$1["header__select"] + " mx-3"
1712
1959
  }, React__default.createElement(CustomSelect, {
1960
+ value: selectedOption,
1713
1961
  options: selectOptions,
1714
1962
  onChange: handleChangeOption,
1715
1963
  isClearable: true
@@ -1722,7 +1970,15 @@ var ChatContainer = function ChatContainer(_ref) {
1722
1970
  var chatHeaderProps = _ref.chatHeaderProps,
1723
1971
  chatListProps = _ref.chatListProps,
1724
1972
  inputProps = _ref.inputProps,
1725
- onRead = _ref.onRead;
1973
+ _ref$scrollOffset = _ref.scrollOffset,
1974
+ scrollOffset = _ref$scrollOffset === void 0 ? 0 : _ref$scrollOffset,
1975
+ _ref$isLoading = _ref.isLoading,
1976
+ isLoading = _ref$isLoading === void 0 ? false : _ref$isLoading,
1977
+ isScrollToEnd = _ref.isScrollToEnd,
1978
+ onRead = _ref.onRead,
1979
+ onReachTop = _ref.onReachTop,
1980
+ onReachBottom = _ref.onReachBottom,
1981
+ onEndScrollToEnd = _ref.onEndScrollToEnd;
1726
1982
  var onReply = chatListProps.onReply,
1727
1983
  onAddExamMessage = chatListProps.onAddExamMessage;
1728
1984
  var onChangeOption = chatHeaderProps.onChangeOption;
@@ -1737,10 +1993,10 @@ var ChatContainer = function ChatContainer(_ref) {
1737
1993
  (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
1738
1994
  onReply === null || onReply === void 0 ? void 0 : onReply(id, content, examId);
1739
1995
  };
1740
- var handleAddExamMessage = function handleAddExamMessage(examId, examTitle) {
1996
+ var handleAddExamMessage = function handleAddExamMessage(examId, examTitle, examCode) {
1741
1997
  var _inputRef$current2;
1742
1998
  (_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 ? void 0 : _inputRef$current2.focus();
1743
- onAddExamMessage(examId, examTitle);
1999
+ onAddExamMessage(examId, examTitle, examCode);
1744
2000
  };
1745
2001
  var handleChangeExamOption = function handleChangeExamOption(val) {
1746
2002
  var _inputRef$current3;
@@ -1748,6 +2004,16 @@ var ChatContainer = function ChatContainer(_ref) {
1748
2004
  onChangeOption === null || onChangeOption === void 0 ? void 0 : onChangeOption(val);
1749
2005
  };
1750
2006
  var handleScroll = function handleScroll() {
2007
+ if (listRef.current) {
2008
+ var scrollTop = listRef.current.scrollTop;
2009
+ var scrollHeight = listRef.current.scrollHeight;
2010
+ var clientHeight = listRef.current.clientHeight;
2011
+ if (scrollTop + clientHeight + scrollOffset >= scrollHeight) {
2012
+ onReachBottom === null || onReachBottom === void 0 ? void 0 : onReachBottom();
2013
+ } else if (scrollTop <= scrollOffset) {
2014
+ onReachTop === null || onReachTop === void 0 ? void 0 : onReachTop();
2015
+ }
2016
+ }
1751
2017
  if (scrollRef.current) clearTimeout(scrollRef.current);
1752
2018
  scrollRef.current = setTimeout(function () {
1753
2019
  onRead === null || onRead === void 0 ? void 0 : onRead();
@@ -1757,36 +2023,40 @@ var ChatContainer = function ChatContainer(_ref) {
1757
2023
  if (focusRef.current) clearTimeout(focusRef.current);
1758
2024
  focusRef.current = setTimeout(function () {
1759
2025
  onRead === null || onRead === void 0 ? void 0 : onRead();
1760
- }, 800);
2026
+ }, 300);
1761
2027
  };
1762
2028
  React.useEffect(function () {
1763
- var _listRef$current, _listItemRef$current, _listItemRef$current$;
2029
+ var _listRef$current, _chatListProps$messag, _listRef$current3;
1764
2030
  scrollRef.current && clearTimeout(scrollRef.current);
1765
2031
  addEventTimeout.current && clearTimeout(addEventTimeout.current);
1766
2032
  (_listRef$current = listRef.current) === null || _listRef$current === void 0 ? void 0 : _listRef$current.removeEventListener("scroll", handleScroll);
1767
- (_listItemRef$current = listItemRef.current) === null || _listItemRef$current === void 0 ? void 0 : (_listItemRef$current$ = _listItemRef$current.lastElementChild) === null || _listItemRef$current$ === void 0 ? void 0 : _listItemRef$current$.scrollIntoView({
1768
- behavior: "smooth"
1769
- });
1770
- addEventTimeout.current = setTimeout(function () {
1771
- var _listRef$current2;
1772
- (_listRef$current2 = listRef.current) === null || _listRef$current2 === void 0 ? void 0 : _listRef$current2.addEventListener("scroll", handleScroll);
1773
- }, 800);
2033
+ if (isScrollToEnd && !isLoading && (_chatListProps$messag = chatListProps.messages) !== null && _chatListProps$messag !== void 0 && _chatListProps$messag.length) {
2034
+ var _listItemRef$current, _listItemRef$current$;
2035
+ (_listItemRef$current = listItemRef.current) === null || _listItemRef$current === void 0 ? void 0 : (_listItemRef$current$ = _listItemRef$current.lastElementChild) === null || _listItemRef$current$ === void 0 ? void 0 : _listItemRef$current$.scrollIntoView({
2036
+ behavior: "smooth"
2037
+ });
2038
+ onEndScrollToEnd === null || onEndScrollToEnd === void 0 ? void 0 : onEndScrollToEnd();
2039
+ addEventTimeout.current = setTimeout(function () {
2040
+ var _listRef$current2;
2041
+ (_listRef$current2 = listRef.current) === null || _listRef$current2 === void 0 ? void 0 : _listRef$current2.addEventListener("scroll", handleScroll);
2042
+ }, 800);
2043
+ } else (_listRef$current3 = listRef.current) === null || _listRef$current3 === void 0 ? void 0 : _listRef$current3.addEventListener("scroll", handleScroll);
1774
2044
  return function () {
1775
- var _listRef$current3;
1776
- (_listRef$current3 = listRef.current) === null || _listRef$current3 === void 0 ? void 0 : _listRef$current3.removeEventListener("scroll", handleScroll);
2045
+ var _listRef$current4;
2046
+ (_listRef$current4 = listRef.current) === null || _listRef$current4 === void 0 ? void 0 : _listRef$current4.removeEventListener("scroll", handleScroll);
1777
2047
  scrollRef.current && clearTimeout(scrollRef.current);
1778
2048
  addEventTimeout.current && clearTimeout(addEventTimeout.current);
1779
2049
  };
1780
- }, [listItemRef.current, JSON.stringify(chatListProps.messages)]);
2050
+ }, [JSON.stringify(chatListProps.messages), scrollOffset, isLoading, onEndScrollToEnd, onRead, isScrollToEnd]);
1781
2051
  React.useEffect(function () {
1782
2052
  var _inputRef$current4;
1783
2053
  (_inputRef$current4 = inputRef.current) === null || _inputRef$current4 === void 0 ? void 0 : _inputRef$current4.addEventListener("focus", handleFocus);
1784
2054
  return function () {
1785
2055
  var _inputRef$current5;
1786
2056
  (_inputRef$current5 = inputRef.current) === null || _inputRef$current5 === void 0 ? void 0 : _inputRef$current5.removeEventListener("focus", handleFocus);
1787
- if (focusRef.current) clearTimeout(focusRef.current);
2057
+ focusRef.current && clearTimeout(focusRef.current);
1788
2058
  };
1789
- }, []);
2059
+ }, [onRead]);
1790
2060
  return React__default.createElement("div", {
1791
2061
  className: "d-flex flex-column w-100 h-100 border border-1 border-light rounded-3 shadow-sm"
1792
2062
  }, React__default.createElement("div", null, React__default.createElement(ChatHeader, Object.assign({}, chatHeaderProps, {
@@ -1794,13 +2064,18 @@ var ChatContainer = function ChatContainer(_ref) {
1794
2064
  }))), React__default.createElement("div", {
1795
2065
  ref: listRef,
1796
2066
  className: "flex-grow-1 " + styles$1["body"]
1797
- }, React__default.createElement(ChatList, Object.assign({}, chatListProps, {
2067
+ }, isLoading && React__default.createElement("div", {
2068
+ className: "d-flex justify-content-center"
2069
+ }, React__default.createElement(reactstrap.Spinner, {
2070
+ color: "secondary",
2071
+ className: "my-2"
2072
+ }, "Loading...")), React__default.createElement(ChatList, Object.assign({}, chatListProps, {
1798
2073
  listItemRef: listItemRef,
1799
2074
  onReply: handleReply,
1800
2075
  onAddExamMessage: handleAddExamMessage
1801
2076
  }))), React__default.createElement("div", null, React__default.createElement(InputChat, Object.assign({}, inputProps, {
1802
2077
  inputRef: inputRef
1803
- }))), React__default.createElement(reactToastify.ToastContainer, null));
2078
+ }))));
1804
2079
  };
1805
2080
 
1806
2081
  var CONVERSATION_URL = BASE_URL + "/api/conversation";
@@ -1843,7 +2118,7 @@ var CONVERSATION_DEFAULT_FILTER = {
1843
2118
  };
1844
2119
  var MESSAGE_DEFAULT_FILTER = {
1845
2120
  currentPage: 1,
1846
- pageSize: -1,
2121
+ pageSize: 12,
1847
2122
  textSearch: "",
1848
2123
  sortColumnDirection: OrderBy.DESC,
1849
2124
  sortColumnName: MessageSortBy.CreatedAt
@@ -1903,43 +2178,69 @@ var useMessageList = function useMessageList(userId, getListExamOptions) {
1903
2178
  var _useState2 = React.useState(MESSAGE_DEFAULT_FILTER),
1904
2179
  messageFilter = _useState2[0],
1905
2180
  setMessageFilter = _useState2[1];
2181
+ var _useState3 = React.useState(false),
2182
+ isLoading = _useState3[0],
2183
+ setLoading = _useState3[1];
1906
2184
  var getMessageList = function getMessageList(conversationId, examId) {
1907
2185
  try {
1908
- var filter = _extends({}, messageFilter, {
1909
- examId: !examId ? messageFilter.examId : examId
1910
- });
1911
- return Promise.resolve(getMessagesByConversation(conversationId, filter)).then(function (res) {
1912
- var _res$data$items;
1913
- function _temp(_getListExamOptions) {
1914
- _getListExamOptions;
1915
- }
1916
- setMessages(((_res$data$items = res.data.items) === null || _res$data$items === void 0 ? void 0 : _res$data$items.reverse()) || []);
1917
- return getListExamOptions ? Promise.resolve(!!getListExamOptions && getListExamOptions(userId)).then(_temp) : _temp(!!getListExamOptions && getListExamOptions(userId));
2186
+ var _temp3 = function _temp3() {
2187
+ setLoading(false);
2188
+ };
2189
+ setLoading(true);
2190
+ var _temp2 = _catch(function () {
2191
+ var filter = _extends({}, messageFilter, {
2192
+ examId: !examId ? messageFilter.examId : examId
2193
+ });
2194
+ return Promise.resolve(getMessagesByConversation(conversationId, filter)).then(function (res) {
2195
+ var _res$data$items2;
2196
+ function _temp(_getListExamOptions) {
2197
+ _getListExamOptions;
2198
+ }
2199
+ if (messageFilter.beforeDate) setMessages(function (state) {
2200
+ var _res$data$items;
2201
+ return [].concat(((_res$data$items = res.data.items) === null || _res$data$items === void 0 ? void 0 : _res$data$items.reverse()) || [], state);
2202
+ });else setMessages((_res$data$items2 = res.data.items) === null || _res$data$items2 === void 0 ? void 0 : _res$data$items2.reverse());
2203
+ return getListExamOptions ? Promise.resolve(!!getListExamOptions && getListExamOptions(userId)).then(_temp) : _temp(!!getListExamOptions && getListExamOptions(userId));
2204
+ });
2205
+ }, function (error) {
2206
+ console.log({
2207
+ error: error
2208
+ });
1918
2209
  });
2210
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2));
1919
2211
  } catch (e) {
1920
2212
  return Promise.reject(e);
1921
2213
  }
1922
2214
  };
2215
+ var handleLoadMore = function handleLoadMore() {
2216
+ if (isLoading) return;
2217
+ var lastItem = messages[0];
2218
+ if (!lastItem) return;
2219
+ var newFilter = _extends({}, messageFilter, {
2220
+ currentPage: 1,
2221
+ beforeDate: lastItem.createdAt
2222
+ });
2223
+ setMessageFilter(newFilter);
2224
+ return JSON.stringify(newFilter) === JSON.stringify(messageFilter);
2225
+ };
1923
2226
  var handleMarkReadMessage = function handleMarkReadMessage(conversationId, messageId) {
1924
2227
  try {
1925
- var _temp2 = _catch(function () {
2228
+ var _temp4 = _catch(function () {
1926
2229
  return Promise.resolve(apiMarkReadMessage(conversationId, messageId)).then(function () {});
1927
2230
  }, function (error) {
1928
2231
  console.log({
1929
2232
  error: error
1930
2233
  });
1931
2234
  });
1932
- return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
2235
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
1933
2236
  } catch (e) {
1934
2237
  return Promise.reject(e);
1935
2238
  }
1936
2239
  };
1937
2240
  var resetMessages = function resetMessages() {
2241
+ setMessageFilter(MESSAGE_DEFAULT_FILTER);
1938
2242
  setMessages([]);
1939
2243
  };
1940
- var handleChangeMessageFilter = function handleChangeMessageFilter(filter) {
1941
- setMessageFilter(_extends({}, messageFilter, filter));
1942
- };
1943
2244
  var handleChangeExamId = function handleChangeExamId(value) {
1944
2245
  setMessageFilter(_extends({}, messageFilter, {
1945
2246
  examId: value === null || value === void 0 ? void 0 : value.value,
@@ -1947,14 +2248,15 @@ var useMessageList = function useMessageList(userId, getListExamOptions) {
1947
2248
  }));
1948
2249
  };
1949
2250
  return {
2251
+ isLoading: isLoading,
1950
2252
  messageFilter: messageFilter,
1951
2253
  messages: messages,
1952
2254
  getMessageList: getMessageList,
1953
2255
  setMessages: setMessages,
1954
2256
  resetMessages: resetMessages,
1955
- handleChangeMessageFilter: handleChangeMessageFilter,
1956
2257
  handleChangeExamId: handleChangeExamId,
1957
- handleMarkReadMessage: handleMarkReadMessage
2258
+ handleMarkReadMessage: handleMarkReadMessage,
2259
+ handleLoadMore: handleLoadMore
1958
2260
  };
1959
2261
  };
1960
2262
 
@@ -1970,6 +2272,7 @@ var useChatContainer = function useChatContainer(props) {
1970
2272
  var channel = React.useRef();
1971
2273
  var channelName = React.useRef();
1972
2274
  var loadingRef = React.useRef(false);
2275
+ var firstLoadRef = React.useRef(true);
1973
2276
  var dispatch = reactRedux.useDispatch();
1974
2277
  var roles = reactRedux.useSelector(function (state) {
1975
2278
  var _state$common, _state$common$user;
@@ -1985,16 +2288,26 @@ var useChatContainer = function useChatContainer(props) {
1985
2288
  var _useState3 = React.useState(MessageStatus.Default),
1986
2289
  messageStatus = _useState3[0],
1987
2290
  setMessageStatus = _useState3[1];
2291
+ var _useState4 = React.useState(true),
2292
+ isScrollToEnd = _useState4[0],
2293
+ setScrollToEnd = _useState4[1];
1988
2294
  var _useExamList = useExamList(isStudent),
1989
2295
  exams = _useExamList.exams,
1990
2296
  getListExam = _useExamList.getListExam;
1991
2297
  var _useMessageList = useMessageList(isStudent ? selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation = selectedConversation.teacher) === null || _selectedConversation === void 0 ? void 0 : _selectedConversation.id : selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation2 = selectedConversation.student) === null || _selectedConversation2 === void 0 ? void 0 : _selectedConversation2.id, !userId ? getListExam : undefined),
2298
+ isLoadingMessages = _useMessageList.isLoading,
1992
2299
  messages = _useMessageList.messages,
1993
2300
  messageFilter = _useMessageList.messageFilter,
1994
2301
  getMessageList = _useMessageList.getMessageList,
1995
2302
  resetMessages = _useMessageList.resetMessages,
1996
2303
  handleChangeExamId = _useMessageList.handleChangeExamId,
1997
- setMessages = _useMessageList.setMessages;
2304
+ setMessages = _useMessageList.setMessages,
2305
+ handleLoadMore = _useMessageList.handleLoadMore;
2306
+ var handleToggleScrollToEnd = function handleToggleScrollToEnd() {
2307
+ setScrollToEnd(function (state) {
2308
+ return !state;
2309
+ });
2310
+ };
1998
2311
  var handleAddMessage = function handleAddMessage() {
1999
2312
  try {
2000
2313
  var _message$content, _message$content$trim;
@@ -2007,6 +2320,7 @@ var useChatContainer = function useChatContainer(props) {
2007
2320
  })) return Promise.resolve();
2008
2321
  loadingRef.current = true;
2009
2322
  if (!(selectedConversation !== null && selectedConversation !== void 0 && selectedConversation.id) || !(message !== null && message !== void 0 && (_message$content = message.content) !== null && _message$content !== void 0 && (_message$content$trim = _message$content.trim()) !== null && _message$content$trim !== void 0 && _message$content$trim.length)) return Promise.resolve();
2323
+ setScrollToEnd(true);
2010
2324
  setMessages(function (state) {
2011
2325
  return [].concat(state, [{
2012
2326
  id: 0,
@@ -2019,7 +2333,7 @@ var useChatContainer = function useChatContainer(props) {
2019
2333
  id: message.examId,
2020
2334
  startTime: moment().format("YYYY-MM-DDTHH:mm:ss"),
2021
2335
  title: message.examTitle || "",
2022
- code: "temp",
2336
+ code: message.examCode || "",
2023
2337
  createdAt: moment().format("YYYY-MM-DDTHH:mm:ss")
2024
2338
  } : undefined,
2025
2339
  isRead: false,
@@ -2059,14 +2373,16 @@ var useChatContainer = function useChatContainer(props) {
2059
2373
  return Promise.reject(e);
2060
2374
  }
2061
2375
  };
2062
- var handleAddExamMessage = function handleAddExamMessage(examId, title) {
2376
+ var handleAddExamMessage = function handleAddExamMessage(examId, title, examCode) {
2063
2377
  setMessage(!!message ? _extends({}, message, {
2064
2378
  examId: examId,
2379
+ examCode: examCode,
2065
2380
  examTitle: title,
2066
2381
  parentId: undefined,
2067
2382
  parentContent: ""
2068
2383
  }) : {
2069
2384
  examId: examId,
2385
+ examCode: examCode,
2070
2386
  content: "",
2071
2387
  examTitle: title,
2072
2388
  parentId: undefined,
@@ -2158,7 +2474,8 @@ var useChatContainer = function useChatContainer(props) {
2158
2474
  return results;
2159
2475
  }, [JSON.stringify(messages), JSON.stringify(message), isStudent, JSON.stringify(selectedConversation), messageFilter.examId, isStudent, userId, messageStatus]);
2160
2476
  var handleNewMessageSent = function handleNewMessageSent(data) {
2161
- if (!messageFilter.examId || messageFilter.examId && data.examId === messageFilter.examId) {
2477
+ if (!messageFilter.examId && !examId || messageFilter.examId && data.examId === messageFilter.examId || examId && examId === data.examId) {
2478
+ setScrollToEnd(true);
2162
2479
  setMessages(function (state) {
2163
2480
  if (state.some(function (i) {
2164
2481
  return i.id === 0;
@@ -2178,6 +2495,11 @@ var useChatContainer = function useChatContainer(props) {
2178
2495
  }));
2179
2496
  });
2180
2497
  };
2498
+ var handleLoadMoreMessages = function handleLoadMoreMessages() {
2499
+ if (handleLoadMore()) {
2500
+ getMessageConversation();
2501
+ }
2502
+ };
2181
2503
  var cleanupPusher = function cleanupPusher() {
2182
2504
  var _pusher$current, _pusher$current2;
2183
2505
  (_pusher$current = pusher.current) === null || _pusher$current === void 0 ? void 0 : _pusher$current.unbind("new-message-event", handleNewMessageSent);
@@ -2203,13 +2525,15 @@ var useChatContainer = function useChatContainer(props) {
2203
2525
  pusher.current.bind("message-read-event", handleMessageMarkRead);
2204
2526
  }
2205
2527
  return cleanupPusher;
2206
- }, [selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.id, messageFilter.examId]);
2528
+ }, [selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.id, messageFilter.examId, examId]);
2207
2529
  React.useEffect(function () {
2208
2530
  var getConversation = function getConversation() {
2209
2531
  try {
2210
2532
  var _temp6 = function _temp6() {
2211
2533
  dispatch(setLoading(false));
2212
2534
  };
2535
+ resetMessages();
2536
+ setScrollToEnd(true);
2213
2537
  if ((conversation === null || conversation === void 0 ? void 0 : conversation.id) !== undefined) {
2214
2538
  setSelectedConversation(conversation);
2215
2539
  return Promise.resolve();
@@ -2242,7 +2566,7 @@ var useChatContainer = function useChatContainer(props) {
2242
2566
  };
2243
2567
  getConversation();
2244
2568
  }, [conversation === null || conversation === void 0 ? void 0 : conversation.id, userId]);
2245
- var handleMarkRead = function handleMarkRead() {
2569
+ var handleMarkRead = React.useCallback(function () {
2246
2570
  try {
2247
2571
  if (!(selectedConversation !== null && selectedConversation !== void 0 && selectedConversation.id)) return Promise.resolve();
2248
2572
  var _temp7 = _catch(function () {
@@ -2256,17 +2580,12 @@ var useChatContainer = function useChatContainer(props) {
2256
2580
  } catch (e) {
2257
2581
  return Promise.reject(e);
2258
2582
  }
2259
- };
2583
+ }, [selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.id]);
2260
2584
  var getMessageConversation = function getMessageConversation() {
2261
2585
  try {
2262
- var _temp12 = function _temp12() {
2263
- dispatch(setLoading(false));
2264
- };
2265
2586
  if (!roles.length) return Promise.resolve();
2266
2587
  if ((selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.id) === undefined) return Promise.resolve();
2267
- if (messageFilter.currentPage === 1) resetMessages();
2268
- dispatch(setLoading(true));
2269
- var _temp11 = _catch(function () {
2588
+ return Promise.resolve(_catch(function () {
2270
2589
  var _temp10 = function () {
2271
2590
  if (selectedConversation.id === 0) {
2272
2591
  var _userId = isStudent ? selectedConversation.teacher.id : selectedConversation.student.id;
@@ -2281,7 +2600,11 @@ var useChatContainer = function useChatContainer(props) {
2281
2600
  });
2282
2601
  };
2283
2602
  var _temp8 = function () {
2284
- if (messageFilter.currentPage === 1) return Promise.resolve(handleMarkRead()).then(function () {});
2603
+ if (firstLoadRef.current) {
2604
+ return Promise.resolve(handleMarkRead()).then(function () {
2605
+ firstLoadRef.current = false;
2606
+ });
2607
+ }
2285
2608
  }();
2286
2609
  return _temp8 && _temp8.then ? _temp8.then(_temp9) : _temp9(_temp8);
2287
2610
  }
@@ -2289,22 +2612,26 @@ var useChatContainer = function useChatContainer(props) {
2289
2612
  if (_temp10 && _temp10.then) return _temp10.then(function () {});
2290
2613
  }, function () {
2291
2614
  reactToastify.toast.error("Fail to fetch data!");
2292
- });
2293
- return Promise.resolve(_temp11 && _temp11.then ? _temp11.then(_temp12) : _temp12(_temp11));
2615
+ }));
2294
2616
  } catch (e) {
2295
2617
  return Promise.reject(e);
2296
2618
  }
2297
2619
  };
2620
+ var handleConversationChange = function handleConversationChange() {
2621
+ resetMessages();
2622
+ setScrollToEnd(true);
2623
+ };
2298
2624
  React.useEffect(function () {
2299
2625
  getMessageConversation();
2300
- }, [selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.id, selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.teacher.id, selectedConversation === null || selectedConversation === void 0 ? void 0 : selectedConversation.student.id, isStudent, roles.length, JSON.stringify(messageFilter), examId]);
2301
- var userName = isStudent ? selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation3 = selectedConversation.teacher) === null || _selectedConversation3 === void 0 ? void 0 : _selectedConversation3.displayName : selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation4 = selectedConversation.student) === null || _selectedConversation4 === void 0 ? void 0 : _selectedConversation4.displayName;
2302
- var userAvatar = isStudent ? selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation5 = selectedConversation.teacher) === null || _selectedConversation5 === void 0 ? void 0 : _selectedConversation5.avatar : selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation6 = selectedConversation.student) === null || _selectedConversation6 === void 0 ? void 0 : _selectedConversation6.avatar;
2626
+ }, [JSON.stringify(selectedConversation), JSON.stringify(roles), JSON.stringify(messageFilter), examId]);
2627
+ var userName = (isStudent ? selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation3 = selectedConversation.teacher) === null || _selectedConversation3 === void 0 ? void 0 : _selectedConversation3.displayName : selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation4 = selectedConversation.student) === null || _selectedConversation4 === void 0 ? void 0 : _selectedConversation4.displayName) || "";
2628
+ var userAvatar = (isStudent ? selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation5 = selectedConversation.teacher) === null || _selectedConversation5 === void 0 ? void 0 : _selectedConversation5.avatar : selectedConversation === null || selectedConversation === void 0 ? void 0 : (_selectedConversation6 = selectedConversation.student) === null || _selectedConversation6 === void 0 ? void 0 : _selectedConversation6.avatar) || "";
2303
2629
  return {
2304
2630
  chatHeaderProps: {
2305
- name: userName || "",
2306
- avatar: userAvatar || "",
2631
+ name: userName,
2632
+ avatar: userAvatar,
2307
2633
  options: exams,
2634
+ selectedOption: messageFilter.examId,
2308
2635
  onChangeOption: handleFilterExam
2309
2636
  },
2310
2637
  chatListProps: {
@@ -2321,15 +2648,19 @@ var useChatContainer = function useChatContainer(props) {
2321
2648
  onSubmit: handleAddMessage,
2322
2649
  onClearReply: !messageFilter.examId || message !== null && message !== void 0 && message.parentContent ? handleClearReply : undefined
2323
2650
  },
2651
+ isScrollToEnd: isScrollToEnd,
2652
+ isLoadingMessages: isLoadingMessages,
2324
2653
  exams: exams,
2325
2654
  messageList: messageList,
2326
2655
  selectedConversation: selectedConversation,
2327
2656
  messageStatus: messageStatus,
2328
2657
  messageFilter: messageFilter,
2658
+ handleToggleScrollToEnd: handleToggleScrollToEnd,
2659
+ handleLoadMoreMessages: handleLoadMoreMessages,
2329
2660
  getMessageList: getMessageList,
2330
2661
  handleFilterExam: handleFilterExam,
2331
2662
  setMessage: setMessage,
2332
- resetMessages: resetMessages,
2663
+ resetMessages: handleConversationChange,
2333
2664
  getMessageConversation: getMessageConversation,
2334
2665
  handleMarkRead: handleMarkRead
2335
2666
  };
@@ -2369,8 +2700,8 @@ var useConversationList = function useConversationList() {
2369
2700
  return i.id === val.id;
2370
2701
  });
2371
2702
  if (index > -1 && JSON.stringify(val) !== JSON.stringify(state[index])) {
2372
- return [].concat(state.slice(0, index), [val], state.slice(index + 1));
2373
- } else return [].concat(state, [val]);
2703
+ return [val].concat(state.slice(0, index), state.slice(index + 1));
2704
+ } else return [val].concat(state);
2374
2705
  });
2375
2706
  setSelectedConversation(function (state) {
2376
2707
  if (!state) return val;
@@ -2466,9 +2797,12 @@ var useConversationList = function useConversationList() {
2466
2797
  return i.id === lastMessage.conversationId;
2467
2798
  });
2468
2799
  if (updateIndex < 0) return state;
2469
- return [].concat(state.slice(0, updateIndex), [_extends({}, state[updateIndex], {
2800
+ console.log({
2470
2801
  lastMessage: lastMessage
2471
- })], state.slice(updateIndex + 1));
2802
+ });
2803
+ return [_extends({}, state[updateIndex], {
2804
+ lastMessage: lastMessage
2805
+ })].concat(state.slice(0, updateIndex), state.slice(updateIndex + 1));
2472
2806
  });
2473
2807
  };
2474
2808
  var handleCreateConversationSuccess = function handleCreateConversationSuccess(id) {
@@ -2557,8 +2891,538 @@ var usePusherConversation = function usePusherConversation(onNewMessageConversat
2557
2891
  return {};
2558
2892
  };
2559
2893
 
2894
+ var _excluded$1 = ["defaultValue", "options", "isDisabled", "scrollBottom", "value", "isMulti"];
2895
+ var CustomCreatable = function CustomCreatable(_ref) {
2896
+ var options = _ref.options,
2897
+ isDisabled = _ref.isDisabled,
2898
+ scrollBottom = _ref.scrollBottom,
2899
+ value = _ref.value,
2900
+ isMulti = _ref.isMulti,
2901
+ rest = _objectWithoutPropertiesLoose(_ref, _excluded$1);
2902
+ var initialValues = Array.isArray(value) ? options.filter(function (i) {
2903
+ return value.includes(i.value);
2904
+ }) : isMulti ? options.filter(function (i) {
2905
+ return i.value == value;
2906
+ }) : options.find(function (i) {
2907
+ return i.value == value;
2908
+ });
2909
+ return React__default.createElement(CreatableSelect, Object.assign({
2910
+ isClearable: true,
2911
+ isDisabled: isDisabled,
2912
+ options: options,
2913
+ value: initialValues,
2914
+ menuPlacement: scrollBottom ? "top" : "auto",
2915
+ isMulti: isMulti
2916
+ }, rest));
2917
+ };
2918
+
2919
+ var _excluded$2 = ["isDefault", "defaultValue", "options", "isDisabled", "scrollBottom", "value", "isMulti"];
2920
+ var CustomAsyncSelect = function CustomAsyncSelect(_ref) {
2921
+ var isDefault = _ref.isDefault,
2922
+ options = _ref.options,
2923
+ isDisabled = _ref.isDisabled,
2924
+ scrollBottom = _ref.scrollBottom,
2925
+ value = _ref.value,
2926
+ isMulti = _ref.isMulti,
2927
+ rest = _objectWithoutPropertiesLoose(_ref, _excluded$2);
2928
+ var initialValues = Array.isArray(value) ? options.filter(function (i) {
2929
+ return value.includes(i.value);
2930
+ }) : isMulti ? options.filter(function (i) {
2931
+ return i.value == value;
2932
+ }) : options.find(function (i) {
2933
+ return i.value == value;
2934
+ });
2935
+ return React__default.createElement(Select__default, Object.assign({
2936
+ isDisabled: isDisabled,
2937
+ options: options,
2938
+ value: !isDefault ? initialValues : undefined,
2939
+ defaultValue: isDefault ? initialValues : undefined,
2940
+ menuPlacement: scrollBottom ? "top" : "auto",
2941
+ isMulti: isMulti
2942
+ }, rest));
2943
+ };
2944
+
2945
+ var styles$2 = {"question":"_2uc_W","question-article":"_2p7kY","question-title":"_2tHmc","question--active":"_3IHYm","question-label":"_26ATj","question-input":"_3R8PR","question-btn":"_1VZac"};
2946
+
2947
+ var DURATION_OPTIONS = Array.from({
2948
+ length: 120
2949
+ }, function (_, i) {
2950
+ return i + 1;
2951
+ });
2952
+ var SCORE_OPTIONS = Array.from({
2953
+ length: 10
2954
+ }, function (_, i) {
2955
+ return i + 1;
2956
+ });
2957
+ var QUESTION_OPTIONS = Array.from({
2958
+ length: 40
2959
+ }, function (_, i) {
2960
+ return i + 1;
2961
+ });
2962
+ var ANSWER_OPTIONS = Array.from({
2963
+ length: 9
2964
+ }, function (_, i) {
2965
+ return i + 2;
2966
+ });
2967
+ var DEFAULT_SCORE = 2;
2968
+ var DEFAULT_ANSWER_COUNT = 5;
2969
+
2970
+ var QuestionView = function QuestionView(_ref) {
2971
+ var index = _ref.index,
2972
+ question = _ref.question,
2973
+ answerCount = _ref.answerCount,
2974
+ isDisabled = _ref.isDisabled,
2975
+ onChangeCorrectAnswers = _ref.onChangeCorrectAnswers,
2976
+ onChangeScoreAnswer = _ref.onChangeScoreAnswer;
2977
+ var scoreOptions = SCORE_OPTIONS.map(function (i) {
2978
+ return {
2979
+ label: DEFAULT_SCORE === i ? i + "\uC810 (\uAE30\uBCF8\uAC12)" : i + "\uC810",
2980
+ value: i
2981
+ };
2982
+ });
2983
+ return React__default.createElement("div", {
2984
+ className: "d-flex justify-content-between"
2985
+ }, React__default.createElement("div", {
2986
+ className: "d-flex flex-grow-1"
2987
+ }, React__default.createElement("div", {
2988
+ className: styles$2["question-title"] + " me-2"
2989
+ }, "\uBB38\uC81C ", question.questionOrder + 1, "\uBC88"), React__default.createElement("div", {
2990
+ className: "d-flex flex-grow-1"
2991
+ }, Array.from({
2992
+ length: answerCount
2993
+ }, function (_, i) {
2994
+ return i + 1;
2995
+ }).map(function (i) {
2996
+ return React__default.createElement(reactstrap.FormGroup, {
2997
+ className: "d-flex flex-column px-4"
2998
+ }, React__default.createElement(reactstrap.Label, {
2999
+ htmlFor: "answer-" + i,
3000
+ className: "" + styles$2["question-label"]
3001
+ }, i, "\uBC88"), React__default.createElement(reactstrap.Input, {
3002
+ id: "answer-" + i,
3003
+ type: "radio",
3004
+ checked: question.correctAnswers.includes(i),
3005
+ onClick: function onClick() {
3006
+ return onChangeCorrectAnswers(i, index);
3007
+ },
3008
+ disabled: isDisabled
3009
+ }));
3010
+ }))), React__default.createElement("div", {
3011
+ className: "d-flex align-items-center"
3012
+ }, React__default.createElement(reactstrap.FormGroup, {
3013
+ className: "mx-3",
3014
+ style: {
3015
+ width: "140px"
3016
+ }
3017
+ }, React__default.createElement(CustomSelect, {
3018
+ value: question.score,
3019
+ options: scoreOptions,
3020
+ onChange: function onChange(value) {
3021
+ return onChangeScoreAnswer(value.value, index);
3022
+ },
3023
+ isDisabled: isDisabled
3024
+ }))));
3025
+ };
3026
+
3027
+ var ArticleGroupView = function ArticleGroupView(_ref) {
3028
+ var categoryOptions = _ref.categoryOptions,
3029
+ article = _ref.article,
3030
+ questions = _ref.questions,
3031
+ answerCount = _ref.answerCount,
3032
+ questionCount = _ref.questionCount,
3033
+ categoryId = _ref.categoryId,
3034
+ isActive = _ref.isActive,
3035
+ isDisabled = _ref.isDisabled,
3036
+ onChangeQuestionCount = _ref.onChangeQuestionCount,
3037
+ onChangeCategory = _ref.onChangeCategory,
3038
+ onChangeAnswerCount = _ref.onChangeAnswerCount,
3039
+ onChangeCorrectAnswers = _ref.onChangeCorrectAnswers,
3040
+ onChangeScoreAnswer = _ref.onChangeScoreAnswer;
3041
+ var _useTranslation = reactI18next.useTranslation(),
3042
+ t = _useTranslation.t;
3043
+ var handleChangeQuestionCount = function handleChangeQuestionCount(value) {
3044
+ onChangeQuestionCount(article, value === null || value === void 0 ? void 0 : value.value, answerCount);
3045
+ };
3046
+ var handleChangeCategory = function handleChangeCategory(value) {
3047
+ onChangeCategory(article, value === null || value === void 0 ? void 0 : value.value);
3048
+ };
3049
+ var handleChangeAnswerCount = function handleChangeAnswerCount(value) {
3050
+ onChangeAnswerCount(article, value === null || value === void 0 ? void 0 : value.value, answerCount);
3051
+ };
3052
+ var handleChangeCorrectAnswers = function handleChangeCorrectAnswers(value, index) {
3053
+ onChangeCorrectAnswers(article, index, value);
3054
+ };
3055
+ var handleChangeScoreAnswer = function handleChangeScoreAnswer(value, index) {
3056
+ onChangeScoreAnswer(article, index, value);
3057
+ };
3058
+ var questionOptions = QUESTION_OPTIONS.map(function (i) {
3059
+ return {
3060
+ label: i + "\uAC1C",
3061
+ value: i
3062
+ };
3063
+ });
3064
+ var answerOptions = ANSWER_OPTIONS.map(function (i) {
3065
+ return {
3066
+ label: i + "\uBC88",
3067
+ value: i
3068
+ };
3069
+ });
3070
+ return React__default.createElement("div", {
3071
+ className: "d-flex " + styles$2["question"] + " " + (isActive ? styles$2["question--active"] : "")
3072
+ }, React__default.createElement("div", {
3073
+ className: "py-1"
3074
+ }, React__default.createElement(pi.PiDotsNineLight, {
3075
+ size: 18
3076
+ })), React__default.createElement("div", {
3077
+ className: "px-4"
3078
+ }, React__default.createElement(reactstrap.Row, null, React__default.createElement(reactstrap.Col, {
3079
+ xs: 12
3080
+ }, React__default.createElement("p", {
3081
+ className: "mb-0 " + styles$2["question-article"]
3082
+ }, "\uBB38\uD56D"), React__default.createElement("p", {
3083
+ className: "text-center " + styles$2["question-article"]
3084
+ }, article)))), React__default.createElement("div", {
3085
+ className: "flex-grow-1"
3086
+ }, React__default.createElement(reactstrap.Row, null, React__default.createElement(reactstrap.Col, {
3087
+ xs: 3
3088
+ }, React__default.createElement(reactstrap.FormGroup, null, React__default.createElement(reactstrap.Label, {
3089
+ htmlFor: "question_count",
3090
+ className: "" + styles$2["question-label"]
3091
+ }, t("question_count")), React__default.createElement(CustomSelect, {
3092
+ inputId: "question_count",
3093
+ value: questionCount,
3094
+ options: questionOptions,
3095
+ onChange: handleChangeQuestionCount,
3096
+ isDisabled: isDisabled
3097
+ }))), React__default.createElement(reactstrap.Col, {
3098
+ xs: 3
3099
+ }, React__default.createElement(reactstrap.FormGroup, null, React__default.createElement(reactstrap.Label, {
3100
+ htmlFor: "category",
3101
+ className: "" + styles$2["question-label"]
3102
+ }, t("category")), React__default.createElement(CustomSelect, {
3103
+ inputId: "category",
3104
+ value: categoryId,
3105
+ options: categoryOptions,
3106
+ onChange: handleChangeCategory,
3107
+ isDisabled: isDisabled
3108
+ }))), React__default.createElement(reactstrap.Col, {
3109
+ xs: 3
3110
+ }, React__default.createElement(reactstrap.FormGroup, null, React__default.createElement(reactstrap.Label, {
3111
+ htmlFor: "answer_count",
3112
+ className: "" + styles$2["question-label"]
3113
+ }, t("answer_count")), React__default.createElement(CustomSelect, {
3114
+ inputId: "answer_count",
3115
+ value: answerCount,
3116
+ options: answerOptions,
3117
+ onChange: handleChangeAnswerCount,
3118
+ isDisabled: isDisabled
3119
+ }))), React__default.createElement(reactstrap.Col, {
3120
+ xs: 3
3121
+ })), React__default.createElement("div", null, questions.map(function (q, index) {
3122
+ return React__default.createElement(QuestionView, {
3123
+ key: index,
3124
+ question: q,
3125
+ answerCount: answerCount,
3126
+ index: index,
3127
+ onChangeCorrectAnswers: handleChangeCorrectAnswers,
3128
+ onChangeScoreAnswer: handleChangeScoreAnswer,
3129
+ isDisabled: isDisabled
3130
+ });
3131
+ }))));
3132
+ };
3133
+
3134
+ var useExamDetailView = function useExamDetailView(props) {
3135
+ var exam = props.exam,
3136
+ onChangeExam = props.onChangeExam;
3137
+ var _useTranslation = reactI18next.useTranslation(),
3138
+ t = _useTranslation.t;
3139
+ var handleChangeQuestionCount = function handleChangeQuestionCount(article, questionCount, answerCount) {
3140
+ if (!exam) return;
3141
+ var examQuestions = exam.questions;
3142
+ var questions = examQuestions.filter(function (i) {
3143
+ return i.article === +article;
3144
+ });
3145
+ var prevQuestions = examQuestions.filter(function (i) {
3146
+ return i.article < +article;
3147
+ });
3148
+ var nextQuestions = examQuestions.filter(function (i) {
3149
+ return i.article > +article;
3150
+ });
3151
+ var lastOrder = questions[questions.length - 1].questionOrder;
3152
+ if (questions.length === questionCount) return;
3153
+ if (questions.length < questionCount) {
3154
+ var additionalQuestions = Array.from({
3155
+ length: questionCount - questions.length
3156
+ }).map(function (_, index) {
3157
+ var _questions$;
3158
+ return {
3159
+ article: +article,
3160
+ correctAnswers: [1],
3161
+ numberOfAnswers: answerCount,
3162
+ categoryId: (_questions$ = questions[0]) === null || _questions$ === void 0 ? void 0 : _questions$.categoryId,
3163
+ score: DEFAULT_SCORE,
3164
+ questionOrder: lastOrder + index + 1
3165
+ };
3166
+ });
3167
+ var newQuestions = [].concat(prevQuestions, questions, additionalQuestions, nextQuestions.map(function (i) {
3168
+ return _extends({}, i, {
3169
+ questionOrder: i.questionOrder + questionCount - questions.length
3170
+ });
3171
+ }));
3172
+ onChangeExam(_extends({}, exam, {
3173
+ questions: [].concat(newQuestions)
3174
+ }));
3175
+ } else {
3176
+ var remainQuestions = questions.slice(0, questionCount);
3177
+ var _newQuestions = [].concat(prevQuestions, remainQuestions, nextQuestions.map(function (i) {
3178
+ return _extends({}, i, {
3179
+ questionOrder: i.questionOrder - questions.length + questionCount
3180
+ });
3181
+ }));
3182
+ onChangeExam(_extends({}, exam, {
3183
+ questions: [].concat(_newQuestions)
3184
+ }));
3185
+ }
3186
+ };
3187
+ var handleChangeCategory = function handleChangeCategory(article, categoryId) {
3188
+ if (!exam) return;
3189
+ var examQuestions = exam.questions;
3190
+ var questions = examQuestions.filter(function (i) {
3191
+ return i.article === +article;
3192
+ });
3193
+ var otherQuestions = examQuestions.filter(function (i) {
3194
+ return i.article !== +article;
3195
+ });
3196
+ onChangeExam(_extends({}, exam, {
3197
+ questions: [].concat(otherQuestions, questions.map(function (q) {
3198
+ return _extends({}, q, {
3199
+ categoryId: categoryId
3200
+ });
3201
+ }))
3202
+ }));
3203
+ };
3204
+ var handleChangeAnswerCount = function handleChangeAnswerCount(article, newAnswerCount, answerCount) {
3205
+ if (!exam) return;
3206
+ if (newAnswerCount === answerCount) return;
3207
+ var examQuestions = exam.questions;
3208
+ var questions = examQuestions.filter(function (i) {
3209
+ return i.article === +article;
3210
+ });
3211
+ var otherQuestions = examQuestions.filter(function (i) {
3212
+ return i.article !== +article;
3213
+ });
3214
+ if (answerCount < newAnswerCount) {
3215
+ onChangeExam(_extends({}, exam, {
3216
+ questions: [].concat(otherQuestions, questions.map(function (q) {
3217
+ return _extends({}, q, {
3218
+ numberOfAnswers: newAnswerCount
3219
+ });
3220
+ }))
3221
+ }));
3222
+ } else {
3223
+ onChangeExam(_extends({}, exam, {
3224
+ questions: [].concat(otherQuestions, questions.map(function (q) {
3225
+ return _extends({}, q, {
3226
+ numberOfAnswers: newAnswerCount,
3227
+ correctAnswers: q.correctAnswers.filter(function (i) {
3228
+ return i <= newAnswerCount;
3229
+ })
3230
+ });
3231
+ }))
3232
+ }));
3233
+ }
3234
+ };
3235
+ var handleChangeCorrectAnswers = function handleChangeCorrectAnswers(article, index, answer) {
3236
+ if (!exam) return;
3237
+ var examQuestions = exam.questions;
3238
+ var questions = examQuestions.filter(function (i) {
3239
+ return i.article === +article;
3240
+ });
3241
+ var otherQuestions = examQuestions.filter(function (i) {
3242
+ return i.article !== +article;
3243
+ });
3244
+ var selectedQuestion = questions[index];
3245
+ onChangeExam(_extends({}, exam, {
3246
+ questions: [].concat(otherQuestions, questions.slice(0, index), [_extends({}, selectedQuestion, {
3247
+ correctAnswers: [answer]
3248
+ })], questions.slice(index + 1))
3249
+ }));
3250
+ };
3251
+ var handleChangeScoreAnswer = function handleChangeScoreAnswer(article, index, score) {
3252
+ if (!exam) return;
3253
+ var examQuestions = exam.questions;
3254
+ var questions = examQuestions.filter(function (i) {
3255
+ return i.article === +article;
3256
+ });
3257
+ var otherQuestions = examQuestions.filter(function (i) {
3258
+ return i.article !== +article;
3259
+ });
3260
+ var selectedQuestion = questions[index];
3261
+ if (score === selectedQuestion.score) return;
3262
+ onChangeExam(_extends({}, exam, {
3263
+ questions: [].concat(otherQuestions, questions.slice(0, index), [_extends({}, selectedQuestion, {
3264
+ score: score
3265
+ })], questions.slice(index + 1))
3266
+ }));
3267
+ };
3268
+ var handleChangeDuration = function handleChangeDuration(value) {
3269
+ if (!exam) return;
3270
+ onChangeExam(_extends({}, exam, {
3271
+ duration: value === null || value === void 0 ? void 0 : value.value
3272
+ }));
3273
+ };
3274
+ var handleChangeTitle = function handleChangeTitle(e) {
3275
+ if (!exam) return;
3276
+ onChangeExam(_extends({}, exam, {
3277
+ title: e.target.value
3278
+ }));
3279
+ };
3280
+ var handleAddArticle = function handleAddArticle() {
3281
+ var _$maxBy, _$maxBy2;
3282
+ if (!exam) return;
3283
+ var maxArticle = ((_$maxBy = _.maxBy(exam.questions, "article")) === null || _$maxBy === void 0 ? void 0 : _$maxBy.article) || 0;
3284
+ var maxOrder = ((_$maxBy2 = _.maxBy(exam.questions, "questionOrder")) === null || _$maxBy2 === void 0 ? void 0 : _$maxBy2.questionOrder) || 0;
3285
+ onChangeExam(_extends({}, exam, {
3286
+ questions: [].concat(exam.questions, [{
3287
+ article: maxArticle + 1,
3288
+ correctAnswers: [1],
3289
+ numberOfAnswers: DEFAULT_ANSWER_COUNT,
3290
+ score: DEFAULT_SCORE,
3291
+ questionOrder: maxOrder + 1
3292
+ }])
3293
+ }));
3294
+ };
3295
+ var examGroupByArticle = React.useMemo(function () {
3296
+ if (!exam) return [];
3297
+ var articles = [];
3298
+ var groupedArticle = _.groupBy(exam.questions, "article");
3299
+ for (var key in groupedArticle) {
3300
+ if (Object.prototype.hasOwnProperty.call(groupedArticle, key)) {
3301
+ var _questions$find, _$maxBy3;
3302
+ var questions = groupedArticle[key];
3303
+ articles.push({
3304
+ article: +key,
3305
+ categoryId: (_questions$find = questions.find(function (i) {
3306
+ return !!i.categoryId;
3307
+ })) === null || _questions$find === void 0 ? void 0 : _questions$find.categoryId,
3308
+ answerCount: ((_$maxBy3 = _.maxBy(questions, "numberOfAnswers")) === null || _$maxBy3 === void 0 ? void 0 : _$maxBy3.numberOfAnswers) || DEFAULT_ANSWER_COUNT,
3309
+ questionCount: questions.length,
3310
+ questions: questions
3311
+ });
3312
+ }
3313
+ }
3314
+ return _.sortBy(articles, "article");
3315
+ }, [JSON.stringify(exam)]);
3316
+ var durationOptions = React.useMemo(function () {
3317
+ var options = DURATION_OPTIONS.map(function (i) {
3318
+ return {
3319
+ label: i + "\uBD84",
3320
+ value: i
3321
+ };
3322
+ });
3323
+ if (!!exam.duration && exam.duration > DURATION_OPTIONS[DURATION_OPTIONS.length - 1]) return [].concat(options, [{
3324
+ label: exam.duration + "\uBD84",
3325
+ value: exam.duration
3326
+ }]);
3327
+ return options;
3328
+ }, [exam.duration]);
3329
+ return {
3330
+ t: t,
3331
+ durationOptions: durationOptions,
3332
+ examGroupByArticle: examGroupByArticle,
3333
+ handleAddArticle: handleAddArticle,
3334
+ handleChangeScoreAnswer: handleChangeScoreAnswer,
3335
+ handleChangeTitle: handleChangeTitle,
3336
+ handleChangeDuration: handleChangeDuration,
3337
+ handleChangeCorrectAnswers: handleChangeCorrectAnswers,
3338
+ handleChangeAnswerCount: handleChangeAnswerCount,
3339
+ handleChangeQuestionCount: handleChangeQuestionCount,
3340
+ handleChangeCategory: handleChangeCategory
3341
+ };
3342
+ };
3343
+
3344
+ var ExamDetailView = function ExamDetailView(_ref) {
3345
+ var _ref$className = _ref.className,
3346
+ className = _ref$className === void 0 ? "" : _ref$className,
3347
+ categoryOptions = _ref.categoryOptions,
3348
+ exam = _ref.exam,
3349
+ _ref$isUsingMui = _ref.isUsingMui,
3350
+ isUsingMui = _ref$isUsingMui === void 0 ? true : _ref$isUsingMui,
3351
+ isDisabled = _ref.isDisabled,
3352
+ onChangeExam = _ref.onChangeExam;
3353
+ var _useExamDetailView = useExamDetailView({
3354
+ exam: exam,
3355
+ onChangeExam: onChangeExam
3356
+ }),
3357
+ t = _useExamDetailView.t,
3358
+ durationOptions = _useExamDetailView.durationOptions,
3359
+ examGroupByArticle = _useExamDetailView.examGroupByArticle,
3360
+ handleAddArticle = _useExamDetailView.handleAddArticle,
3361
+ handleChangeScoreAnswer = _useExamDetailView.handleChangeScoreAnswer,
3362
+ handleChangeTitle = _useExamDetailView.handleChangeTitle,
3363
+ handleChangeDuration = _useExamDetailView.handleChangeDuration,
3364
+ handleChangeCorrectAnswers = _useExamDetailView.handleChangeCorrectAnswers,
3365
+ handleChangeAnswerCount = _useExamDetailView.handleChangeAnswerCount,
3366
+ handleChangeQuestionCount = _useExamDetailView.handleChangeQuestionCount,
3367
+ handleChangeCategory = _useExamDetailView.handleChangeCategory;
3368
+ return React__default.createElement(reactstrap.Row, {
3369
+ className: "" + className
3370
+ }, React__default.createElement(reactstrap.Col, {
3371
+ xs: 5
3372
+ }, React__default.createElement(reactstrap.FormGroup, null, React__default.createElement(reactstrap.Label, {
3373
+ className: "" + styles$2["question-label"],
3374
+ htmlFor: "title"
3375
+ }, t("title")), React__default.createElement(reactstrap.Input, {
3376
+ disabled: isDisabled,
3377
+ className: "w-100 rounded-2 " + styles$2["question-input"],
3378
+ value: exam.title,
3379
+ id: "title",
3380
+ placeholder: t("enter_title"),
3381
+ onChange: handleChangeTitle
3382
+ }))), React__default.createElement(reactstrap.Col, {
3383
+ xs: 3
3384
+ }, React__default.createElement(reactstrap.FormGroup, null, React__default.createElement(reactstrap.Label, {
3385
+ className: "" + styles$2["question-label"],
3386
+ htmlFor: "duration"
3387
+ }, t("duration")), React__default.createElement(CustomSelect, {
3388
+ inputId: "duration",
3389
+ value: exam.duration,
3390
+ options: durationOptions,
3391
+ onChange: handleChangeDuration,
3392
+ isDisabled: isDisabled
3393
+ }))), React__default.createElement(reactstrap.Col, {
3394
+ xs: 4
3395
+ }), examGroupByArticle.map(function (i, index) {
3396
+ return React__default.createElement(reactstrap.Col, {
3397
+ xs: 12,
3398
+ key: i.article,
3399
+ className: (index === 0 && !isUsingMui ? "mt-3" : "") + " " + (!isUsingMui ? "mb-4" : "")
3400
+ }, React__default.createElement(ArticleGroupView, Object.assign({}, i, {
3401
+ categoryOptions: categoryOptions,
3402
+ isActive: index === examGroupByArticle.length - 1,
3403
+ onChangeQuestionCount: handleChangeQuestionCount,
3404
+ onChangeCategory: handleChangeCategory,
3405
+ onChangeAnswerCount: handleChangeAnswerCount,
3406
+ onChangeCorrectAnswers: handleChangeCorrectAnswers,
3407
+ onChangeScoreAnswer: handleChangeScoreAnswer,
3408
+ isDisabled: isDisabled
3409
+ })));
3410
+ }), React__default.createElement(reactstrap.Col, {
3411
+ xs: 12
3412
+ }, React__default.createElement(reactstrap.Button, {
3413
+ disabled: isDisabled,
3414
+ className: "w-100 d-flex justify-content-center align-items-center " + styles$2["question-btn"],
3415
+ color: "primary",
3416
+ outline: true,
3417
+ onClick: handleAddArticle
3418
+ }, React__default.createElement(fa.FaPlusCircle, {
3419
+ className: "me-2"
3420
+ }), "\uBB38\uD56D \uCD94\uAC00\uD558\uAE30")));
3421
+ };
3422
+
2560
3423
  var historyCore = history.createBrowserHistory();
2561
3424
 
3425
+ exports.moment = moment;
2562
3426
  Object.defineProperty(exports, 'I18nextProvider', {
2563
3427
  enumerable: true,
2564
3428
  get: function () {
@@ -2571,17 +3435,33 @@ Object.defineProperty(exports, 'useTranslation', {
2571
3435
  return reactI18next.useTranslation;
2572
3436
  }
2573
3437
  });
3438
+ Object.defineProperty(exports, 'ToastContainer', {
3439
+ enumerable: true,
3440
+ get: function () {
3441
+ return reactToastify.ToastContainer;
3442
+ }
3443
+ });
3444
+ Object.defineProperty(exports, 'toast', {
3445
+ enumerable: true,
3446
+ get: function () {
3447
+ return reactToastify.toast;
3448
+ }
3449
+ });
2574
3450
  exports.ACCESS_TOKEN = ACCESS_TOKEN;
2575
3451
  exports.BASE_URL = BASE_URL;
2576
3452
  exports.ChatContainer = ChatContainer;
2577
3453
  exports.CommonAlert = CommonAlert;
2578
3454
  exports.CommonDialog = CommonDialog;
2579
3455
  exports.ConfirmDialog = ConfirmDialog;
3456
+ exports.CustomAsyncSelect = CustomAsyncSelect;
3457
+ exports.CustomCreatable = CustomCreatable;
2580
3458
  exports.CustomPagination = CustomPagination;
2581
3459
  exports.CustomSelect = CustomSelect;
2582
3460
  exports.DATE_MIN_VALUE = DATE_MIN_VALUE;
2583
3461
  exports.EXAM_CHANNEL = EXAM_CHANNEL;
2584
3462
  exports.EXAM_STUDENT_CHANNEL = EXAM_STUDENT_CHANNEL;
3463
+ exports.ExamDetailView = ExamDetailView;
3464
+ exports.LANGUAGES = LANGUAGES;
2585
3465
  exports.LayoutContext = LayoutContext;
2586
3466
  exports.Loading = Loading;
2587
3467
  exports.Login = Login;
@@ -2605,6 +3485,7 @@ exports.toISOString = toISOString;
2605
3485
  exports.useChatContainer = useChatContainer;
2606
3486
  exports.useConversationList = useConversationList;
2607
3487
  exports.useGoogleSignOut = useGoogleSignOut;
3488
+ exports.useLanguage = useLanguage;
2608
3489
  exports.usePusherConversation = usePusherConversation;
2609
3490
  exports.utcToLocalTime = utcToLocalTime;
2610
3491
  //# sourceMappingURL=index.js.map