diff --git a/apps/client/apis/studyDetailApi.ts b/apps/client/apis/studyDetailApi.ts new file mode 100644 index 00000000..76ce3458 --- /dev/null +++ b/apps/client/apis/studyDetailApi.ts @@ -0,0 +1,20 @@ +import { fetcher } from "@wow-class/utils"; +import { apiPath } from "constants/apiPath"; +import { tags } from "constants/tags"; +import type { StudyDetailDashboardDto } from "types/dtos/study-detail-dashboard"; + +export const studyDetailApi = { + getStudyDetailDashboard: async (studyId: number) => { + const response = await fetcher.get( + `${apiPath.studyDetail}/dashboard?studyId=${studyId}`, + { + next: { tags: [tags.studyDetailDashboard] }, + headers: { + Authorization: `Bearer ${process.env.DEV_AUTH_TOKEN}`, + }, + } + ); + + return response.data; + }, +}; diff --git a/apps/client/apis/studyHistoryApi.ts b/apps/client/apis/studyHistoryApi.ts index 46b188ee..1298fa10 100644 --- a/apps/client/apis/studyHistoryApi.ts +++ b/apps/client/apis/studyHistoryApi.ts @@ -9,6 +9,7 @@ export const studyHistoryApi = { `${apiPath.studyHistory}/assignments?studyId=${studyId}`, { next: { tags: [tags.studyHistory] }, + cache: "force-cache", headers: { Authorization: `Bearer ${process.env.DEV_AUTH_TOKEN}`, }, diff --git a/apps/client/app/(afterLogin)/my-study/my-homework/_components/HomeworkBoxWithLinkEdit.tsx b/apps/client/app/(afterLogin)/my-study/my-homework/_components/HomeworkBoxWithLinkEdit.tsx new file mode 100644 index 00000000..50a54b2f --- /dev/null +++ b/apps/client/app/(afterLogin)/my-study/my-homework/_components/HomeworkBoxWithLinkEdit.tsx @@ -0,0 +1,72 @@ +"use client"; + +import { Space, Text } from "@wow-class/ui"; +import { tags } from "constants/tags"; +import { revalidateTag } from "next/cache"; +import type { SubmittableAssignment } from "types/dtos/study-detail-dashboard"; +import { Link, Reload } from "wowds-icons"; +import Box from "wowds-ui/Box"; +import Button from "wowds-ui/Button"; +import TextButton from "wowds-ui/TextButton"; + +interface HomeworkOverviewBoxProps { + assignments: SubmittableAssignment[]; + repositoryLink: string; +} +export const HomeworkBoxWithLinkEdit = ({ + assignments, + repositoryLink, +}: HomeworkOverviewBoxProps) => { + const handleClickSubmissionComplete = async () => { + revalidateTag(tags.studyDetailDashboard); + }; + return ( + <> + {assignments.map((assignment) => ( + + + {assignment.week}주차 + + + + {assignment.title} + + + + 종료 일시 : {assignment.deadline} + + + + + + + } + /> + ))} + + ); +}; diff --git a/apps/client/app/(afterLogin)/my-study/my-homework/_components/HomeworkOverviewBox.tsx b/apps/client/app/(afterLogin)/my-study/my-homework/_components/HomeworkOverviewBox.tsx index 5793bfb5..70f45c74 100644 --- a/apps/client/app/(afterLogin)/my-study/my-homework/_components/HomeworkOverviewBox.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-homework/_components/HomeworkOverviewBox.tsx @@ -1,56 +1,89 @@ +"use client"; + import { Flex, styled } from "@styled-system/jsx"; import { Space, Text } from "@wow-class/ui"; +import { tags } from "constants/tags"; +import { revalidateTag } from "next/cache"; import Image from "next/image"; +import type { SubmittableAssignment } from "types/dtos/study-detail-dashboard"; import { Link, Reload } from "wowds-icons"; import Box from "wowds-ui/Box"; import Button from "wowds-ui/Button"; import Tag from "wowds-ui/Tag"; import TextButton from "wowds-ui/TextButton"; -export const HomeworkOverviewBox = () => { +interface HomeworkOverviewBoxProps { + assignments: SubmittableAssignment[]; +} +export const HomeworkOverviewBox = ({ + assignments, +}: HomeworkOverviewBoxProps) => { + const handleClickSubmissionComplete = async () => { + revalidateTag(tags.studyDetailDashboard); + }; return ( - - - 4주차 - - - - - HTTP 통신 코드 작성하기 - - - 제출 완료 - - - - - 종료 일시 : 2024년 5월 23일 23:59 - - - 제출한 과제 : - - 2024-1-Web-Study/Week4 + <> + {assignments.map((assignment) => ( + + + {assignment.week}주차 - - dot - 글자수 충족 - - - - - - - } - /> + + + + {assignment.title} + + + {assignment.assignmentSubmissionStatus} + + + + + 종료 일시 : {assignment.deadline} + + + 제출한 과제 + + {assignment.title} + + + dot + + {assignment.assignmentSubmissionStatus === "FAILURE" + ? assignment.submissionFailureType + : "글자수 충족"} + + + + + + + + } + /> + ))} + ); }; diff --git a/apps/client/app/(afterLogin)/my-study/my-homework/_components/RepositorySubmissionBox.tsx b/apps/client/app/(afterLogin)/my-study/my-homework/_components/RepositorySubmissionBox.tsx index 5750886f..5449afc1 100644 --- a/apps/client/app/(afterLogin)/my-study/my-homework/_components/RepositorySubmissionBox.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-homework/_components/RepositorySubmissionBox.tsx @@ -2,37 +2,54 @@ import { Flex } from "@styled-system/jsx"; import { Space, Text } from "@wow-class/ui"; -import { useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { Edit, Trash, Warn } from "wowds-icons"; import Box from "wowds-ui/Box"; import Button from "wowds-ui/Button"; import Tag from "wowds-ui/Tag"; import TextField from "wowds-ui/TextField"; -export const RepositorySubmissionBox = () => { - const [url, setUrl] = useState(""); - const [isEditing, setIsEditing] = useState(true); +interface RepositorySubmissionBoxProps { + repositoryLink: string; +} + +type RepositorySubmissionStatus = "none" | "editing" | "submitted"; + +export const RepositorySubmissionBox = ({ + repositoryLink, +}: RepositorySubmissionBoxProps) => { + const [url, setUrl] = useState(repositoryLink); const [isInitialSubmit, setIsInitialSubmit] = useState(true); + const [status, setStatus] = useState("none"); - const handleChange = (value: string) => { + const handleClickChange = useCallback((value: string) => { setUrl(value); - }; + }, []); - const handleEditButtonClick = () => { - setIsEditing(true); - }; + const handleClickEditButton = useCallback(() => { + setStatus("editing"); + }, []); - const handleSubmitButtonClick = () => { + const handleClickSubmitButton = useCallback(async () => { if (isInitialSubmit) { setIsInitialSubmit(false); } else { console.log("모달 오픈"); } - setIsEditing(false); - }; + setStatus("submitted"); + //TODO: studyHistoryId 넣어주기 + //await studyHistoryApi.putRepository(1, url); + }, [isInitialSubmit]); + + useEffect(() => { + if (isInitialSubmit) { + setStatus(repositoryLink ? "submitted" : "none"); + } + }, [isInitialSubmit, repositoryLink]); return ( @@ -43,14 +60,14 @@ export const RepositorySubmissionBox = () => { 과제 제출을 위한 레포지토리 URL 입력하기 - {!isEditing && ( + {status === "submitted" && ( 제출 완료 )} - {isEditing && isInitialSubmit && ( + {status === "none" && ( @@ -58,19 +75,19 @@ export const RepositorySubmissionBox = () => { )} - {!isEditing && !isInitialSubmit && ( + {status === "submitted" && ( 최초 과제 제출 전 까지만 수정이 가능해요. )} - {isEditing && ( + {status !== "submitted" && ( )} - {!isEditing && ( + {status === "submitted" && ( { > {url} - + @@ -90,7 +107,7 @@ export const RepositorySubmissionBox = () => { diff --git a/apps/client/app/(afterLogin)/my-study/my-homework/_components/mockData.ts b/apps/client/app/(afterLogin)/my-study/my-homework/_components/mockData.ts index 4200e9cd..14e94373 100644 --- a/apps/client/app/(afterLogin)/my-study/my-homework/_components/mockData.ts +++ b/apps/client/app/(afterLogin)/my-study/my-homework/_components/mockData.ts @@ -1,3 +1,4 @@ +import type { StudyDetailDashboardDto } from "types/dtos/study-detail-dashboard"; import type { AssignmentHistoryDto } from "types/dtos/study-history"; export const history: AssignmentHistoryDto[] = [ @@ -7,7 +8,7 @@ export const history: AssignmentHistoryDto[] = [ deadline: "2024-08-17T06:02:17.417Z", descriptionLink: "", submissionLink: "http://example.com/submission1", - assignmentSubmissionStatus: "PENDING", + assignmentSubmissionStatus: "SUCCESS", week: 1, }, { @@ -16,7 +17,25 @@ export const history: AssignmentHistoryDto[] = [ deadline: "2024-08-24T06:02:17.417Z", descriptionLink: "http://example.com/assignment2", submissionLink: "", - assignmentSubmissionStatus: "COMPLETED", + assignmentSubmissionStatus: "FAIL", week: 2, }, ]; + +export const studyDashBoardData: StudyDetailDashboardDto = { + repositoryLink: "https://example.com/assignments/react-basics", + isLinkEditable: true, + submittableAssignments: [ + { + studyDetailId: 1, + assignmentStatus: "OPEN", + week: 1, + title: "React Basics", + assignmentSubmissionStatus: "FAILURE", + descriptionLink: "https://example.com/assignments/react-basics", + deadline: "2024-08-18T17:56:01.155Z", + submissionLink: "https://example.com/submissions/react-basics", + submissionFailureType: "NOT_SUBMITTED", + }, + ], +}; diff --git a/apps/client/app/(afterLogin)/my-study/my-homework/page.tsx b/apps/client/app/(afterLogin)/my-study/my-homework/page.tsx index 66ad468f..40bb14a9 100644 --- a/apps/client/app/(afterLogin)/my-study/my-homework/page.tsx +++ b/apps/client/app/(afterLogin)/my-study/my-homework/page.tsx @@ -8,7 +8,15 @@ import { RepositorySubmissionBox, } from "@/(afterLogin)/my-study/my-homework/_components"; -const MyHomeworkPage = () => { +import { HomeworkBoxWithLinkEdit } from "./_components/HomeworkBoxWithLinkEdit"; +import { studyDashBoardData } from "./_components/mockData"; + +const MyHomeworkPage = async () => { + // const studyDashboard = await studyDetailApi.getStudyDetailDashboard(1); + + //TODO: studyDashboard.isLinkEditable 가 false 면 이번 주 과제 조회 api 사용 + const studyDashboard = studyDashBoardData; + return ( <> @@ -26,8 +34,22 @@ const MyHomeworkPage = () => { - - + {studyDashBoardData.isLinkEditable && ( + <> + + + + )} + {/* {!studyDashBoardData.isLinkEditable && ( + + )} */} diff --git a/apps/client/constants/apiPath.ts b/apps/client/constants/apiPath.ts index 11d67a8a..37e58851 100644 --- a/apps/client/constants/apiPath.ts +++ b/apps/client/constants/apiPath.ts @@ -3,4 +3,5 @@ export const enum apiPath { applyStudy = "/studies/apply", studyHistory = "/study-history", + studyDetail = "/study-details/assignments", } diff --git a/apps/client/constants/tags.ts b/apps/client/constants/tags.ts index 75822ae9..72356afb 100644 --- a/apps/client/constants/tags.ts +++ b/apps/client/constants/tags.ts @@ -2,4 +2,5 @@ export const enum tags { dashboard = "dashboard", studyApply = "studyApply", studyHistory = "studyHistory", + studyDetailDashboard = "studyDetailDashboard", } diff --git a/apps/client/types/dtos/study-detail-dashboard.ts b/apps/client/types/dtos/study-detail-dashboard.ts new file mode 100644 index 00000000..2686d05e --- /dev/null +++ b/apps/client/types/dtos/study-detail-dashboard.ts @@ -0,0 +1,21 @@ +export interface StudyDetailDashboardDto { + repositoryLink: string; + isLinkEditable: boolean; + submittableAssignments: SubmittableAssignment[]; +} + +export interface SubmittableAssignment { + studyDetailId: number; + assignmentStatus: "NONE" | "OPEN" | "CANCELLED"; + week: number; + title: string; + assignmentSubmissionStatus: "FAILURE" | "SUCCESS"; + descriptionLink: string; + deadline: string; + submissionLink: string; + submissionFailureType: + | "NONE" + | "NOT_SUBMITTED" + | "WORD_COUNT_INSUFFICIENT" + | "LOCATION_UNIDENTIFIABLE"; +}