Skip to content

Commit

Permalink
[Refactor] 과제 api 연결 및 바뀐 dto 반영 (#114)
Browse files Browse the repository at this point in the history
* feat: 큐에이 반영

* fix: 소문자로 변경

* refactor: api dto 반영, 이번 주 과제 조회 api 연결

* feat: 히스토리 api 수정된 dto 반영

* feat: 히스토리 api 수정된 거 반영, 레포지토리 입력 api 반영

* refactor: 레포 모달 창 상태 관리 컴포넌트로 벼녕

* feat: 필요없는 로직 삭제

* feat: 이번 주 과제 조회 스터디 추가

* feat: 모달 라우팅 삭제

* feat: submissionLink 에서 폴더

* chore: 안쓰는 상수 삭제

* chore: 말줄임 처리, github url 인지 체크

* feat: 스터디 시작 날짜가 현재 날짜인지 확인하고 disabled 처리

* feat: 공통 타입은 common 으로 옮기기, 리뷰 반영

* fix: 빠진 네이밍 수정 반영

* feat: Button asProp 으로 Link 전달, css 수정

* refactor: NonNullable 처리, Initial 로 관리

* feat: github 관련 유틸 분리,css 수정

* chore: 필요없는 프래그먼트 삭제

* chore: cache 속서 추가

* feat: currentPath href 매치될 때만 active 되게 navItem 수정

* chore: myStudy 용 타입 추가

* chore: EDITING_WITH_WARNING 타입 삭제, 상태 네이밍 변경

* chore: 조건식 간소화

* chore: submissionLink null 로 내려오는 부분 우선 삭제
  • Loading branch information
SeieunYoo authored Sep 4, 2024
1 parent a6ebbc1 commit 09ac371
Show file tree
Hide file tree
Showing 38 changed files with 535 additions and 404 deletions.
17 changes: 16 additions & 1 deletion apps/client/apis/studyDetailApi.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
import { fetcher } from "@wow-class/utils";
import { apiPath } from "constants/apiPath";
import { tags } from "constants/tags";
import type { StudyDetailDashboardDto } from "types/dtos/studyDetail";
import type {
StudyDetailDashboardDto,
UpcomingStudyDto,
} from "types/dtos/studyDetail";

export const studyDetailApi = {
getStudyDetailDashboard: async (studyId: number) => {
const response = await fetcher.get<StudyDetailDashboardDto>(
`${apiPath.studyDetail}/dashboard?studyId=${studyId}`,
{
next: { tags: [tags.studyDetailDashboard] },
cache: "force-cache",
}
);

return response.data;
},
getUpcomingStudy: async (studyId: number) => {
const response = await fetcher.get<UpcomingStudyDto>(
`${apiPath.studyDetail}/upcoming?studyId=${studyId}`,
{
next: { tags: [tags.upcomingStudy] },
cache: "force-cache",
}
);

Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,39 +1,102 @@
"use client";

import { Space } from "@wow-class/ui";
import { myStudyApi } from "apis/myStudyApi";
import { studyDetailApi } from "apis/studyDetailApi";
import { studyHistoryApi } from "apis/studyHistoryApi";
import { tags } from "constants/tags";
import Link from "next/link";
import { useEffect, useState } from "react";
import type { Assignment } from "types/dtos/studyDetail";
import type { AssignmentSubmissionStatusType } from "types/entities/common/assignment";
import { isDeadlinePassed } from "utils";
import { getIsAfterStartDate } from "utils/getIsAfterStartDate";
import { isDeadlinePassed } from "utils/isDeadlinePassed";
import { revalidateTagByName } from "utils/revalidateTagByName";
import { Link as LinkIcon, Reload as ReloadIcon } from "wowds-icons";
import Button from "wowds-ui/Button";

interface AssignmentBoxButtonsProps {
assignment: Assignment;
buttonsDisabled?: boolean;
}

export const AssignmentBoxButtons = ({
...rest
buttonsDisabled: buttonDisabledProp,
assignment,
}: AssignmentBoxButtonsProps) => {
const [startDate, setStartDate] = useState("");

const targetWeek = assignment.week;

useEffect(() => {
const fetchAssignmentStartDate = async () => {
const ongoingStudyInfo = await myStudyApi.getMyOngoingStudyInfo();

if (ongoingStudyInfo?.studyId) {
const curriculumData = await myStudyApi.getStudyCurriculumList(
ongoingStudyInfo.studyId
);

const matchingWeek = curriculumData?.find(
(item) => item.week === targetWeek
);

if (matchingWeek) {
setStartDate(matchingWeek.period.startDate);
}
}
};

fetchAssignmentStartDate();
}, [targetWeek]);

const buttonsDisabled = buttonDisabledProp || !getIsAfterStartDate(startDate);

return (
<>
<PrimaryButton {...rest} />
<PrimaryButton
assignment={assignment}
buttonsDisabled={buttonsDisabled}
/>
<Space height={8} />
<SecondaryButton {...rest} />
<SecondaryButton
assignment={assignment}
buttonsDisabled={buttonsDisabled}
/>
</>
);
};
const PrimaryButton = ({
assignment,
buttonsDisabled,
}: AssignmentBoxButtonsProps) => {
const [repositoryLink, setRepositoryLink] = useState("");

useEffect(() => {
const fetchStudyDashBoard = async () => {
const ongoingStudyInfo = await myStudyApi.getMyOngoingStudyInfo();
if (!ongoingStudyInfo) {
return;
}
const studyDashboard = await studyDetailApi.getStudyDetailDashboard(
ongoingStudyInfo.studyId
);

if (!studyDashboard) {
return;
} else {
setRepositoryLink(studyDashboard.repositoryLink);
}
};

fetchStudyDashBoard();
}, []);

const { assignmentSubmissionStatus, submissionFailureType, submissionLink } =
assignment;
const { primaryButtonText } = buttonProps[assignmentSubmissionStatus];
const { primaryButtonText } =
assignmentSubmissionStatus === null
? buttonTextMap.INITIAL
: buttonTextMap[assignmentSubmissionStatus];

if (
assignmentSubmissionStatus === "FAILURE" &&
Expand All @@ -42,17 +105,21 @@ const PrimaryButton = ({
return;
}
const stroke = buttonsDisabled ? "mono100" : "primary";
const link =
assignmentSubmissionStatus === null ? repositoryLink : submissionLink;

return (
<Link href={submissionLink} target="_blank">
<Button
disabled={buttonsDisabled}
icon={<LinkIcon height={20} stroke={stroke} width={20} />}
style={buttonStyle}
variant="outline"
>
{primaryButtonText}
</Button>
</Link>
<Button
asProp={Link}
disabled={buttonsDisabled}
href={link ?? ""}
icon={<LinkIcon height={20} stroke={stroke} width={20} />}
style={buttonStyle}
target="_blank"
variant="outline"
>
{primaryButtonText}
</Button>
);
};

Expand All @@ -62,13 +129,21 @@ const SecondaryButton = ({
}: AssignmentBoxButtonsProps) => {
const { assignmentSubmissionStatus, studyDetailId, deadline, committedAt } =
assignment;
const { secondaryButtonText } = buttonProps[assignmentSubmissionStatus];
const { secondaryButtonText } =
assignmentSubmissionStatus === null
? buttonTextMap.INITIAL
: buttonTextMap[assignmentSubmissionStatus];
const handleClickSubmissionComplete = async () => {
const response = await studyHistoryApi.submitAssignment(studyDetailId);
if (response.success) {
//TODO: 과제 제출 이후에는 과제 상태에 대한 업데이트 필요
//이번주 과제 조회 api, 대시보드 api revaliate
revalidateTagByName(tags.studyDetailDashboard);
revalidateTagByName(
assignmentSubmissionStatus === null
? tags.studyDetailDashboard
: tags.upcomingStudy
);
revalidateTagByName(tags.studyHistory);
}
};

Expand Down Expand Up @@ -98,13 +173,16 @@ const SecondaryButton = ({

const buttonStyle = {
maxWidth: "100%",
height: "48px !important",
};

const buttonProps: Record<
AssignmentSubmissionStatusType,
const buttonTextMap: Record<
NonNullable<AssignmentSubmissionStatusType>,
{ primaryButtonText: string; secondaryButtonText: string }
> = {
PENDING: {
> & {
INITIAL: { primaryButtonText: string; secondaryButtonText: string };
} = {
INITIAL: {
primaryButtonText: "제출하러 가기",
secondaryButtonText: "제출 완료하기",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ interface AssignmentBoxInfoProps {
assignment: Assignment;
}

export const AssignmentBoxInfo = ({ assignment }: AssignmentBoxInfoProps) => {
const { deadline, title, assignmentSubmissionStatus, submissionFailureType } =
assignment;
export const AssignmentBoxInfo = async ({
assignment,
}: AssignmentBoxInfoProps) => {
const {
deadline,
assignmentSubmissionStatus,
submissionFailureType,
submissionLink,
} = assignment;

const { year, month, day, hours, minutes } = parseISODate(deadline);

Expand All @@ -31,7 +37,7 @@ export const AssignmentBoxInfo = ({ assignment }: AssignmentBoxInfoProps) => {
<Text as="div" color="sub">
제출한 과제
<Text as="span" color="textBlack">
{title}
과제 이름
</Text>
</Text>
<Image alt="dot" height={6} src="/images/dot.svg" width={6} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ interface AssignmentBoxTitleProps {
export const AssignmentBoxTitle = ({ assignment }: AssignmentBoxTitleProps) => {
const { week, title, assignmentSubmissionStatus } = assignment;
const { color, message } =
assignmentSubmissionMap[assignmentSubmissionStatus];
assignmentSubmissionStatus === null
? assignmentSubmissionMap.INITIAL
: assignmentSubmissionMap[assignmentSubmissionStatus];

return (
<>
Expand All @@ -21,10 +23,10 @@ export const AssignmentBoxTitle = ({ assignment }: AssignmentBoxTitleProps) => {
</Text>
<Space height={16} />
<Flex gap="xs">
<Text as="h2" typo="h2">
<Text as="h2" style={textStyle} typo="h2">
{title}
</Text>
{assignmentSubmissionStatus !== "PENDING" && (
{assignmentSubmissionStatus !== null && (
<Tag color={color ?? "blue"} variant="solid2">
{message}
</Tag>
Expand All @@ -34,10 +36,17 @@ export const AssignmentBoxTitle = ({ assignment }: AssignmentBoxTitleProps) => {
);
};

const textStyle = {
textOverflow: "ellipsis",
whiteSpace: "nowrap",
overflow: "hidden",
};
const assignmentSubmissionMap: Record<
AssignmentSubmissionStatusType,
NonNullable<AssignmentSubmissionStatusType>,
{ message: string; color: ComponentProps<typeof Tag>["color"] }
> = {
> & {
INITIAL: { message: string; color: ComponentProps<typeof Tag>["color"] };
} = {
FAILURE: {
message: "제출 실패",
color: "red",
Expand All @@ -46,7 +55,7 @@ const assignmentSubmissionMap: Record<
message: "제출 완료",
color: "blue",
},
PENDING: {
INITIAL: {
message: "",
color: "grey",
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Flex } from "@styled-system/jsx";
import { Text } from "@wow-class/ui";
import Popover from "components/Popover";
import type { SubmissionFailureType } from "types/entities/common/assignment";
import type { AssignmentSubmissionFailureType } from "types/entities/common/assignment";
import { Help as HelpIcon } from "wowds-icons";

interface FailurePopoverProps {
submissionFailureType: SubmissionFailureType;
submissionFailureType: AssignmentSubmissionFailureType;
}
export const FailurePopover = ({
submissionFailureType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ export const AssignmentOverviewBox = ({
text={
<>
<AssignmentBoxTitle assignment={assignment} />
<Link href={assignment.descriptionLink} target="_blank">
<TextButton style={textButtonstyle} text="과제 명세 확인" />
</Link>
<TextButton
asProp={Link}
href={assignment.descriptionLink}
style={textButtonstyle}
target="_blank"
text="과제 명세 확인"
/>
<AssignmentBoxInfo assignment={assignment} />
<Space height={26} />
<AssignmentBoxButtons
Expand All @@ -47,6 +51,8 @@ export const AssignmentOverviewBox = ({
const textButtonstyle = {
paddingLeft: "0px",
paddingRight: "0px",
display: "block",
width: "fit-content",
};

const boxStyle = {
Expand Down
Loading

0 comments on commit 09ac371

Please sign in to comment.