diff --git a/apps/client/apis/studyHistoryApi.ts b/apps/client/apis/studyHistoryApi.ts index 1cac542e..0289018b 100644 --- a/apps/client/apis/studyHistoryApi.ts +++ b/apps/client/apis/studyHistoryApi.ts @@ -1,7 +1,10 @@ import { fetcher } from "@wow-class/utils"; import { apiPath } from "constants/apiPath"; import { tags } from "constants/tags"; -import type { AssignmentHistoryDto } from "types/dtos/studyHistory"; +import type { + AssignmentHistoryDto, + CompletedStudyDto, +} from "types/dtos/studyHistory"; export const studyHistoryApi = { getStudyHistory: async (studyId: number) => { @@ -34,4 +37,15 @@ export const studyHistoryApi = { return { success: response.ok }; }, + getMyCompletedStudy: async () => { + const response = await fetcher.get( + `${apiPath.studyHistory}/me/complete`, + { + next: { tags: [tags.studyHistory] }, + cache: "force-cache", + } + ); + + return response.data; + }, }; diff --git a/apps/client/app/(afterLogin)/my-page/_components/CompletedStudy.tsx b/apps/client/app/(afterLogin)/my-page/_components/CompletedStudy.tsx new file mode 100644 index 00000000..0edef3d8 --- /dev/null +++ b/apps/client/app/(afterLogin)/my-page/_components/CompletedStudy.tsx @@ -0,0 +1,149 @@ +"use client"; + +import { css } from "@styled-system/css"; +import { Flex } from "@styled-system/jsx"; +import { AwardIcon, Space, StarCheckIcon, Text } from "@wow-class/ui"; +import { studyHistoryApi } from "apis/studyHistoryApi"; +import Link from "next/link"; +import type { ComponentProps, CSSProperties } from "react"; +import type { AchievmentType, StudyType } from "types/entities/common/study"; +import Table from "wowds-ui/Table"; +import Tag from "wowds-ui/Tag"; + +export const CompletedStudy = async () => { + const data = await studyHistoryApi.getMyCompletedStudy(); + if (!data) return null; + + return ( + + + 스터디 이름 + 멘토 + 학기 + 코스 기간 + 수료 + 우수 + + + {data.map( + ({ + studyId, + title, + studyType, + notionLink, + introduction, + mentorName, + academicYear, + semesterType, + totalWeek, + studyHistoryStatus, + achievements, + }) => ( +
+ + + + {title} + + {studyType} + + + {introduction && ( + + + {introduction} + + + )} + + + {mentorName} 멘토 + + + + {academicYear}-{semesterType === "FIRST" ? "1" : "2"} + + + + {totalWeek}주 코스 + + + {studyHistoryStatus === "COMPLETED" ? ( + + ) : ( + - + )} + + + + + + + + +
+ ) + )} +
+
+ ); +}; + +const AchievementIcons = ({ achievements }: { achievements: string[] }) => { + const achievementTypes: AchievmentType[] = [ + "FIRST_ROUND_OUTSTANDING_STUDENT", + "SECOND_ROUND_OUTSTANDING_STUDENT", + ]; + + const isAchievment = achievementTypes.some((type) => + achievements.includes(type) + ); + + return isAchievment ? ( + <> + {achievementTypes.map( + (type) => + achievements.includes(type) && ( + + ) + )} + + ) : ( + - + ); +}; + +const curriculumColors: Record["color"]> = + { + "과제 스터디": "green", + "온라인 스터디": "blue", + "오프라인 스터디": "yellow", + }; + +const introductionLinkTextStyle = css({ + whiteSpace: "nowrap", + overflow: "hidden", + textOverflow: "ellipsis", + textDecoration: "underline", +}); + +const mentorTextstyle = css({ + display: "flex", + alignItems: "center", +}); + +const tdStyle: CSSProperties = { + paddingBottom: "20px", + paddingTop: "16px", +}; + +const emptyTextStyle = css({ + paddingLeft: "5px", +}); diff --git a/apps/client/app/(afterLogin)/my-page/page.tsx b/apps/client/app/(afterLogin)/my-page/page.tsx index 31d3d123..50b54dd0 100644 --- a/apps/client/app/(afterLogin)/my-page/page.tsx +++ b/apps/client/app/(afterLogin)/my-page/page.tsx @@ -1,5 +1,6 @@ import { Space, Text } from "@wow-class/ui"; +import { CompletedStudy } from "./_components/CompletedStudy"; import { MyInfoBox } from "./_components/MyInfoBox"; const MyPage = () => { @@ -8,6 +9,8 @@ const MyPage = () => { 마이 페이지 + + ); }; diff --git a/apps/client/types/dtos/studyHistory.ts b/apps/client/types/dtos/studyHistory.ts index 7cfade33..1b8a7b9c 100644 --- a/apps/client/types/dtos/studyHistory.ts +++ b/apps/client/types/dtos/studyHistory.ts @@ -3,6 +3,7 @@ import type { AssignmentSubmissionFailureType, AssignmentSubmissionStatusType, } from "types/entities/common/assignment"; +import type { AchievmentType, StudyType } from "types/entities/common/study"; export interface AssignmentHistoryDto { assignmentHistoryId: number; @@ -15,3 +16,17 @@ export interface AssignmentHistoryDto { submissionFailureType: AssignmentSubmissionFailureType; week: number; } + +export interface CompletedStudyDto { + studyId: number; + academicYear: number; + semesterType: "FIRST" | "SECOND"; + title: string; + studyType: StudyType; + notionLink?: string; + introduction?: string; + mentorName: string; + totalWeek: number; + studyHistoryStatus: "NONE" | "COMPLETED"; + achievements: Array; +} diff --git a/apps/client/types/entities/common/study.ts b/apps/client/types/entities/common/study.ts index 05fa56f8..07f7fea1 100644 --- a/apps/client/types/entities/common/study.ts +++ b/apps/client/types/entities/common/study.ts @@ -1 +1,4 @@ export type StudyType = "과제 스터디" | "온라인 스터디" | "오프라인 스터디"; +export type AchievmentType = + | "FIRST_ROUND_OUTSTANDING_STUDENT" + | "SECOND_ROUND_OUTSTANDING_STUDENT";