|
1 | 1 | import classNames from 'classnames'; |
2 | | -import { FormattedMessage, useIntl } from 'react-intl'; |
| 2 | +import { FormattedMessage } from 'react-intl'; |
3 | 3 | import PropTypes from 'prop-types'; |
4 | 4 | import React, { useCallback, useEffect, useRef, useState } from 'react'; |
5 | 5 |
|
@@ -49,7 +49,6 @@ const TeacherClassDetail = ({ |
49 | 49 | group, |
50 | 50 | shared, |
51 | 51 | }) => { |
52 | | - const intl = useIntl(); |
53 | 52 | // Destructured with handle-prefixed names for the embedded editor |
54 | 53 | // (react/jsx-handler-names requires handler props to look like handlers). |
55 | 54 | const descEditor = assignmentEditor || {}; |
@@ -156,6 +155,13 @@ const TeacherClassDetail = ({ |
156 | 155 | onShowCodeDisplay(selectedClassroom.classroomId); |
157 | 156 | }, [onShowCodeDisplay, selectedClassroom]); |
158 | 157 |
|
| 158 | + const [inviteCopied, setInviteCopied] = useState(false); |
| 159 | + const handleCopyInvite = useCallback(() => { |
| 160 | + onCopyInviteLink(selectedClassroom); |
| 161 | + setInviteCopied(true); |
| 162 | + setTimeout(() => setInviteCopied(false), 2000); |
| 163 | + }, [onCopyInviteLink, selectedClassroom]); |
| 164 | + |
159 | 165 | const handleCloseCode = useCallback(() => { |
160 | 166 | setShowCodeDisplay(false); |
161 | 167 | onCloseCodeDisplay(); |
@@ -241,97 +247,108 @@ const TeacherClassDetail = ({ |
241 | 247 | onBlur={handleAssignmentNameBlur} |
242 | 248 | onChange={handleAssignmentNameChange} |
243 | 249 | /> |
244 | | - {/* Google Classroom linkage now lives on the class |
245 | | - (group), so an assignment posts to the group's |
246 | | - course even when it has no courseId of its own. |
247 | | - The posted/unposted branch below still keys off |
248 | | - the assignment's own alternateLink. */} |
249 | | - {(selectedClassroom.googleClassroomCourseId || |
250 | | - (group && group.googleClassroomCourseId)) && |
251 | | - (selectedClassroom.googleClassroomAlternateLink ? ( |
252 | | - <a |
253 | | - className={ |
254 | | - styles.secondaryButton |
255 | | - } |
256 | | - data-testid="classroom-view-assignment" |
257 | | - href={ |
258 | | - selectedClassroom.googleClassroomAlternateLink |
259 | | - } |
260 | | - rel="noopener noreferrer" |
261 | | - target="_blank" |
262 | | - > |
263 | | - <img |
264 | | - alt="" |
265 | | - className={ |
266 | | - styles.gcImportIcon |
267 | | - } |
268 | | - src={ |
269 | | - googleClassroomIcon |
270 | | - } |
271 | | - /> |
| 250 | + </div> |
| 251 | + |
| 252 | + |
| 253 | + {/* 参加コードカード: コード + 全画面 / 招待リンク / |
| 254 | + Google Classroom に参加コードを共有 をまとめる。 |
| 255 | + 「配信」の何をするか(=参加コードを GC で生徒に |
| 256 | + 配る)が一目でわかるよう文言・配置を整理した。 */} |
| 257 | + <div className={styles.joinCodeCard}> |
| 258 | + <div className={styles.joinCodeRow}> |
| 259 | + <span className={styles.joinCodeLabel}> |
| 260 | + <FormattedMessage |
| 261 | + defaultMessage="Join Code" |
| 262 | + description="Join code label" |
| 263 | + id="gui.classroom.joinCode.label" |
| 264 | + /> |
| 265 | + {': '} |
| 266 | + </span> |
| 267 | + <span |
| 268 | + className={styles.joinCodeValue} |
| 269 | + data-testid="classroom-detail-join-code" |
| 270 | + > |
| 271 | + {selectedClassroom.joinCode.toLowerCase()} |
| 272 | + </span> |
| 273 | + </div> |
| 274 | + <div className={styles.joinCodeActions}> |
| 275 | + <button |
| 276 | + className={styles.joinCodeAction} |
| 277 | + data-testid="classroom-detail-expand-code" |
| 278 | + type="button" |
| 279 | + onClick={handleShowCode} |
| 280 | + > |
| 281 | + {'⛶ '} |
| 282 | + <FormattedMessage |
| 283 | + defaultMessage="Show fullscreen" |
| 284 | + description="Fullscreen the join code" |
| 285 | + id="gui.classroom.joinCode.fullscreen" |
| 286 | + /> |
| 287 | + </button> |
| 288 | + <button |
| 289 | + className={styles.joinCodeAction} |
| 290 | + data-testid="classroom-detail-copy-link" |
| 291 | + type="button" |
| 292 | + onClick={handleCopyInvite} |
| 293 | + > |
| 294 | + {inviteCopied ? ( |
272 | 295 | <FormattedMessage |
273 | | - defaultMessage="View Assignment" |
274 | | - description="View posted assignment on Google Classroom" |
275 | | - id="gui.classroom.postAssignment.viewAssignment" |
276 | | - /> |
277 | | - </a> |
278 | | - ) : ( |
279 | | - <button |
280 | | - className={ |
281 | | - styles.secondaryButton |
282 | | - } |
283 | | - data-testid="classroom-post-assignment" |
284 | | - onClick={ |
285 | | - onShowPostAssignment |
286 | | - } |
287 | | - > |
288 | | - <img |
289 | | - alt="" |
290 | | - className={ |
291 | | - styles.gcImportIcon |
292 | | - } |
293 | | - src={ |
294 | | - googleClassroomIcon |
295 | | - } |
| 296 | + defaultMessage="Copied" |
| 297 | + description="Confirmation after copying invite link" |
| 298 | + id="gui.classroom.codeDisplay.copied" |
296 | 299 | /> |
| 300 | + ) : ( |
297 | 301 | <FormattedMessage |
298 | | - defaultMessage="Post Assignment" |
299 | | - description="Post assignment to Google Classroom" |
300 | | - id="gui.classroom.postAssignment.title" |
| 302 | + defaultMessage="Copy invite link" |
| 303 | + description="Button to copy classroom invite link" |
| 304 | + id="gui.classroom.codeDisplay.copyLink" |
301 | 305 | /> |
302 | | - </button> |
303 | | - ))} |
304 | | - </div> |
305 | | - |
306 | | - |
307 | | - {/* Join code with expand button */} |
308 | | - <div className={styles.joinCodeDisplay}> |
309 | | - <span className={styles.joinCodeLabel}> |
310 | | - <FormattedMessage |
311 | | - defaultMessage="Join Code" |
312 | | - description="Join code label" |
313 | | - id="gui.classroom.joinCode.label" |
314 | | - /> |
315 | | - {': '} |
316 | | - </span> |
317 | | - <span |
318 | | - className={styles.joinCodeValue} |
319 | | - data-testid="classroom-detail-join-code" |
320 | | - > |
321 | | - {selectedClassroom.joinCode.toLowerCase()} |
322 | | - </span> |
323 | | - <button |
324 | | - className={styles.expandIconButton} |
325 | | - data-testid="classroom-detail-expand-code" |
326 | | - onClick={handleShowCode} |
327 | | - title={intl.formatMessage({ |
328 | | - defaultMessage: 'Show fullscreen', |
329 | | - description: 'Tooltip for join code fullscreen button', |
330 | | - id: 'gui.classroom.joinCode.fullscreen', |
331 | | - })} |
332 | | - > |
333 | | - {'⛶'} |
334 | | - </button> |
| 306 | + )} |
| 307 | + </button> |
| 308 | + {/* Google Classroom linkage lives on the class |
| 309 | + (group), so an assignment posts to the group's |
| 310 | + course even without its own courseId. */} |
| 311 | + {(selectedClassroom.googleClassroomCourseId || |
| 312 | + (group && group.googleClassroomCourseId)) && |
| 313 | + (selectedClassroom.googleClassroomAlternateLink ? ( |
| 314 | + <a |
| 315 | + className={classNames(styles.joinCodeAction, styles.joinCodeActionGc)} |
| 316 | + data-testid="classroom-view-assignment" |
| 317 | + href={selectedClassroom.googleClassroomAlternateLink} |
| 318 | + rel="noopener noreferrer" |
| 319 | + target="_blank" |
| 320 | + > |
| 321 | + <img |
| 322 | + alt="" |
| 323 | + className={styles.gcImportIcon} |
| 324 | + src={googleClassroomIcon} |
| 325 | + /> |
| 326 | + <FormattedMessage |
| 327 | + defaultMessage="Open in Google Classroom" |
| 328 | + description="Open the posted assignment on Google Classroom" |
| 329 | + id="gui.classroom.joinCode.openInGc" |
| 330 | + /> |
| 331 | + </a> |
| 332 | + ) : ( |
| 333 | + <button |
| 334 | + className={classNames(styles.joinCodeAction, styles.joinCodeActionGc)} |
| 335 | + data-testid="classroom-post-assignment" |
| 336 | + type="button" |
| 337 | + onClick={onShowPostAssignment} |
| 338 | + > |
| 339 | + <img |
| 340 | + alt="" |
| 341 | + className={styles.gcImportIcon} |
| 342 | + src={googleClassroomIcon} |
| 343 | + /> |
| 344 | + <FormattedMessage |
| 345 | + defaultMessage="Share join code to Google Classroom" |
| 346 | + description="Post the join code to Google Classroom for students" |
| 347 | + id="gui.classroom.joinCode.shareToGc" |
| 348 | + /> |
| 349 | + </button> |
| 350 | + ))} |
| 351 | + </div> |
335 | 352 | </div> |
336 | 353 | {selectedClassroom.expiresAt && ( |
337 | 354 | <div className={styles.expiresAtText}> |
|
0 commit comments