@elice/material-assignment 1.220803.0

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 (48) hide show
  1. package/README.md +3 -0
  2. package/cjs/components/index.d.ts +2 -0
  3. package/cjs/components/material-assignment/MaterialAssignment.d.ts +9 -0
  4. package/cjs/components/material-assignment/MaterialAssignment.js +40 -0
  5. package/cjs/components/material-assignment/MaterialAssignmentContent.d.ts +7 -0
  6. package/cjs/components/material-assignment/MaterialAssignmentContent.js +397 -0
  7. package/cjs/components/material-assignment/MaterialAssignmentUploadModal.d.ts +9 -0
  8. package/cjs/components/material-assignment/MaterialAssignmentUploadModal.js +201 -0
  9. package/cjs/components/material-assignment/index.d.ts +2 -0
  10. package/cjs/components/material-assignment/locales.d.ts +39 -0
  11. package/cjs/components/material-assignment/locales.js +83 -0
  12. package/cjs/components/material-assignment-admin/MaterialAssignmentAdmin.d.ts +14 -0
  13. package/cjs/components/material-assignment-admin/MaterialAssignmentAdmin.js +64 -0
  14. package/cjs/components/material-assignment-admin/MaterialAssignmentAdmin.styled.d.ts +13 -0
  15. package/cjs/components/material-assignment-admin/MaterialAssignmentAdmin.styled.js +41 -0
  16. package/cjs/components/material-assignment-admin/MaterialAssignmentAdminContent.d.ts +12 -0
  17. package/cjs/components/material-assignment-admin/MaterialAssignmentAdminContent.js +815 -0
  18. package/cjs/components/material-assignment-admin/MaterialAssignmentAdminContentTa.d.ts +8 -0
  19. package/cjs/components/material-assignment-admin/MaterialAssignmentAdminContentTa.js +479 -0
  20. package/cjs/components/material-assignment-admin/index.d.ts +3 -0
  21. package/cjs/components/shared/MaterialAssignmentContainer.d.ts +6 -0
  22. package/cjs/components/shared/MaterialAssignmentContainer.js +34 -0
  23. package/cjs/index.d.ts +1 -0
  24. package/cjs/index.js +11 -0
  25. package/es/components/index.d.ts +2 -0
  26. package/es/components/material-assignment/MaterialAssignment.d.ts +9 -0
  27. package/es/components/material-assignment/MaterialAssignment.js +33 -0
  28. package/es/components/material-assignment/MaterialAssignmentContent.d.ts +7 -0
  29. package/es/components/material-assignment/MaterialAssignmentContent.js +391 -0
  30. package/es/components/material-assignment/MaterialAssignmentUploadModal.d.ts +9 -0
  31. package/es/components/material-assignment/MaterialAssignmentUploadModal.js +194 -0
  32. package/es/components/material-assignment/index.d.ts +2 -0
  33. package/es/components/material-assignment/locales.d.ts +39 -0
  34. package/es/components/material-assignment/locales.js +78 -0
  35. package/es/components/material-assignment-admin/MaterialAssignmentAdmin.d.ts +14 -0
  36. package/es/components/material-assignment-admin/MaterialAssignmentAdmin.js +57 -0
  37. package/es/components/material-assignment-admin/MaterialAssignmentAdmin.styled.d.ts +13 -0
  38. package/es/components/material-assignment-admin/MaterialAssignmentAdmin.styled.js +27 -0
  39. package/es/components/material-assignment-admin/MaterialAssignmentAdminContent.d.ts +12 -0
  40. package/es/components/material-assignment-admin/MaterialAssignmentAdminContent.js +808 -0
  41. package/es/components/material-assignment-admin/MaterialAssignmentAdminContentTa.d.ts +8 -0
  42. package/es/components/material-assignment-admin/MaterialAssignmentAdminContentTa.js +472 -0
  43. package/es/components/material-assignment-admin/index.d.ts +3 -0
  44. package/es/components/shared/MaterialAssignmentContainer.d.ts +6 -0
  45. package/es/components/shared/MaterialAssignmentContainer.js +27 -0
  46. package/es/index.d.ts +1 -0
  47. package/es/index.js +2 -0
  48. package/package.json +70 -0
