Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Deploy] 과제 페이지 , 수강 신청 페이지 QA 반영 #142

Merged
merged 5 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions apps/admin/apis/auth/dashboardApi.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { fetcher } from "@wow-class/utils";
import { apiPath, mentorApiPath } from "constants/apiPath";
import { apiPath } from "constants/apiPath";
import { tags } from "constants/tags";
import type { DashboardApiResponseDto } from "types/dtos/auth";
import type { MyStudyListApiResponseDto } from "types/dtos/studyList";

export const dashboardApi = {
getDashboardInfo: async () => {
Expand All @@ -19,14 +18,4 @@ export const dashboardApi = {

return { studyRole, manageRole };
},
getMyStudyList: async () => {
const response = await fetcher.get<MyStudyListApiResponseDto[]>(
mentorApiPath.studyList,
{
next: { tags: [tags.dashboard] },
cache: "force-cache",
}
);
return response.data;
},
};
10 changes: 10 additions & 0 deletions apps/admin/apis/study/studyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ export const studyApi = {

return response.data;
},
getMyStudyList: async () => {
const response = await fetcher.get<StudyListApiResponseDto[]>(
mentorApiPath.studyList,
{
next: { tags: [tags.myStudyList] },
cache: "force-cache",
}
);
return response.data;
},
getStudyBasicInfo: async (studyId: number) => {
const response = await fetcher.get<StudyBasicInfoApiResponseDto>(
`/common/studies/${studyId}`,
Expand Down
6 changes: 5 additions & 1 deletion apps/admin/app/studies/_components/StudyList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { css } from "@styled-system/css";
import { studyApi } from "apis/study/studyApi";
import isAdmin from "utils/isAdmin";

import EmptyStudyList from "./EmptyStudyList";
import StudyListItem from "./StudyListItem";

const StudyList = async () => {
const studyList = await studyApi.getStudyList();
const adminStatus = await isAdmin();
const studyList = adminStatus
? await studyApi.getStudyList()
: await studyApi.getMyStudyList();

if (studyList?.length === 0) {
return <EmptyStudyList />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const CreatedStudyCheckModal = () => {

if (result.success) {
await revalidateTagByName(tags.studyList);
await revalidateTagByName(tags.myStudyList);
window.alert("스터디 생성에 성공했어요.");
router.push(`${routerPath.root.href}`);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,6 @@ const StudyStartDatePick = () => {
}
}, [handleStudyDateSelect, studyDate.fromValue, studyDate.toValue, week]);

const disableDateList = [
{
from: new Date(0),
to: yesterday,
},
...(watch("applicationEndDate")
? [
{
from: new Date(0),
to: studyApplyEndDate,
},
]
: []),
];

return (
<Flex direction="column" position="relative" width={358}>
<Text color="sub" style={{ marginBottom: "8px" }} typo="label2">
Expand Down Expand Up @@ -115,9 +100,12 @@ const StudyStartDatePick = () => {
{isOpen && (
<div ref={datepickerRef}>
<DayPicker
disabled={disableDateList}
mode="range"
weekStartsOn={1}
disabled={{
from: new Date(0),
to: yesterday,
}}
selected={{
from: formatStringToDate(studyDate.fromValue),
to: formatStringToDate(studyDate.toValue),
Expand Down
6 changes: 3 additions & 3 deletions apps/admin/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { css } from "@styled-system/css";
import { NavItem } from "@wow-class/ui";
import { dashboardApi } from "apis/auth/dashboardApi";
import { studyApi } from "apis/study/studyApi";
import { clientUrl } from "constants/url";
import Image from "next/image";
Expand All @@ -18,9 +17,10 @@ import participantImageUrl from "../public/images/particpant.svg";
*/

const Navbar = async () => {
const studyList = (await isAdmin())
const adminStatus = await isAdmin();
const studyList = adminStatus
? await studyApi.getStudyList()
: await dashboardApi.getMyStudyList();
: await studyApi.getMyStudyList();

const navMenu = [
{
Expand Down
1 change: 1 addition & 0 deletions apps/admin/constants/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const enum tags {
assignments = "assignments",
curriculums = "curriculums",
studyList = "studyList",
myStudyList = "myStudyList",
studyBasicInfo = "studyBasicInfo",
announcements = "announcements",
memberList = "memberList",
Expand Down
15 changes: 1 addition & 14 deletions apps/admin/types/dtos/studyList.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import type { DayOfWeekType } from "types/entities/dayofweek";
import type {
StudyKoreanType,
StudySemesterType,
StudyType,
} from "types/entities/study";
import type { StudyKoreanType, StudySemesterType } from "types/entities/study";
import type { TimeType } from "types/entities/time";

export interface StudyListApiResponseDto {
Expand All @@ -20,12 +16,3 @@ export interface StudyListApiResponseDto {
totalWeek: number;
openingDate: string;
}

export interface MyStudyListApiResponseDto {
studyId: number;
semester: string;
title: string;
studyType: StudyType;
notionLink: string;
mentorName: string;
}
18 changes: 2 additions & 16 deletions apps/client/apis/studyDetailApi.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
import { fetcher } from "@wow-class/utils";
import { apiPath } from "constants/apiPath";
import { tags } from "constants/tags";
import type {
StudyDetailDashboardDto,
UpcomingStudyDto,
} from "types/dtos/studyDetail";
import type { StudyDetailDashboardDto } 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",
cache: "no-store",
}
);

Expand Down
2 changes: 1 addition & 1 deletion apps/client/apis/studyHistoryApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const studyHistoryApi = {
`${apiPath.studyHistory}/assignments?studyId=${studyId}`,
{
next: { tags: [tags.studyHistory] },
cache: "force-cache",
cache: "no-store",
}
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,34 @@
"use client";

import { Space } from "@wow-class/ui";
import { myStudyApi } from "apis/myStudyApi";
import { studyDetailApi } from "apis/studyDetailApi";
import { padWithZero, parseISODate } from "@wow-class/utils";
import { studyHistoryApi } from "apis/studyHistoryApi";
import { tags } from "constants/tags";
import Link from "next/link";
import { useEffect, useState } from "react";
import { toast } from "react-toastify";
import type { Assignment } from "types/dtos/studyDetail";
import type { AssignmentSubmissionStatusType } from "types/entities/common/assignment";
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;
repositoryLink?: string;
buttonsDisabled?: boolean;
}

export const AssignmentBoxButtons = ({
buttonsDisabled: buttonDisabledProp,
buttonsDisabled,
assignment,
repositoryLink,
}: 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
assignment={assignment}
buttonsDisabled={buttonsDisabled}
repositoryLink={repositoryLink}
/>
<Space height={8} />
<SecondaryButton
Expand All @@ -68,29 +41,8 @@ export const AssignmentBoxButtons = ({
const PrimaryButton = ({
assignment,
buttonsDisabled,
repositoryLink,
}: 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 } =
Expand All @@ -105,14 +57,13 @@ const PrimaryButton = ({
return;
}
const stroke = buttonsDisabled ? "mono100" : "primary";
const link =
assignmentSubmissionStatus === null ? repositoryLink : submissionLink;

const primaryButtonHref =
assignmentSubmissionStatus === "SUCCESS" ? submissionLink : repositoryLink;
return (
<Button
asProp={Link}
disabled={buttonsDisabled}
href={link ?? ""}
href={primaryButtonHref ?? ""}
icon={<LinkIcon height={20} stroke={stroke} width={20} />}
style={buttonStyle}
target="_blank"
Expand All @@ -126,43 +77,43 @@ const PrimaryButton = ({
const SecondaryButton = ({
assignment,
buttonsDisabled,
}: AssignmentBoxButtonsProps) => {
}: Omit<AssignmentBoxButtonsProps, "repositoryLink">) => {
const { assignmentSubmissionStatus, studyDetailId, deadline, committedAt } =
assignment;
if (isDeadlinePassed(deadline)) {
return (
<Button disabled={true} style={buttonStyle}>
마감
</Button>
);
}
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(
assignmentSubmissionStatus === null
? tags.studyDetailDashboard
: tags.upcomingStudy
);
revalidateTagByName(tags.studyDetailDashboard);
revalidateTagByName(tags.studyHistory);
toast.success("과제 제출이 완료되었어요.");
}
};

if (isDeadlinePassed(deadline)) {
return (
<Button disabled={true} style={buttonStyle}>
마감
</Button>
);
}
const stroke = buttonsDisabled ? "mono100" : "backgroundNormal";
const { year, month, day, hours, minutes } = parseISODate(
committedAt as string
);
const commitText = `최종 수정일자 ${year}년 ${month}월 ${day}일 ${padWithZero(hours)}:${padWithZero(minutes)}`;
return (
<Button
disabled={buttonsDisabled}
icon={<ReloadIcon height={20} stroke={stroke} width={20} />}
style={buttonStyle}
{...(assignmentSubmissionStatus === "SUCCESS" &&
committedAt && {
subText: `최종 수정일자 ${committedAt}`,
subText: commitText,
})}
onClick={handleClickSubmissionComplete}
>
Expand All @@ -173,7 +124,7 @@ const SecondaryButton = ({

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

const buttonTextMap: Record<
Expand Down
Loading
Loading