From 5ebcc66f0e042db4c247044615893b7354807ad7 Mon Sep 17 00:00:00 2001 From: SeieunYoo Date: Sat, 2 Nov 2024 12:10:39 +0900 Subject: [PATCH 01/62] =?UTF-8?q?fix:=20=EB=82=B4=20=ED=95=A0=EC=9D=BC=20a?= =?UTF-8?q?pi=20dto=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/(afterLogin)/my-study/_components/DailyTaskItem.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/client/app/(afterLogin)/my-study/_components/DailyTaskItem.tsx b/apps/client/app/(afterLogin)/my-study/_components/DailyTaskItem.tsx index 53134d0a..4771c665 100644 --- a/apps/client/app/(afterLogin)/my-study/_components/DailyTaskItem.tsx +++ b/apps/client/app/(afterLogin)/my-study/_components/DailyTaskItem.tsx @@ -11,7 +11,7 @@ const DailyTaskItem = ({ index: number; }) => { const { - todoType, + taskType, week, deadLine, attendanceStatus, @@ -20,7 +20,7 @@ const DailyTaskItem = ({ studyDetailId, } = dailyTask; - return todoType === "ATTENDANCE" ? ( + return taskType === "ATTENDANCE" ? ( Date: Sat, 2 Nov 2024 12:15:34 +0900 Subject: [PATCH 02/62] =?UTF-8?q?fix:=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/types/dtos/myStudy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/types/dtos/myStudy.ts b/apps/client/types/dtos/myStudy.ts index df6bba1c..7e445924 100644 --- a/apps/client/types/dtos/myStudy.ts +++ b/apps/client/types/dtos/myStudy.ts @@ -72,7 +72,7 @@ export type StudyCurriculumListDtoType = StudyCurriculumDto[]; export interface DailyTaskDto { studyDetailId: number; week: number; - todoType: T; + taskType: T; deadLine: string; attendanceStatus: T extends "ATTENDANCE" ? AttendanceStatusType : never; assignmentTitle: T extends "ASSIGNMENT" ? string : never; From 868084ba98d1b300f6daa47bf566137062363fca Mon Sep 17 00:00:00 2001 From: SeieunYoo Date: Mon, 4 Nov 2024 00:15:23 +0900 Subject: [PATCH 03/62] =?UTF-8?q?fix:=20CANCELED=20=EB=A1=9C=20=EC=9B=8C?= =?UTF-8?q?=EB=94=A9=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../my-study/_components/StudyCurriculum.tsx | 6 +++--- .../AssignmentHistory/AssignmentHistoryItem.tsx | 10 +++++----- apps/client/types/entities/common/assignment.ts | 2 +- apps/client/types/entities/myStudy.ts | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/client/app/(afterLogin)/my-study/_components/StudyCurriculum.tsx b/apps/client/app/(afterLogin)/my-study/_components/StudyCurriculum.tsx index be631a45..95c455f2 100644 --- a/apps/client/app/(afterLogin)/my-study/_components/StudyCurriculum.tsx +++ b/apps/client/app/(afterLogin)/my-study/_components/StudyCurriculum.tsx @@ -52,7 +52,7 @@ const StudyCurriculum = async () => { color: attendanceStatusColor, } = attendanceStatusMap[ - curriculumStatus === "CANCELLED" ? "ATTENDED" : attendanceStatus + curriculumStatus === "CANCELED" ? "ATTENDED" : attendanceStatus ]; const isAssignmentSubmissionSuccess = @@ -74,7 +74,7 @@ const StudyCurriculum = async () => { const buttonDisabled = !isCurrentWeek || assignmentSubmissionStatus === "FAILURE" || - assignmentStatus === "CANCELLED"; + assignmentStatus === "CANCELED"; const noDescriptionTextColor = description ? "black" : "sub"; @@ -90,7 +90,7 @@ const StudyCurriculum = async () => {
- {curriculumStatus === "CANCELLED" ? ( + {curriculumStatus === "CANCELED" ? ( 휴강 주차 diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx index 2afccd42..6884f2c7 100644 --- a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx @@ -103,8 +103,8 @@ const getTagProps = ( status: AssignmentStatusType, assignmentSubmissionStatus: AssignmentSubmissionStatusType ) => { - if (status === "CANCELLED") { - return assignmentSubmissionMap.CANCELLED; + if (status === "CANCELED") { + return assignmentSubmissionMap.CANCELED; } if ( @@ -113,7 +113,7 @@ const getTagProps = ( ) { return assignmentSubmissionMap[assignmentSubmissionStatus]; } - return assignmentSubmissionMap.CANCELLED; + return assignmentSubmissionMap.CANCELED; }; const weekStyle = css({ @@ -159,10 +159,10 @@ const tagContainerStyle = css({ }); const assignmentSubmissionMap: Record< - "CANCELLED" | "FAILURE" | "SUCCESS", + "CANCELED" | "FAILURE" | "SUCCESS", { tagText: string; tagColor: ComponentProps["color"] } > = { - CANCELLED: { tagText: "과제 휴강", tagColor: "grey" }, + CANCELED: { tagText: "과제 휴강", tagColor: "grey" }, FAILURE: { tagText: "제출 실패", tagColor: "red" }, SUCCESS: { tagText: "제출 완료", tagColor: "blue" }, }; diff --git a/apps/client/types/entities/common/assignment.ts b/apps/client/types/entities/common/assignment.ts index 8558c02a..2182b7f5 100644 --- a/apps/client/types/entities/common/assignment.ts +++ b/apps/client/types/entities/common/assignment.ts @@ -1,5 +1,5 @@ export type AssignmentSubmissionStatusType = "FAILURE" | "SUCCESS" | null; -export type AssignmentStatusType = "NONE" | "OPEN" | "CANCELLED"; +export type AssignmentStatusType = "NONE" | "OPEN" | "CANCELED"; export type AssignmentSubmissionFailureType = | "NONE" | "NOT_SUBMITTED" diff --git a/apps/client/types/entities/myStudy.ts b/apps/client/types/entities/myStudy.ts index d30377c9..675ec38e 100644 --- a/apps/client/types/entities/myStudy.ts +++ b/apps/client/types/entities/myStudy.ts @@ -5,7 +5,7 @@ export type AttendanceStatusType = export type StudyDifficultyType = "BASIC" | "LOW" | "MEDIUM" | "HIGH"; -export type StudyCurriculumStatusType = "NONE" | "OPEN" | "CANCELLED"; +export type StudyCurriculumStatusType = "NONE" | "OPEN" | "CANCELED"; export type DailyTaskType = "ATTENDANCE" | "ASSIGNMENT"; From 10d72198e7fea37876fa8e4152ff6fbb5f6c6323 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sat, 2 Nov 2024 02:12:39 +0900 Subject: [PATCH 04/62] =?UTF-8?q?chore:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=EC=8B=9C=EC=8A=A4=ED=85=9C=200.1.19=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- pnpm-lock.yaml | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e9a1fdac..15f3fa8c 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,6 @@ "clsx": "^2.1.1", "wowds-icons": "^0.1.4", "wowds-tokens": "^0.1.1", - "wowds-ui": "^0.1.16" + "wowds-ui": "^0.1.19" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29eca237..d85ccd67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^0.1.1 version: 0.1.3 wowds-ui: - specifier: ^0.1.16 - version: 0.1.16(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) + specifier: ^0.1.19 + version: 0.1.19(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) devDependencies: '@pandacss/dev': specifier: ^0.44.0 @@ -13476,6 +13476,11 @@ packages: engines: {node: '>= 0.4.0'} dev: true + /uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + dev: false + /uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -13751,6 +13756,10 @@ packages: resolution: {integrity: sha512-2mYkhEOZFNXbkH++osn0Qabni08wa0HkbUjnEQVh8j+cni0Te64ZkF9HbynHk2gj1nrFyD6oOSNsIwnJ1IQqmQ==} dev: false + /wowds-icons@0.1.5: + resolution: {integrity: sha512-F2M4+oL2onugKcDH1yizQiVzwMXWA1+L7KI+ryRmCdmclkguVaxQJpboTAH9M2tVs3PrI3OeDV6Q6rCumzkR9w==} + dev: false + /wowds-theme@0.1.3: resolution: {integrity: sha512-dygJMMwFTVB0A9bo217Y4hD/AMIrAOb0n4G9clz7tz5E1jVdgfippx3LXoXewJeoZuGY4LZejxRBbfg4pAQAxQ==} dev: true @@ -13759,8 +13768,8 @@ packages: resolution: {integrity: sha512-Pej6MuUec/i6A04gWELi4bb/T2I8gf/57L9rX8G7ElVeMc7/03ELoM0nBFWKybtpYExXhhlQPp0Lg7iqATpy6Q==} dev: false - /wowds-ui@0.1.16(next@14.2.5)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-pJM0k67+j1mNjOtxuOWLfSaTs3PKzKKCoUDZ3gUGE8yfwpZr5QgE0vDd8hgGiZweB35+q/5QWO4NPAJKQkPIug==} + /wowds-ui@0.1.19(next@14.2.5)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-N+AF9zLW9Tdipa53tlvcNcZS4oCelWZZsQ1CT6E1QWkF2Bn4mcj+D+KtkZDXJlK67JNlatMzmLmmOJWUHjUI0A==} peerDependencies: next: ^14.1.1 react: ^18.2.0 @@ -13770,7 +13779,8 @@ packages: next: 14.2.5(@babel/core@7.25.2)(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-day-picker: 9.0.8(react@18.3.1) - wowds-icons: 0.1.4 + uuid: 10.0.0 + wowds-icons: 0.1.5 transitivePeerDependencies: - react-dom dev: false From 899423e7c7f1ea0f4e39586c5e324d925a3f223a Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sat, 2 Nov 2024 22:33:29 +0900 Subject: [PATCH 05/62] =?UTF-8?q?feat:=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EB=90=9C=20DTO=20=EB=93=B1=EB=A1=9D(StudyStu?= =?UTF-8?q?dentApiResponseDto,=20PageStudyStudentApiResponseDto)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/types/dtos/studyStudent.ts | 52 +++++++++++++++++++++++++++ apps/admin/types/entities/page.ts | 22 ++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 apps/admin/types/entities/page.ts diff --git a/apps/admin/types/dtos/studyStudent.ts b/apps/admin/types/dtos/studyStudent.ts index f9867939..c9fecb8a 100644 --- a/apps/admin/types/dtos/studyStudent.ts +++ b/apps/admin/types/dtos/studyStudent.ts @@ -1,3 +1,5 @@ +import type { PageableObject, SortType } from "types/entities/page"; + export interface StudyStudentApiResponseDto { memberId: number; name: string; @@ -5,4 +7,54 @@ export interface StudyStudentApiResponseDto { discordUsername: string; nickname: string; githubLink: string; + studyHistoryStatus: "NONE" | "COMPLETED"; + isFirstRoundOutstandingStudent: boolean; + isSecondRoundOutstandingStudent: boolean; + studyTasks: StudyTaskResponseDto<"ATTENDANCE" | "ASSIGNMENT">[]; + assignmentRate: number; + attendanceRate: number; } + +export interface PageStudyStudentApiResponseDto { + totalElements: number; + totalPages: number; + size: number; + content: StudyStudentApiResponseDto[]; + number: number; + sort: SortType; + numberOfElements: number; + pageable: PageableObject; + first: boolean; + last: boolean; + empty: boolean; +} + +export interface StudyTaskResponseDtoBase { + studyDetailId: number; + week: number; + deadLine: string; + assignment: boolean; + attendance: boolean; +} + +export interface AttendanceTask extends StudyTaskResponseDtoBase { + taskType: "ATTENDANCE"; + attendanceStatus: + | "ATTENDED" + | "NOT_ATTENDED" + | "BEFORE_ATTENDANCE" + | "CANCELED"; +} + +export interface AssignmentTask extends StudyTaskResponseDtoBase { + taskType: "ASSIGNMENT"; + assignmentTitle: string; + assignmentSubmissionStatus: + | "NOT_SUBMITTED" + | "FAILURE" + | "SUCCESS" + | "CANCELED"; +} + +export type StudyTaskResponseDto = + T extends "ATTENDANCE" ? AttendanceTask : AssignmentTask; diff --git a/apps/admin/types/entities/page.ts b/apps/admin/types/entities/page.ts new file mode 100644 index 00000000..f6118f08 --- /dev/null +++ b/apps/admin/types/entities/page.ts @@ -0,0 +1,22 @@ +export type SortType = { + empty: boolean; + sorted: boolean; + unsorted: boolean; +}; + +export type PageableType = { + page: number; + size: number; + sort: []; +}; + +export type PageableObject = { + pageable: { + offset: number; + sort: SortType; + pageNumber: number; + pageSize: number; + unpaged: boolean; + paged: boolean; + }; +}; From 9f6fa7671b6aafb76ae55dbf4ca552c88accd285 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sat, 2 Nov 2024 22:42:52 +0900 Subject: [PATCH 06/62] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=9E=84=EC=8B=9C=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/apis/study/studyApi.ts | 10 +++++++--- apps/admin/hooks/fetch/useFetchStudents.ts | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/apps/admin/apis/study/studyApi.ts b/apps/admin/apis/study/studyApi.ts index bbd4d1b8..8c80a745 100644 --- a/apps/admin/apis/study/studyApi.ts +++ b/apps/admin/apis/study/studyApi.ts @@ -9,7 +9,8 @@ import type { import type { AttendanceApiResponseDto } from "types/dtos/attendance"; import type { CurriculumApiResponseDto } from "types/dtos/curriculumList"; import type { StudyBasicInfoApiResponseDto } from "types/dtos/studyBasicInfo"; -import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; +import type { PageStudyStudentApiResponseDto } from "types/dtos/studyStudent"; +import type { PageableType } from "types/entities/page"; import type { StudyAnnouncementType } from "types/entities/study"; import type { StudyListApiResponseDto } from "../../types/dtos/studyList"; @@ -149,12 +150,15 @@ export const studyApi = { ); return response.data; }, - getStudyStudents: async (studyId: number) => { - const response = await fetcher.get( + getStudyStudents: async (studyId: number, pageable: PageableType) => { + const response = await fetcher.get( `/mentor/studies/${studyId}/students`, { next: { tags: [tags.students] }, cache: "force-cache", + }, + { + params: pageable, } ); return response.data; diff --git a/apps/admin/hooks/fetch/useFetchStudents.ts b/apps/admin/hooks/fetch/useFetchStudents.ts index c35eecdb..51fd70ec 100644 --- a/apps/admin/hooks/fetch/useFetchStudents.ts +++ b/apps/admin/hooks/fetch/useFetchStudents.ts @@ -14,8 +14,12 @@ const useFetchStudents = ( useEffect(() => { const fetchStudentsData = async () => { if (study) { - const studentsData = await studyApi.getStudyStudents(study.studyId); - if (studentsData) setStudentList(studentsData); + const studentsData = await studyApi.getStudyStudents(study.studyId, { + page: 1, + size: 1, + sort: [], + }); + if (studentsData) setStudentList(studentsData.content); } }; From 1aa4973dd553be906da2d4f972dfe31729816480 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 17:03:44 +0900 Subject: [PATCH 07/62] =?UTF-8?q?feat:=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C=EC=8A=A4=ED=85=9C=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentList.tsx | 73 ++++++++++--------- .../students/_components/StudentListItem.tsx | 51 ------------- 2 files changed, 39 insertions(+), 85 deletions(-) delete mode 100644 apps/admin/app/students/_components/StudentListItem.tsx diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index 652ef925..bbfb47ba 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -1,9 +1,9 @@ -import { css } from "@styled-system/css"; -import { styled } from "@styled-system/jsx"; import { Text } from "@wow-class/ui"; +import Link from "next/link"; +import type { CSSProperties } from "react"; import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; - -import StudentListItem from "./StudentListItem"; +import Table from "wowds-ui/Table"; +import TextButton from "wowds-ui/TextButton"; const StudentList = ({ studentList, @@ -13,38 +13,43 @@ const StudentList = ({ if (!studentList.length) return 스터디 수강생이 없어요.; return ( - - - - - 이름 - - - 학번 - - - 디스코드 사용자명 - - - 디스코드 닉네임 - - - 깃허브 링크 - - - - - {studentList.map((student) => ( - - ))} - - + + + 이름 + 학번 + 디스코드 사용자명 + 디스코드 닉네임 + 깃허브 링크 + + + {studentList.map((student) => { + const { name, studentId, discordUsername, nickname, githubLink } = + student; + return ( + + {name} + {studentId} + {discordUsername} + {nickname} + + + + + ); + })} + +
); }; -const tableThStyle = css({ - padding: "1rem", - textAlign: "left", -}); +const textButtonStyle: CSSProperties = { + width: "fit-content", + padding: 0, +}; export default StudentList; diff --git a/apps/admin/app/students/_components/StudentListItem.tsx b/apps/admin/app/students/_components/StudentListItem.tsx deleted file mode 100644 index d4f00256..00000000 --- a/apps/admin/app/students/_components/StudentListItem.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { css } from "@styled-system/css"; -import { styled } from "@styled-system/jsx"; -import { Text } from "@wow-class/ui"; -import Link from "next/link"; -import type { CSSProperties } from "react"; -import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; -import TextButton from "wowds-ui/TextButton"; - -const StudentListItem = ({ - name, - studentId, - discordUsername, - nickname, - githubLink, -}: StudyStudentApiResponseDto) => { - return ( - - - {name} - - - {studentId} - - - {discordUsername} - - - {nickname} - - - - - - ); -}; - -const tableThStyle = css({ - padding: "1rem", -}); - -const textButtonStyle: CSSProperties = { - width: "fit-content", - padding: 0, -}; - -export default StudentListItem; From 528b4c918dcd5ae71b2233697d47f355552e8999 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 18:10:48 +0900 Subject: [PATCH 08/62] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/StudentPagination.tsx | 20 ++++++++++++ apps/admin/app/students/page.tsx | 14 +++++++-- apps/admin/hooks/fetch/useFetchStudents.ts | 31 ++++++++++++++----- 3 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 apps/admin/app/students/_components/StudentPagination.tsx diff --git a/apps/admin/app/students/_components/StudentPagination.tsx b/apps/admin/app/students/_components/StudentPagination.tsx new file mode 100644 index 00000000..4d7bebb6 --- /dev/null +++ b/apps/admin/app/students/_components/StudentPagination.tsx @@ -0,0 +1,20 @@ +import type { PageStudyStudentApiResponseDto } from "types/dtos/studyStudent"; +import Pagination from "wowds-ui/Pagination"; + +const StudentPagination = ({ + pageInfo, + handleClickChangePage, +}: { + pageInfo: Omit; + handleClickChangePage: (nextPage: number) => void; +}) => { + if (!pageInfo || !pageInfo.numberOfElements) return null; + return ( + + ); +}; + +export default StudentPagination; diff --git a/apps/admin/app/students/page.tsx b/apps/admin/app/students/page.tsx index 0d957d08..deb38b9d 100644 --- a/apps/admin/app/students/page.tsx +++ b/apps/admin/app/students/page.tsx @@ -10,6 +10,7 @@ import type { StudyListApiResponseDto } from "types/dtos/studyList"; import isAdmin from "utils/isAdmin"; import StudentList from "./_components/StudentList"; +import StudentPagination from "./_components/StudentPagination"; import StudentsHeader from "./_components/StudentsHeader"; import { studyAtom } from "./_contexts/StudyProvider"; @@ -33,13 +34,22 @@ const StudentsPage = () => { fetchData(); }, [setSelectedStudy]); - const student = useFetchStudents(selectedStudy); + const [page, setPage] = useState(1); + const handleClickChangePage = (nextPage: number) => { + setPage(nextPage); + }; + + const { studentList, pageInfo } = useFetchStudents(selectedStudy, page); if (!studyList) return 담당한 스터디가 없어요.; return ( - + + ); }; diff --git a/apps/admin/hooks/fetch/useFetchStudents.ts b/apps/admin/hooks/fetch/useFetchStudents.ts index 51fd70ec..45dd2f9c 100644 --- a/apps/admin/hooks/fetch/useFetchStudents.ts +++ b/apps/admin/hooks/fetch/useFetchStudents.ts @@ -1,32 +1,47 @@ import { studyApi } from "apis/study/studyApi"; import { useEffect, useState } from "react"; -import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; +import type { + PageStudyStudentApiResponseDto, + StudyStudentApiResponseDto, +} from "types/dtos/studyStudent"; import type { StudyAtomprops } from "@/students/_contexts/StudyProvider"; +const PAGE_SIZE = 10; + const useFetchStudents = ( - study: StudyAtomprops | undefined -): { studentList: StudyStudentApiResponseDto[] | [] } => { + study: StudyAtomprops | undefined, + page: number +): { + studentList: StudyStudentApiResponseDto[] | []; + pageInfo: Omit; +} => { const [studentList, setStudentList] = useState< StudyStudentApiResponseDto[] | [] >([]); + const [pageInfo, setPageInfo] = + useState>(null); useEffect(() => { const fetchStudentsData = async () => { if (study) { const studentsData = await studyApi.getStudyStudents(study.studyId, { - page: 1, - size: 1, + page: page, + size: PAGE_SIZE, sort: [], }); - if (studentsData) setStudentList(studentsData.content); + if (studentsData) { + const { content, ...rest } = studentsData; + setStudentList(content); + setPageInfo(rest); + } } }; fetchStudentsData(); - }, [study]); + }, [study, page]); - return { studentList }; + return { studentList, pageInfo }; }; export default useFetchStudents; From c49175d255a7e0312caec6ec78d5518703a201d3 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 19:10:25 +0900 Subject: [PATCH 09/62] =?UTF-8?q?feat:=20=EC=9A=B0=EC=88=98=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=20=EB=B0=B0=EC=A7=80=20AwardIcon=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/src/components/AwardIcon/index.tsx | 69 ++ packages/ui/src/components/index.ts | 1 + packages/ui/src/styles.css | 847 +----------------- 3 files changed, 71 insertions(+), 846 deletions(-) create mode 100644 packages/ui/src/components/AwardIcon/index.tsx diff --git a/packages/ui/src/components/AwardIcon/index.tsx b/packages/ui/src/components/AwardIcon/index.tsx new file mode 100644 index 00000000..720e687b --- /dev/null +++ b/packages/ui/src/components/AwardIcon/index.tsx @@ -0,0 +1,69 @@ +const AwardIcon = ({ disabled = true }: { disabled?: boolean }) => { + return ( + + + + + + + {disabled ? ( + + + + + + ) : ( + + + + + + + + + + + + + + )} + + ); +}; + +export default AwardIcon; diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index f30b81fb..5ca7f29e 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -1,3 +1,4 @@ +export { default as AwardIcon } from "./AwardIcon"; export { default as Header } from "./Header"; export { default as Modal } from "./Modal"; export { default as NavItem } from "./NavItem"; diff --git a/packages/ui/src/styles.css b/packages/ui/src/styles.css index c9711fe5..906ebd06 100644 --- a/packages/ui/src/styles.css +++ b/packages/ui/src/styles.css @@ -1,846 +1 @@ -:host, -html { - --font-fallback: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, - "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - -webkit-text-size-adjust: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -moz-tab-size: 4; - tab-size: 4; - -webkit-tap-highlight-color: transparent; - line-height: 1.5; - font-family: var(--global-font-body, var(--font-fallback)); -} -*, -::backdrop, -::file-selector-button, -:after, -:before { - margin: 0px; - padding: 0px; - box-sizing: border-box; - border-width: 0px; - border-style: solid; - border-color: var(--global-color-border, currentColor); -} -hr { - height: 0px; - color: inherit; - border-top-width: 1px; -} -body { - height: 100%; - line-height: inherit; -} -img { - border-style: none; -} -audio, -canvas, -embed, -iframe, -img, -object, -svg, -video { - display: block; - vertical-align: middle; -} -img, -video { - max-width: 100%; - height: auto; -} -h1, -h2, -h3, -h4, -h5, -h6 { - text-wrap: balance; - font-size: inherit; - font-weight: inherit; -} -h1, -h2, -h3, -h4, -h5, -h6, -p { - overflow-wrap: break-word; -} -menu, -ol, -ul { - list-style: none; -} -::file-selector-button, -button, -input:where([type="button"], [type="reset"], [type="submit"]) { - appearance: button; - -webkit-appearance: button; -} -::file-selector-button, -button, -input, -optgroup, -select, -textarea { - font: inherit; - font-feature-settings: inherit; - font-variation-settings: inherit; - letter-spacing: inherit; - color: inherit; - background: transparent; -} -::placeholder { - opacity: 1; - --placeholder-fallback: color-mix(in srgb, currentColor 50%, transparent); - color: var(--global-color-placeholder, var(--placeholder-fallback)); -} -textarea { - resize: vertical; -} -table { - text-indent: 0px; - border-collapse: collapse; - border-color: inherit; -} -summary { - display: list-item; -} -small { - font-size: 80%; -} -sub, -sup { - position: relative; - vertical-align: baseline; - font-size: 75%; - line-height: 0; -} -sub { - bottom: -0.25em; -} -sup { - top: -0.5em; -} -dialog { - padding: 0px; -} -a { - color: inherit; - text-decoration: inherit; -} -abbr:where([title]) { - text-decoration: underline dotted; -} -b, -strong { - font-weight: bolder; -} -code, -kbd, -pre, -samp { - --font-mono-fallback: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, - "Liberation Mono", "Courier New"; - font-feature-settings: normal; - font-variation-settings: normal; - font-family: var(--global-font-mono, var(--font-mono-fallback)); - font-size: 1em; -} -progress { - vertical-align: baseline; -} -::-webkit-search-cancel-button, -::-webkit-search-decoration { - -webkit-appearance: none; -} -::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; -} -:-moz-ui-invalid { - box-shadow: none; -} -:-moz-focusring { - outline: auto; -} -[hidden]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - display: none !important; -} -:where(:root, :host):not(#\#):not(#\#) { - --colors-red-50: #fdeceb; - --colors-red-100: #fbd9d7; - --colors-red-150: #f9c7c2; - --colors-red-200: #f7b4ae; - --colors-red-300: #f28e86; - --colors-red-400: #ee695d; - --colors-red-500: #ea4335; - --colors-red-600: #bb362a; - --colors-red-700: #8c2820; - --colors-red-800: #5e1b15; - --colors-red-850: #461410; - --colors-red-900: #2f0d0b; - --colors-red-950: #170705; - --colors-blue-50: #ebf4fe; - --colors-blue-100: #d7e9fd; - --colors-blue-150: #c3ddfd; - --colors-blue-200: #afd2fc; - --colors-blue-300: #86bcfa; - --colors-blue-400: #5ea5f9; - --colors-blue-500: #368ff7; - --colors-blue-600: #2b72c6; - --colors-blue-700: #205694; - --colors-blue-800: #163963; - --colors-blue-850: #102b4a; - --colors-blue-900: #0b1d31; - --colors-blue-950: #050e19; - --colors-yellow-50: #fef7e6; - --colors-yellow-100: #feeecc; - --colors-yellow-150: #fde6b3; - --colors-yellow-200: #fddd99; - --colors-yellow-300: #fbcd66; - --colors-yellow-400: #fabc33; - --colors-yellow-500: #f9ab00; - --colors-yellow-600: #c78900; - --colors-yellow-700: #956700; - --colors-yellow-800: #644400; - --colors-yellow-850: #4b3300; - --colors-yellow-900: #322200; - --colors-yellow-950: #191100; - --colors-green-50: #ebf6ee; - --colors-green-100: #d6eedd; - --colors-green-150: #c2e5cb; - --colors-green-200: #aedcba; - --colors-green-300: #85cb98; - --colors-green-400: #5db975; - --colors-green-500: #34a853; - --colors-green-600: #2a8642; - --colors-green-700: #1f6532; - --colors-green-800: #154321; - --colors-green-850: #103219; - --colors-green-900: #0a2211; - --colors-green-950: #051108; - --colors-mono-50: #f7f7f7; - --colors-mono-100: #f0f0f0; - --colors-mono-150: #e8e8e8; - --colors-mono-200: #e1e1e1; - --colors-mono-300: #d1d1d1; - --colors-mono-400: #c2c2c2; - --colors-mono-500: #b3b3b3; - --colors-mono-600: #8f8f8f; - --colors-mono-700: #6b6b6b; - --colors-mono-800: #484848; - --colors-mono-900: #242424; - --colors-mono-950: #121212; - --colors-white: #ffffff; - --colors-black: #000000; - --spacing-xl: 1.5rem; - --radii-md: 0.5rem; - --border-widths-button: 1px; - --shadows-mono: 0px 4px 8px 0px rgba(0, 0, 0, 0.2); - --colors-primary: #368ff7; - --colors-success: #2a8642; - --colors-error: #bb362a; - --colors-background-normal: #ffffff; - --colors-background-alternative: #f7f7f7; - --colors-background-dimmer: rgba(0, 0, 0, 0.8); - --colors-sub: #6b6b6b; - --colors-outline: #c2c2c2; - --colors-text-black: #121212; - --colors-text-white: #ffffff; - --colors-dark-disabled: #c2c2c2; - --colors-light-disabled: #e1e1e1; - --colors-blue-hover: #2b72c6; - --colors-mono-hover: #121212; - --colors-elevated-hover: rgba(16, 43, 74, 0.2); - --colors-blue-pressed: #5ea5f9; - --colors-blue-background-pressed: #ebf4fe; - --colors-mono-background-pressed: #f7f7f7; - --colors-shadow-small: rgba(0, 0, 0, 0.1); - --colors-shadow-medium: rgba(0, 0, 0, 0.2); - --colors-blue-shadow: rgba(16, 43, 74, 0.2); - --colors-discord: #5566fb; - --colors-github: #000000; - --colors-secondary-yellow: #f9ab00; - --colors-secondary-green: #34a853; - --colors-secondary-red: #ea4335; - --colors-error-background: #fbd9d7; - --colors-blue-disabled: #d7e9fd; - --colors-text-blue-disabled: #afd2fc; -} -.textStyle_body1:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.01rem; - font-size: 1rem; - line-height: 160%; - font-weight: 500; -} -.textStyle_body0:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.01125rem; - font-size: 1.125rem; - line-height: 160%; - font-weight: 500; -} -.textStyle_body2:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.00875rem; - font-size: 0.875rem; - line-height: 160%; - font-weight: 500; -} -.textStyle_body3:not(#\#):not(#\#):not(#\#):not(#\#) { - font-size: 0.75rem; - line-height: 140%; - font-weight: 500; -} -.textStyle_display1:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.025rem; - font-size: 2.5rem; - line-height: 130%; - font-weight: 700; -} -.textStyle_display2:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.02rem; - font-size: 2rem; - line-height: 130%; - font-weight: 700; -} -.textStyle_h1:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.015rem; - font-size: 1.5rem; - line-height: 130%; - font-weight: 600; -} -.textStyle_h2:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.01125rem; - font-size: 1.125rem; - line-height: 130%; - font-weight: 600; -} -.textStyle_h3:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.01rem; - font-size: 1rem; - line-height: 130%; - font-weight: 600; -} -.textStyle_label1:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.01rem; - font-size: 1rem; - line-height: 100%; - font-weight: 600; -} -.textStyle_label2:not(#\#):not(#\#):not(#\#):not(#\#) { - letter-spacing: -0.01rem; - font-size: 0.875rem; - line-height: 100%; - font-weight: 600; -} -.textStyle_label3:not(#\#):not(#\#):not(#\#):not(#\#) { - font-size: 0.75rem; - line-height: 100%; - font-weight: 600; -} -.h_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 24px; -} -.w_49:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 49px; -} -.w_100vw:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 100vw; -} -.h_54px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 54px; -} -.d_flex:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - display: flex; -} -.gap_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - gap: 8px; -} -.w_956px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 956px; -} -.px_16px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - padding-inline: 16px; -} -.cursor_pointer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - cursor: pointer; -} -.w_49px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 49px; -} -.h_24px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 24px; -} -.c_primary:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-primary); -} -.w_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 24px; -} -.w_40\.75rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 40.75rem; -} -.h_28\.125rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 28.125rem; -} -.pos_relative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - position: relative; -} -.bdr_md:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - border-radius: var(--radii-md); -} -.bx-sh_mono:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - box-shadow: var(--shadows-mono); -} -.h_100vh:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 100vh; -} -.pos_fixed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - position: fixed; -} -.z_9999:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - z-index: 9999; -} -.bg_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - background: var(--colors-background-dimmer); -} -.pos_absolute:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - position: absolute; -} -.li-s_none:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - list-style: none; -} -.h_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 20px; -} -.w_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 20px; -} -.gap_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - gap: 12px; -} -.p_11px_18px_11px_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - padding: 11px 18px 11px 20px; -} -.bg_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - background: var(--colors-mono-background-pressed); -} -.bg_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - background: var(--colors-white); -} -.w_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 20px; -} -.h_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 20px; -} -.h_80px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - height: 80px; -} -.w_100\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - width: 100%; -} -.c_textBlack:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-text-black); -} -.c_blue\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-50); -} -.c_blue\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-100); -} -.c_blue\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-150); -} -.c_blue\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-200); -} -.c_blue\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-300); -} -.c_blue\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-400); -} -.c_blue\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-500); -} -.c_blue\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-600); -} -.c_blue\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-700); -} -.c_blue\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-800); -} -.c_blue\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-850); -} -.c_blue\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-900); -} -.c_blue\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-950); -} -.c_yellow\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-50); -} -.c_yellow\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-100); -} -.c_yellow\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-150); -} -.c_yellow\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-200); -} -.c_yellow\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-300); -} -.c_yellow\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-400); -} -.c_yellow\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-500); -} -.c_yellow\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-600); -} -.c_yellow\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-700); -} -.c_yellow\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-800); -} -.c_yellow\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-850); -} -.c_yellow\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-900); -} -.c_yellow\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-yellow-950); -} -.c_green\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-50); -} -.c_green\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-100); -} -.c_green\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-150); -} -.c_green\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-200); -} -.c_green\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-300); -} -.c_green\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-400); -} -.c_green\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-500); -} -.c_green\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-600); -} -.c_green\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-700); -} -.c_green\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-800); -} -.c_green\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-850); -} -.c_green\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-900); -} -.c_green\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-green-950); -} -.c_red\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-50); -} -.c_red\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-100); -} -.c_red\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-150); -} -.c_red\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-200); -} -.c_red\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-300); -} -.c_red\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-400); -} -.c_red\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-500); -} -.c_red\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-600); -} -.c_red\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-700); -} -.c_red\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-800); -} -.c_red\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-850); -} -.c_red\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-900); -} -.c_red\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-red-950); -} -.c_mono\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-50); -} -.c_mono\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-100); -} -.c_mono\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-150); -} -.c_mono\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-200); -} -.c_mono\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-300); -} -.c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-400); -} -.c_mono\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-500); -} -.c_mono\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-600); -} -.c_mono\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-700); -} -.c_mono\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-800); -} -.c_mono\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: mono.850; -} -.c_mono\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-900); -} -.c_mono\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-950); -} -.c_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-white); -} -.c_black:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-black); -} -.c_whiteOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: whiteOpacity.20; -} -.c_whiteOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: whiteOpacity.40; -} -.c_whiteOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: whiteOpacity.60; -} -.c_whiteOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: whiteOpacity.80; -} -.c_blackOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: blackOpacity.20; -} -.c_blackOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: blackOpacity.40; -} -.c_blackOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: blackOpacity.60; -} -.c_blackOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: blackOpacity.80; -} -.c_success:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-success); -} -.c_error:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-error); -} -.c_backgroundNormal:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-background-normal); -} -.c_backgroundAlternative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-background-alternative); -} -.c_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-background-dimmer); -} -.c_errorBackground:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-error-background); -} -.c_sub:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-sub); -} -.c_outline:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-outline); -} -.c_textWhite:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-text-white); -} -.c_darkDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-dark-disabled); -} -.c_lightDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-light-disabled); -} -.c_blueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-disabled); -} -.c_textBlueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-text-blue-disabled); -} -.c_blueHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-hover); -} -.c_monoHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-hover); -} -.c_elevatedHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-elevated-hover); -} -.c_bluePressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-pressed); -} -.c_blueBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-background-pressed); -} -.c_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-mono-background-pressed); -} -.c_shadowSmall:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-shadow-small); -} -.c_shadowMedium:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-shadow-medium); -} -.c_blueShadow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-blue-shadow); -} -.c_discord:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-discord); -} -.c_github:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-github); -} -.c_secondaryYellow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-secondary-yellow); -} -.c_secondaryGreen:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-secondary-green); -} -.c_secondaryRed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: var(--colors-secondary-red); -} -.c_blueGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: blueGradientDark; -} -.c_blueGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: blueGradientLight; -} -.c_redGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: redGradientDark; -} -.c_redGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: redGradientLight; -} -.c_greenGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: greenGradientDark; -} -.c_greenGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: greenGradientLight; -} -.c_yellowGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: yellowGradientDark; -} -.c_yellowGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - color: yellowGradientLight; -} -.bd-b-w_button:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - border-bottom-width: var(--border-widths-button); -} -.bd-b-c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - border-bottom-color: var(--colors-mono-400); -} -.border-bottom-style_solid:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - border-bottom-style: solid; -} -.ai_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - align-items: center; -} -.jc_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - justify-content: center; -} -.ff_Product_Sans:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - font-family: Product Sans; -} -.fw_700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - font-weight: 700; -} -.fs_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - font-size: 20px; -} -.lh_130\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - line-height: 130%; -} -.fw_400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - font-weight: 400; -} -.fs_14px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - font-size: 14px; -} -.flex-d_column:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - flex-direction: column; -} -.top_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - top: 0; -} -.left_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - left: 0; -} -.top_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - top: var(--spacing-xl); -} -.right_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - right: var(--spacing-xl); -} -.mr_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - margin-right: 8px; -} -.ml_auto:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - margin-left: auto; -} -.jc_space-between:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - justify-content: space-between; -} -.mb_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - margin-bottom: 12px; -} -.jc_flex-start:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - justify-content: flex-start; -} -.jc_flex-end:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { - justify-content: flex-end; -} +:host,html{--font-fallback:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent;line-height:1.5;font-family:var(--global-font-body,var(--font-fallback))}*,::backdrop,::file-selector-button,:after,:before{margin:0px;padding:0px;box-sizing:border-box;border-width:0px;border-style:solid;border-color:var(--global-color-border,currentColor)}hr{height:0px;color:inherit;border-top-width:1px}body{height:100%;line-height:inherit}img{border-style:none}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}h1,h2,h3,h4,h5,h6{text-wrap:balance;font-size:inherit;font-weight:inherit}h1,h2,h3,h4,h5,h6,p{overflow-wrap:break-word}menu,ol,ul{list-style:none}::file-selector-button,button,input:where([type=button],[type=reset],[type=submit]){appearance:button;-webkit-appearance:button}::file-selector-button,button,input,optgroup,select,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;background:transparent}::placeholder{opacity:1;--placeholder-fallback:color-mix(in srgb,currentColor 50%,transparent);color:var(--global-color-placeholder,var(--placeholder-fallback))}textarea{resize:vertical}table{text-indent:0px;border-collapse:collapse;border-color:inherit}summary{display:list-item}small{font-size:80%}sub,sup{position:relative;vertical-align:baseline;font-size:75%;line-height:0}sub{bottom:-0.25em}sup{top:-0.5em}dialog{padding:0px}a{color:inherit;text-decoration:inherit}abbr:where([title]){text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{--font-mono-fallback:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New';font-feature-settings:normal;font-variation-settings:normal;font-family:var(--global-font-mono,var(--font-mono-fallback));font-size:1em}progress{vertical-align:baseline}::-webkit-search-cancel-button,::-webkit-search-decoration{-webkit-appearance:none}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}:-moz-ui-invalid{box-shadow:none}:-moz-focusring{outline:auto}[hidden]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){display:none!important}:where(:root,:host):not(#\#):not(#\#){--colors-red-50:#FDECEB;--colors-red-100:#FBD9D7;--colors-red-150:#F9C7C2;--colors-red-200:#F7B4AE;--colors-red-300:#F28E86;--colors-red-400:#EE695D;--colors-red-500:#EA4335;--colors-red-600:#BB362A;--colors-red-700:#8C2820;--colors-red-800:#5E1B15;--colors-red-850:#461410;--colors-red-900:#2F0D0B;--colors-red-950:#170705;--colors-blue-50:#EBF4FE;--colors-blue-100:#D7E9FD;--colors-blue-150:#C3DDFD;--colors-blue-200:#AFD2FC;--colors-blue-300:#86BCFA;--colors-blue-400:#5EA5F9;--colors-blue-500:#368FF7;--colors-blue-600:#2B72C6;--colors-blue-700:#205694;--colors-blue-800:#163963;--colors-blue-850:#102B4A;--colors-blue-900:#0B1D31;--colors-blue-950:#050E19;--colors-yellow-50:#FEF7E6;--colors-yellow-100:#FEEECC;--colors-yellow-150:#FDE6B3;--colors-yellow-200:#FDDD99;--colors-yellow-300:#FBCD66;--colors-yellow-400:#FABC33;--colors-yellow-500:#F9AB00;--colors-yellow-600:#C78900;--colors-yellow-700:#956700;--colors-yellow-800:#644400;--colors-yellow-850:#4B3300;--colors-yellow-900:#322200;--colors-yellow-950:#191100;--colors-green-50:#EBF6EE;--colors-green-100:#D6EEDD;--colors-green-150:#C2E5CB;--colors-green-200:#AEDCBA;--colors-green-300:#85CB98;--colors-green-400:#5DB975;--colors-green-500:#34A853;--colors-green-600:#2A8642;--colors-green-700:#1F6532;--colors-green-800:#154321;--colors-green-850:#103219;--colors-green-900:#0A2211;--colors-green-950:#051108;--colors-mono-50:#F7F7F7;--colors-mono-100:#F0F0F0;--colors-mono-150:#E8E8E8;--colors-mono-200:#E1E1E1;--colors-mono-300:#D1D1D1;--colors-mono-400:#C2C2C2;--colors-mono-500:#B3B3B3;--colors-mono-600:#8F8F8F;--colors-mono-700:#6B6B6B;--colors-mono-800:#484848;--colors-mono-900:#242424;--colors-mono-950:#121212;--colors-white:#FFFFFF;--colors-black:#000000;--spacing-xl:1.5rem;--radii-md:0.5rem;--border-widths-button:1px;--shadows-mono:0px 4px 8px 0px rgba(0,0,0,0.2);--colors-primary:#368FF7;--colors-success:#2A8642;--colors-error:#BB362A;--colors-background-normal:#FFFFFF;--colors-background-alternative:#F7F7F7;--colors-background-dimmer:rgba(0,0,0,0.8);--colors-sub:#6B6B6B;--colors-outline:#C2C2C2;--colors-text-black:#121212;--colors-text-white:#FFFFFF;--colors-dark-disabled:#C2C2C2;--colors-light-disabled:#E1E1E1;--colors-blue-hover:#2B72C6;--colors-mono-hover:#121212;--colors-elevated-hover:rgba(16,43,74,0.2);--colors-blue-pressed:#5EA5F9;--colors-blue-background-pressed:#EBF4FE;--colors-mono-background-pressed:#F7F7F7;--colors-shadow-small:rgba(0,0,0,0.1);--colors-shadow-medium:rgba(0,0,0,0.2);--colors-blue-shadow:rgba(16,43,74,0.2);--colors-discord:#5566FB;--colors-github:#000000;--colors-secondary-yellow:#F9AB00;--colors-secondary-green:#34A853;--colors-secondary-red:#EA4335;--colors-error-background:#FBD9D7;--colors-blue-disabled:#D7E9FD;--colors-text-blue-disabled:#AFD2FC}.textStyle_body1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:1rem;line-height:160%;font-weight:500}.textStyle_body0:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01125rem;font-size:1.125rem;line-height:160%;font-weight:500}.textStyle_body2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.00875rem;font-size:0.875rem;line-height:160%;font-weight:500}.textStyle_body3:not(#\#):not(#\#):not(#\#):not(#\#){font-size:0.75rem;line-height:140%;font-weight:500}.textStyle_display1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.025rem;font-size:2.5rem;line-height:130%;font-weight:700}.textStyle_display2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.02rem;font-size:2rem;line-height:130%;font-weight:700}.textStyle_h1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.015rem;font-size:1.5rem;line-height:130%;font-weight:600}.textStyle_h2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01125rem;font-size:1.125rem;line-height:130%;font-weight:600}.textStyle_h3:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:1rem;line-height:130%;font-weight:600}.textStyle_label1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:1rem;line-height:100%;font-weight:600}.textStyle_label2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:0.875rem;line-height:100%;font-weight:600}.textStyle_label3:not(#\#):not(#\#):not(#\#):not(#\#){font-size:0.75rem;line-height:100%;font-weight:600}.h_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:24px}.w_49:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:49px}.w_100vw:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:100vw}.h_54px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:54px}.d_flex:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){display:flex}.gap_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){gap:8px}.w_956px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:956px}.px_16px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){padding-inline:16px}.cursor_pointer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){cursor:pointer}.w_49px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:49px}.h_24px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:24px}.c_primary:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-primary)}.w_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:24px}.w_40\.75rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:40.75rem}.h_28\.125rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:28.125rem}.pos_relative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){position:relative}.bdr_md:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-radius:var(--radii-md)}.bx-sh_mono:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){box-shadow:var(--shadows-mono)}.h_100vh:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:100vh}.pos_fixed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){position:fixed}.z_9999:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){z-index:9999}.bg_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background:var(--colors-background-dimmer)}.pos_absolute:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){position:absolute}.li-s_none:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){list-style:none}.h_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:20px}.w_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:20px}.gap_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){gap:12px}.p_11px_18px_11px_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){padding:11px 18px 11px 20px}.bg_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background:var(--colors-mono-background-pressed)}.bg_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background:var(--colors-white)}.w_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:20px}.h_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:20px}.h_80px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:80px}.w_100\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:100%}.c_textBlack:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-text-black)}.c_blue\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-50)}.c_blue\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-100)}.c_blue\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-150)}.c_blue\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-200)}.c_blue\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-300)}.c_blue\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-400)}.c_blue\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-500)}.c_blue\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-600)}.c_blue\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-700)}.c_blue\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-800)}.c_blue\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-850)}.c_blue\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-900)}.c_blue\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-950)}.c_yellow\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-50)}.c_yellow\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-100)}.c_yellow\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-150)}.c_yellow\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-200)}.c_yellow\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-300)}.c_yellow\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-400)}.c_yellow\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-500)}.c_yellow\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-600)}.c_yellow\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-700)}.c_yellow\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-800)}.c_yellow\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-850)}.c_yellow\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-900)}.c_yellow\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-950)}.c_green\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-50)}.c_green\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-100)}.c_green\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-150)}.c_green\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-200)}.c_green\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-300)}.c_green\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-400)}.c_green\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-500)}.c_green\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-600)}.c_green\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-700)}.c_green\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-800)}.c_green\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-850)}.c_green\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-900)}.c_green\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-950)}.c_red\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-50)}.c_red\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-100)}.c_red\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-150)}.c_red\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-200)}.c_red\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-300)}.c_red\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-400)}.c_red\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-500)}.c_red\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-600)}.c_red\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-700)}.c_red\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-800)}.c_red\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-850)}.c_red\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-900)}.c_red\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-950)}.c_mono\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-50)}.c_mono\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-100)}.c_mono\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-150)}.c_mono\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-200)}.c_mono\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-300)}.c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-400)}.c_mono\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-500)}.c_mono\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-600)}.c_mono\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-700)}.c_mono\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-800)}.c_mono\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:mono.850}.c_mono\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-900)}.c_mono\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-950)}.c_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-white)}.c_black:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-black)}.c_whiteOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.20}.c_whiteOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.40}.c_whiteOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.60}.c_whiteOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.80}.c_blackOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.20}.c_blackOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.40}.c_blackOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.60}.c_blackOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.80}.c_success:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-success)}.c_error:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-error)}.c_backgroundNormal:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-background-normal)}.c_backgroundAlternative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-background-alternative)}.c_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-background-dimmer)}.c_errorBackground:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-error-background)}.c_sub:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-sub)}.c_outline:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-outline)}.c_textWhite:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-text-white)}.c_darkDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-dark-disabled)}.c_lightDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-light-disabled)}.c_blueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-disabled)}.c_textBlueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-text-blue-disabled)}.c_blueHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-hover)}.c_monoHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-hover)}.c_elevatedHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-elevated-hover)}.c_bluePressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-pressed)}.c_blueBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-background-pressed)}.c_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-background-pressed)}.c_shadowSmall:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-shadow-small)}.c_shadowMedium:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-shadow-medium)}.c_blueShadow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-shadow)}.c_discord:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-discord)}.c_github:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-github)}.c_secondaryYellow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-secondary-yellow)}.c_secondaryGreen:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-secondary-green)}.c_secondaryRed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-secondary-red)}.c_blueGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blueGradientDark}.c_blueGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blueGradientLight}.c_redGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:redGradientDark}.c_redGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:redGradientLight}.c_greenGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:greenGradientDark}.c_greenGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:greenGradientLight}.c_yellowGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:yellowGradientDark}.c_yellowGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:yellowGradientLight}.bd-b-w_button:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-width:var(--border-widths-button)}.bd-b-c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-color:var(--colors-mono-400)}.border-bottom-style_solid:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-style:solid}.ai_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){align-items:center}.jc_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:center}.ff_Product_Sans:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-family:Product Sans}.fw_700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-weight:700}.fs_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-size:20px}.lh_130\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){line-height:130%}.fw_400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-weight:400}.fs_14px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-size:14px}.flex-d_column:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){flex-direction:column}.top_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){top:0}.left_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){left:0}.top_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){top:var(--spacing-xl)}.right_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){right:var(--spacing-xl)}.mr_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){margin-right:8px}.ml_auto:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){margin-left:auto}.jc_space-between:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:space-between}.mb_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:12px}.jc_flex-start:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:flex-start}.jc_flex-end:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:flex-end} \ No newline at end of file From 9db08975a156692ab92f1397c88cff3ed69d2912 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 19:11:01 +0900 Subject: [PATCH 10/62] =?UTF-8?q?feat:=201=EC=B0=A8=20=EC=9A=B0=EC=88=98?= =?UTF-8?q?=ED=9A=8C=EC=9B=90,=202=EC=B0=A8=20=EC=9A=B0=EC=88=98=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=20=ED=91=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentList.tsx | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index bbfb47ba..1746de22 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -1,4 +1,4 @@ -import { Text } from "@wow-class/ui"; +import { AwardIcon, Text } from "@wow-class/ui"; import Link from "next/link"; import type { CSSProperties } from "react"; import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; @@ -15,6 +15,9 @@ const StudentList = ({ return ( + 수료 + 1차 우수회원 + 2차 우수회원 이름 학번 디스코드 사용자명 @@ -23,10 +26,31 @@ const StudentList = ({ {studentList.map((student) => { - const { name, studentId, discordUsername, nickname, githubLink } = - student; + const { + studyHistoryStatus, + isFirstRoundOutstandingStudent, + isSecondRoundOutstandingStudent, + name, + studentId, + discordUsername, + nickname, + githubLink, + } = student; return ( + {studyHistoryStatus} + + + + 1차 + + + + + + 2차 + + {name} {studentId} {discordUsername} @@ -52,4 +76,9 @@ const textButtonStyle: CSSProperties = { padding: 0, }; +const awardTextStyle: CSSProperties = { + display: "flex", + gap: "0.25rem", + alignItems: "center", +}; export default StudentList; From a61d5f1bad0195c7b43658a99ecf4291a03ea7af Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 19:18:07 +0900 Subject: [PATCH 11/62] =?UTF-8?q?feat:=20=EC=88=98=EB=A3=8C=20=EC=B2=B4?= =?UTF-8?q?=ED=81=AC=EB=B0=95=EC=8A=A4=20StarCheckIcon=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/src/components/StarCheckIcon/index.tsx | 37 +++++++++++++++++++ packages/ui/src/components/index.ts | 1 + 2 files changed, 38 insertions(+) create mode 100644 packages/ui/src/components/StarCheckIcon/index.tsx diff --git a/packages/ui/src/components/StarCheckIcon/index.tsx b/packages/ui/src/components/StarCheckIcon/index.tsx new file mode 100644 index 00000000..d7b8c5b3 --- /dev/null +++ b/packages/ui/src/components/StarCheckIcon/index.tsx @@ -0,0 +1,37 @@ +import { color } from "wowds-tokens"; + +const StarCheckIcon = ({ checked }: { checked: boolean }) => { + return ( + + + + + + + + + + + + ); +}; + +export default StarCheckIcon; diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 5ca7f29e..30e6daec 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -3,5 +3,6 @@ export { default as Header } from "./Header"; export { default as Modal } from "./Modal"; export { default as NavItem } from "./NavItem"; export { default as Space } from "./Space"; +export { default as StarCheckIcon } from "./StarCheckIcon"; export { default as Table } from "./Table"; export { default as Text } from "./Text"; From a169bb23d4d1b88285d3481695ddcd41d08aac07 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 19:18:29 +0900 Subject: [PATCH 12/62] =?UTF-8?q?feat:=20=EC=88=98=EB=A3=8C=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=ED=91=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/app/students/_components/StudentList.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index 1746de22..2d352f10 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -1,4 +1,4 @@ -import { AwardIcon, Text } from "@wow-class/ui"; +import { AwardIcon, StarCheckIcon, Text } from "@wow-class/ui"; import Link from "next/link"; import type { CSSProperties } from "react"; import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; @@ -38,7 +38,9 @@ const StudentList = ({ } = student; return ( - {studyHistoryStatus} + + + From e1513ad72b28f93656b4fbf2aa53888055ccf1a7 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 19:21:11 +0900 Subject: [PATCH 13/62] =?UTF-8?q?refactor:=20=EC=88=98=EA=B0=95=EC=83=9D?= =?UTF-8?q?=20Th=20=EC=A0=95=EB=B3=B4=20=EB=B0=B0=EC=97=B4=EB=A1=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentList.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index 2d352f10..c876e357 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -5,6 +5,17 @@ import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; import Table from "wowds-ui/Table"; import TextButton from "wowds-ui/TextButton"; +const STUENT_INFO_LIST = [ + "수료", + "1차 우수회원", + "2차 우수회원", + "이름", + "학번", + "디스코드 사용자명", + "디스코드 닉네임", + "깃허브 링크", +]; + const StudentList = ({ studentList, }: { @@ -15,14 +26,9 @@ const StudentList = ({ return (
- 수료 - 1차 우수회원 - 2차 우수회원 - 이름 - 학번 - 디스코드 사용자명 - 디스코드 닉네임 - 깃허브 링크 + {STUENT_INFO_LIST.map((info) => ( + {info} + ))} {studentList.map((student) => { From 5baaec6a978b4cc976831dc17e5e750a19d228fa Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 19:50:30 +0900 Subject: [PATCH 14/62] =?UTF-8?q?feat:=20=EA=B3=BC=EC=A0=9C=20=EC=A0=9C?= =?UTF-8?q?=EC=B6=9C=20=ED=83=80=EC=9E=85=20=EC=97=94=ED=8B=B0=ED=8B=B0=20?= =?UTF-8?q?=EB=B0=8F=20=ED=83=9C=EA=B7=B8=20=EB=A7=B5=20=EA=B0=9D=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/status/assignmentStatusMap.ts | 17 ++++++++++++++++- apps/admin/types/dtos/studyStudent.ts | 7 ++----- apps/admin/types/entities/assignment.ts | 5 +++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/admin/constants/status/assignmentStatusMap.ts b/apps/admin/constants/status/assignmentStatusMap.ts index 1b72d005..97ed1d11 100644 --- a/apps/admin/constants/status/assignmentStatusMap.ts +++ b/apps/admin/constants/status/assignmentStatusMap.ts @@ -1,4 +1,9 @@ -import type { AssignmentStatusType } from "types/entities/assignment"; +import type { ComponentProps } from "react"; +import type { + AssignmentStatusType, + AssignmentSubmissionStatusType, +} from "types/entities/assignment"; +import type Tag from "wowds-ui/Tag"; export const assignmentStatusMap: Record< AssignmentStatusType, @@ -8,3 +13,13 @@ export const assignmentStatusMap: Record< OPEN: "수정", CANCELLED: "개설", }; + +export const assignmentSubmissionStatusMap: Record< + AssignmentSubmissionStatusType, + { tagText: string; tagColor: ComponentProps["color"] } +> = { + NOT_SUBMITTED: { tagText: "기간아님", tagColor: "grey" }, + FAILURE: { tagText: "제출실패", tagColor: "red" }, + SUCCESS: { tagText: "제출완료", tagColor: "blue" }, + CANCELED: { tagText: "휴강", tagColor: "grey" }, +}; diff --git a/apps/admin/types/dtos/studyStudent.ts b/apps/admin/types/dtos/studyStudent.ts index c9fecb8a..2eba90cc 100644 --- a/apps/admin/types/dtos/studyStudent.ts +++ b/apps/admin/types/dtos/studyStudent.ts @@ -1,3 +1,4 @@ +import type { AssignmentSubmissionStatusType } from "types/entities/assignment"; import type { PageableObject, SortType } from "types/entities/page"; export interface StudyStudentApiResponseDto { @@ -49,11 +50,7 @@ export interface AttendanceTask extends StudyTaskResponseDtoBase { export interface AssignmentTask extends StudyTaskResponseDtoBase { taskType: "ASSIGNMENT"; assignmentTitle: string; - assignmentSubmissionStatus: - | "NOT_SUBMITTED" - | "FAILURE" - | "SUCCESS" - | "CANCELED"; + assignmentSubmissionStatus: AssignmentSubmissionStatusType; } export type StudyTaskResponseDto = diff --git a/apps/admin/types/entities/assignment.ts b/apps/admin/types/entities/assignment.ts index 936248af..73954854 100644 --- a/apps/admin/types/entities/assignment.ts +++ b/apps/admin/types/entities/assignment.ts @@ -1 +1,6 @@ export type AssignmentStatusType = "NONE" | "OPEN" | "CANCELLED"; +export type AssignmentSubmissionStatusType = + | "NOT_SUBMITTED" + | "FAILURE" + | "SUCCESS" + | "CANCELED"; From eb1e29d3c38344aec23aebc2e28367f18eca2605 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 20:01:12 +0900 Subject: [PATCH 15/62] =?UTF-8?q?feat:=20=EA=B3=BC=EC=A0=9C=20=EC=A0=9C?= =?UTF-8?q?=EC=B6=9C=20=ED=83=9C=EA=B7=B8=20=ED=91=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentList.tsx | 46 ++++++++++++++++++- .../app/students/_components/TaskTag.tsx | 22 +++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 apps/admin/app/students/_components/TaskTag.tsx diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index c876e357..bdde8e61 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -1,10 +1,15 @@ import { AwardIcon, StarCheckIcon, Text } from "@wow-class/ui"; import Link from "next/link"; import type { CSSProperties } from "react"; -import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; +import type { + StudyStudentApiResponseDto, + StudyTaskResponseDto, +} from "types/dtos/studyStudent"; import Table from "wowds-ui/Table"; import TextButton from "wowds-ui/TextButton"; +import TaskTag from "./TaskTag"; + const STUENT_INFO_LIST = [ "수료", "1차 우수회원", @@ -29,6 +34,7 @@ const StudentList = ({ {STUENT_INFO_LIST.map((info) => ( {info} ))} + {studentList[0] && } {studentList.map((student) => { @@ -41,6 +47,7 @@ const StudentList = ({ discordUsername, nickname, githubLink, + studyTasks, } = student; return ( @@ -71,6 +78,7 @@ const StudentList = ({ text={githubLink} /> + ); })} @@ -79,6 +87,42 @@ const StudentList = ({ ); }; +const StudyTasksThs = ({ + tasks, +}: { + tasks: ( + | StudyTaskResponseDto<"ASSIGNMENT"> + | StudyTaskResponseDto<"ATTENDANCE"> + )[]; +}) => { + return tasks.map((task) => { + const { studyDetailId, week, taskType } = task; + return ( + + {taskType === "ATTENDANCE" ? `${week}주차 출석` : `${week}주차 과제`} + + ); + }); +}; + +const StudyTasksTds = ({ + tasks, +}: { + tasks: ( + | StudyTaskResponseDto<"ASSIGNMENT"> + | StudyTaskResponseDto<"ATTENDANCE"> + )[]; +}) => { + return tasks.map((task) => { + const { studyDetailId } = task; + return ( + + + + ); + }); +}; + const textButtonStyle: CSSProperties = { width: "fit-content", padding: 0, diff --git a/apps/admin/app/students/_components/TaskTag.tsx b/apps/admin/app/students/_components/TaskTag.tsx new file mode 100644 index 00000000..48cf4b54 --- /dev/null +++ b/apps/admin/app/students/_components/TaskTag.tsx @@ -0,0 +1,22 @@ +import { assignmentSubmissionStatusMap } from "constants/status/assignmentStatusMap"; +import type { StudyTaskResponseDto } from "types/dtos/studyStudent"; +import Tag from "wowds-ui/Tag"; + +const TaskTag = ({ task }: { task: StudyTaskResponseDto }) => { + const { taskType } = task; + if (taskType === "ATTENDACE") { + return null; + } + if (taskType === "ASSIGNMENT") { + const { assignmentSubmissionStatus } = task; + const { tagText, tagColor } = + assignmentSubmissionStatusMap[assignmentSubmissionStatus]; + return ( + + {tagText} + + ); + } +}; + +export default TaskTag; From 81c74076b73dad31b437bec435b1712d807f207e Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 20:20:27 +0900 Subject: [PATCH 16/62] =?UTF-8?q?feat:=20task,=20attendance=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EB=B0=8F=20studyTask?= =?UTF-8?q?s=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/types/dtos/studyStudent.ts | 18 ++++++++++-------- apps/admin/types/entities/attendance.ts | 5 +++++ apps/admin/types/entities/task.ts | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 apps/admin/types/entities/attendance.ts create mode 100644 apps/admin/types/entities/task.ts diff --git a/apps/admin/types/dtos/studyStudent.ts b/apps/admin/types/dtos/studyStudent.ts index 2eba90cc..38da75d2 100644 --- a/apps/admin/types/dtos/studyStudent.ts +++ b/apps/admin/types/dtos/studyStudent.ts @@ -1,5 +1,7 @@ import type { AssignmentSubmissionStatusType } from "types/entities/assignment"; +import type { AttendanceStatusType } from "types/entities/attendance"; import type { PageableObject, SortType } from "types/entities/page"; +import type { TaskType } from "types/entities/task"; export interface StudyStudentApiResponseDto { memberId: number; @@ -11,7 +13,10 @@ export interface StudyStudentApiResponseDto { studyHistoryStatus: "NONE" | "COMPLETED"; isFirstRoundOutstandingStudent: boolean; isSecondRoundOutstandingStudent: boolean; - studyTasks: StudyTaskResponseDto<"ATTENDANCE" | "ASSIGNMENT">[]; + studyTasks: ( + | StudyTaskResponseDto<"ASSIGNMENT"> + | StudyTaskResponseDto<"ATTENDANCE"> + )[]; assignmentRate: number; attendanceRate: number; } @@ -40,11 +45,7 @@ export interface StudyTaskResponseDtoBase { export interface AttendanceTask extends StudyTaskResponseDtoBase { taskType: "ATTENDANCE"; - attendanceStatus: - | "ATTENDED" - | "NOT_ATTENDED" - | "BEFORE_ATTENDANCE" - | "CANCELED"; + attendanceStatus: AttendanceStatusType; } export interface AssignmentTask extends StudyTaskResponseDtoBase { @@ -53,5 +54,6 @@ export interface AssignmentTask extends StudyTaskResponseDtoBase { assignmentSubmissionStatus: AssignmentSubmissionStatusType; } -export type StudyTaskResponseDto = - T extends "ATTENDANCE" ? AttendanceTask : AssignmentTask; +export type StudyTaskResponseDto = T extends "ATTENDANCE" + ? AttendanceTask + : AssignmentTask; diff --git a/apps/admin/types/entities/attendance.ts b/apps/admin/types/entities/attendance.ts new file mode 100644 index 00000000..3e60d0e5 --- /dev/null +++ b/apps/admin/types/entities/attendance.ts @@ -0,0 +1,5 @@ +export type AttendanceStatusType = + | "ATTENDED" + | "NOT_ATTENDED" + | "BEFORE_ATTENDANCE" + | "CANCELED"; diff --git a/apps/admin/types/entities/task.ts b/apps/admin/types/entities/task.ts new file mode 100644 index 00000000..77c989c9 --- /dev/null +++ b/apps/admin/types/entities/task.ts @@ -0,0 +1 @@ +export type TaskType = "ATTENDANCE" | "ASSIGNMENT"; From d7370db439699e74ff6f1f83251f2087ca3ec4bc Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 20:20:55 +0900 Subject: [PATCH 17/62] =?UTF-8?q?feat:=20=EA=B3=BC=EC=A0=9C=20=EC=B6=9C?= =?UTF-8?q?=EC=84=9D=20=ED=83=9C=EA=B7=B8=20=EB=A7=B5=20=EA=B0=9D=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/constants/status/attendanceStatusMap.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/admin/constants/status/attendanceStatusMap.ts b/apps/admin/constants/status/attendanceStatusMap.ts index b993aee8..688ea938 100644 --- a/apps/admin/constants/status/attendanceStatusMap.ts +++ b/apps/admin/constants/status/attendanceStatusMap.ts @@ -1,4 +1,5 @@ import type { ComponentProps } from "react"; +import type { AttendanceStatusType } from "types/entities/attendance"; import type Tag from "wowds-ui/Tag"; export const attendanceStatusMap: Record< @@ -8,3 +9,13 @@ export const attendanceStatusMap: Record< ONGOING_ATTENDANCE: { label: "진행중", color: "blue" }, BEFORE_ATTENDANCE: { label: "진행전", color: "grey" }, }; + +export const attendanceTaskStatusMap: Record< + AttendanceStatusType, + { tagText: string; tagColor: ComponentProps["color"] } +> = { + BEFORE_ATTENDANCE: { tagText: "기간아님", tagColor: "grey" }, + NOT_ATTENDED: { tagText: "미출석", tagColor: "red" }, + ATTENDED: { tagText: "출석완료", tagColor: "blue" }, + CANCELED: { tagText: "휴강", tagColor: "grey" }, +}; From 49b0ac5349a84401d5911d0bb58ad3a6fc994420 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 20:21:21 +0900 Subject: [PATCH 18/62] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=EB=90=9C=20key?= =?UTF-8?q?=20=EC=9C=A0=EB=8B=88=ED=81=AC=ED=95=98=EA=B2=8C=20=EB=B0=94?= =?UTF-8?q?=EA=BE=B8=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/app/students/_components/StudentList.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index bdde8e61..fde10c3a 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -96,9 +96,9 @@ const StudyTasksThs = ({ )[]; }) => { return tasks.map((task) => { - const { studyDetailId, week, taskType } = task; + const { week, taskType } = task; return ( - + {taskType === "ATTENDANCE" ? `${week}주차 출석` : `${week}주차 과제`} ); @@ -114,9 +114,9 @@ const StudyTasksTds = ({ )[]; }) => { return tasks.map((task) => { - const { studyDetailId } = task; + const { week, taskType } = task; return ( - + ); From df66b73f87baba71c85e6bf27addf070e6e82dec Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 20:22:03 +0900 Subject: [PATCH 19/62] =?UTF-8?q?feat:=20=EA=B3=BC=EC=A0=9C=20=EC=B6=9C?= =?UTF-8?q?=EC=84=9D=20=ED=83=9C=EA=B7=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/app/students/_components/TaskTag.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/admin/app/students/_components/TaskTag.tsx b/apps/admin/app/students/_components/TaskTag.tsx index 48cf4b54..3d09374d 100644 --- a/apps/admin/app/students/_components/TaskTag.tsx +++ b/apps/admin/app/students/_components/TaskTag.tsx @@ -1,11 +1,18 @@ import { assignmentSubmissionStatusMap } from "constants/status/assignmentStatusMap"; +import { attendanceTaskStatusMap } from "constants/status/attendanceStatusMap"; import type { StudyTaskResponseDto } from "types/dtos/studyStudent"; import Tag from "wowds-ui/Tag"; const TaskTag = ({ task }: { task: StudyTaskResponseDto }) => { const { taskType } = task; - if (taskType === "ATTENDACE") { - return null; + if (taskType === "ATTENDANCE") { + const { attendanceStatus } = task; + const { tagText, tagColor } = attendanceTaskStatusMap[attendanceStatus]; + return ( + + {tagText} + + ); } if (taskType === "ASSIGNMENT") { const { assignmentSubmissionStatus } = task; @@ -17,6 +24,7 @@ const TaskTag = ({ task }: { task: StudyTaskResponseDto }) => { ); } + return null; }; export default TaskTag; From 2ed77585c402f297a595adb519832a11cc987cec Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 20:27:34 +0900 Subject: [PATCH 20/62] =?UTF-8?q?refactor:=20StudentListItem=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentList.tsx | 93 ++++++++++--------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index fde10c3a..a7477d4f 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -37,56 +37,59 @@ const StudentList = ({ {studentList[0] && } - {studentList.map((student) => { - const { - studyHistoryStatus, - isFirstRoundOutstandingStudent, - isSecondRoundOutstandingStudent, - name, - studentId, - discordUsername, - nickname, - githubLink, - studyTasks, - } = student; - return ( - - - - - - - - 1차 - - - - - - 2차 - - - {name} - {studentId} - {discordUsername} - {nickname} - - - - - - ); - })} + {studentList.map((student) => ( + + ))}
); }; +const StudentListItem = ({ + studyHistoryStatus, + isFirstRoundOutstandingStudent, + isSecondRoundOutstandingStudent, + name, + studentId, + discordUsername, + nickname, + githubLink, + studyTasks, +}: StudyStudentApiResponseDto) => { + return ( + + + + + + + + 1차 + + + + + + 2차 + + + {name} + {studentId} + {discordUsername} + {nickname} + + + + + + ); +}; + const StudyTasksThs = ({ tasks, }: { From f5540f8c1fb453ebbd225ab59c5c9701742d4533 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 20:35:39 +0900 Subject: [PATCH 21/62] =?UTF-8?q?feat:=20=EC=B6=9C=EC=84=9D=EB=A5=A0,=20?= =?UTF-8?q?=EA=B3=BC=EC=A0=9C=20=EC=88=98=ED=96=89=EB=A5=A0=20=ED=91=9C=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentList.tsx | 16 +++++++++++++--- apps/admin/utils/formatNumber.ts | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 apps/admin/utils/formatNumber.ts diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index a7477d4f..a8d7b528 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -5,12 +5,13 @@ import type { StudyStudentApiResponseDto, StudyTaskResponseDto, } from "types/dtos/studyStudent"; +import { formatNumberToPercent } from "utils/formatNumber"; import Table from "wowds-ui/Table"; import TextButton from "wowds-ui/TextButton"; import TaskTag from "./TaskTag"; -const STUENT_INFO_LIST = [ +const STUENT_INFO_LIST_BEFORE = [ "수료", "1차 우수회원", "2차 우수회원", @@ -21,6 +22,8 @@ const STUENT_INFO_LIST = [ "깃허브 링크", ]; +const STUDENT_INFO_LIST_AFTER = ["출석률", "과제 수행률", "전체 수행정도"]; + const StudentList = ({ studentList, }: { @@ -31,14 +34,17 @@ const StudentList = ({ return ( - {STUENT_INFO_LIST.map((info) => ( + {STUENT_INFO_LIST_BEFORE.map((info) => ( {info} ))} {studentList[0] && } + {STUDENT_INFO_LIST_AFTER.map((info) => ( + {info} + ))} {studentList.map((student) => ( - + ))}
@@ -55,6 +61,8 @@ const StudentListItem = ({ nickname, githubLink, studyTasks, + assignmentRate, + attendanceRate, }: StudyStudentApiResponseDto) => { return ( @@ -86,6 +94,8 @@ const StudentListItem = ({ /> + {formatNumberToPercent(assignmentRate)} + {formatNumberToPercent(attendanceRate)} ); }; diff --git a/apps/admin/utils/formatNumber.ts b/apps/admin/utils/formatNumber.ts new file mode 100644 index 00000000..e1907c64 --- /dev/null +++ b/apps/admin/utils/formatNumber.ts @@ -0,0 +1,3 @@ +export const formatNumberToPercent = (number: number) => { + return `${number.toFixed(2)}%`; +}; From f07ee8dedcd1be1828b3bc3fc8aecd156af80ab5 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Sun, 3 Nov 2024 22:35:22 +0900 Subject: [PATCH 22/62] =?UTF-8?q?fix:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/apis/study/studyApi.ts | 4 +--- apps/admin/hooks/fetch/useFetchStudents.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/admin/apis/study/studyApi.ts b/apps/admin/apis/study/studyApi.ts index 8c80a745..38dd2deb 100644 --- a/apps/admin/apis/study/studyApi.ts +++ b/apps/admin/apis/study/studyApi.ts @@ -157,9 +157,7 @@ export const studyApi = { next: { tags: [tags.students] }, cache: "force-cache", }, - { - params: pageable, - } + pageable ); return response.data; }, diff --git a/apps/admin/hooks/fetch/useFetchStudents.ts b/apps/admin/hooks/fetch/useFetchStudents.ts index 45dd2f9c..91397ce3 100644 --- a/apps/admin/hooks/fetch/useFetchStudents.ts +++ b/apps/admin/hooks/fetch/useFetchStudents.ts @@ -26,7 +26,7 @@ const useFetchStudents = ( const fetchStudentsData = async () => { if (study) { const studentsData = await studyApi.getStudyStudents(study.studyId, { - page: page, + page: page - 1, size: PAGE_SIZE, sort: [], }); From 3c93fd5c009314680fad8629c9a7cc907691c94c Mon Sep 17 00:00:00 2001 From: hamo-o Date: Mon, 4 Nov 2024 02:46:59 +0900 Subject: [PATCH 23/62] =?UTF-8?q?fix:=20=EA=B3=BC=EC=A0=9C=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20NOT=5FSUBMITTED=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/constants/status/assignmentStatusMap.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/admin/constants/status/assignmentStatusMap.ts b/apps/admin/constants/status/assignmentStatusMap.ts index 97ed1d11..4ed4c0e5 100644 --- a/apps/admin/constants/status/assignmentStatusMap.ts +++ b/apps/admin/constants/status/assignmentStatusMap.ts @@ -18,7 +18,7 @@ export const assignmentSubmissionStatusMap: Record< AssignmentSubmissionStatusType, { tagText: string; tagColor: ComponentProps["color"] } > = { - NOT_SUBMITTED: { tagText: "기간아님", tagColor: "grey" }, + NOT_SUBMITTED: { tagText: "미제출", tagColor: "red" }, FAILURE: { tagText: "제출실패", tagColor: "red" }, SUCCESS: { tagText: "제출완료", tagColor: "blue" }, CANCELED: { tagText: "휴강", tagColor: "grey" }, From d4c61588adc28d0a2eba3c19a1965f819bfccacf Mon Sep 17 00:00:00 2001 From: hamo-o Date: Mon, 4 Nov 2024 02:47:29 +0900 Subject: [PATCH 24/62] =?UTF-8?q?feat:=20=EC=88=98=EA=B0=95=EC=83=9D=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentFilter.tsx | 13 +++++++++++++ .../app/students/_components/StudentsHeader.tsx | 11 +++++++---- apps/admin/app/students/page.tsx | 4 +++- 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 apps/admin/app/students/_components/StudentFilter.tsx diff --git a/apps/admin/app/students/_components/StudentFilter.tsx b/apps/admin/app/students/_components/StudentFilter.tsx new file mode 100644 index 00000000..af9a3c2e --- /dev/null +++ b/apps/admin/app/students/_components/StudentFilter.tsx @@ -0,0 +1,13 @@ +import { Flex } from "@styled-system/jsx"; +import Chip from "wowds-ui/Chip"; + +const StudentFilter = () => { + return ( + + + + + ); +}; + +export default StudentFilter; diff --git a/apps/admin/app/students/_components/StudentsHeader.tsx b/apps/admin/app/students/_components/StudentsHeader.tsx index 3ab763dd..a20dde34 100644 --- a/apps/admin/app/students/_components/StudentsHeader.tsx +++ b/apps/admin/app/students/_components/StudentsHeader.tsx @@ -1,3 +1,4 @@ +import { Flex } from "@styled-system/jsx"; import { Text } from "@wow-class/ui"; import ItemSeparator from "components/ItemSeparator"; import type { CSSProperties } from "react"; @@ -11,10 +12,12 @@ const StudentsHeader = ({ studyList: StudyListApiResponseDto[]; }) => { return ( - - 수강생 관리 - - + + + 수강생 관리 + + + ); }; diff --git a/apps/admin/app/students/page.tsx b/apps/admin/app/students/page.tsx index deb38b9d..74df6895 100644 --- a/apps/admin/app/students/page.tsx +++ b/apps/admin/app/students/page.tsx @@ -9,6 +9,7 @@ import { useEffect, useState } from "react"; import type { StudyListApiResponseDto } from "types/dtos/studyList"; import isAdmin from "utils/isAdmin"; +import StudentFilter from "./_components/StudentFilter"; import StudentList from "./_components/StudentList"; import StudentPagination from "./_components/StudentPagination"; import StudentsHeader from "./_components/StudentsHeader"; @@ -43,8 +44,9 @@ const StudentsPage = () => { if (!studyList) return 담당한 스터디가 없어요.; return ( - + + {studentList.length ? : null} Date: Mon, 4 Nov 2024 03:01:42 +0900 Subject: [PATCH 25/62] =?UTF-8?q?feat:=20=EC=97=91=EC=85=80=20=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=B2=84=ED=8A=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/students/_components/StudentsHeader.tsx | 13 +++++++++++-- apps/admin/public/images/download.svg | 5 +++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 apps/admin/public/images/download.svg diff --git a/apps/admin/app/students/_components/StudentsHeader.tsx b/apps/admin/app/students/_components/StudentsHeader.tsx index a20dde34..26b7f97d 100644 --- a/apps/admin/app/students/_components/StudentsHeader.tsx +++ b/apps/admin/app/students/_components/StudentsHeader.tsx @@ -1,6 +1,7 @@ -import { Flex } from "@styled-system/jsx"; +import { Flex, styled } from "@styled-system/jsx"; import { Text } from "@wow-class/ui"; import ItemSeparator from "components/ItemSeparator"; +import Image from "next/image"; import type { CSSProperties } from "react"; import type { StudyListApiResponseDto } from "types/dtos/studyList"; @@ -12,11 +13,19 @@ const StudentsHeader = ({ studyList: StudyListApiResponseDto[]; }) => { return ( - + 수강생 관리 + + 다운로드 + ); }; diff --git a/apps/admin/public/images/download.svg b/apps/admin/public/images/download.svg new file mode 100644 index 00000000..f8e55530 --- /dev/null +++ b/apps/admin/public/images/download.svg @@ -0,0 +1,5 @@ + + + + + From 080cc27bff730a11f71517c6eb31e825a920c736 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Mon, 4 Nov 2024 03:12:32 +0900 Subject: [PATCH 26/62] =?UTF-8?q?fix:=20=EC=88=98=EA=B0=95=EC=83=9D=20?= =?UTF-8?q?=EC=97=86=EC=9D=84=20=EB=95=8C=EC=99=80=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=B0=9B=EB=8A=94=20=EC=A4=91=EC=9D=BC=20=EB=95=8C?= =?UTF-8?q?=20=EA=B5=AC=EB=B6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/app/students/_components/StudentList.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/admin/app/students/_components/StudentList.tsx b/apps/admin/app/students/_components/StudentList.tsx index a8d7b528..8639544e 100644 --- a/apps/admin/app/students/_components/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentList.tsx @@ -29,6 +29,7 @@ const StudentList = ({ }: { studentList: StudyStudentApiResponseDto[] | []; }) => { + if (!studentList) return null; if (!studentList.length) return 스터디 수강생이 없어요.; return ( From 2910db51849004547e6ff6be4061524ffd6181f7 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Mon, 4 Nov 2024 05:19:43 +0900 Subject: [PATCH 27/62] =?UTF-8?q?fix:=20application/octet-stream=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EB=8F=84=20blob=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EC=9D=BD=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/utils/src/fetcher/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/utils/src/fetcher/index.ts b/packages/utils/src/fetcher/index.ts index 451775a3..5c9c8b66 100644 --- a/packages/utils/src/fetcher/index.ts +++ b/packages/utils/src/fetcher/index.ts @@ -65,7 +65,10 @@ class Fetcher { if (contentType.includes("application/json")) { return response.json(); - } else if (contentType.startsWith("image/")) { + } else if ( + contentType.startsWith("image/") || + contentType.startsWith("application/octet-stream") + ) { return response.blob(); } From 839f51d64485bc8b8086760d5c3ff6f57ebb1e44 Mon Sep 17 00:00:00 2001 From: hamo-o Date: Mon, 4 Nov 2024 05:29:52 +0900 Subject: [PATCH 28/62] =?UTF-8?q?feat:=20=EC=88=98=EA=B0=95=EC=83=9D=20?= =?UTF-8?q?=EC=97=91=EC=85=80=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C,=20?= =?UTF-8?q?=EC=8A=A4=ED=84=B0=EB=94=94=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EC=96=B4=EB=A9=A4=EB=B2=84=EB=8F=84=20=EC=9E=90?= =?UTF-8?q?=EC=8B=A0=EC=9D=B4=20=EC=83=9D=EC=84=B1=ED=95=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=94=94=EB=A7=8C=20=EB=B3=B4=EC=9D=B4=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=84=EC=8B=9C=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/apis/study/studyApi.ts | 11 ++++++ .../students/_components/StudentsHeader.tsx | 39 +++++++++++++++---- apps/admin/app/students/page.tsx | 15 +++++-- apps/admin/constants/tags.ts | 1 + 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/apps/admin/apis/study/studyApi.ts b/apps/admin/apis/study/studyApi.ts index 38dd2deb..4bad8934 100644 --- a/apps/admin/apis/study/studyApi.ts +++ b/apps/admin/apis/study/studyApi.ts @@ -161,4 +161,15 @@ export const studyApi = { ); return response.data; }, + getStudyStudentsExcel: async (studyId: number) => { + const response = await fetcher.get( + `/mentor/studies/${studyId}/students/excel`, + { + next: { tags: [tags.studentsExcel] }, + cache: "force-cache", + } + ); + + return response.data; + }, }; diff --git a/apps/admin/app/students/_components/StudentsHeader.tsx b/apps/admin/app/students/_components/StudentsHeader.tsx index 26b7f97d..3cd386a8 100644 --- a/apps/admin/app/students/_components/StudentsHeader.tsx +++ b/apps/admin/app/students/_components/StudentsHeader.tsx @@ -1,31 +1,54 @@ import { Flex, styled } from "@styled-system/jsx"; import { Text } from "@wow-class/ui"; +import { studyApi } from "apis/study/studyApi"; import ItemSeparator from "components/ItemSeparator"; import Image from "next/image"; import type { CSSProperties } from "react"; +import { useEffect, useState } from "react"; import type { StudyListApiResponseDto } from "types/dtos/studyList"; import StudyDropDown from "./StudyDropDown"; const StudentsHeader = ({ studyList, + studyId, + studentLength, }: { studyList: StudyListApiResponseDto[]; + studyId?: number; + studentLength: number; }) => { + const [url, setUrl] = useState(""); + + useEffect(() => { + const fetchData = async () => { + const response = await studyApi.getStudyStudentsExcel(studyId); + const blob = new Blob([response], { + type: "application/vnd.ms-excel", + }); + const url = URL.createObjectURL(blob); + if (url) setUrl(url); + }; + + if (studentLength) fetchData(); + }, [studyId, studentLength]); + return ( 수강생 관리 - - 다운로드 - + {studyId && studentLength ? ( + + 다운로드 + + ) : null} ); }; diff --git a/apps/admin/app/students/page.tsx b/apps/admin/app/students/page.tsx index 74df6895..a35abd86 100644 --- a/apps/admin/app/students/page.tsx +++ b/apps/admin/app/students/page.tsx @@ -22,9 +22,11 @@ const StudentsPage = () => { useEffect(() => { const fetchData = async () => { const adminStatus = await isAdmin(); - const data = adminStatus - ? await studyApi.getStudyList() - : await studyApi.getMyStudyList(); + const data = + // adminStatus + // ? await studyApi.getStudyList() + // : + await studyApi.getMyStudyList(); if (data && data.length && data[0]) { setStudyList(data); @@ -41,11 +43,16 @@ const StudentsPage = () => { }; const { studentList, pageInfo } = useFetchStudents(selectedStudy, page); + if (!selectedStudy) return null; if (!studyList) return 담당한 스터디가 없어요.; return ( - + {studentList.length ? : null} Date: Mon, 4 Nov 2024 23:54:24 +0900 Subject: [PATCH 29/62] =?UTF-8?q?fix:=20CANCELED=EB=A1=9C=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[studyId]/_components/assignment/AssignmentButtons.tsx | 2 +- .../_components/curriculum/CurriculumListItem.tsx | 2 +- .../[studyDetailId]/_components/AssignmentHeader.tsx | 2 +- .../assignments/[studyDetailId]/edit-assignment/page.tsx | 2 +- .../[studyId]/_components/StudyInfoBox/StudyInfoStatus.tsx | 7 ++----- .../[studyId]/_hooks/usePrefillStudyDetailInfo.ts | 2 +- apps/admin/constants/status/assignmentStatusMap.ts | 2 +- apps/admin/types/entities/assignment.ts | 2 +- apps/admin/types/entities/study.ts | 2 +- apps/admin/utils/validate/studyDetailInfo.ts | 2 +- 10 files changed, 11 insertions(+), 14 deletions(-) diff --git a/apps/admin/app/studies/[studyId]/_components/assignment/AssignmentButtons.tsx b/apps/admin/app/studies/[studyId]/_components/assignment/AssignmentButtons.tsx index 166b45b6..5367eb4e 100644 --- a/apps/admin/app/studies/[studyId]/_components/assignment/AssignmentButtons.tsx +++ b/apps/admin/app/studies/[studyId]/_components/assignment/AssignmentButtons.tsx @@ -39,7 +39,7 @@ const AssignmentButtons = ({ ); } - if (assignmentStatus === "CANCELLED") { + if (assignmentStatus === "CANCELED") { return ( + ) : ( + + ); +}; + +export default CompleteModalButton; diff --git a/apps/admin/app/students/@modal/_components/OutstandingModalButton.tsx b/apps/admin/app/students/@modal/_components/OutstandingModalButton.tsx new file mode 100644 index 00000000..53ea7e1c --- /dev/null +++ b/apps/admin/app/students/@modal/_components/OutstandingModalButton.tsx @@ -0,0 +1,56 @@ +"use client"; + +import studyAchievementApi from "apis/study/studyAchievementApi"; +import { useAtomValue } from "jotai"; +import type { AchievementType } from "types/entities/achievement"; +import Button from "wowds-ui/Button"; + +import { + enabledOutstandingStudentsAtom, + outstandingStudentsAtom, + selectedStudentsAtom, + studyAtom, +} from "@/students/_contexts/StudyProvider"; + +import useCloseStudentStatusModal from "../_hooks/useCloseStudentStatusModal"; + +const OutstandingModalButton = () => { + const study = useAtomValue(studyAtom); + const { enabled } = useAtomValue(enabledOutstandingStudentsAtom); + const { type, achievement } = useAtomValue(outstandingStudentsAtom); + const { students } = useAtomValue(selectedStudentsAtom); + + const { + handleClickCloseModal, + closeModalWithSuccess, + closeModalWithFailure, + } = useCloseStudentStatusModal(); + + const handleClickOutstanding = async () => { + if (!study || !achievement || !type) return; + + const apiMap = { + 처리: studyAchievementApi.postStudyAchievement, + 철회: studyAchievementApi.deleteStudyAchievement, + }; + + const fetchApi = () => { + const fetch = apiMap[type]; + return fetch(study.studyId, { + studentIds: Array.from(students), + achievementType: achievement as AchievementType, + }); + }; + const result = await fetchApi(); + if (result.success) closeModalWithSuccess(); + else closeModalWithFailure(); + }; + + return enabled ? ( + + ) : ( + + ); +}; + +export default OutstandingModalButton; diff --git a/apps/admin/app/students/@modal/_components/StudentStatusModal.tsx b/apps/admin/app/students/@modal/_components/StudentStatusModal.tsx new file mode 100644 index 00000000..cc7f63a9 --- /dev/null +++ b/apps/admin/app/students/@modal/_components/StudentStatusModal.tsx @@ -0,0 +1,50 @@ +"use client"; + +import { Flex, styled } from "@styled-system/jsx"; +import { Modal, Text } from "@wow-class/ui"; +import { useAtomValue } from "jotai"; + +import { + outstandingStudentsAtom, + selectedStudentsAtom, +} from "@/students/_contexts/StudyProvider"; + +import CompleteModalButton from "./CompleteModalButton"; +import OutstandingModalButton from "./OutstandingModalButton"; +import StudentStatusModalHeader from "./StudentStatusModalHeader"; + +const StudentStatusModal = () => { + const { firstStudentName, students } = useAtomValue(selectedStudentsAtom); + const { type, achievement } = useAtomValue(outstandingStudentsAtom); + + const STUDENTS_NUM = students.size; + if (!type || !achievement) return null; + if (!STUDENTS_NUM) return 선택된 수강생이 없습니다.; + + const renderAdditionalStudents = () => { + if (STUDENTS_NUM === 1) return null; + return ( + + 외 {STUDENTS_NUM - 1}명 + + ); + }; + + return ( + + + + + {firstStudentName} 님 {renderAdditionalStudents()} + + {achievement === "COMPLETE" ? ( + + ) : ( + + )} + + + ); +}; + +export default StudentStatusModal; diff --git a/apps/admin/app/students/@modal/_components/StudentStatusModalHeader.tsx b/apps/admin/app/students/@modal/_components/StudentStatusModalHeader.tsx new file mode 100644 index 00000000..240e70ac --- /dev/null +++ b/apps/admin/app/students/@modal/_components/StudentStatusModalHeader.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { Text } from "@wow-class/ui"; +import { + outstandingRoundMap, + outstandingTypeMap, +} from "constants/status/outstandigOptions"; +import { useAtomValue } from "jotai"; + +import { + enabledOutstandingStudentsAtom, + outstandingStudentsAtom, +} from "@/students/_contexts/StudyProvider"; + +const StudentStatusModalHeader = () => { + const { enabled } = useAtomValue(enabledOutstandingStudentsAtom); + const { type, achievement } = useAtomValue(outstandingStudentsAtom); + + if (!type || !achievement) return null; + return enabled ? ( + + 선택한 수강생을
+ {outstandingRoundMap[achievement]} {outstandingTypeMap[type]} + 하시겠어요? +
+ ) : ( + + {outstandingRoundMap[achievement]} {outstandingTypeMap[type]} + 되었어요. + + ); +}; +export default StudentStatusModalHeader; diff --git a/apps/admin/app/students/@modal/_hooks/useCloseStudentStatusModal.ts b/apps/admin/app/students/@modal/_hooks/useCloseStudentStatusModal.ts new file mode 100644 index 00000000..7dba684c --- /dev/null +++ b/apps/admin/app/students/@modal/_hooks/useCloseStudentStatusModal.ts @@ -0,0 +1,51 @@ +import { useModalRoute } from "@wow-class/ui/hooks"; +import { tags } from "constants/tags"; +import { useSetAtom } from "jotai"; +import { revalidateTagByName } from "utils/revalidateTagByName"; + +import { + enabledOutstandingStudentsAtom, + selectedStudentsAtom, +} from "@/students/_contexts/StudyProvider"; + +const useCloseStudentStatusModal = () => { + const setSelectedStudents = useSetAtom(selectedStudentsAtom); + const setEnabledOutstandingStudents = useSetAtom( + enabledOutstandingStudentsAtom + ); + const { onClose } = useModalRoute(); + + const handleClickCloseModal = () => { + setSelectedStudents({ + students: new Set(), + firstStudentName: "", + }); + onClose(); + }; + + const resetStudents = () => { + revalidateTagByName(tags.students); + setEnabledOutstandingStudents({ + enabled: false, + }); + }; + + const closeModalWithSuccess = () => { + resetStudents(); + setTimeout(() => { + handleClickCloseModal(); + }, 1000); + }; + + const closeModalWithFailure = () => { + resetStudents(); + handleClickCloseModal(); + }; + + return { + handleClickCloseModal, + closeModalWithSuccess, + closeModalWithFailure, + }; +}; +export default useCloseStudentStatusModal; diff --git a/apps/admin/app/students/@modal/default.tsx b/apps/admin/app/students/@modal/default.tsx new file mode 100644 index 00000000..395785b9 --- /dev/null +++ b/apps/admin/app/students/@modal/default.tsx @@ -0,0 +1,5 @@ +const Default = () => { + return null; +}; + +export default Default; diff --git a/apps/admin/app/students/_components/OutstandingDropDown/DropDownTrigger.tsx b/apps/admin/app/students/_components/OutstandingDropDown/DropDownTrigger.tsx new file mode 100644 index 00000000..68187263 --- /dev/null +++ b/apps/admin/app/students/_components/OutstandingDropDown/DropDownTrigger.tsx @@ -0,0 +1,12 @@ +import type { OutstandingType } from "constants/status/outstandigOptions"; +import Button from "wowds-ui/Button"; + +const DropDownTrigger = ({ type }: { type: OutstandingType }) => { + return ( + + ); +}; + +export default DropDownTrigger; diff --git a/apps/admin/app/students/_components/OutstandingDropDown/index.tsx b/apps/admin/app/students/_components/OutstandingDropDown/index.tsx new file mode 100644 index 00000000..12d1a4ef --- /dev/null +++ b/apps/admin/app/students/_components/OutstandingDropDown/index.tsx @@ -0,0 +1,64 @@ +"use client"; + +import { styled } from "@styled-system/jsx"; +import type { OutstandingType } from "constants/status/outstandigOptions"; +import { + OUTSTANDING_ADD_OPTIONS, + OUTSTANDING_DEL_OPTIONS, +} from "constants/status/outstandigOptions"; +import { useSetAtom } from "jotai"; +import type { AchievementType } from "types/entities/achievement"; +import DropDown from "wowds-ui/DropDown"; +import DropDownOption from "wowds-ui/DropDownOption"; + +import { + enabledOutstandingStudentsAtom, + outstandingStudentsAtom, +} from "@/students/_contexts/StudyProvider"; + +import DropDownTrigger from "./DropDownTrigger"; + +const OutstandingDropDown = ({ type }: { type: OutstandingType }) => { + const setOutstandingStudents = useSetAtom(outstandingStudentsAtom); + const setEnabled = useSetAtom(enabledOutstandingStudentsAtom); + + const findOptions = () => { + if (type === "처리") return OUTSTANDING_ADD_OPTIONS; + if (type === "철회") return OUTSTANDING_DEL_OPTIONS; + return null; + }; + + const options = findOptions(); + + return ( + + + + } + onChange={(value: { + selectedValue: string; + selectedText: React.ReactNode; + }) => { + setOutstandingStudents({ + type, + achievement: value.selectedValue as AchievementType, + }); + setEnabled({ enabled: true }); + }} + > + {options && + options.map((option) => ( + + ))} + + ); +}; + +export default OutstandingDropDown; diff --git a/apps/admin/app/students/_components/StudentTable/StudentList.tsx b/apps/admin/app/students/_components/StudentTable/StudentList.tsx index 205ab035..4095f143 100644 --- a/apps/admin/app/students/_components/StudentTable/StudentList.tsx +++ b/apps/admin/app/students/_components/StudentTable/StudentList.tsx @@ -1,7 +1,16 @@ +import { styled } from "@styled-system/jsx"; import { Text } from "@wow-class/ui"; +import { useAtom, useAtomValue } from "jotai"; import type { StudyStudentApiResponseDto } from "types/dtos/studyStudent"; +import Checkbox from "wowds-ui/Checkbox"; import Table from "wowds-ui/Table"; +import { + enabledOutstandingStudentsAtom, + outstandingStudentsAtom, + selectedStudentsAtom, +} from "@/students/_contexts/StudyProvider"; + import StudentListItem from "./StudentListItem"; import { StudyTasksThs } from "./StudyTasks"; @@ -23,25 +32,113 @@ const StudentList = ({ }: { studentList: StudyStudentApiResponseDto[] | []; }) => { + const { enabled } = useAtomValue(enabledOutstandingStudentsAtom); + const { type, achievement } = useAtomValue(outstandingStudentsAtom); + const [selectedStudents, setSelectedStudents] = useAtom(selectedStudentsAtom); + if (!studentList) return null; if (!studentList.length) return 스터디 수강생이 없어요.; + const handleChangeSelectedStudents = (ids: number[]) => { + const firstStudent = studentList.find( + (student) => student.memberId === ids[0] + )?.name; + + setSelectedStudents({ + firstStudentName: firstStudent, + students: new Set(ids), + }); + }; + + const isDisabled = (student: StudyStudentApiResponseDto) => { + if (achievement === "COMPLETE") { + return type === "처리" + ? student.studyHistoryStatus === "COMPLETED" + : student.studyHistoryStatus !== "COMPLETED"; + } else if (achievement === "FIRST_ROUND_OUTSTANDING_STUDENT") { + return type === "처리" + ? student.isFirstRoundOutstandingStudent + : !student.isFirstRoundOutstandingStudent; + } else if (achievement === "SECOND_ROUND_OUTSTANDING_STUDENT") { + return type === "처리" + ? student.isSecondRoundOutstandingStudent + : !student.isSecondRoundOutstandingStudent; + } + }; + + const isAllChecked = + studentList.filter((student) => !isDisabled(student)).length === + selectedStudents.students.size; + + const handleChangeAllChecked = () => { + if (isAllChecked) { + setSelectedStudents({ + firstStudentName: "", + students: new Set(), + }); + return; + } + handleChangeSelectedStudents( + studentList + .filter((student) => !isDisabled(student)) + .map((student) => student.memberId) + ); + }; + + const handleChangeSingleChecked = (id: number) => { + if (selectedStudents.students.has(id)) { + const newSet = new Set(selectedStudents.students); + newSet.delete(id); + handleChangeSelectedStudents([...newSet]); + return; + } + handleChangeSelectedStudents([...selectedStudents.students, id]); + }; + return ( - - - {STUENT_INFO_LIST_BEFORE.map((info) => ( - {info} - ))} - {studentList[0] && } - {STUDENT_INFO_LIST_AFTER.map((info) => ( - {info} - ))} - +
+ + + {enabled && ( + + + + )} + {STUENT_INFO_LIST_BEFORE.map((info) => ( + {info} + ))} + {studentList[0] && ( + + )} + {STUDENT_INFO_LIST_AFTER.map((info) => ( + {info} + ))} + + {studentList.map((student) => ( - + + {enabled && ( + + handleChangeSingleChecked(student.memberId)} + /> + + )} - + ))}
@@ -49,3 +146,11 @@ const StudentList = ({ }; export default StudentList; + +const tableCheckBoxStyle = { + minWidth: "15px", + display: "flex", + minHeight: "44px", + justifyContent: "center", + alignItems: "center", +}; diff --git a/apps/admin/app/students/_components/StudentsContent.tsx b/apps/admin/app/students/_components/StudentsContent.tsx new file mode 100644 index 00000000..90088ee4 --- /dev/null +++ b/apps/admin/app/students/_components/StudentsContent.tsx @@ -0,0 +1,37 @@ +"use client"; + +import { Text } from "@wow-class/ui"; +import useFetchStudents from "hooks/fetch/useFetchStudents"; +import { useAtomValue } from "jotai"; +import { useState } from "react"; + +import { studyAtom } from "../_contexts/StudyProvider"; +import StudentFilter from "./StudentFilter"; +import StudentPagination from "./StudentPagination"; +import StudentList from "./StudentTable/StudentList"; + +const StudentsContent = () => { + const selectedStudy = useAtomValue(studyAtom); + const [page, setPage] = useState(1); + const handleClickChangePage = (nextPage: number) => { + setPage(nextPage); + }; + + const { studentList, pageInfo } = useFetchStudents(selectedStudy, page); + if (!selectedStudy) return 담당한 스터디가 없어요.; + + return ( + <> + {/* TODO: 페이지네이션 API 필터 추가 후 주석 해제 + {studentList.length ? : null} + */} + + + + ); +}; + +export default StudentsContent; diff --git a/apps/admin/app/students/_components/StudentsHeader.tsx b/apps/admin/app/students/_components/StudentsHeader.tsx deleted file mode 100644 index 10029b52..00000000 --- a/apps/admin/app/students/_components/StudentsHeader.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Flex, styled } from "@styled-system/jsx"; -import { Text } from "@wow-class/ui"; -import { studyApi } from "apis/study/studyApi"; -import ItemSeparator from "components/ItemSeparator"; -import Image from "next/image"; -import type { CSSProperties } from "react"; -import { useEffect, useState } from "react"; -import type { StudyListApiResponseDto } from "types/dtos/studyList"; - -import StudyDropDown from "./StudyDropDown"; - -const StudentsHeader = ({ - studyList, - studyId, - studentLength, -}: { - studyList: StudyListApiResponseDto[]; - studyId: number; - studentLength: number; -}) => { - const [url, setUrl] = useState(""); - - useEffect(() => { - const fetchData = async () => { - const response = await studyApi.getStudyStudentsExcel(studyId); - const blob = new Blob([response], { - type: "application/vnd.ms-excel", - }); - const url = URL.createObjectURL(blob); - if (url) setUrl(url); - }; - - if (studentLength) fetchData(); - }, [studyId, studentLength]); - - return ( - - - 수강생 관리 - - - {studyId && !!studentLength && ( - - 다운로드 - - )} - - ); -}; - -const titleStyle: CSSProperties = { - display: "flex", - alignItems: "center", - gap: "0.75rem", - whiteSpace: "nowrap", -}; - -export default StudentsHeader; diff --git a/apps/admin/app/students/_components/StudentsHeader/DownloadButton.tsx b/apps/admin/app/students/_components/StudentsHeader/DownloadButton.tsx new file mode 100644 index 00000000..c0c65452 --- /dev/null +++ b/apps/admin/app/students/_components/StudentsHeader/DownloadButton.tsx @@ -0,0 +1,16 @@ +import { styled } from "@styled-system/jsx"; +import useFetchStudentsExcelUrl from "hooks/fetch/useFetchStudentsExcelUrl"; +import Image from "next/image"; + +const DownloadButton = ({ studyId }: { studyId: number }) => { + const url = useFetchStudentsExcelUrl({ + studyId, + }); + + return ( + + 다운로드 + + ); +}; +export default DownloadButton; diff --git a/apps/admin/app/students/_components/StudentsHeader/StudentHeaderButtons.tsx b/apps/admin/app/students/_components/StudentsHeader/StudentHeaderButtons.tsx new file mode 100644 index 00000000..43da08a4 --- /dev/null +++ b/apps/admin/app/students/_components/StudentsHeader/StudentHeaderButtons.tsx @@ -0,0 +1,47 @@ +import { outstandingRoundMap } from "constants/status/outstandigOptions"; +import { useAtom, useAtomValue } from "jotai"; +import Link from "next/link"; +import Button from "wowds-ui/Button"; + +import { + enabledOutstandingStudentsAtom, + outstandingStudentsAtom, + selectedStudentsAtom, +} from "../../_contexts/StudyProvider"; +import OutstandingDropDown from "../OutstandingDropDown"; + +const StudentsHeaderButtons = () => { + const [{ enabled }, setEnabledOutstandingStudents] = useAtom( + enabledOutstandingStudentsAtom + ); + const { type, achievement } = useAtomValue(outstandingStudentsAtom); + const [{ students }, setSelectedStudents] = useAtom(selectedStudentsAtom); + + const handleClickCancelButton = () => { + setEnabledOutstandingStudents({ enabled: false }); + setSelectedStudents({ firstStudentName: "", students: new Set() }); + }; + + return enabled ? ( + <> + + + + ) : ( + <> + + + + ); +}; + +export default StudentsHeaderButtons; diff --git a/apps/admin/app/students/_components/StudentsHeader/index.tsx b/apps/admin/app/students/_components/StudentsHeader/index.tsx new file mode 100644 index 00000000..356af097 --- /dev/null +++ b/apps/admin/app/students/_components/StudentsHeader/index.tsx @@ -0,0 +1,63 @@ +"use client"; + +import { Flex } from "@styled-system/jsx"; +import { Text } from "@wow-class/ui"; +import { studyApi } from "apis/study/studyApi"; +import ItemSeparator from "components/ItemSeparator"; +import { useAtom } from "jotai"; +import type { CSSProperties } from "react"; +import { useEffect, useState } from "react"; +import type { StudyListApiResponseDto } from "types/dtos/studyList"; +import isAdmin from "utils/isAdmin"; + +import { studyAtom } from "../../_contexts/StudyProvider"; +import StudyDropDown from "../StudyDropDown"; +import DownloadButton from "./DownloadButton"; +import StudentsHeaderButtons from "./StudentHeaderButtons"; + +const StudentsHeader = () => { + const [studyList, setStudyList] = useState(); + const [selectedStudy, setSelectedStudy] = useAtom(studyAtom); + + useEffect(() => { + const fetchData = async () => { + const adminStatus = await isAdmin(); + const data = adminStatus + ? await studyApi.getStudyList() + : await studyApi.getMyStudyList(); + + if (data && data.length && data[0]) { + setStudyList(data); + setSelectedStudy({ studyId: data[0].studyId, title: data[0].title }); + } + }; + + fetchData(); + }, [setSelectedStudy]); + + if (!selectedStudy || !studyList) return null; + + return ( + + + 수강생 관리 + + + + + {selectedStudy.studyId && ( + + )} + + + ); +}; + +const titleStyle: CSSProperties = { + display: "flex", + alignItems: "center", + gap: "0.75rem", + whiteSpace: "nowrap", +}; + +export default StudentsHeader; diff --git a/apps/admin/app/students/_components/StudyDropDown/index.tsx b/apps/admin/app/students/_components/StudyDropDown/index.tsx index d19a55a9..161864f6 100644 --- a/apps/admin/app/students/_components/StudyDropDown/index.tsx +++ b/apps/admin/app/students/_components/StudyDropDown/index.tsx @@ -1,11 +1,15 @@ import { Flex } from "@styled-system/jsx"; -import { useAtom } from "jotai"; +import { useAtom, useSetAtom } from "jotai"; import type { ReactNode } from "react"; import type { StudyListApiResponseDto } from "types/dtos/studyList"; import DropDown from "wowds-ui/DropDown"; import DropDownOption from "wowds-ui/DropDownOption"; -import { studyAtom } from "../../_contexts/StudyProvider"; +import { + enabledOutstandingStudentsAtom, + selectedStudentsAtom, + studyAtom, +} from "../../_contexts/StudyProvider"; import DropDownTrigger from "./DropDownTrigger"; const StudyDropDown = ({ @@ -14,6 +18,8 @@ const StudyDropDown = ({ studyList: StudyListApiResponseDto[]; }) => { const [study, setStudy] = useAtom(studyAtom); + const setSelectedStudents = useSetAtom(selectedStudentsAtom); + const setEnabled = useSetAtom(enabledOutstandingStudentsAtom); if (!study) return null; @@ -36,6 +42,13 @@ const StudyDropDown = ({ studyId: +value.selectedValue, title: value.selectedText, }); + setSelectedStudents({ + firstStudentName: "", + students: new Set(), + }); + setEnabled({ + enabled: false, + }); }} > {studyList.map((study: StudyListApiResponseDto) => ( diff --git a/apps/admin/app/students/_contexts/StudyProvider.tsx b/apps/admin/app/students/_contexts/StudyProvider.tsx index 484a8224..4ac53adb 100644 --- a/apps/admin/app/students/_contexts/StudyProvider.tsx +++ b/apps/admin/app/students/_contexts/StudyProvider.tsx @@ -1,7 +1,12 @@ "use client"; +import type { + CompleteType, + OutstandingType, +} from "constants/status/outstandigOptions"; import { atom, createStore, Provider } from "jotai"; import type { PropsWithChildren, ReactNode } from "react"; +import type { AchievementType } from "types/entities/achievement"; const studyIdStore = createStore(); @@ -10,8 +15,31 @@ export type StudyAtomprops = { title: ReactNode; }; +export type OutstandingStudentsProps = { + type?: OutstandingType; + achievement?: AchievementType | CompleteType; +}; + +export type SetOutstandingStudentsProps = { + enabled: boolean; +}; + +export type SelectedStudentsProps = { + firstStudentName?: string; + students: Set; +}; + export const studyAtom = atom(); -studyIdStore.set(studyAtom, undefined); + +export const outstandingStudentsAtom = atom({}); + +export const selectedStudentsAtom = atom({ + students: new Set(), +}); + +export const enabledOutstandingStudentsAtom = atom( + { enabled: false } +); export const StudyProvider = ({ children }: PropsWithChildren) => { return {children}; diff --git a/apps/admin/app/students/default.tsx b/apps/admin/app/students/default.tsx new file mode 100644 index 00000000..395785b9 --- /dev/null +++ b/apps/admin/app/students/default.tsx @@ -0,0 +1,5 @@ +const Default = () => { + return null; +}; + +export default Default; diff --git a/apps/admin/app/students/layout.tsx b/apps/admin/app/students/layout.tsx index 5b02ec4c..6b0ed40a 100644 --- a/apps/admin/app/students/layout.tsx +++ b/apps/admin/app/students/layout.tsx @@ -1,25 +1,29 @@ import { css } from "@styled-system/css"; -import { styled } from "@styled-system/jsx"; import Navbar from "components/Navbar"; import { StudyProvider } from "./_contexts/StudyProvider"; const StudentsLayout = ({ children, + modal, }: Readonly<{ children: React.ReactNode; + modal: React.ReactNode; }>) => { return ( - {children} +
+ {children} + {modal} +
); }; export default StudentsLayout; -const StudentsLayoutStyle = css({ +const studentsLayoutStyle = css({ display: "flex", flexDirection: "column", gap: "sm", diff --git a/apps/admin/app/students/page.tsx b/apps/admin/app/students/page.tsx index defba01f..d06a1807 100644 --- a/apps/admin/app/students/page.tsx +++ b/apps/admin/app/students/page.tsx @@ -1,65 +1,13 @@ -"use client"; - import { Flex } from "@styled-system/jsx"; -import { Text } from "@wow-class/ui"; -import { studyApi } from "apis/study/studyApi"; -import useFetchStudents from "hooks/fetch/useFetchStudents"; -import { useAtom } from "jotai"; -import { useEffect, useState } from "react"; -import type { StudyListApiResponseDto } from "types/dtos/studyList"; -import isAdmin from "utils/isAdmin"; -import StudentFilter from "./_components/StudentFilter"; -import StudentPagination from "./_components/StudentPagination"; +import StudentsContent from "./_components/StudentsContent"; import StudentsHeader from "./_components/StudentsHeader"; -import StudentList from "./_components/StudentTable/StudentList"; -import { studyAtom } from "./_contexts/StudyProvider"; const StudentsPage = () => { - const [studyList, setStudyList] = useState(); - const [selectedStudy, setSelectedStudy] = useAtom(studyAtom); - - useEffect(() => { - const fetchData = async () => { - const adminStatus = await isAdmin(); - const data = adminStatus - ? await studyApi.getStudyList() - : await studyApi.getMyStudyList(); - - if (data && data.length && data[0]) { - setStudyList(data); - setSelectedStudy({ studyId: data[0].studyId, title: data[0].title }); - } - }; - - fetchData(); - }, [setSelectedStudy]); - - const [page, setPage] = useState(1); - const handleClickChangePage = (nextPage: number) => { - setPage(nextPage); - }; - - const { studentList, pageInfo } = useFetchStudents(selectedStudy, page); - if (!selectedStudy) return null; - if (!studyList) return 담당한 스터디가 없어요.; - return ( - - - {/* TODO: 페이지네이션 API 필터 추가 후 주석 해제 - {studentList.length ? : null} - */} - - + + ); }; diff --git a/apps/admin/app/students/status/page.tsx b/apps/admin/app/students/status/page.tsx new file mode 100644 index 00000000..3d5aa234 --- /dev/null +++ b/apps/admin/app/students/status/page.tsx @@ -0,0 +1,8 @@ +import { routerPath } from "constants/router/routerPath"; +import { redirect } from "next/navigation"; + +const StudentStatusPage = () => { + return redirect(routerPath.students.href); +}; + +export default StudentStatusPage; diff --git a/apps/admin/app/studies/layout.tsx b/apps/admin/app/studies/layout.tsx index 7cb5699e..8bba047b 100644 --- a/apps/admin/app/studies/layout.tsx +++ b/apps/admin/app/studies/layout.tsx @@ -1,5 +1,4 @@ import { css } from "@styled-system/css"; -import { styled } from "@styled-system/jsx"; import Navbar from "components/Navbar"; const StudiesLayout = ({ @@ -10,14 +9,14 @@ const StudiesLayout = ({ return ( <> - {children} +
{children}
); }; export default StudiesLayout; -const StudiesLayoutStyle = css({ +const studiesLayoutStyle = css({ display: "flex", flexDirection: "column", gap: "sm", diff --git a/apps/admin/constants/router/routerPath.ts b/apps/admin/constants/router/routerPath.ts index b8415d60..7eb8a83c 100644 --- a/apps/admin/constants/router/routerPath.ts +++ b/apps/admin/constants/router/routerPath.ts @@ -39,4 +39,8 @@ export const routerPath = { href: (studyDetailId: number | string) => `/studies/assignments/${studyDetailId}/edit-assignment`, }, + students: { + description: "스터디 학생 관리 페이지로 이동합니다.", + href: "/students", + }, }; diff --git a/apps/admin/constants/status/outstandigOptions.ts b/apps/admin/constants/status/outstandigOptions.ts new file mode 100644 index 00000000..7b22bac2 --- /dev/null +++ b/apps/admin/constants/status/outstandigOptions.ts @@ -0,0 +1,36 @@ +import type { AchievementType } from "types/entities/achievement"; + +export type CompleteType = "COMPLETE"; + +export type OutstandingDropDownOption = { + id: number; + text: string; + value: AchievementType | CompleteType; +}; + +export const OUTSTANDING_ADD_OPTIONS: OutstandingDropDownOption[] = [ + { id: 1, text: "1차 우수 처리", value: "FIRST_ROUND_OUTSTANDING_STUDENT" }, + { id: 2, text: "2차 우수 처리", value: "SECOND_ROUND_OUTSTANDING_STUDENT" }, + { id: 3, text: "수료 처리", value: "COMPLETE" }, +]; +export const OUTSTANDING_DEL_OPTIONS: OutstandingDropDownOption[] = [ + { id: 1, text: "1차 우수 철회", value: "FIRST_ROUND_OUTSTANDING_STUDENT" }, + { id: 2, text: "2차 우수 철회", value: "SECOND_ROUND_OUTSTANDING_STUDENT" }, + { id: 3, text: "수료 철회", value: "COMPLETE" }, +]; + +export const outstandingRoundMap: Record< + AchievementType | CompleteType, + "1차 우수" | "2차 우수" | "수료" +> = { + FIRST_ROUND_OUTSTANDING_STUDENT: "1차 우수", + SECOND_ROUND_OUTSTANDING_STUDENT: "2차 우수", + COMPLETE: "수료", +}; + +export type OutstandingType = "처리" | "철회"; + +export const outstandingTypeMap: Record = { + 처리: "회원으로 등록", + 철회: "회원에서 철회", +}; diff --git a/apps/admin/hooks/fetch/useFetchStudents.ts b/apps/admin/hooks/fetch/useFetchStudents.ts index 43296d8d..5dbb0a6d 100644 --- a/apps/admin/hooks/fetch/useFetchStudents.ts +++ b/apps/admin/hooks/fetch/useFetchStudents.ts @@ -1,4 +1,5 @@ import { studyApi } from "apis/study/studyApi"; +import { usePathname } from "next/navigation"; import { useEffect, useState } from "react"; import type { PaginatedStudyStudentResponseDto, @@ -23,6 +24,7 @@ const useFetchStudents = ( PaginatedStudyStudentResponseDto, "content" > | null>(null); + const pathname = usePathname(); useEffect(() => { const fetchStudentsData = async () => { @@ -40,7 +42,7 @@ const useFetchStudents = ( }; fetchStudentsData(); - }, [study, page]); + }, [study, page, pathname]); return { studentList, pageInfo }; }; diff --git a/apps/admin/hooks/fetch/useFetchStudentsExcelUrl.ts b/apps/admin/hooks/fetch/useFetchStudentsExcelUrl.ts new file mode 100644 index 00000000..b61c44a1 --- /dev/null +++ b/apps/admin/hooks/fetch/useFetchStudentsExcelUrl.ts @@ -0,0 +1,23 @@ +import { studyApi } from "apis/study/studyApi"; +import { useEffect, useState } from "react"; + +const useFetchStudentsExcelUrl = ({ studyId }: { studyId: number }) => { + const [url, setUrl] = useState(""); + + useEffect(() => { + const fetchData = async () => { + const response = await studyApi.getStudyStudentsExcel(studyId); + const blob = new Blob([response], { + type: "application/vnd.ms-excel", + }); + const url = URL.createObjectURL(blob); + if (url) setUrl(url); + }; + + fetchData(); + }, [studyId]); + + return url; +}; + +export default useFetchStudentsExcelUrl; diff --git a/apps/admin/types/dtos/outstandingStudent.ts b/apps/admin/types/dtos/outstandingStudent.ts new file mode 100644 index 00000000..17e11527 --- /dev/null +++ b/apps/admin/types/dtos/outstandingStudent.ts @@ -0,0 +1,6 @@ +import type { AchievementType } from "../entities/achievement"; + +export interface OutstandingStudentApiRequestDto { + studentIds: number[]; + achievementType: AchievementType; +} diff --git a/apps/admin/types/dtos/studyComplete.ts b/apps/admin/types/dtos/studyComplete.ts new file mode 100644 index 00000000..cc488078 --- /dev/null +++ b/apps/admin/types/dtos/studyComplete.ts @@ -0,0 +1,4 @@ +export interface StudyCompleteRequestDto { + studyId: number; + studentIds: number[]; +} diff --git a/apps/admin/types/entities/achievement.ts b/apps/admin/types/entities/achievement.ts new file mode 100644 index 00000000..d08d93bb --- /dev/null +++ b/apps/admin/types/entities/achievement.ts @@ -0,0 +1,3 @@ +export type AchievementType = + | "FIRST_ROUND_OUTSTANDING_STUDENT" + | "SECOND_ROUND_OUTSTANDING_STUDENT"; diff --git a/package.json b/package.json index 15f3fa8c..02559cde 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,6 @@ "clsx": "^2.1.1", "wowds-icons": "^0.1.4", "wowds-tokens": "^0.1.1", - "wowds-ui": "^0.1.19" + "wowds-ui": "^0.1.20" } } diff --git a/packages/utils/src/fetcher/index.ts b/packages/utils/src/fetcher/index.ts index 5c9c8b66..7e1ad6e6 100644 --- a/packages/utils/src/fetcher/index.ts +++ b/packages/utils/src/fetcher/index.ts @@ -157,7 +157,7 @@ class Fetcher { patch( url: string, - body: any, + body: any = {}, options: RequestInit = {} ): Promise> { return this.request(url, { @@ -169,9 +169,14 @@ class Fetcher { delete( url: string, + body: any = {}, options: RequestInit = {} ): Promise> { - return this.request(url, { ...options, method: "DELETE" }); + return this.request(url, { + ...options, + method: "DELETE", + body: JSON.stringify(body), + }); } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d85ccd67..ee3fdfef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^0.1.1 version: 0.1.3 wowds-ui: - specifier: ^0.1.19 - version: 0.1.19(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) + specifier: ^0.1.20 + version: 0.1.20(next@14.2.5)(react-dom@18.3.1)(react@18.3.1) devDependencies: '@pandacss/dev': specifier: ^0.44.0 @@ -13756,8 +13756,8 @@ packages: resolution: {integrity: sha512-2mYkhEOZFNXbkH++osn0Qabni08wa0HkbUjnEQVh8j+cni0Te64ZkF9HbynHk2gj1nrFyD6oOSNsIwnJ1IQqmQ==} dev: false - /wowds-icons@0.1.5: - resolution: {integrity: sha512-F2M4+oL2onugKcDH1yizQiVzwMXWA1+L7KI+ryRmCdmclkguVaxQJpboTAH9M2tVs3PrI3OeDV6Q6rCumzkR9w==} + /wowds-icons@0.1.6: + resolution: {integrity: sha512-/7xLOIvHNTuOfMhSM+JfPF6MaDwS5jC6JN7JXPvo3T52l63Wy63cNskwWrZ1WaD5fHvuG9Il4p9AOB8+zp/ppg==} dev: false /wowds-theme@0.1.3: @@ -13768,8 +13768,8 @@ packages: resolution: {integrity: sha512-Pej6MuUec/i6A04gWELi4bb/T2I8gf/57L9rX8G7ElVeMc7/03ELoM0nBFWKybtpYExXhhlQPp0Lg7iqATpy6Q==} dev: false - /wowds-ui@0.1.19(next@14.2.5)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-N+AF9zLW9Tdipa53tlvcNcZS4oCelWZZsQ1CT6E1QWkF2Bn4mcj+D+KtkZDXJlK67JNlatMzmLmmOJWUHjUI0A==} + /wowds-ui@0.1.20(next@14.2.5)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-UhdmUrN/fSEt0dpWC3UflSE2qK5Y+n46tR9ZEvfvLOW5J8fwBFhbKhgW867qKGxC851GP/o16TOTU9jMsuzZ8A==} peerDependencies: next: ^14.1.1 react: ^18.2.0 @@ -13780,7 +13780,7 @@ packages: react: 18.3.1 react-day-picker: 9.0.8(react@18.3.1) uuid: 10.0.0 - wowds-icons: 0.1.5 + wowds-icons: 0.1.6 transitivePeerDependencies: - react-dom dev: false From 4d19b922a55fbec114e13438c5c70284c2d6ff66 Mon Sep 17 00:00:00 2001 From: SeieunYoo Date: Sat, 28 Dec 2024 22:24:04 +0900 Subject: [PATCH 53/62] =?UTF-8?q?feat:=20=EB=A0=88=ED=8F=AC=EC=A7=80?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=B0=95=EC=8A=A4=20=EB=AC=B8=EA=B5=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AssignmentContent/RepositorySubmissionBox.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx index 5139509c..1196b290 100644 --- a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx @@ -21,6 +21,8 @@ interface RepositorySubmissionBoxProps { repositoryLink: string; } +const repositoryInfoMessage = "과제 제출 후에도 레포지토리 수정이 가능해요."; + export const RepositorySubmissionBox = ({ repositoryLink: initialRepositoryUrl, }: RepositorySubmissionBoxProps) => { @@ -124,9 +126,7 @@ export const RepositorySubmissionBox = ({ <> {repositorySubmissionStatus === "SUBMITTED" && ( <> - - 최초 과제 제출 전 까지만 수정이 가능해요. - + {repositoryInfoMessage}
{repositoryUrl}
@@ -184,7 +184,7 @@ export const RepositorySubmissionBox = ({ 레포지토리를 입력하시겠어요? - 최초 과제 제출 전까지 수정이 가능해요. + {repositoryInfoMessage}
{repositoryUrl}
@@ -219,9 +219,6 @@ const modalUrlBoxStyle = css({ paddingX: "lg", paddingY: "sm", textStyle: "h2", - overflow: "hidden", - textOverflow: "ellipsis", - whiteSpace: "nowrap", width: "375px", }); const boxStyle = { From e37446dc93abd66ccdaa0003554f213355745a20 Mon Sep 17 00:00:00 2001 From: SeieunYoo Date: Sat, 28 Dec 2024 22:27:16 +0900 Subject: [PATCH 54/62] =?UTF-8?q?feat:=201=EC=A3=BC=EC=B0=A8=20=EA=B3=BC?= =?UTF-8?q?=EC=A0=9C=EA=B0=80=20=EC=9E=88=EC=9C=BC=EB=A9=B4=20=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EB=B0=95=EC=8A=A4=20=EC=99=BC=EC=AA=BD=EC=97=90=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/AssignmentContent/index.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx index c8d8eecf..3f2250cd 100644 --- a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx @@ -33,19 +33,24 @@ export const AssignmentContent = async () => { ); } + const isAnyFirstWeekAssignment = studyDashboard.submittableAssignments.some( + ({ week }) => week === 1 + ); return (
- - {studyDashboard.isLinkEditable && ( - - )} + +
); From f40b396d8d9ab3fca036cd62dd8a658dc47d7ccb Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Sun, 29 Dec 2024 19:51:03 +0900 Subject: [PATCH 55/62] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ndanceRate.tsx => StudyAnalyticsGraph.tsx} | 24 ++++---- .../statics/StudyAssignmentRate.tsx | 60 ------------------- .../_components/statics/StudyCompleteRate.tsx | 3 +- .../_components/statics/StudyStatics.tsx | 15 +++-- .../_components/statics/graph/BarGraph.tsx | 23 ++++--- .../_components/statics/graph/CircleGraph.tsx | 12 ++-- .../statics/graph/GraphToolTip.tsx | 12 ++-- .../_components/AssignmentDescription.tsx | 2 +- apps/client/components/Tooltip.tsx | 54 ----------------- .../components/Tooltip/Tooltip.stories.tsx | 39 ++++++++++++ .../ui/src/components/Tooltip/index.tsx | 2 +- packages/ui/src/components/index.ts | 1 + 12 files changed, 86 insertions(+), 161 deletions(-) rename apps/admin/app/studies/[studyId]/_components/statics/{StudyAttendanceRate.tsx => StudyAnalyticsGraph.tsx} (77%) delete mode 100644 apps/admin/app/studies/[studyId]/_components/statics/StudyAssignmentRate.tsx delete mode 100644 apps/client/components/Tooltip.tsx create mode 100644 packages/ui/src/components/Tooltip/Tooltip.stories.tsx rename apps/admin/components/Tooltip.tsx => packages/ui/src/components/Tooltip/index.tsx (95%) diff --git a/apps/admin/app/studies/[studyId]/_components/statics/StudyAttendanceRate.tsx b/apps/admin/app/studies/[studyId]/_components/statics/StudyAnalyticsGraph.tsx similarity index 77% rename from apps/admin/app/studies/[studyId]/_components/statics/StudyAttendanceRate.tsx rename to apps/admin/app/studies/[studyId]/_components/statics/StudyAnalyticsGraph.tsx index 4da8ef05..53f17f7d 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/StudyAttendanceRate.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/StudyAnalyticsGraph.tsx @@ -5,19 +5,21 @@ import type { StudyWeekStatisticsApiResponseDto } from "types/dtos/studyStatisti import BarGraph from "./graph/BarGraph"; -const StudyAttendanceRate = ({ - averageAttendanceRate = 0, +const StudyAnalyticsGraph = ({ + graphTitle, + averageRate = 0, totalStudent, studyWeekStatisticsResponses, }: { - averageAttendanceRate?: number; + graphTitle: string; + averageRate?: number; totalStudent?: number; studyWeekStatisticsResponses?: StudyWeekStatisticsApiResponseDto[]; }) => { return ( - - 출석률 + + {graphTitle} @@ -25,7 +27,7 @@ const StudyAttendanceRate = ({ @@ -39,13 +41,13 @@ const StudyAttendanceRate = ({ ))} - + 평균 @@ -54,12 +56,12 @@ const StudyAttendanceRate = ({ ); }; -export default StudyAttendanceRate; +export default StudyAnalyticsGraph; -const StudyWeekStyle = css({ +const studyWeekStyle = css({ minWidth: "45px", }); -const StaticsTitleStyle = css({ +const staticsTitleStyle = css({ marginBottom: "10px", }); diff --git a/apps/admin/app/studies/[studyId]/_components/statics/StudyAssignmentRate.tsx b/apps/admin/app/studies/[studyId]/_components/statics/StudyAssignmentRate.tsx deleted file mode 100644 index 9490a2cd..00000000 --- a/apps/admin/app/studies/[studyId]/_components/statics/StudyAssignmentRate.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { css } from "@styled-system/css"; -import { Flex } from "@styled-system/jsx"; -import { Text } from "@wow-class/ui"; -import type { StudyWeekStatisticsApiResponseDto } from "types/dtos/studyStatistics"; - -import BarGraph from "./graph/BarGraph"; - -const StudyAssignmentRate = ({ - averageAssignmentSubmissionRate, - totalStudent, - studyWeekStatisticsResponses, -}: { - averageAssignmentSubmissionRate?: number; - totalStudent?: number; - studyWeekStatisticsResponses?: StudyWeekStatisticsApiResponseDto[]; -}) => { - return ( - - - 과제 제출률 - - - - {studyWeekStatisticsResponses?.map((data) => ( - - - {data.week}주차 - - - - ))} - - - 평균 - - - - - - - ); -}; - -export default StudyAssignmentRate; - -const StudyWeekStyle = css({ - minWidth: "45px", -}); - -const StaticsTitleStyle = css({ - marginBottom: "10px", -}); diff --git a/apps/admin/app/studies/[studyId]/_components/statics/StudyCompleteRate.tsx b/apps/admin/app/studies/[studyId]/_components/statics/StudyCompleteRate.tsx index f864ad0e..c0f9e418 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/StudyCompleteRate.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/StudyCompleteRate.tsx @@ -1,7 +1,6 @@ "use client"; import { Flex } from "@styled-system/jsx"; -import { Text } from "@wow-class/ui"; -import Tooltip from "components/Tooltip"; +import { Text, Tooltip } from "@wow-class/ui"; import { Help } from "wowds-icons"; import CircleGraph from "./graph/CircleGraph"; diff --git a/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx b/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx index b1a126a1..43de41ae 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx @@ -2,8 +2,7 @@ import { Flex } from "@styled-system/jsx"; import { Space, Text } from "@wow-class/ui"; import { studyApi } from "apis/study/studyApi"; -import StudyAssignmentRate from "./StudyAssignmentRate"; -import StudyAttendanceRate from "./StudyAttendanceRate"; +import StudyAnalyticsGraph from "./StudyAnalyticsGraph"; import StudyCompleteRate from "./StudyCompleteRate"; const StudyStatics = async ({ studyId }: { studyId: string }) => { @@ -22,18 +21,18 @@ const StudyStatics = async ({ studyId }: { studyId: string }) => { - - { const [showTooltip, setShowTooltip] = useState(false); + const toggleTooltip = () => { + if (isToolTipActive) setShowTooltip((prevState) => !prevState); + }; return ( 0 ? (
{ - if (isToolTipActive) setShowTooltip(true); - }} - onMouseLeave={() => { - if (isToolTipActive) setShowTooltip(false); - }} + onMouseEnter={toggleTooltip} + onMouseLeave={toggleTooltip} > -
+
{percent > 0 && `${percent}%`} @@ -57,7 +56,7 @@ const BarGraph = ({
) : ( - + 0% )} @@ -98,7 +97,7 @@ const BarGraphBackgroundStyle = cva({ }, }); -const BarGraphStyle = cva({ +const barGraphStyle = cva({ base: { position: "absolute", zIndex: 10, @@ -128,12 +127,12 @@ const percentLabelStyle = css({ alignItems: "center", }); -const BarGraphInnerStyle = css({ +const barGraphInnerStyle = css({ position: "relative", width: "100%", height: "100%", }); -const ZeroPercentLabel = css({ +const zeroPercentLabelStyle = css({ marginLeft: "8px", }); diff --git a/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx b/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx index e0680c23..406cf5ef 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx @@ -20,9 +20,9 @@ const CircleGraph = ({ return ( -
+
- + {percentage}%
@@ -56,17 +56,17 @@ const CircleGraph = ({ export default CircleGraph; -const CircleGraphStyle = css({ +const circleGraphStyle = css({ width: "100%", transform: "rotate(-90deg)", }); -const CircleGraphWrapperStyle = css({ +const circleGraphWrapperStyle = css({ width: "100%", position: "relative", }); -const CircleGraphLabelStyle = css({ +const circleGraphLabelStyle = css({ position: "absolute", top: "50%", left: "50%", diff --git a/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx b/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx index 88d9a171..3327f70f 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx @@ -2,20 +2,20 @@ import { css } from "@styled-system/css"; import { Text } from "@wow-class/ui"; const GraphToolTip = ({ studentCount }: { studentCount: number }) => { return ( -
-
+
+
{studentCount}명
-
+
); }; export default GraphToolTip; -const ToolTipContainerStyle = css({ +const toolTipContainerStyle = css({ position: "absolute", width: "43px", height: "38px", @@ -25,7 +25,7 @@ const ToolTipContainerStyle = css({ zIndex: 20, }); -const ToolTipStyle = css({ +const toolTipStyle = css({ position: "relative", width: "100%", height: "24px", @@ -36,7 +36,7 @@ const ToolTipStyle = css({ zIndex: 20, }); -const ToolTipDecoStyle = css({ +const toolTipDecoStyle = css({ position: "absolute", bottom: 0, left: "50%", diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentDescription.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentDescription.tsx index 1e1899e6..a1ac5bd6 100644 --- a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentDescription.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentDescription.tsx @@ -1,7 +1,7 @@ import { css } from "@styled-system/css"; +import { Tooltip } from "@wow-class/ui"; import { myStudyApi } from "apis/myStudyApi"; import { studyDetailApi } from "apis/studyDetailApi"; -import Tooltip from "components/Tooltip"; import Link from "next/link"; export const AssignmentDescription = async () => { diff --git a/apps/client/components/Tooltip.tsx b/apps/client/components/Tooltip.tsx deleted file mode 100644 index e0aa338a..00000000 --- a/apps/client/components/Tooltip.tsx +++ /dev/null @@ -1,54 +0,0 @@ -"use client"; - -import { css } from "@styled-system/css"; -import { useOpenState } from "@wow-class/ui/hooks"; -import type { PropsWithChildren, ReactNode } from "react"; - -interface TooltipProps extends PropsWithChildren { - content: ReactNode; -} - -const Tooltip = ({ content, children }: TooltipProps) => { - const { open, onOpen, onClose } = useOpenState(); - - const handleMouseEnter = () => { - onOpen(); - }; - - const handleMouseLeave = () => { - onClose(); - }; - - return ( - - {children} - {open && {content}} - - ); -}; - -export default Tooltip; - -const tooltipContainerStyle = css({ - position: "relative", - display: "inline-block", -}); - -const tooltipStyle = css({ - position: "absolute", - top: "100%", - left: 0, - borderRadius: "md", - backgroundColor: "rgba(0,0,0,0.6)", - zIndex: 10000, - paddingX: "md", - paddingY: "sm", - boxShadow: "mono", - backdropFilter: "blur(15px)", - color: "textWhite", - whiteSpace: "nowrap", -}); diff --git a/packages/ui/src/components/Tooltip/Tooltip.stories.tsx b/packages/ui/src/components/Tooltip/Tooltip.stories.tsx new file mode 100644 index 00000000..0089a6d8 --- /dev/null +++ b/packages/ui/src/components/Tooltip/Tooltip.stories.tsx @@ -0,0 +1,39 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import Tooltip from "."; + +const meta: Meta = { + title: "Shared/Tooltip", + component: Tooltip, + tags: ["autodocs"], + parameters: { + componentSubtitle: "Tooltip 컴포넌트", + }, + argTypes: { + content: { + description: "Tooltip 안에 들어갈 요소를 작성합니다.", + table: { + type: { summary: "ReactNode" }, + control: false, + }, + }, + children: { + description: "Tooltip 컴포넌트의 MouseOver 엘리먼트입니다.", + table: { + type: { summary: "ReactNode" }, + control: false, + }, + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + content: "툴팁 내용입니다", + children: "마우스를 올려보세요!", + }, +}; diff --git a/apps/admin/components/Tooltip.tsx b/packages/ui/src/components/Tooltip/index.tsx similarity index 95% rename from apps/admin/components/Tooltip.tsx rename to packages/ui/src/components/Tooltip/index.tsx index e0aa338a..f4f1da35 100644 --- a/apps/admin/components/Tooltip.tsx +++ b/packages/ui/src/components/Tooltip/index.tsx @@ -1,8 +1,8 @@ "use client"; import { css } from "@styled-system/css"; -import { useOpenState } from "@wow-class/ui/hooks"; import type { PropsWithChildren, ReactNode } from "react"; +import { useOpenState } from "src/hooks"; interface TooltipProps extends PropsWithChildren { content: ReactNode; diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 30e6daec..d9a2121d 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -6,3 +6,4 @@ export { default as Space } from "./Space"; export { default as StarCheckIcon } from "./StarCheckIcon"; export { default as Table } from "./Table"; export { default as Text } from "./Text"; +export { default as Tooltip } from "./Tooltip"; From 2c69717e5bce0a543f88b357508351dbe61e6f79 Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Sun, 29 Dec 2024 20:30:06 +0900 Subject: [PATCH 56/62] =?UTF-8?q?fix:=20=EB=B9=8C=EB=93=9C=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=20=EA=B3=A0=EC=B9=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui/src/components/Tooltip/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/Tooltip/index.tsx b/packages/ui/src/components/Tooltip/index.tsx index f4f1da35..e4332d13 100644 --- a/packages/ui/src/components/Tooltip/index.tsx +++ b/packages/ui/src/components/Tooltip/index.tsx @@ -2,7 +2,8 @@ import { css } from "@styled-system/css"; import type { PropsWithChildren, ReactNode } from "react"; -import { useOpenState } from "src/hooks"; + +import useOpenState from "../../hooks/useOpenState"; interface TooltipProps extends PropsWithChildren { content: ReactNode; From ebd99eff93709abdf3b7a9d91cd9755c682af006 Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Mon, 30 Dec 2024 14:28:52 +0900 Subject: [PATCH 57/62] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/statics/StudyStatics.tsx | 1 + .../_components/statics/graph/BarGraph.tsx | 19 ++++++++++++++----- packages/ui/src/styles.css | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx b/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx index 43de41ae..79288f37 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/StudyStatics.tsx @@ -42,6 +42,7 @@ const StudyStatics = async ({ studyId }: { studyId: string }) => { studyCompleteRate={studyStatistics?.studyCompleteRate} /> + ); }; diff --git a/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx b/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx index 78f74958..bdc65855 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx @@ -20,8 +20,17 @@ const BarGraph = ({ isCurriculumCanceled?: boolean; }) => { const [showTooltip, setShowTooltip] = useState(false); - const toggleTooltip = () => { - if (isToolTipActive) setShowTooltip((prevState) => !prevState); + + const handleMouseEnter = () => { + if (isToolTipActive) { + setShowTooltip(true); + } + }; + + const handleMouseLeave = () => { + if (isToolTipActive) { + setShowTooltip(false); + } }; return (
- {percent > 0 && `${percent}%`} + {percent}% {showTooltip && ( Date: Fri, 3 Jan 2025 16:55:34 +0900 Subject: [PATCH 58/62] =?UTF-8?q?fix:=20=EB=A7=88=EC=9A=B0=EC=8A=A4=20?= =?UTF-8?q?=EB=B9=A0=EB=A5=B4=EA=B2=8C=20=EC=A7=80=EB=82=98=EA=B0=88=20?= =?UTF-8?q?=EB=95=8C=20onMouseLeave=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EB=8F=99=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/statics/graph/BarGraph.tsx | 40 +- .../_components/statics/graph/CircleGraph.tsx | 1 - .../statics/graph/GraphToolTip.tsx | 4 +- packages/ui/src/styles.css | 874 +++++++++++++++++- 4 files changed, 892 insertions(+), 27 deletions(-) diff --git a/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx b/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx index bdc65855..7610e8b8 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/graph/BarGraph.tsx @@ -2,7 +2,7 @@ import { css, cva } from "@styled-system/css"; import { Flex } from "@styled-system/jsx"; import { Text } from "@wow-class/ui"; -import { useState } from "react"; +import clsx from "clsx"; import GraphToolTip from "./GraphToolTip"; @@ -19,19 +19,6 @@ const BarGraph = ({ percent?: number; isCurriculumCanceled?: boolean; }) => { - const [showTooltip, setShowTooltip] = useState(false); - - const handleMouseEnter = () => { - if (isToolTipActive) { - setShowTooltip(true); - } - }; - - const handleMouseLeave = () => { - if (isToolTipActive) { - setShowTooltip(false); - } - }; return ( 0 ? (
{percent}% - {showTooltip && ( - - )} +
) : ( @@ -118,6 +109,7 @@ const barGraphStyle = cva({ alignItems: "center", borderRadius: "4px", }, + variants: { type: { default: { diff --git a/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx b/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx index 406cf5ef..ecf54d46 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/graph/CircleGraph.tsx @@ -1,7 +1,6 @@ import { css } from "@styled-system/css"; import { Flex } from "@styled-system/jsx"; import { Text } from "@wow-class/ui"; -import React from "react"; import { color } from "wowds-tokens"; const CircleGraph = ({ diff --git a/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx b/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx index 3327f70f..e2a3d68c 100644 --- a/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx +++ b/apps/admin/app/studies/[studyId]/_components/statics/graph/GraphToolTip.tsx @@ -1,8 +1,9 @@ import { css } from "@styled-system/css"; import { Text } from "@wow-class/ui"; +import clsx from "clsx"; const GraphToolTip = ({ studentCount }: { studentCount: number }) => { return ( -
+
{studentCount}명 @@ -23,6 +24,7 @@ const toolTipContainerStyle = css({ transform: "translate(50%, -50%)", right: "-8px", zIndex: 20, + visibility: "hidden", }); const toolTipStyle = css({ diff --git a/packages/ui/src/styles.css b/packages/ui/src/styles.css index 102543fb..461cf8f9 100644 --- a/packages/ui/src/styles.css +++ b/packages/ui/src/styles.css @@ -1 +1,873 @@ -:host,html{--font-fallback:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent;line-height:1.5;font-family:var(--global-font-body,var(--font-fallback))}*,::backdrop,::file-selector-button,:after,:before{margin:0px;padding:0px;box-sizing:border-box;border-width:0px;border-style:solid;border-color:var(--global-color-border,currentColor)}hr{height:0px;color:inherit;border-top-width:1px}body{height:100%;line-height:inherit}img{border-style:none}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}h1,h2,h3,h4,h5,h6{text-wrap:balance;font-size:inherit;font-weight:inherit}h1,h2,h3,h4,h5,h6,p{overflow-wrap:break-word}menu,ol,ul{list-style:none}::file-selector-button,button,input:where([type=button],[type=reset],[type=submit]){appearance:button;-webkit-appearance:button}::file-selector-button,button,input,optgroup,select,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;background:transparent}::placeholder{opacity:1;--placeholder-fallback:color-mix(in srgb,currentColor 50%,transparent);color:var(--global-color-placeholder,var(--placeholder-fallback))}textarea{resize:vertical}table{text-indent:0px;border-collapse:collapse;border-color:inherit}summary{display:list-item}small{font-size:80%}sub,sup{position:relative;vertical-align:baseline;font-size:75%;line-height:0}sub{bottom:-0.25em}sup{top:-0.5em}dialog{padding:0px}a{color:inherit;text-decoration:inherit}abbr:where([title]){text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{--font-mono-fallback:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New';font-feature-settings:normal;font-variation-settings:normal;font-family:var(--global-font-mono,var(--font-mono-fallback));font-size:1em}progress{vertical-align:baseline}::-webkit-search-cancel-button,::-webkit-search-decoration{-webkit-appearance:none}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}:-moz-ui-invalid{box-shadow:none}:-moz-focusring{outline:auto}[hidden]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){display:none!important}:where(:root,:host):not(#\#):not(#\#){--colors-red-50:#FDECEB;--colors-red-100:#FBD9D7;--colors-red-150:#F9C7C2;--colors-red-200:#F7B4AE;--colors-red-300:#F28E86;--colors-red-400:#EE695D;--colors-red-500:#EA4335;--colors-red-600:#BB362A;--colors-red-700:#8C2820;--colors-red-800:#5E1B15;--colors-red-850:#461410;--colors-red-900:#2F0D0B;--colors-red-950:#170705;--colors-blue-50:#EBF4FE;--colors-blue-100:#D7E9FD;--colors-blue-150:#C3DDFD;--colors-blue-200:#AFD2FC;--colors-blue-300:#86BCFA;--colors-blue-400:#5EA5F9;--colors-blue-500:#368FF7;--colors-blue-600:#2B72C6;--colors-blue-700:#205694;--colors-blue-800:#163963;--colors-blue-850:#102B4A;--colors-blue-900:#0B1D31;--colors-blue-950:#050E19;--colors-yellow-50:#FEF7E6;--colors-yellow-100:#FEEECC;--colors-yellow-150:#FDE6B3;--colors-yellow-200:#FDDD99;--colors-yellow-300:#FBCD66;--colors-yellow-400:#FABC33;--colors-yellow-500:#F9AB00;--colors-yellow-600:#C78900;--colors-yellow-700:#956700;--colors-yellow-800:#644400;--colors-yellow-850:#4B3300;--colors-yellow-900:#322200;--colors-yellow-950:#191100;--colors-green-50:#EBF6EE;--colors-green-100:#D6EEDD;--colors-green-150:#C2E5CB;--colors-green-200:#AEDCBA;--colors-green-300:#85CB98;--colors-green-400:#5DB975;--colors-green-500:#34A853;--colors-green-600:#2A8642;--colors-green-700:#1F6532;--colors-green-800:#154321;--colors-green-850:#103219;--colors-green-900:#0A2211;--colors-green-950:#051108;--colors-mono-50:#F7F7F7;--colors-mono-100:#F0F0F0;--colors-mono-150:#E8E8E8;--colors-mono-200:#E1E1E1;--colors-mono-300:#D1D1D1;--colors-mono-400:#C2C2C2;--colors-mono-500:#B3B3B3;--colors-mono-600:#8F8F8F;--colors-mono-700:#6B6B6B;--colors-mono-800:#484848;--colors-mono-900:#242424;--colors-mono-950:#121212;--colors-white:#FFFFFF;--colors-black:#000000;--spacing-sm:0.75rem;--spacing-md:1rem;--spacing-xl:1.5rem;--radii-md:0.5rem;--border-widths-button:1px;--shadows-mono:0px 4px 8px 0px rgba(0,0,0,0.2);--colors-primary:#368FF7;--colors-success:#2A8642;--colors-error:#BB362A;--colors-background-normal:#FFFFFF;--colors-background-alternative:#F7F7F7;--colors-background-dimmer:rgba(0,0,0,0.8);--colors-sub:#6B6B6B;--colors-outline:#C2C2C2;--colors-text-black:#121212;--colors-text-white:#FFFFFF;--colors-dark-disabled:#C2C2C2;--colors-light-disabled:#E1E1E1;--colors-blue-hover:#2B72C6;--colors-mono-hover:#121212;--colors-elevated-hover:rgba(16,43,74,0.2);--colors-blue-pressed:#5EA5F9;--colors-blue-background-pressed:#EBF4FE;--colors-mono-background-pressed:#F7F7F7;--colors-shadow-small:rgba(0,0,0,0.1);--colors-shadow-medium:rgba(0,0,0,0.2);--colors-blue-shadow:rgba(16,43,74,0.2);--colors-discord:#5566FB;--colors-github:#000000;--colors-secondary-yellow:#F9AB00;--colors-secondary-green:#34A853;--colors-secondary-red:#EA4335;--colors-error-background:#FBD9D7;--colors-blue-disabled:#D7E9FD;--colors-text-blue-disabled:#AFD2FC}.textStyle_body1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:1rem;line-height:160%;font-weight:500}.textStyle_body0:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01125rem;font-size:1.125rem;line-height:160%;font-weight:500}.textStyle_body2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.00875rem;font-size:0.875rem;line-height:160%;font-weight:500}.textStyle_body3:not(#\#):not(#\#):not(#\#):not(#\#){font-size:0.75rem;line-height:140%;font-weight:500}.textStyle_display1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.025rem;font-size:2.5rem;line-height:130%;font-weight:700}.textStyle_display2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.02rem;font-size:2rem;line-height:130%;font-weight:700}.textStyle_h1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.015rem;font-size:1.5rem;line-height:130%;font-weight:600}.textStyle_h2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01125rem;font-size:1.125rem;line-height:130%;font-weight:600}.textStyle_h3:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:1rem;line-height:130%;font-weight:600}.textStyle_label1:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:1rem;line-height:100%;font-weight:600}.textStyle_label2:not(#\#):not(#\#):not(#\#):not(#\#){letter-spacing:-0.01rem;font-size:0.875rem;line-height:100%;font-weight:600}.textStyle_label3:not(#\#):not(#\#):not(#\#):not(#\#){font-size:0.75rem;line-height:100%;font-weight:600}.h_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:24px}.w_49:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:49px}.w_100vw:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:100vw}.h_54px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:54px}.d_flex:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){display:flex}.gap_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){gap:8px}.w_956px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:956px}.px_16px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){padding-inline:16px}.cursor_pointer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){cursor:pointer}.w_49px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:49px}.h_24px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:24px}.c_primary:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-primary)}.w_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:24px}.w_40\.75rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:40.75rem}.h_28\.125rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:28.125rem}.pos_relative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){position:relative}.bdr_md:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-radius:var(--radii-md)}.bx-sh_mono:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){box-shadow:var(--shadows-mono)}.h_100vh:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:100vh}.pos_fixed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){position:fixed}.z_9999:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){z-index:9999}.bg_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background:var(--colors-background-dimmer)}.pos_absolute:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){position:absolute}.li-s_none:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){list-style:none}.h_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:20px}.w_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:20px}.gap_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){gap:12px}.p_11px_18px_11px_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){padding:11px 18px 11px 20px}.bg_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background:var(--colors-mono-background-pressed)}.bg_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background:var(--colors-white)}.w_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:20px}.h_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:20px}.h_80px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){height:80px}.w_100\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){width:100%}.c_textBlack:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-text-black)}.d_inline-block:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){display:inline-block}.z_10000:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){z-index:10000}.px_md:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){padding-inline:var(--spacing-md)}.py_sm:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){padding-block:var(--spacing-sm)}.bkdp_blur\(15px\):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){backdrop-filter:blur(15px);-webkit-backdrop-filter:blur(15px)}.c_textWhite:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-text-white)}.white-space_nowrap:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){white-space:nowrap}.c_blue\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-50)}.c_blue\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-100)}.c_blue\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-150)}.c_blue\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-200)}.c_blue\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-300)}.c_blue\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-400)}.c_blue\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-500)}.c_blue\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-600)}.c_blue\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-700)}.c_blue\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-800)}.c_blue\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-850)}.c_blue\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-900)}.c_blue\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-950)}.c_yellow\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-50)}.c_yellow\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-100)}.c_yellow\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-150)}.c_yellow\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-200)}.c_yellow\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-300)}.c_yellow\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-400)}.c_yellow\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-500)}.c_yellow\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-600)}.c_yellow\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-700)}.c_yellow\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-800)}.c_yellow\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-850)}.c_yellow\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-900)}.c_yellow\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-yellow-950)}.c_green\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-50)}.c_green\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-100)}.c_green\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-150)}.c_green\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-200)}.c_green\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-300)}.c_green\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-400)}.c_green\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-500)}.c_green\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-600)}.c_green\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-700)}.c_green\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-800)}.c_green\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-850)}.c_green\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-900)}.c_green\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-green-950)}.c_red\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-50)}.c_red\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-100)}.c_red\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-150)}.c_red\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-200)}.c_red\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-300)}.c_red\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-400)}.c_red\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-500)}.c_red\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-600)}.c_red\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-700)}.c_red\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-800)}.c_red\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-850)}.c_red\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-900)}.c_red\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-red-950)}.c_mono\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-50)}.c_mono\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-100)}.c_mono\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-150)}.c_mono\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-200)}.c_mono\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-300)}.c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-400)}.c_mono\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-500)}.c_mono\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-600)}.c_mono\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-700)}.c_mono\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-800)}.c_mono\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:mono.850}.c_mono\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-900)}.c_mono\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-950)}.c_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-white)}.c_black:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-black)}.c_whiteOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.20}.c_whiteOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.40}.c_whiteOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.60}.c_whiteOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:whiteOpacity.80}.c_blackOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.20}.c_blackOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.40}.c_blackOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.60}.c_blackOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blackOpacity.80}.c_success:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-success)}.c_error:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-error)}.c_backgroundNormal:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-background-normal)}.c_backgroundAlternative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-background-alternative)}.c_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-background-dimmer)}.c_errorBackground:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-error-background)}.c_sub:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-sub)}.c_outline:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-outline)}.c_darkDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-dark-disabled)}.c_lightDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-light-disabled)}.c_blueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-disabled)}.c_textBlueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-text-blue-disabled)}.c_blueHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-hover)}.c_monoHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-hover)}.c_elevatedHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-elevated-hover)}.c_bluePressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-pressed)}.c_blueBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-background-pressed)}.c_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-mono-background-pressed)}.c_shadowSmall:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-shadow-small)}.c_shadowMedium:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-shadow-medium)}.c_blueShadow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-blue-shadow)}.c_discord:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-discord)}.c_github:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-github)}.c_secondaryYellow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-secondary-yellow)}.c_secondaryGreen:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-secondary-green)}.c_secondaryRed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:var(--colors-secondary-red)}.c_blueGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blueGradientDark}.c_blueGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:blueGradientLight}.c_redGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:redGradientDark}.c_redGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:redGradientLight}.c_greenGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:greenGradientDark}.c_greenGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:greenGradientLight}.c_yellowGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:yellowGradientDark}.c_yellowGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){color:yellowGradientLight}.bd-b-w_button:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-width:var(--border-widths-button)}.bd-b-c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-color:var(--colors-mono-400)}.border-bottom-style_solid:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-style:solid}.ai_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){align-items:center}.jc_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:center}.ff_Product_Sans:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-family:Product Sans}.fw_700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-weight:700}.fs_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-size:20px}.lh_130\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){line-height:130%}.fw_400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-weight:400}.fs_14px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){font-size:14px}.flex-d_column:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){flex-direction:column}.top_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){top:0}.left_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){left:0}.top_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){top:var(--spacing-xl)}.right_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){right:var(--spacing-xl)}.mr_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){margin-right:8px}.ml_auto:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){margin-left:auto}.jc_space-between:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:space-between}.mb_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:12px}.jc_flex-start:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:flex-start}.jc_flex-end:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){justify-content:flex-end}.top_100\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){top:100%}.bg-c_rgba\(0\,0\,0\,0\.6\):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background-color:rgba(0,0,0,0.6)} \ No newline at end of file +:host, +html { + --font-fallback: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -moz-tab-size: 4; + tab-size: 4; + -webkit-tap-highlight-color: transparent; + line-height: 1.5; + font-family: var(--global-font-body, var(--font-fallback)); +} +*, +::backdrop, +::file-selector-button, +:after, +:before { + margin: 0px; + padding: 0px; + box-sizing: border-box; + border-width: 0px; + border-style: solid; + border-color: var(--global-color-border, currentColor); +} +hr { + height: 0px; + color: inherit; + border-top-width: 1px; +} +body { + height: 100%; + line-height: inherit; +} +img { + border-style: none; +} +audio, +canvas, +embed, +iframe, +img, +object, +svg, +video { + display: block; + vertical-align: middle; +} +img, +video { + max-width: 100%; + height: auto; +} +h1, +h2, +h3, +h4, +h5, +h6 { + text-wrap: balance; + font-size: inherit; + font-weight: inherit; +} +h1, +h2, +h3, +h4, +h5, +h6, +p { + overflow-wrap: break-word; +} +menu, +ol, +ul { + list-style: none; +} +::file-selector-button, +button, +input:where([type="button"], [type="reset"], [type="submit"]) { + appearance: button; + -webkit-appearance: button; +} +::file-selector-button, +button, +input, +optgroup, +select, +textarea { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + background: transparent; +} +::placeholder { + opacity: 1; + --placeholder-fallback: color-mix(in srgb, currentColor 50%, transparent); + color: var(--global-color-placeholder, var(--placeholder-fallback)); +} +textarea { + resize: vertical; +} +table { + text-indent: 0px; + border-collapse: collapse; + border-color: inherit; +} +summary { + display: list-item; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + vertical-align: baseline; + font-size: 75%; + line-height: 0; +} +sub { + bottom: -0.25em; +} +sup { + top: -0.5em; +} +dialog { + padding: 0px; +} +a { + color: inherit; + text-decoration: inherit; +} +abbr:where([title]) { + text-decoration: underline dotted; +} +b, +strong { + font-weight: bolder; +} +code, +kbd, +pre, +samp { + --font-mono-fallback: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New"; + font-feature-settings: normal; + font-variation-settings: normal; + font-family: var(--global-font-mono, var(--font-mono-fallback)); + font-size: 1em; +} +progress { + vertical-align: baseline; +} +::-webkit-search-cancel-button, +::-webkit-search-decoration { + -webkit-appearance: none; +} +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} +:-moz-ui-invalid { + box-shadow: none; +} +:-moz-focusring { + outline: auto; +} +[hidden]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + display: none !important; +} +:where(:root, :host):not(#\#):not(#\#) { + --colors-red-50: #fdeceb; + --colors-red-100: #fbd9d7; + --colors-red-150: #f9c7c2; + --colors-red-200: #f7b4ae; + --colors-red-300: #f28e86; + --colors-red-400: #ee695d; + --colors-red-500: #ea4335; + --colors-red-600: #bb362a; + --colors-red-700: #8c2820; + --colors-red-800: #5e1b15; + --colors-red-850: #461410; + --colors-red-900: #2f0d0b; + --colors-red-950: #170705; + --colors-blue-50: #ebf4fe; + --colors-blue-100: #d7e9fd; + --colors-blue-150: #c3ddfd; + --colors-blue-200: #afd2fc; + --colors-blue-300: #86bcfa; + --colors-blue-400: #5ea5f9; + --colors-blue-500: #368ff7; + --colors-blue-600: #2b72c6; + --colors-blue-700: #205694; + --colors-blue-800: #163963; + --colors-blue-850: #102b4a; + --colors-blue-900: #0b1d31; + --colors-blue-950: #050e19; + --colors-yellow-50: #fef7e6; + --colors-yellow-100: #feeecc; + --colors-yellow-150: #fde6b3; + --colors-yellow-200: #fddd99; + --colors-yellow-300: #fbcd66; + --colors-yellow-400: #fabc33; + --colors-yellow-500: #f9ab00; + --colors-yellow-600: #c78900; + --colors-yellow-700: #956700; + --colors-yellow-800: #644400; + --colors-yellow-850: #4b3300; + --colors-yellow-900: #322200; + --colors-yellow-950: #191100; + --colors-green-50: #ebf6ee; + --colors-green-100: #d6eedd; + --colors-green-150: #c2e5cb; + --colors-green-200: #aedcba; + --colors-green-300: #85cb98; + --colors-green-400: #5db975; + --colors-green-500: #34a853; + --colors-green-600: #2a8642; + --colors-green-700: #1f6532; + --colors-green-800: #154321; + --colors-green-850: #103219; + --colors-green-900: #0a2211; + --colors-green-950: #051108; + --colors-mono-50: #f7f7f7; + --colors-mono-100: #f0f0f0; + --colors-mono-150: #e8e8e8; + --colors-mono-200: #e1e1e1; + --colors-mono-300: #d1d1d1; + --colors-mono-400: #c2c2c2; + --colors-mono-500: #b3b3b3; + --colors-mono-600: #8f8f8f; + --colors-mono-700: #6b6b6b; + --colors-mono-800: #484848; + --colors-mono-900: #242424; + --colors-mono-950: #121212; + --colors-white: #ffffff; + --colors-black: #000000; + --spacing-sm: 0.75rem; + --spacing-md: 1rem; + --spacing-xl: 1.5rem; + --radii-md: 0.5rem; + --border-widths-button: 1px; + --shadows-mono: 0px 4px 8px 0px rgba(0, 0, 0, 0.2); + --colors-primary: #368ff7; + --colors-success: #2a8642; + --colors-error: #bb362a; + --colors-background-normal: #ffffff; + --colors-background-alternative: #f7f7f7; + --colors-background-dimmer: rgba(0, 0, 0, 0.8); + --colors-sub: #6b6b6b; + --colors-outline: #c2c2c2; + --colors-text-black: #121212; + --colors-text-white: #ffffff; + --colors-dark-disabled: #c2c2c2; + --colors-light-disabled: #e1e1e1; + --colors-blue-hover: #2b72c6; + --colors-mono-hover: #121212; + --colors-elevated-hover: rgba(16, 43, 74, 0.2); + --colors-blue-pressed: #5ea5f9; + --colors-blue-background-pressed: #ebf4fe; + --colors-mono-background-pressed: #f7f7f7; + --colors-shadow-small: rgba(0, 0, 0, 0.1); + --colors-shadow-medium: rgba(0, 0, 0, 0.2); + --colors-blue-shadow: rgba(16, 43, 74, 0.2); + --colors-discord: #5566fb; + --colors-github: #000000; + --colors-secondary-yellow: #f9ab00; + --colors-secondary-green: #34a853; + --colors-secondary-red: #ea4335; + --colors-error-background: #fbd9d7; + --colors-blue-disabled: #d7e9fd; + --colors-text-blue-disabled: #afd2fc; +} +.textStyle_body1:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.01rem; + font-size: 1rem; + line-height: 160%; + font-weight: 500; +} +.textStyle_body0:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.01125rem; + font-size: 1.125rem; + line-height: 160%; + font-weight: 500; +} +.textStyle_body2:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.00875rem; + font-size: 0.875rem; + line-height: 160%; + font-weight: 500; +} +.textStyle_body3:not(#\#):not(#\#):not(#\#):not(#\#) { + font-size: 0.75rem; + line-height: 140%; + font-weight: 500; +} +.textStyle_display1:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.025rem; + font-size: 2.5rem; + line-height: 130%; + font-weight: 700; +} +.textStyle_display2:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.02rem; + font-size: 2rem; + line-height: 130%; + font-weight: 700; +} +.textStyle_h1:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.015rem; + font-size: 1.5rem; + line-height: 130%; + font-weight: 600; +} +.textStyle_h2:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.01125rem; + font-size: 1.125rem; + line-height: 130%; + font-weight: 600; +} +.textStyle_h3:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.01rem; + font-size: 1rem; + line-height: 130%; + font-weight: 600; +} +.textStyle_label1:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.01rem; + font-size: 1rem; + line-height: 100%; + font-weight: 600; +} +.textStyle_label2:not(#\#):not(#\#):not(#\#):not(#\#) { + letter-spacing: -0.01rem; + font-size: 0.875rem; + line-height: 100%; + font-weight: 600; +} +.textStyle_label3:not(#\#):not(#\#):not(#\#):not(#\#) { + font-size: 0.75rem; + line-height: 100%; + font-weight: 600; +} +.h_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 24px; +} +.w_49:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 49px; +} +.w_100vw:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 100vw; +} +.h_54px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 54px; +} +.d_flex:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + display: flex; +} +.gap_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + gap: 8px; +} +.w_956px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 956px; +} +.px_16px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + padding-inline: 16px; +} +.cursor_pointer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + cursor: pointer; +} +.w_49px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 49px; +} +.h_24px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 24px; +} +.c_primary:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-primary); +} +.w_24:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 24px; +} +.w_40\.75rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 40.75rem; +} +.h_28\.125rem:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 28.125rem; +} +.pos_relative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + position: relative; +} +.bdr_md:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + border-radius: var(--radii-md); +} +.bx-sh_mono:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + box-shadow: var(--shadows-mono); +} +.h_100vh:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 100vh; +} +.pos_fixed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + position: fixed; +} +.z_9999:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + z-index: 9999; +} +.bg_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + background: var(--colors-background-dimmer); +} +.pos_absolute:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + position: absolute; +} +.li-s_none:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + list-style: none; +} +.h_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 20px; +} +.w_20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 20px; +} +.gap_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + gap: 12px; +} +.p_11px_18px_11px_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + padding: 11px 18px 11px 20px; +} +.bg_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + background: var(--colors-mono-background-pressed); +} +.bg_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + background: var(--colors-white); +} +.w_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 20px; +} +.h_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 20px; +} +.h_80px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + height: 80px; +} +.w_100\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + width: 100%; +} +.c_textBlack:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-text-black); +} +.d_inline-block:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + display: inline-block; +} +.z_10000:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + z-index: 10000; +} +.px_md:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + padding-inline: var(--spacing-md); +} +.py_sm:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + padding-block: var(--spacing-sm); +} +.bkdp_blur\(15px\):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + backdrop-filter: blur(15px); + -webkit-backdrop-filter: blur(15px); +} +.c_textWhite:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-text-white); +} +.white-space_nowrap:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + white-space: nowrap; +} +.c_blue\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-50); +} +.c_blue\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-100); +} +.c_blue\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-150); +} +.c_blue\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-200); +} +.c_blue\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-300); +} +.c_blue\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-400); +} +.c_blue\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-500); +} +.c_blue\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-600); +} +.c_blue\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-700); +} +.c_blue\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-800); +} +.c_blue\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-850); +} +.c_blue\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-900); +} +.c_blue\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-950); +} +.c_yellow\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-50); +} +.c_yellow\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-100); +} +.c_yellow\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-150); +} +.c_yellow\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-200); +} +.c_yellow\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-300); +} +.c_yellow\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-400); +} +.c_yellow\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-500); +} +.c_yellow\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-600); +} +.c_yellow\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-700); +} +.c_yellow\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-800); +} +.c_yellow\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-850); +} +.c_yellow\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-900); +} +.c_yellow\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-yellow-950); +} +.c_green\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-50); +} +.c_green\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-100); +} +.c_green\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-150); +} +.c_green\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-200); +} +.c_green\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-300); +} +.c_green\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-400); +} +.c_green\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-500); +} +.c_green\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-600); +} +.c_green\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-700); +} +.c_green\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-800); +} +.c_green\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-850); +} +.c_green\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-900); +} +.c_green\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-green-950); +} +.c_red\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-50); +} +.c_red\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-100); +} +.c_red\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-150); +} +.c_red\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-200); +} +.c_red\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-300); +} +.c_red\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-400); +} +.c_red\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-500); +} +.c_red\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-600); +} +.c_red\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-700); +} +.c_red\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-800); +} +.c_red\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-850); +} +.c_red\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-900); +} +.c_red\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-red-950); +} +.c_mono\.50:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-50); +} +.c_mono\.100:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-100); +} +.c_mono\.150:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-150); +} +.c_mono\.200:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-200); +} +.c_mono\.300:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-300); +} +.c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-400); +} +.c_mono\.500:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-500); +} +.c_mono\.600:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-600); +} +.c_mono\.700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-700); +} +.c_mono\.800:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-800); +} +.c_mono\.850:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: mono.850; +} +.c_mono\.900:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-900); +} +.c_mono\.950:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-950); +} +.c_white:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-white); +} +.c_black:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-black); +} +.c_whiteOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: whiteOpacity.20; +} +.c_whiteOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: whiteOpacity.40; +} +.c_whiteOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: whiteOpacity.60; +} +.c_whiteOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: whiteOpacity.80; +} +.c_blackOpacity\.20:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: blackOpacity.20; +} +.c_blackOpacity\.40:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: blackOpacity.40; +} +.c_blackOpacity\.60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: blackOpacity.60; +} +.c_blackOpacity\.80:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: blackOpacity.80; +} +.c_success:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-success); +} +.c_error:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-error); +} +.c_backgroundNormal:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-background-normal); +} +.c_backgroundAlternative:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-background-alternative); +} +.c_backgroundDimmer:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-background-dimmer); +} +.c_errorBackground:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-error-background); +} +.c_sub:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-sub); +} +.c_outline:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-outline); +} +.c_darkDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-dark-disabled); +} +.c_lightDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-light-disabled); +} +.c_blueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-disabled); +} +.c_textBlueDisabled:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-text-blue-disabled); +} +.c_blueHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-hover); +} +.c_monoHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-hover); +} +.c_elevatedHover:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-elevated-hover); +} +.c_bluePressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-pressed); +} +.c_blueBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-background-pressed); +} +.c_monoBackgroundPressed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-mono-background-pressed); +} +.c_shadowSmall:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-shadow-small); +} +.c_shadowMedium:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-shadow-medium); +} +.c_blueShadow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-blue-shadow); +} +.c_discord:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-discord); +} +.c_github:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-github); +} +.c_secondaryYellow:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-secondary-yellow); +} +.c_secondaryGreen:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-secondary-green); +} +.c_secondaryRed:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: var(--colors-secondary-red); +} +.c_blueGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: blueGradientDark; +} +.c_blueGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: blueGradientLight; +} +.c_redGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: redGradientDark; +} +.c_redGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: redGradientLight; +} +.c_greenGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: greenGradientDark; +} +.c_greenGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: greenGradientLight; +} +.c_yellowGradientDark:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: yellowGradientDark; +} +.c_yellowGradientLight:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + color: yellowGradientLight; +} +.bd-b-w_button:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + border-bottom-width: var(--border-widths-button); +} +.bd-b-c_mono\.400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + border-bottom-color: var(--colors-mono-400); +} +.border-bottom-style_solid:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + border-bottom-style: solid; +} +.ai_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + align-items: center; +} +.jc_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + justify-content: center; +} +.ff_Product_Sans:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + font-family: Product Sans; +} +.fw_700:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + font-weight: 700; +} +.fs_20px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + font-size: 20px; +} +.lh_130\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + line-height: 130%; +} +.fw_400:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + font-weight: 400; +} +.fs_14px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + font-size: 14px; +} +.flex-d_column:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + flex-direction: column; +} +.top_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + top: 0; +} +.left_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + left: 0; +} +.top_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + top: var(--spacing-xl); +} +.right_xl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + right: var(--spacing-xl); +} +.mr_8px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + margin-right: 8px; +} +.ml_auto:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + margin-left: auto; +} +.jc_space-between:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + justify-content: space-between; +} +.mb_12px:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + margin-bottom: 12px; +} +.jc_flex-start:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + justify-content: flex-start; +} +.jc_flex-end:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + justify-content: flex-end; +} +.top_100\%:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + top: 100%; +} +.bg-c_rgba\(0\,0\,0\,0\.6\):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + background-color: rgba(0, 0, 0, 0.6); +} From 5f61619dd32524f88d76225da8494c00ad80d21e Mon Sep 17 00:00:00 2001 From: SeieunYoo Date: Sun, 5 Jan 2025 16:33:01 +0900 Subject: [PATCH 59/62] =?UTF-8?q?feat:=20=EB=B2=84=ED=8A=BC=20=EB=AC=B8?= =?UTF-8?q?=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AssignmentOverviewBox/AssignmentBoxButtons.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx index d0438e4b..c1298893 100644 --- a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx @@ -128,7 +128,7 @@ const SecondaryButton = ({ const { year, month, day, hours, minutes } = parseISODate( committedAt as string ); - const commitText = `최종 수정일자 ${year}년 ${month}월 ${day}일 ${padWithZero(hours)}:${padWithZero(minutes)}`; + const commitText = `최종 수정 일시 : ${year}년 ${month}월 ${day}일 ${padWithZero(hours)}:${padWithZero(minutes)}`; return (