-
Notifications
You must be signed in to change notification settings - Fork 16
feat(fe): change design in duplicate course and add semester #3499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ import { Button } from '@/components/shadcn/button' | |
| import { DUPLICATE_COURSE } from '@/graphql/course/mutation' | ||
| import { useMutation } from '@apollo/client' | ||
| import { useState } from 'react' | ||
| import { useMemo } from 'react' | ||
| import { GoAlertFill } from 'react-icons/go' | ||
| import { IoCopy } from 'react-icons/io5' | ||
| import { toast } from 'sonner' | ||
|
|
@@ -14,11 +15,18 @@ import { useDataTable } from '../../_components/table/context' | |
| interface DuplicateCourseButtonProps { | ||
| onSuccess: () => void | ||
| } | ||
| type CourseRow = { | ||
| id: number | ||
| title: string | ||
| code: string | ||
| semester: string | ||
| studentCount: number | ||
| } | ||
|
|
||
| export function DuplicateCourseButton({ | ||
| onSuccess | ||
| }: DuplicateCourseButtonProps) { | ||
| const { table } = useDataTable<{ id: number; title: string }>() | ||
| const { table } = useDataTable<CourseRow>() | ||
| const [duplicateCourse] = useMutation(DUPLICATE_COURSE) | ||
| const selectedCount = table.getSelectedRowModel().rows.length | ||
| const canDuplicate = selectedCount === 1 | ||
|
|
@@ -29,12 +37,33 @@ export function DuplicateCourseButton({ | |
| const [classNum, setClassNum] = useState('') | ||
|
|
||
| const handleDuplicateButtonClick = () => { | ||
| if (table.getSelectedRowModel().rows.length !== 1) { | ||
| const selectedRows = table.getSelectedRowModel().rows | ||
| if (selectedRows.length !== 1) { | ||
| return | ||
| } | ||
| const selectedCourse = selectedRows[0].original | ||
| console.log('selected Course: ', selectedCourse) | ||
| setCourseNum(selectedCourse.title ?? '') | ||
| setSemester(selectedCourse.semester ?? '') | ||
| setClassNum('') | ||
| setIsDialogOpen(true) | ||
| } | ||
|
|
||
| const classNumError = useMemo(() => { | ||
| if (classNum.trim() === ' ') { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 띄어쓰기 한칸 ' '이렇게 있는게 맞아요 아니면 '' 그냥 붙여쓰는게 맞아요? (진짜 몰라서 물어보는 거임...)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 이 부분은 빈칸인지 확인하는 코드인데 중현님 말씀대로 붙여 쓰는게 맞을 것 같습니다.. 수정할게요! |
||
| return 'Class Number must be entered.' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 근데 이렇게 되면 맨처음 입력하라는 팝업창(?)이 뜨게 되면 아무것도 입력되지 않은 빈상태일텐데 바로 에러 나는거 아니에요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 지금은 classNum 에 초기값이 아무것도 없어서 classNumError 가 활성화 되는 게 맞습니다. 근데, 이게 에러가 난다고 해서 터지거나 하는 게 아니라 단순하게 빨간 글씨로 경고 문구만 생기는 거라 괜찮을 것 같아요!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 근데 초기에 아무값 없는 상태에서 duplicate 버튼을 눌렀을때에만 경고가 떠야하는데, 지금 이 로직이면 classNum을 입력하는 팝업창이 뜨자마자 활성화되는거아니에요?? 아닐 수도 ㅋㅋ
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| if (!/^\d+$/.test(classNum)) { | ||
| return 'Class Number must be an integer between 1 and 99.' | ||
| } | ||
| const parsedClassNum = Number(classNum) | ||
| if (parsedClassNum < 1 || parsedClassNum > 99) { | ||
| return 'Class Number must be an integer between 1 and 99.' | ||
| } | ||
|
|
||
| return '' | ||
| }, [classNum]) | ||
|
|
||
| const handleDuplicateRows = async () => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 지금은 에러가 있어도 복제버튼을 누르면 백엔드 서버로 요청이 날아가지네요 뭔가 방어 코드를 추가해주는 것이 좋을 것 같아요
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 제가 에러가 있으면 복제 버튼이 비활성화 되는 식으로 변경해보도록 하겠습니다. 좋은 지적 감사합니다! |
||
| const selectedRows = table.getSelectedRowModel().rows | ||
|
|
||
|
|
@@ -98,53 +127,75 @@ export function DuplicateCourseButton({ | |
| onClick: handleDuplicateRows | ||
| }} | ||
| > | ||
| <ModalSection | ||
| title="Courses that will be Copied" | ||
| description="Make sure to review the courses that will be duplicated." | ||
| items={[ | ||
| table | ||
| .getSelectedRowModel() | ||
| .rows.map((row) => row.original.title) | ||
| .join(', ') | ||
| ]} | ||
| /> | ||
| <div className="flex h-[37px] w-full items-center gap-[6px] bg-[#FFEBEE] px-[18px] py-[8px]"> | ||
| <GoAlertFill size={16} color="#FF3B2F" /> | ||
| <span className="text-sm text-[#FF3B2F]"> | ||
| Course Info, Assignments and Exercises will be duplicated. | ||
| </span> | ||
| </div> | ||
|
|
||
| <div className="flex flex-col gap-4"> | ||
| <div className="flex flex-col gap-2"> | ||
| <label className="text-sm font-medium">Course Number</label> | ||
| <input | ||
| value={courseNum} | ||
| onChange={(e) => setCourseNum(e.target.value)} | ||
| placeholder="Enter course number" | ||
| className="w-full rounded-md border px-3 py-2 text-sm" | ||
| <div className="max-h-[70vh] w-full min-w-0 overflow-y-auto overflow-x-hidden pr-1"> | ||
| <div className="flex w-full min-w-0 flex-col gap-4"> | ||
| <ModalSection | ||
| title="Courses that will be Copied" | ||
| description="Make sure to review the courses that will be duplicated." | ||
| items={[ | ||
| table | ||
| .getSelectedRowModel() | ||
| .rows.map((row) => row.original.title) | ||
| .join(', ') | ||
| ]} | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="flex flex-col gap-2"> | ||
| <label className="text-sm font-medium">Semester</label> | ||
| <input | ||
| value={semester} | ||
| onChange={(e) => setSemester(e.target.value)} | ||
| placeholder="Enter semester" | ||
| className="w-full rounded-md border px-3 py-2 text-sm" | ||
| /> | ||
| <div className="flex w-full min-w-0 items-start gap-[6px] rounded-md bg-[#FFEBEE] px-[18px] py-[8px]"> | ||
| <GoAlertFill | ||
| size={16} | ||
| color="#FF3B2F" | ||
| className="mt-[2px] shrink-0" | ||
| /> | ||
| <span className="break-words text-sm text-[#FF3B2F]"> | ||
| Course Info, Assignments and Exercises will be duplicated. | ||
| </span> | ||
| </div> | ||
|
|
||
| <div className="flex w-full min-w-0 flex-col gap-4"> | ||
| <div className="flex w-full min-w-0 flex-col gap-2"> | ||
| <label className="text-sm font-medium">Course Number</label> | ||
| <input | ||
| value={courseNum} | ||
| onChange={(e) => setCourseNum(e.target.value)} | ||
| placeholder="Enter course number" | ||
| className="box-border w-full min-w-0 rounded-md border border-gray-300 px-3 py-2 text-sm" | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="flex w-full min-w-0 flex-col gap-2"> | ||
| <label className="text-sm font-medium">Semester</label> | ||
| <input | ||
| value={semester} | ||
| onChange={(e) => setSemester(e.target.value)} | ||
| placeholder="Enter semester" | ||
| className="box-border w-full min-w-0 rounded-md border border-gray-300 px-3 py-2 text-sm" | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="flex w-full min-w-0 flex-col gap-2"> | ||
| <label className="text-sm font-medium">Class Number</label> | ||
| <input | ||
| value={classNum} | ||
| onChange={(e) => setClassNum(e.target.value)} | ||
| placeholder="Enter class number" | ||
| className={`box-border w-full min-w-0 rounded-md border px-3 py-2 text-sm ${ | ||
| classNumError | ||
| ? 'border-red-500 focus:outline-none focus:ring-1 focus:ring-red-500' | ||
| : 'border-gray-300' | ||
| }`} | ||
| /> | ||
|
|
||
| <p | ||
| className={`min-h-[20px] text-sm ${ | ||
| classNumError ? 'text-red-500' : 'invisible' | ||
| }`} | ||
| > | ||
| {classNumError || 'placeholder'} | ||
| </p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <div className="flex flex-col gap-2"> | ||
| <label className="text-sm font-medium">Class Number</label> | ||
| <input | ||
| value={classNum} | ||
| onChange={(e) => setClassNum(e.target.value)} | ||
| placeholder="Enter class number" | ||
| className="w-full rounded-md border px-3 py-2 text-sm" | ||
| /> | ||
| </div> | ||
| </AlertModal> | ||
| ) | ||
| } | ||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
courseNum이랑 semester 입력칸에 빈값 제출하면 어떻게 되나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금은 기본 값으로 복제하려는 원본 코스의 정보를 넣어서 사용자가 일부러 빈 칸으로 만들지 않으면 그렇게 되지는 않지만, 빈 칸일 경우에 별도의 에러 메세지가 출력 되지 않습니다. 이 부분도 수정해서 빈 칸일 때 빨간 메세지가 뜨고, 복제 버튼이 비활성화되는 식으로 조치하도록 하겠습니다.