@@ -0,0 +1,808 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { useForm, Controller } from 'react-hook-form';
3
+ import { FormattedDate } from 'react-intl';
4
+ import { config, getOrgUserGet, getOrgMaterialAssignmentGet, getOrgMaterialAssignmentSubmissionList, getOrgMaterialAssignmentGradeResultGet, getOrgMaterialAssignmentGradeList, postOrgMaterialAssignmentGradeEdit, postOrgMaterialAssignmentGradeResultManualScoreEdit, postOrgMaterialAssignmentGradeDelete } from '@elice/api-client';
5
+ import { Notification, Flex, ProfileImage, Hspace, Text, Tooltip, Icon, Vspace, InfoTable, Button, TableNext, IconButton, Pagination, Modal, Label, Input, Textarea, Alert } from '@elice/blocks';
6
+ import { base } from '@elice/design-tokens';
7
+ import { eilStatusInfo, eilChat, eilDelete, eilArrowRightwardsBasic } from '@elice/icons';
8
+ import { useMaterialConfigApiClientUpdate } from '@elice/material-shared-utils';
9
+ import dayjs from 'dayjs';
10
+ import MaterialAssignmentContainer from '../shared/MaterialAssignmentContainer.js';
11
+ import { StyledMaterialAssignmentAdminHeader, StyledMaterialAssignmentAdminHeaderCell, StyledMaterialAssignmentAdminGradeWrapper, StyledMaterialAssignmentAdminManualScoreEditButtonWrapper, StyledMaterialAssignmentAdminManualScoreEditButton, StyledMaterialAssignmentAdminTextareaWrapper } from './MaterialAssignmentAdmin.styled.js';
12
+
13
+ const FETCH_GRADE_LIST_COUNT = 5;
14
+ const MaterialAssignmentAdminContent = forwardRef(({
15
+ materialAssignmentId,
16
+ userId,
17
+ adminUserId,
18
+ updateMaterialUserBrowserResponse
19
+ }, ref) => {
20
+ var _a; // Form
21
+
22
+
23
+ const gradeEditFormMethods = useForm({
24
+ defaultValues: {
25
+ score: 0,
26
+ comment: ''
27
+ },
28
+ mode: 'onChange'
29
+ });
30
+ const manualScoreEditFormMethods = useForm({
31
+ defaultValues: {
32
+ manualScore: 0
33
+ },
34
+ mode: 'onChange'
35
+ }); // API Status
36
+
37
+ const isReady = useMaterialConfigApiClientUpdate(config.init);
38
+ const [submissionListGetStatus, setSubmissionListGetStatus] = React.useState('idle');
39
+ const [gradeDeleteStatus, setGradeDeleteStatus] = React.useState('idle'); // State related with component
40
+
41
+ const [showGradeEditModal, setShowGradeEditModal] = React.useState(false);
42
+ const [showManualScoreEditModal, setShowManualScoreEditModal] = React.useState(false);
43
+ const [selectedGradeForShow, setSelectedGradeForShow] = React.useState(null);
44
+ const [selectedGradeForDelete, setSelectedGradeForDelete] = React.useState(null); // State related with api
45
+
46
+ const [user, setUser] = React.useState(null);
47
+ const [materialAssignment, setMaterialAssignment] = React.useState(null);
48
+ const [userSubmission, setUserSubmission] = React.useState(null);
49
+ const [myGrade, setMyGrade] = React.useState(null);
50
+ const [gradeResult, setGradeResult] = React.useState(null);
51
+ const [gradeList, setGradeList] = React.useState([]);
52
+ const [gradeListCount, setGradeListCount] = React.useState(0);
53
+ const [gradeListPage, setGradeListPage] = React.useState(1);
54
+ const gradeListOffset = (gradeListPage - 1) * FETCH_GRADE_LIST_COUNT;
55
+ const isAssignmentClosed = dayjs().isAfter(dayjs(materialAssignment === null || materialAssignment === void 0 ? void 0 : materialAssignment.closeDatetime));
56
+ const isScoreFinalized = Boolean(materialAssignment === null || materialAssignment === void 0 ? void 0 : materialAssignment.scoreFinalizedDatetime);
57
+ const isUserSubmitted = Boolean(userSubmission);
58
+ const fetchUserGet = React.useCallback(() => {
59
+ void getOrgUserGet({
60
+ userId
61
+ }).then(res => res.user).then(setUser);
62
+ }, [userId]);
63
+ const fetchMaterialAssignmentGet = React.useCallback(() => {
64
+ void getOrgMaterialAssignmentGet({
65
+ materialAssignmentId
66
+ }).then(res => res.materialAssignment).then(setMaterialAssignment);
67
+ }, [materialAssignmentId]);
68
+ const fetchSubmissionList = React.useCallback(() => {
69
+ setSubmissionListGetStatus('pending');
70
+ void getOrgMaterialAssignmentSubmissionList({
71
+ materialAssignmentId,
72
+ offset: 0,
73
+ count: 1,
74
+ filterConditions: {
75
+ isLast: true,
76
+ userIds: [userId]
77
+ }
78
+ }).then(res => res.materialAssignmentSubmissions[0]).then(submission => {
79
+ setUserSubmission(submission !== null && submission !== void 0 ? submission : null);
80
+ setSubmissionListGetStatus('resolved');
81
+ }).catch(err => {
82
+ console.error(err);
83
+ setSubmissionListGetStatus('rejected');
84
+ });
85
+ }, [materialAssignmentId, userId]);
86
+ const fetchGradeResult = React.useCallback(() => {
87
+ void getOrgMaterialAssignmentGradeResultGet({
88
+ materialAssignmentId,
89
+ userId
90
+ }).then(res => res.materialAssignmentGradeResult).then(setGradeResult).catch(() => {
91
+ setGradeResult(null);
92
+ });
93
+ }, [materialAssignmentId, userId]);
94
+ const fetchGradeList = React.useCallback(() => {
95
+ void getOrgMaterialAssignmentGradeList({
96
+ materialAssignmentId,
97
+ offset: gradeListOffset,
98
+ count: FETCH_GRADE_LIST_COUNT,
99
+ filterConditions: {
100
+ userId
101
+ }
102
+ }).then(({
103
+ materialAssignmentGrades,
104
+ materialAssignmentGradeCount
105
+ }) => {
106
+ setGradeList(materialAssignmentGrades);
107
+ setGradeListCount(materialAssignmentGradeCount);
108
+ });
109
+ }, [gradeListOffset, materialAssignmentId, userId]);
110
+ const fetchMyGrade = React.useCallback(() => {
111
+ void getOrgMaterialAssignmentGradeList({
112
+ materialAssignmentId,
113
+ offset: 0,
114
+ count: 1,
115
+ filterConditions: {
116
+ userId,
117
+ gradeUserId: adminUserId
118
+ }
119
+ }).then(res => res.materialAssignmentGrades[0]).then(grade => setMyGrade(grade !== null && grade !== void 0 ? grade : null));
120
+ }, [adminUserId, materialAssignmentId, userId]);
121
+
122
+ const handleManualScoreEditClick = () => {
123
+ var _a, _b;
124
+
125
+ setShowManualScoreEditModal(true);
126
+ manualScoreEditFormMethods.reset({
127
+ manualScore: (_b = (_a = gradeResult === null || gradeResult === void 0 ? void 0 : gradeResult.manualScore) !== null && _a !== void 0 ? _a : gradeResult === null || gradeResult === void 0 ? void 0 : gradeResult.avgCalcScore) !== null && _b !== void 0 ? _b : 0
128
+ });
129
+ };
130
+
131
+ const handleGradeEditClick = () => {
132
+ var _a, _b;
133
+
134
+ setShowGradeEditModal(true);
135
+ gradeEditFormMethods.reset({
136
+ score: (_a = myGrade === null || myGrade === void 0 ? void 0 : myGrade.score) !== null && _a !== void 0 ? _a : 0,
137
+ comment: (_b = myGrade === null || myGrade === void 0 ? void 0 : myGrade.comment) !== null && _b !== void 0 ? _b : ''
138
+ });
139
+ };
140
+
141
+ const handleGradeEditSubmit = gradeEditFormMethods.handleSubmit(async ({
142
+ score,
143
+ comment
144
+ }) => {
145
+ try {
146
+ await postOrgMaterialAssignmentGradeEdit({
147
+ materialAssignmentGradeId: myGrade === null || myGrade === void 0 ? void 0 : myGrade.id,
148
+ materialAssignmentId,
149
+ userId,
150
+ score,
151
+ comment
152
+ });
153
+ fetchMyGrade();
154
+ fetchGradeResult();
155
+ fetchGradeList();
156
+
157
+ if (typeof updateMaterialUserBrowserResponse === 'function') {
158
+ updateMaterialUserBrowserResponse(userId);
159
+ }
160
+
161
+ Notification.success('저장되었습니다');
162
+ } catch (err) {
163
+ console.error(err);
164
+ Notification.error('오류가 발생했습니다.');
165
+ } finally {
166
+ setShowGradeEditModal(false);
167
+ }
168
+ });
169
+
170
+ const handleGradeDeleteSubmit = async () => {
171
+ if (!selectedGradeForDelete) {
172
+ return;
173
+ }
174
+
175
+ try {
176
+ setGradeDeleteStatus('pending');
177
+ await postOrgMaterialAssignmentGradeDelete({
178
+ materialAssignmentGradeId: selectedGradeForDelete.id
179
+ }); // If delete my grade, re-fetch my grade data.
180
+
181
+ if (adminUserId === selectedGradeForDelete.gradeUser.id) {
182
+ fetchMyGrade();
183
+ }
184
+
185
+ fetchGradeList();
186
+ fetchGradeResult();
187
+ setGradeDeleteStatus('resolved');
188
+
189
+ if (typeof updateMaterialUserBrowserResponse === 'function') {
190
+ updateMaterialUserBrowserResponse(userId);
191
+ }
192
+
193
+ Notification.success('저장되었습니다');
194
+ } catch (err) {
195
+ console.error(err);
196
+ setGradeDeleteStatus('rejected');
197
+ Notification.error('오류가 발생했습니다.');
198
+ } finally {
199
+ setSelectedGradeForDelete(null);
200
+ }
201
+ };
202
+
203
+ const handleManualScoreEditSubmit = manualScoreEditFormMethods.handleSubmit(async ({
204
+ manualScore
205
+ }) => {
206
+ try {
207
+ await postOrgMaterialAssignmentGradeResultManualScoreEdit({
208
+ userId,
209
+ manualScore,
210
+ materialAssignmentId
211
+ });
212
+ fetchGradeResult();
213
+
214
+ if (typeof updateMaterialUserBrowserResponse === 'function') {
215
+ updateMaterialUserBrowserResponse(userId);
216
+ }
217
+
218
+ Notification.success('저장되었습니다');
219
+ } catch (err) {
220
+ console.error(err);
221
+ Notification.error('오류가 발생했습니다.');
222
+ } finally {
223
+ setShowManualScoreEditModal(false);
224
+ }
225
+ });
226
+ React.useEffect(() => {
227
+ if (!isReady) {
228
+ return;
229
+ }
230
+
231
+ fetchUserGet();
232
+ fetchMyGrade();
233
+ fetchGradeList();
234
+ fetchGradeResult();
235
+ fetchSubmissionList();
236
+ fetchMaterialAssignmentGet();
237
+ }, [isReady, fetchUserGet, fetchMyGrade, fetchGradeList, fetchGradeResult, fetchSubmissionList, fetchMaterialAssignmentGet]);
238
+ React.useImperativeHandle(ref, () => ({
239
+ refreshMaterialAssignment: () => {
240
+ fetchMaterialAssignmentGet();
241
+ }
242
+ }), [fetchMaterialAssignmentGet]);
243
+
244
+ const renderHeader = () => {
245
+ var _a, _b, _c;
246
+
247
+ return React.createElement(StyledMaterialAssignmentAdminHeader, {
248
+ align: "center",
249
+ padding: "1rem",
250
+ width: "100%"
251
+ }, React.createElement(Flex, {
252
+ auto: true,
253
+ align: "center"
254
+ }, React.createElement(ProfileImage, {
255
+ src: (_a = user === null || user === void 0 ? void 0 : user.profileUrl) !== null && _a !== void 0 ? _a : '',
256
+ width: "2.5rem",
257
+ height: "2.5rem"
258
+ }), React.createElement(Hspace, {
259
+ width: 1
260
+ }), React.createElement(Text, {
261
+ size: "small",
262
+ role: "warmwhite"
263
+ }, user === null || user === void 0 ? void 0 : user.fullname)), React.createElement(StyledMaterialAssignmentAdminHeaderCell, null, React.createElement(Text, {
264
+ size: "tiny",
265
+ role: "gray4"
266
+ }, "\uC810\uC218"), React.createElement(Text, {
267
+ size: "small",
268
+ role: "white"
269
+ }, gradeResult ? `${(_c = (_b = gradeResult.manualScore) !== null && _b !== void 0 ? _b : gradeResult.avgCalcScore) !== null && _c !== void 0 ? _c : 0}${isScoreFinalized ? '(공개됨)' : '(비공개)'}` : '--')), React.createElement(StyledMaterialAssignmentAdminHeaderCell, null, React.createElement(Text, {
270
+ size: "tiny",
271
+ role: "gray4"
272
+ }, "\uC81C\uCD9C \uC77C\uC2DC"), React.createElement(Text, {
273
+ size: "small",
274
+ role: "white"
275
+ }, userSubmission ? React.createElement(FormattedDate, {
276
+ value: userSubmission.createdDatetime,
277
+ dateStyle: "medium",
278
+ timeStyle: "short",
279
+ hour12: false
280
+ }) : '--')));
281
+ };
282
+
283
+ const renderManualScoreEditButton = () => {
284
+ return React.createElement(Tooltip, {
285
+ placement: "top",
286
+ title: isUserSubmitted ? '제출 기한이 지난 이후 조정할 수 있습니다.' : '미제출인 경우 조정할 수 없습니다.',
287
+ visible: !isAssignmentClosed || !isUserSubmitted ? undefined : false
288
+ }, React.createElement(StyledMaterialAssignmentAdminManualScoreEditButtonWrapper, {
289
+ disabled: !isAssignmentClosed || !isUserSubmitted
290
+ }, React.createElement(StyledMaterialAssignmentAdminManualScoreEditButton, {
291
+ disabled: !isAssignmentClosed || !isUserSubmitted,
292
+ underline: true,
293
+ role: "navy3",
294
+ size: "tiny",
295
+ onClick: handleManualScoreEditClick
296
+ }, "\uC810\uC218 \uC870\uC815\uD558\uAE30")));
297
+ };
298
+
299
+ const renderGradeResult = () => {
300
+ var _a, _b;
301
+
302
+ return React.createElement(StyledMaterialAssignmentAdminGradeWrapper, {
303
+ wrap: true,
304
+ width: "100%",
305
+ align: "center"
306
+ }, React.createElement(Flex, {
307
+ auto: true,
308
+ align: "center"
309
+ }, React.createElement(Text, {
310
+ role: "navy1",
311
+ size: "small",
312
+ lineHeight: "1.375rem"
313
+ }, user ? `${user.fullname} 님의 점수` : null), React.createElement(Hspace, {
314
+ width: 0.25
315
+ }), React.createElement(Tooltip, {
316
+ useMaxWidth: true,
317
+ placement: "top",
318
+ title: "모든 채점 점수의 평균값이 반영된 종합 점수입니다. 평균값을 사용하지 않으려면 ‘조정하기'를 클릭해 직접 점수를 입력하세요."
319
+ }, React.createElement(Icon, {
320
+ icon: eilStatusInfo,
321
+ color: base.color.navy1
322
+ })), React.createElement(Hspace, {
323
+ width: 0.75
324
+ }), React.createElement(Text, {
325
+ bold: true,
326
+ role: "white"
327
+ }, gradeResult ? `${(_b = (_a = gradeResult.manualScore) !== null && _a !== void 0 ? _a : gradeResult.avgCalcScore) !== null && _b !== void 0 ? _b : 0}${isScoreFinalized ? '(공개됨)' : '(비공개)'}` : '--')), renderManualScoreEditButton());
328
+ };
329
+
330
+ const renderSubmissionInfo = () => {
331
+ const statusText = (() => {
332
+ if (submissionListGetStatus === 'pending') {
333
+ return null;
334
+ }
335
+
336
+ switch (true) {
337
+ case !isUserSubmitted && isAssignmentClosed:
338
+ return React.createElement(Text, {
339
+ bold: true,
340
+ role: "danger",
341
+ size: "small"
342
+ }, "\uC81C\uCD9C \uAE30\uD55C \uB9CC\uB8CC");
343
+
344
+ case isScoreFinalized:
345
+ return React.createElement(Text, {
346
+ bold: true,
347
+ role: "lightpurple",
348
+ size: "small"
349
+ }, "\uCC44\uC810 \uC644\uB8CC");
350
+
351
+ case isUserSubmitted:
352
+ return React.createElement(Text, {
353
+ bold: true,
354
+ role: "success",
355
+ size: "small"
356
+ }, "\uC81C\uCD9C\uB428");
357
+
358
+ case !isUserSubmitted:
359
+ return React.createElement(Text, {
360
+ bold: true,
361
+ role: "warning",
362
+ size: "small"
363
+ }, "\uBBF8\uC81C\uCD9C");
364
+ }
365
+ })();
366
+
367
+ const submissionAttachment = (() => {
368
+ if (!userSubmission) {
369
+ return '--';
370
+ }
371
+
372
+ if (userSubmission.assignmentFileUrl) {
373
+ const assignmentFilename = decodeURIComponent(userSubmission.assignmentFileUrl && new URL(userSubmission.assignmentFileUrl).pathname.split('/').pop() || '');
374
+ return React.createElement("a", {
375
+ href: userSubmission.assignmentFileUrl,
376
+ download: assignmentFilename,
377
+ target: "_blank",
378
+ rel: "noopener noreferrer"
379
+ }, React.createElement(Text, {
380
+ hoverable: true,
381
+ underline: true,
382
+ role: "white",
383
+ size: "small"
384
+ }, assignmentFilename));
385
+ }
386
+
387
+ if (userSubmission === null || userSubmission === void 0 ? void 0 : userSubmission.assignmentUrl) {
388
+ return React.createElement("a", {
389
+ href: userSubmission.assignmentUrl,
390
+ target: "_blank",
391
+ rel: "noopener noreferrer"
392
+ }, React.createElement(Text, {
393
+ hoverable: true,
394
+ underline: true,
395
+ role: "white",
396
+ size: "small"
397
+ }, userSubmission.assignmentUrl));
398
+ }
399
+ })();
400
+
401
+ return React.createElement(InfoTable, {
402
+ dark: true
403
+ }, React.createElement("tbody", null, React.createElement("tr", null, React.createElement("td", null, "\uC0C1\uD0DC"), React.createElement("td", null, statusText)), React.createElement("tr", null, React.createElement("td", null, "\uACFC\uC81C \uC81C\uCD9C \uAE30\uD55C"), React.createElement("td", null, React.createElement(FormattedDate, {
404
+ value: materialAssignment === null || materialAssignment === void 0 ? void 0 : materialAssignment.closeDatetime,
405
+ dateStyle: "medium",
406
+ timeStyle: "short",
407
+ hour12: false
408
+ }))), React.createElement("tr", null, React.createElement("td", null, "\uC81C\uCD9C \uC77C\uC2DC"), React.createElement("td", null, userSubmission ? React.createElement(FormattedDate, {
409
+ value: userSubmission.createdDatetime,
410
+ dateStyle: "medium",
411
+ timeStyle: "short",
412
+ hour12: false
413
+ }) : '--')), React.createElement("tr", null, React.createElement("td", null, "\uC5C5\uB85C\uB4DC\uB41C \uACFC\uC81C"), React.createElement("td", null, submissionAttachment))));
414
+ };
415
+
416
+ const renderGradeList = () => {
417
+ return React.createElement(Flex, {
418
+ column: true,
419
+ align: "center"
420
+ }, React.createElement(Flex, {
421
+ align: "center",
422
+ width: "100%"
423
+ }, React.createElement(Flex, {
424
+ column: true,
425
+ auto: true
426
+ }, React.createElement(Text, {
427
+ block: true,
428
+ bold: true,
429
+ role: "white",
430
+ lineHeight: 1.375
431
+ }, "\uCC44\uC810 \uD604\uD669"), React.createElement(Text, {
432
+ block: true,
433
+ size: "tiny",
434
+ role: "navy3",
435
+ lineHeight: 1.6
436
+ }, "\uCC44\uC810\uC644\uB8CC\uD55C \uCC44\uC810\uC790\uC758 \uC810\uC218\uC640 \uD53C\uB4DC\uBC31\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4.")), React.createElement(Tooltip, {
437
+ placement: "top",
438
+ title: isUserSubmitted ? '제출 기한이 지난 이후 채점할 수 있습니다.' : '미제출인 경우 채점할 수 없습니다.',
439
+ visible: !isAssignmentClosed || !isUserSubmitted ? undefined : false
440
+ }, React.createElement("span", null, React.createElement(Button, {
441
+ size: "small",
442
+ role: "lightpurple",
443
+ disabled: !isAssignmentClosed || !isUserSubmitted,
444
+ onClick: handleGradeEditClick
445
+ }, Boolean(myGrade) ? '내 채점 수정' : '내 채점 시작')))), React.createElement(Vspace, {
446
+ height: 0.75
447
+ }), React.createElement(TableNext, {
448
+ dark: true,
449
+ emptyMessage: "\uCC44\uC810 \uC644\uB8CC\uD55C \uCC44\uC810\uC790\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
450
+ columns: [{
451
+ Header: '채점자명',
452
+ accessor: 'fullname'
453
+ }, {
454
+ Header: '과제 점수',
455
+ accessor: 'grade'
456
+ }, {
457
+ Header: '채점 일시',
458
+ accessor: 'created',
459
+ textAlign: 'left'
460
+ }],
461
+ data: gradeList.map(grade => ({
462
+ fullname: React.createElement(Flex, null, React.createElement(Text, {
463
+ noWrap: true,
464
+ role: "navy0",
465
+ size: "small"
466
+ }, `${grade.gradeUser.fullname}${grade.gradeUser.id === adminUserId ? '(나)' : ''}`), React.createElement(Hspace, {
467
+ width: 0.25
468
+ }), React.createElement(Text, {
469
+ ellipsis: true,
470
+ role: "navy3",
471
+ size: "small"
472
+ }, grade.gradeUser.email)),
473
+ grade: grade.score,
474
+ created: React.createElement(Flex, {
475
+ align: "center",
476
+ justify: "space-between"
477
+ }, React.createElement(FormattedDate, {
478
+ value: grade.createdDatetime,
479
+ dateStyle: "medium",
480
+ timeStyle: "short",
481
+ hour12: false
482
+ }), React.createElement(Flex, {
483
+ align: "center"
484
+ }, React.createElement(IconButton, {
485
+ icon: eilChat,
486
+ size: "tiny",
487
+ role: "navy3",
488
+ onClick: () => {
489
+ setSelectedGradeForShow(grade);
490
+ }
491
+ }), React.createElement(Hspace, {
492
+ width: 0.5
493
+ }), React.createElement(IconButton, {
494
+ icon: eilDelete,
495
+ size: "tiny",
496
+ role: "navy3",
497
+ onClick: () => {
498
+ setSelectedGradeForDelete(grade);
499
+ }
500
+ })))
501
+ }))
502
+ }), React.createElement(Vspace, {
503
+ height: 0.5
504
+ }), React.createElement(Pagination, {
505
+ dark: true,
506
+ offset: gradeListOffset,
507
+ count: FETCH_GRADE_LIST_COUNT,
508
+ total: gradeListCount,
509
+ isNext: gradeListOffset + FETCH_GRADE_LIST_COUNT < gradeListCount,
510
+ isPrev: gradeListOffset > 0,
511
+ onClickNext: () => {
512
+ setGradeListPage(gradeListPage + 1);
513
+ },
514
+ onClickPrev: () => {
515
+ setGradeListPage(gradeListPage - 1);
516
+ }
517
+ }));
518
+ };
519
+
520
+ const renderGradeEditModal = () => {
521
+ if (!showGradeEditModal) {
522
+ return null;
523
+ }
524
+
525
+ return React.createElement(Modal, {
526
+ title: Boolean(myGrade) ? '내 채점 수정' : '과제 채점',
527
+ footerButtons: [{
528
+ label: '확인',
529
+ size: 'small',
530
+ role: 'primary',
531
+ loading: gradeEditFormMethods.formState.isSubmitting,
532
+ disabled: gradeEditFormMethods.formState.isSubmitting || !gradeEditFormMethods.formState.isValid,
533
+ onClick: handleGradeEditSubmit
534
+ }, {
535
+ label: '취소',
536
+ size: 'small',
537
+ role: 'gray1',
538
+ onClick: () => {
539
+ setShowGradeEditModal(false);
540
+ }
541
+ }],
542
+ onHide: () => {
543
+ setShowGradeEditModal(false);
544
+ }
545
+ }, React.createElement(Label, {
546
+ bold: true,
547
+ block: true,
548
+ required: true
549
+ }, "\uC810\uC218"), React.createElement(Vspace, {
550
+ height: 0.5
551
+ }), React.createElement(Flex, {
552
+ align: "center"
553
+ }, React.createElement(Controller, {
554
+ control: gradeEditFormMethods.control,
555
+ name: "score",
556
+ rules: {
557
+ required: true,
558
+ min: 0,
559
+ max: 100
560
+ },
561
+ render: ({
562
+ field,
563
+ fieldState
564
+ }) => React.createElement(Input, Object.assign({}, field, {
565
+ invalid: fieldState.invalid,
566
+ size: "small",
567
+ width: "xsmall",
568
+ type: "number"
569
+ }))
570
+ }), React.createElement(Hspace, {
571
+ width: 0.5
572
+ }), React.createElement(Text, {
573
+ bold: true,
574
+ role: "gray9",
575
+ size: "small"
576
+ }, "\uC810"), React.createElement(Text, {
577
+ role: "gray6",
578
+ size: "small"
579
+ }, ' / 100점 만점')), React.createElement(Vspace, {
580
+ height: 1.25
581
+ }), React.createElement(Label, {
582
+ bold: true,
583
+ block: true
584
+ }, "\uD53C\uB4DC\uBC31"), React.createElement(Vspace, {
585
+ height: 0.5
586
+ }), React.createElement(Controller, {
587
+ control: gradeEditFormMethods.control,
588
+ name: "comment",
589
+ rules: {
590
+ maxLength: 1000
591
+ },
592
+ render: ({
593
+ field
594
+ }) => React.createElement(Textarea, {
595
+ value: field.value,
596
+ wordLimit: 1000,
597
+ rows: 8,
598
+ onChange: field.onChange
599
+ })
600
+ }));
601
+ };
602
+
603
+ const renderGradeShowModal = () => {
604
+ if (!selectedGradeForShow) {
605
+ return null;
606
+ }
607
+
608
+ return React.createElement(Modal, {
609
+ title: "\uCC44\uC810 \uACB0\uACFC \uD655\uC778",
610
+ footerButtons: [{
611
+ label: '확인',
612
+ size: 'small',
613
+ role: 'primary',
614
+ onClick: () => {
615
+ setSelectedGradeForShow(null);
616
+ }
617
+ }],
618
+ onHide: () => {
619
+ setSelectedGradeForShow(null);
620
+ }
621
+ }, React.createElement(Label, {
622
+ bold: true,
623
+ block: true,
624
+ required: true
625
+ }, "\uC810\uC218"), React.createElement(Vspace, {
626
+ height: 0.5
627
+ }), React.createElement(Flex, {
628
+ align: "center"
629
+ }, React.createElement(Input, {
630
+ disabled: true,
631
+ value: selectedGradeForShow.score,
632
+ size: "small",
633
+ width: "xsmall",
634
+ type: "number"
635
+ }), React.createElement(Hspace, {
636
+ width: 0.5
637
+ }), React.createElement(Text, {
638
+ bold: true,
639
+ role: "gray9",
640
+ size: "small"
641
+ }, "\uC810"), React.createElement(Text, {
642
+ role: "gray6",
643
+ size: "small"
644
+ }, ' / 100점 만점')), React.createElement(Vspace, {
645
+ height: 1.25
646
+ }), React.createElement(Label, {
647
+ bold: true,
648
+ block: true
649
+ }, "\uD53C\uB4DC\uBC31"), React.createElement(Vspace, {
650
+ height: 0.5
651
+ }), React.createElement(StyledMaterialAssignmentAdminTextareaWrapper, null, React.createElement(Textarea, {
652
+ disabled: true,
653
+ value: selectedGradeForShow.comment,
654
+ wordLimit: 1000,
655
+ rows: 8
656
+ })));
657
+ };
658
+
659
+ const renderGradeDeleteModal = () => {
660
+ if (!selectedGradeForDelete) {
661
+ return null;
662
+ }
663
+
664
+ return React.createElement(Modal, {
665
+ title: "\uCC44\uC810 \uC0AD\uC81C",
666
+ width: "narrow",
667
+ footerButtons: [{
668
+ label: '확인',
669
+ size: 'small',
670
+ role: 'primary',
671
+ loading: gradeDeleteStatus === 'pending',
672
+ disabled: gradeDeleteStatus === 'pending',
673
+ onClick: handleGradeDeleteSubmit
674
+ }, {
675
+ label: '취소',
676
+ size: 'small',
677
+ role: 'gray1',
678
+ onClick: () => {
679
+ setSelectedGradeForDelete(null);
680
+ }
681
+ }],
682
+ onHide: () => {
683
+ setSelectedGradeForDelete(null);
684
+ }
685
+ }, React.createElement(Text, {
686
+ role: "gray9"
687
+ }, "\uC0AD\uC81C\uB41C \uC810\uC218\uC640 \uD53C\uB4DC\uBC31\uC740 \uB2E4\uC2DC \uBCF5\uAD6C\uB420 \uC218 \uC5C6\uC73C\uBA70 \uD559\uC0DD\uC758 \uD3C9\uADE0 \uC810\uC218\uAC00 \uBCC0\uACBD\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4."), React.createElement(Vspace, {
688
+ height: 0.75
689
+ }), React.createElement(TableNext, {
690
+ columns: [{
691
+ Header: '채점자명',
692
+ accessor: 'fullname'
693
+ }, {
694
+ Header: '최종 점수',
695
+ accessor: 'score'
696
+ }],
697
+ data: [{
698
+ fullname: React.createElement(Flex, null, React.createElement(Text, {
699
+ noWrap: true,
700
+ role: "gray9",
701
+ size: "small"
702
+ }, selectedGradeForDelete.gradeUser.fullname), React.createElement(Hspace, {
703
+ width: 0.25
704
+ }), React.createElement(Text, {
705
+ ellipsis: true,
706
+ role: "gray5",
707
+ size: "small"
708
+ }, selectedGradeForDelete.gradeUser.email)),
709
+ score: selectedGradeForDelete.score
710
+ }]
711
+ }));
712
+ };
713
+
714
+ const renderManualScoreEditModal = () => {
715
+ var _a, _b;
716
+
717
+ if (!showManualScoreEditModal) {
718
+ return null;
719
+ }
720
+
721
+ return React.createElement(Modal, {
722
+ title: "\uC810\uC218 \uC870\uC815",
723
+ width: "narrow",
724
+ footerButtons: [{
725
+ label: '확인',
726
+ size: 'small',
727
+ role: 'primary',
728
+ loading: manualScoreEditFormMethods.formState.isSubmitting,
729
+ disabled: manualScoreEditFormMethods.formState.isSubmitting || !manualScoreEditFormMethods.formState.isValid,
730
+ onClick: handleManualScoreEditSubmit
731
+ }, {
732
+ label: '취소',
733
+ size: 'small',
734
+ role: 'gray1',
735
+ onClick: () => {
736
+ setShowManualScoreEditModal(false);
737
+ }
738
+ }],
739
+ onHide: () => {
740
+ setShowManualScoreEditModal(false);
741
+ }
742
+ }, React.createElement(Alert, {
743
+ role: "warning"
744
+ }, "\uC810\uC218 \uC870\uC815 \uC774\uD6C4 \uB2E4\uC2DC \uD3C9\uADE0\uAC12\uC73C\uB85C \uB418\uB3CC\uB9B4 \uC218 \uC5C6\uC73C\uB2C8 \uC720\uC758\uD574 \uC8FC\uC138\uC694."), React.createElement(Vspace, {
745
+ height: 1
746
+ }), React.createElement(Flex, {
747
+ align: "center"
748
+ }, React.createElement(Input, {
749
+ disabled: true,
750
+ size: "small",
751
+ width: "xsmall",
752
+ type: "number",
753
+ label: "\uC774\uC804 \uC810\uC218",
754
+ value: (_b = (_a = gradeResult === null || gradeResult === void 0 ? void 0 : gradeResult.manualScore) !== null && _a !== void 0 ? _a : gradeResult === null || gradeResult === void 0 ? void 0 : gradeResult.avgCalcScore) !== null && _b !== void 0 ? _b : 0
755
+ }), React.createElement(Hspace, {
756
+ width: 1
757
+ }), React.createElement(Icon, {
758
+ icon: eilArrowRightwardsBasic
759
+ }), React.createElement(Hspace, {
760
+ width: 1
761
+ }), React.createElement(Controller, {
762
+ control: manualScoreEditFormMethods.control,
763
+ name: "manualScore",
764
+ rules: {
765
+ required: true,
766
+ min: 0,
767
+ max: 100
768
+ },
769
+ render: ({
770
+ field,
771
+ fieldState
772
+ }) => React.createElement(Input, Object.assign({}, field, {
773
+ invalid: fieldState.invalid,
774
+ size: "small",
775
+ width: "xsmall",
776
+ type: "number",
777
+ label: "\uC870\uC815 \uC810\uC218"
778
+ }))
779
+ }), React.createElement(Hspace, {
780
+ width: 0.75
781
+ }), React.createElement(Text, {
782
+ bold: true,
783
+ role: "gray9",
784
+ size: "small"
785
+ }, "\uC810"), React.createElement(Text, {
786
+ role: "gray6",
787
+ size: "small"
788
+ }, ' / 100점 만점')));
789
+ };
790
+
791
+ return React.createElement(React.Fragment, null, renderHeader(), React.createElement(Flex, {
792
+ column: true,
793
+ auto: true,
794
+ padding: "3.625rem",
795
+ width: "100%",
796
+ height: "100%",
797
+ overflow: "hidden",
798
+ align: "center"
799
+ }, React.createElement(MaterialAssignmentContainer, {
800
+ title: (_a = materialAssignment === null || materialAssignment === void 0 ? void 0 : materialAssignment.title) !== null && _a !== void 0 ? _a : ''
801
+ }, renderGradeResult(), React.createElement(Vspace, {
802
+ height: 1.25
803
+ }), renderSubmissionInfo(), React.createElement(Vspace, {
804
+ height: 1.5
805
+ }), renderGradeList())), renderGradeEditModal(), renderGradeShowModal(), renderGradeDeleteModal(), renderManualScoreEditModal());
806
+ });
807
+
808
+ export { MaterialAssignmentAdminContent as default };