From bc1c665f3b2562a05adabf0f0c1ce29b5dee3cb7 Mon Sep 17 00:00:00 2001
From: SeieunYoo <101736358+SeieunYoo@users.noreply.github.com>
Date: Sat, 24 Aug 2024 02:41:45 +0900
Subject: [PATCH] =?UTF-8?q?[Feature]=20=EB=A0=88=ED=8F=AC=EC=A7=80?=
=?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EC=9E=85=EB=A0=A5=ED=95=A0=20=EB=95=8C=20?=
=?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EC=B6=94?=
=?UTF-8?q?=EA=B0=80=20(#46)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: 신청 모달, 취소 모달
* feat: 컴포넌트 로직 분리
* chore: 문구 수정
* chore: 헤더 제거
* chore: fetcher 주석 해제
* feat: 레포지토리 입력 모달
* feat: 헤더 제거
* feat: match되는 studyHistoryId 찾는 훅 추가
* chore: modal 라우팅 경로 수정
* chore: my-study/my-assignment 로 이동
* chore: 이전 브랜치에 남은 로직 삭제
* feat: modal 라우팅 수정, url 쿼리paramter 넘기는 것으로 수정
* feat: 분기문 수정
* chore: 컴포넌트명 수정
* refactor: AssignmentBoxButtons 리팩토링
* feat: AssignmentBoxInfo 로 수정
* refactor: RepositorySubmissionBox 리팩토링
* feat: customRevalidate 삭제
* chore: 스타일 객체 하단으로 분리, 문구 수정
* feat: 추가된 히스토리 api dto 반영, 과제 없을 때 ui 추가
* feat: 입력할 때 빈 문자에 대한 validate 추가, 컴포넌트 하단 분리
* chore: 프로퍼티 스프레드로
* feat: 모달 url 변경
* feat: 에러 상태 핸들링 수정, 텍스트필드 height 고정
* chore: ui css반영
* feat: 모달 플로우 수정, 입력하기 버튼 누르면 모달 열리게
---
.../AssignmenBoxButtons.tsx | 122 ------------
.../RepositorySubmissionBox.tsx | 125 ------------
.../(.)repository-url/confirmation/page.tsx | 46 +++++
.../@modal/(.)repository-url/default.tsx | 5 +
.../my-study/my-assignment/@modal/default.tsx | 5 +
.../AssignmentBoxButtons.tsx | 119 +++++++++++
.../AssignmentBoxInfo.tsx} | 12 +-
.../AssignmentBoxTitle.tsx | 0
.../AssignmentOverviewBox/index.tsx | 10 +-
.../AssignmentContent/EmptyAssignmentBox.tsx | 25 +++
.../RepositorySubmissionBox.tsx | 185 ++++++++++++++++++
.../_components/AssignmentContent/index.tsx | 21 +-
.../AssignmentHistoryItem.tsx | 0
.../_components/AssignmentHistory/index.tsx | 6 +-
.../my-assignment/_components/index.ts | 0
.../my-study/my-assignment/default.tsx | 5 +
.../my-study/my-assignment/layout.tsx | 18 ++
.../{ => my-study}/my-assignment/page.tsx | 0
.../repository-url/confirmation/page.tsx | 8 +
apps/client/constants/assignmentMockData.ts | 2 +-
apps/client/constants/routePath.ts | 6 +-
apps/client/hooks/useMatchedStudyHistoryId.ts | 33 ++++
apps/client/middleware.ts | 7 +-
apps/client/types/dtos/studyHistory.ts | 6 +-
apps/client/types/entities/myAssignment.ts | 5 +-
packages/ui/src/styles.css | 3 +
26 files changed, 495 insertions(+), 279 deletions(-)
delete mode 100644 apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmenBoxButtons.tsx
delete mode 100644 apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/confirmation/page.tsx
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/default.tsx
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/@modal/default.tsx
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx
rename apps/client/app/(afterLogin)/{my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmetBoxInfo.tsx => my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx} (82%)
rename apps/client/app/(afterLogin)/{ => my-study}/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx (100%)
rename apps/client/app/(afterLogin)/{ => my-study}/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx (82%)
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
rename apps/client/app/(afterLogin)/{ => my-study}/my-assignment/_components/AssignmentContent/index.tsx (56%)
rename apps/client/app/(afterLogin)/{ => my-study}/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx (100%)
rename apps/client/app/(afterLogin)/{ => my-study}/my-assignment/_components/AssignmentHistory/index.tsx (87%)
rename apps/client/app/(afterLogin)/{ => my-study}/my-assignment/_components/index.ts (100%)
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/default.tsx
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/layout.tsx
rename apps/client/app/(afterLogin)/{ => my-study}/my-assignment/page.tsx (100%)
create mode 100644 apps/client/app/(afterLogin)/my-study/my-assignment/repository-url/confirmation/page.tsx
create mode 100644 apps/client/hooks/useMatchedStudyHistoryId.ts
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmenBoxButtons.tsx b/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmenBoxButtons.tsx
deleted file mode 100644
index 65a34f46..00000000
--- a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmenBoxButtons.tsx
+++ /dev/null
@@ -1,122 +0,0 @@
-"use client";
-
-import { Space } from "@wow-class/ui";
-import { studyHistoryApi } from "apis/studyHistoryApi";
-import { tags } from "constants/tags";
-import { revalidateTag } from "next/cache";
-import Link from "next/dist/client/link";
-import type { Assignment } from "types/dtos/studyDetail";
-import { isDeadlinePassed } from "utils";
-import { Link as LinkIcon, Reload as ReloadIcon } from "wowds-icons";
-import Button from "wowds-ui/Button";
-
-interface AssignmentButtonsProps {
- assignment: Assignment;
- buttonsDisabled?: boolean;
-}
-
-export const AssignmentButtons = ({
- assignment,
- buttonsDisabled,
-}: AssignmentButtonsProps) => {
- const {
- assignmentSubmissionStatus,
- submissionFailureType,
- submissionLink,
- deadline,
- committedAt,
- studyDetailId,
- } = assignment;
-
- const handleClickSubmissionComplete = async () => {
- const response = await studyHistoryApi.submitAssignment(studyDetailId);
- if (response.success) {
- //TODO: 과제 제출 이후에는 과제 상태에 대한 업데이트 필요
- //이번주 과제 조회 api, 대시보드 api revaliate
- //revalidateTag()
- }
- };
-
- const getButtonProps = () => {
- if (assignmentSubmissionStatus === "PENDING") {
- const stroke = buttonsDisabled ? "mono100" : "backgroundNormal";
- return {
- primaryButtonText: "제출하러 가기",
- secondaryButtonText: "제출 완료하기",
- icon: ,
- };
- } else if (assignmentSubmissionStatus === "SUCCESS") {
- return {
- primaryButtonText: "제출한 과제 보러가기",
- secondaryButtonText: "제출 갱신하기",
- icon: ,
- };
- } else {
- return {
- primaryButtonText: "제출한 과제 보러가기",
- secondaryButtonText: "제출 완료하기",
- icon: ,
- };
- }
- };
-
- const renderPrimaryButton = (text: string) => {
- if (
- assignmentSubmissionStatus === "FAILURE" &&
- submissionFailureType === "NOT_SUBMITTED"
- ) {
- return null;
- }
- const stroke = buttonsDisabled ? "mono100" : "primary";
- return (
-
- }
- style={buttonStyle}
- variant="outline"
- >
- {text}
-
-
- );
- };
-
- const renderSecondaryButton = (text: string, icon: JSX.Element) => {
- if (isDeadlinePassed(deadline)) {
- return (
-
- );
- }
- return (
-
- );
- };
-
- const { primaryButtonText, secondaryButtonText, icon } = getButtonProps();
-
- return (
- <>
- {renderPrimaryButton(primaryButtonText)}
-
- {renderSecondaryButton(secondaryButtonText, icon)}
- >
- );
-};
-
-const buttonStyle = {
- maxWidth: "100%",
-};
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx b/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
deleted file mode 100644
index 46dd4632..00000000
--- a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
+++ /dev/null
@@ -1,125 +0,0 @@
-"use client";
-
-import { css } from "@styled-system/css";
-import { Flex } from "@styled-system/jsx";
-import { Space, Text } from "@wow-class/ui";
-import { useCallback, useEffect, useState } from "react";
-import type { RepositorySubmissionStatusType } from "types/entities/myAssignment";
-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";
-interface RepositorySubmissionBoxProps {
- repositoryLink: string;
-}
-
-export const RepositorySubmissionBox = ({
- repositoryLink,
-}: RepositorySubmissionBoxProps) => {
- const [url, setUrl] = useState(repositoryLink);
- const [isInitialSubmit, setIsInitialSubmit] = useState(true);
- const [repositorySubmissionStatus, setRepositorySubmissionStatus] =
- useState("EDITING");
-
- const handleClickChange = useCallback((value: string) => {
- setUrl(value);
- }, []);
-
- const handleClickEditButton = useCallback(() => {
- setRepositorySubmissionStatus("EDITING");
- }, []);
-
- const handleClickSubmitButton = useCallback(async () => {
- if (isInitialSubmit) {
- setIsInitialSubmit(false);
- } else {
- console.log("모달 오픈");
- }
- setRepositorySubmissionStatus("SUBMITTED");
- //TODO: studyHistoryId 넣어주기
- //await studyHistoryApi.putRepository(1, url);
- }, [isInitialSubmit]);
-
- useEffect(() => {
- if (isInitialSubmit) {
- setRepositorySubmissionStatus(repositoryLink ? "SUBMITTED" : "EDITING");
- }
- }, [isInitialSubmit, repositoryLink]);
-
- return (
-
-
- 레포지토리
-
-
-
-
- 과제 제출을 위한 레포지토리 URL 입력하기
-
- {repositorySubmissionStatus === "SUBMITTED" && (
-
- 제출 완료
-
- )}
-
-
- {isInitialSubmit && repositorySubmissionStatus === "EDITING" && (
-
-
-
- 입력하지 않으면 앞으로의 과제를 제출할 수 없어요.
-
-
- )}
- {repositorySubmissionStatus === "SUBMITTED" && (
- 최초 과제 제출 전 까지만 수정이 가능해요.
- )}
-
- {repositorySubmissionStatus === "EDITING" && (
-
- )}
- {repositorySubmissionStatus === "SUBMITTED" && (
-
- {url}
-
-
-
-
-
- )}
-
-
- >
- }
- />
- );
-};
-
-const urlBoxStyle = css({
- backgroundColor: "backgroundAlternative",
- borderRadius: "5px",
- color: "sub",
- justifyContent: "space-between",
- paddingX: "24px",
- paddingY: "18px",
- textStyle: "h2",
-});
-
-const boxStyle = {
- minWidth: "484px",
-};
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/confirmation/page.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/confirmation/page.tsx
new file mode 100644
index 00000000..4c98645a
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/confirmation/page.tsx
@@ -0,0 +1,46 @@
+"use client";
+
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Modal, Space, Text } from "@wow-class/ui";
+import { tags } from "constants/tags";
+import useMatchedStudyHistoryId from "hooks/useMatchedStudyHistoryId";
+import { useSearchParams } from "next/navigation";
+import { revalidateTagByName } from "utils/revalidateTagByName";
+import Button from "wowds-ui/Button";
+
+const RepositoryUrlConfirmationModal = () => {
+ const searchParams = useSearchParams();
+ const url = searchParams.get("repositoryUrl");
+ //const studyHistoryId = useMatchedStudyHistoryId();
+
+ const handleClickSubmitButton = async () => {
+ //await studyHistoryApi.putRepository(studyHistoryId, url);
+ //TODO: 제출 후에 RepositoryBox 를 SUBMITTED 로 상태로 바꿔줘야함.
+ revalidateTagByName(tags.studyDetailDashboard);
+ };
+ return (
+
+
+ 레포지토리를 입력하시겠어요?
+
+ 최초 과제 제출 전까지 수정이 가능해요.
+
+ {url}
+
+
+
+
+ );
+};
+
+export default RepositoryUrlConfirmationModal;
+
+const urlBoxStyle = css({
+ backgroundColor: "backgroundAlternative",
+ borderRadius: "5px",
+ color: "sub",
+ paddingX: "lg",
+ paddingY: "md",
+ textStyle: "h2",
+});
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/default.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/default.tsx
new file mode 100644
index 00000000..395785b9
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/(.)repository-url/default.tsx
@@ -0,0 +1,5 @@
+const Default = () => {
+ return null;
+};
+
+export default Default;
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/default.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/default.tsx
new file mode 100644
index 00000000..395785b9
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/@modal/default.tsx
@@ -0,0 +1,5 @@
+const Default = () => {
+ return null;
+};
+
+export default Default;
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
new file mode 100644
index 00000000..ea9b7bbe
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxButtons.tsx
@@ -0,0 +1,119 @@
+"use client";
+
+import { Space } from "@wow-class/ui";
+import { studyHistoryApi } from "apis/studyHistoryApi";
+import { tags } from "constants/tags";
+import Link from "next/link";
+import type { Assignment } from "types/dtos/studyDetail";
+import type { AssignmentSubmissionStatusType } from "types/entities/common/assignment";
+import { isDeadlinePassed } from "utils";
+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
+}: AssignmentBoxButtonsProps) => {
+ return (
+ <>
+
+
+
+ >
+ );
+};
+const PrimaryButton = ({
+ assignment,
+ buttonsDisabled,
+}: AssignmentBoxButtonsProps) => {
+ const { assignmentSubmissionStatus, submissionFailureType, submissionLink } =
+ assignment;
+ const { primaryButtonText } = buttonProps[assignmentSubmissionStatus];
+
+ if (
+ assignmentSubmissionStatus === "FAILURE" &&
+ submissionFailureType === "NOT_SUBMITTED"
+ ) {
+ return;
+ }
+ const stroke = buttonsDisabled ? "mono100" : "primary";
+ return (
+
+ }
+ style={buttonStyle}
+ variant="outline"
+ >
+ {primaryButtonText}
+
+
+ );
+};
+
+const SecondaryButton = ({
+ assignment,
+ buttonsDisabled,
+}: AssignmentBoxButtonsProps) => {
+ const { assignmentSubmissionStatus, studyDetailId, deadline, committedAt } =
+ assignment;
+ const { secondaryButtonText } = buttonProps[assignmentSubmissionStatus];
+ const handleClickSubmissionComplete = async () => {
+ const response = await studyHistoryApi.submitAssignment(studyDetailId);
+ if (response.success) {
+ //TODO: 과제 제출 이후에는 과제 상태에 대한 업데이트 필요
+ //이번주 과제 조회 api, 대시보드 api revaliate
+ revalidateTagByName(tags.studyDetailDashboard);
+ }
+ };
+
+ if (isDeadlinePassed(deadline)) {
+ return (
+
+ );
+ }
+ const stroke = buttonsDisabled ? "mono100" : "backgroundNormal";
+ return (
+ }
+ style={buttonStyle}
+ {...(assignmentSubmissionStatus === "SUCCESS" &&
+ committedAt && {
+ subText: `최종 수정일자 ${committedAt}`,
+ })}
+ onClick={handleClickSubmissionComplete}
+ >
+ {secondaryButtonText}
+
+ );
+};
+
+const buttonStyle = {
+ maxWidth: "100%",
+};
+
+const buttonProps: Record<
+ AssignmentSubmissionStatusType,
+ { primaryButtonText: string; secondaryButtonText: string }
+> = {
+ PENDING: {
+ primaryButtonText: "제출하러 가기",
+ secondaryButtonText: "제출 완료하기",
+ },
+ SUCCESS: {
+ primaryButtonText: "제출한 과제 보러가기",
+ secondaryButtonText: "제출 갱신하기",
+ },
+ FAILURE: {
+ primaryButtonText: "제출한 과제 보러가기",
+ secondaryButtonText: "제출 완료하기",
+ },
+};
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmetBoxInfo.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx
similarity index 82%
rename from apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmetBoxInfo.tsx
rename to apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx
index b5ab9c3b..051499cd 100644
--- a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmetBoxInfo.tsx
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxInfo.tsx
@@ -4,13 +4,11 @@ import { padWithZero, parseISODate } from "@wow-class/utils";
import Image from "next/image";
import type { Assignment } from "types/dtos/studyDetail";
-interface AssignmentSubmissionInfoProps {
+interface AssignmentBoxInfoProps {
assignment: Assignment;
}
-export const AssignmentSubmissionInfo = ({
- assignment,
-}: AssignmentSubmissionInfoProps) => {
+export const AssignmentBoxInfo = ({ assignment }: AssignmentBoxInfoProps) => {
const { deadline, title, assignmentSubmissionStatus, submissionFailureType } =
assignment;
@@ -20,14 +18,14 @@ export const AssignmentSubmissionInfo = ({
hours
)}:${padWithZero(minutes)}까지`;
+ const isSuccess = assignmentSubmissionStatus === "SUCCESS";
const isFailure = assignmentSubmissionStatus === "FAILURE";
- const isPending = assignmentSubmissionStatus === "PENDING";
- const isNotSubmitted = submissionFailureType === "NOT_SUBMITTED";
+ const isNotSubmitted = isFailure && submissionFailureType === "NOT_SUBMITTED";
return (
<>
{deadlineText}
- {!(isPending || isNotSubmitted) && (
+ {(isSuccess || (isFailure && !isNotSubmitted)) && (
제출한 과제
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx
rename to apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/AssignmentBoxTitle.tsx
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
similarity index 82%
rename from apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
rename to apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
index 296c33d5..29f916ad 100644
--- a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/AssignmentOverviewBox/index.tsx
@@ -4,9 +4,9 @@ import type { Assignment } from "types/dtos/studyDetail";
import Box from "wowds-ui/Box";
import TextButton from "wowds-ui/TextButton";
-import { AssignmentButtons } from "./AssignmenBoxButtons";
+import { AssignmentBoxButtons } from "./AssignmentBoxButtons";
+import { AssignmentBoxInfo } from "./AssignmentBoxInfo";
import { AssignmentBoxTitle } from "./AssignmentBoxTitle";
-import { AssignmentSubmissionInfo } from "./AssignmetBoxInfo";
interface AssignmentOverviewBoxProps {
assignments: Assignment[];
@@ -27,13 +27,12 @@ export const AssignmentOverviewBox = ({
text={
<>
-
-
+
-
@@ -52,4 +51,5 @@ const textButtonstyle = {
const boxStyle = {
minWidth: "484px",
+ height: "fit-content",
};
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx
new file mode 100644
index 00000000..08a61c66
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/EmptyAssignmentBox.tsx
@@ -0,0 +1,25 @@
+import { Space, Text } from "@wow-class/ui";
+import Box from "wowds-ui/Box";
+
+export const EmptyAssignmentBox = ({ week }: { week: number }) => {
+ return (
+
+
+ {week}주차
+
+
+
+ 과제가 없어요
+
+ >
+ }
+ />
+ );
+};
+
+const boxStyle = {
+ paddingBottom: "50px",
+};
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
new file mode 100644
index 00000000..d59197c5
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/RepositorySubmissionBox.tsx
@@ -0,0 +1,185 @@
+"use client";
+
+import { css } from "@styled-system/css";
+import { Flex } from "@styled-system/jsx";
+import { Space, Text } from "@wow-class/ui";
+import { routePath } from "constants/routePath";
+import { useRouter } from "next/navigation";
+import { useCallback, useState } from "react";
+import type { RepositorySubmissionStatusType } from "types/entities/myAssignment";
+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";
+
+interface RepositorySubmissionBoxProps {
+ repositoryLink: string;
+}
+
+export const RepositorySubmissionBox = ({
+ repositoryLink: initialRepositoryUrl,
+}: RepositorySubmissionBoxProps) => {
+ const [repositoryUrl, setRepositoryUrl] = useState(initialRepositoryUrl);
+ const [repositorySubmissionStatus, setRepositorySubmissionStatus] =
+ useState(
+ initialRepositoryUrl ? "SUBMITTED" : "EDITING_WITH_WARNING"
+ );
+ const [error, setError] = useState(false);
+
+ const router = useRouter();
+
+ const handleClickEditButton = useCallback(() => {
+ setError(false);
+ setRepositorySubmissionStatus("EDITING");
+ }, []);
+
+ const handleClickDeleteButton = useCallback(() => {
+ setRepositoryUrl("");
+ setError(false);
+ setRepositorySubmissionStatus("EDITING_WITH_WARNING");
+ }, []);
+
+ const handleChange = useCallback(
+ (value: string) => {
+ setRepositoryUrl(value);
+ },
+ [setRepositoryUrl]
+ );
+
+ const handleClickSubmitButton = useCallback(async () => {
+ if (!repositoryUrl) {
+ setError(true);
+ } else {
+ router.push(
+ `${routePath["my-assignment-repository-url-confirmation"]}?repositoryUrl=${repositoryUrl}`
+ );
+ }
+ }, [router, repositoryUrl]);
+
+ return (
+
+
+ 레포지토리
+
+
+
+
+ 과제 제출을 위한 레포지토리 URL 입력하기
+
+ {repositorySubmissionStatus !== "EDITING_WITH_WARNING" && (
+
+ 제출 완료
+
+ )}
+
+
+ <>
+ {repositorySubmissionStatus === "SUBMITTED" && (
+ <>
+
+ 최초 과제 제출 전 까지만 수정이 가능해요.
+
+
+
+ {repositoryUrl}
+
+
+
+
+
+ >
+ )}
+ {repositorySubmissionStatus === "EDITING_WITH_WARNING" && (
+ <>
+
+
+
+ 입력하지 않으면 앞으로의 과제를 제출할 수 없어요.
+
+
+
+
+
+
+ >
+ )}
+ {repositorySubmissionStatus === "EDITING" && (
+ <>
+
+
+
+
+ >
+ )}
+ >
+
+ }
+ />
+ );
+};
+
+const errorMessage = 빈 URL은 입력할 수 없습니다.;
+
+const urlBoxStyle = css({
+ backgroundColor: "backgroundAlternative",
+ borderRadius: "5px",
+ color: "sub",
+ justifyContent: "space-between",
+ paddingX: "24px",
+ paddingY: "18px",
+ textStyle: "h2",
+});
+
+const boxStyle = {
+ minWidth: "484px",
+};
+
+const iconStyle = {
+ cursor: "pointer",
+};
+
+const buttonStyle = {
+ maxWidth: "100%",
+};
+
+const textFieldStyle = {
+ gap: "0px",
+ height: "58px !important",
+};
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/index.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx
similarity index 56%
rename from apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/index.tsx
rename to apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx
index 076e3d6c..34c8ed71 100644
--- a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentContent/index.tsx
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentContent/index.tsx
@@ -6,29 +6,36 @@ import {
} from "constants/assignmentMockData";
import { AssignmentOverviewBox } from "./AssignmentOverviewBox";
+import { EmptyAssignmentBox } from "./EmptyAssignmentBox";
import { RepositorySubmissionBox } from "./RepositorySubmissionBox";
export const AssignmentContent = () => {
- // const studyDashboard = await studyDetailApi.getStudyDetailDashboard(1);
+ //TODO:수강 중인 스터디 api 호출
+ //const studyId = await myStudyApi.getMyOngoingStudyInfo();
+ //const studyDashboard = await studyDetailApi.getStudyDetailDashboard(studyId);
//TODO: studyDashboard.isLinkEditable 가 false 면 이번 주 과제 조회 api 사용
const studyDashboard = studyDashBoardData;
+ const currentAssignments = assignmentData;
return (
<>
- {studyDashBoardData.isLinkEditable && (
+ {studyDashboard.isLinkEditable && (
<>
>
)}
- {!studyDashBoardData.isLinkEditable && (
-
- )}
+ {!studyDashboard.isLinkEditable &&
+ (currentAssignments ? (
+
+ ) : (
+
+ ))}
>
);
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx
rename to apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/AssignmentHistoryItem.tsx
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentHistory/index.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/index.tsx
similarity index 87%
rename from apps/client/app/(afterLogin)/my-assignment/_components/AssignmentHistory/index.tsx
rename to apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/index.tsx
index 1393bb40..4fc5e560 100644
--- a/apps/client/app/(afterLogin)/my-assignment/_components/AssignmentHistory/index.tsx
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/AssignmentHistory/index.tsx
@@ -1,14 +1,16 @@
import { Flex } from "@styled-system/jsx";
import { Space, Text } from "@wow-class/ui";
+import { studyHistoryApi } from "apis/studyHistoryApi";
import { history } from "constants/assignmentMockData";
import Image from "next/image";
import { AssignmentHistoryItem } from "./AssignmentHistoryItem";
export const AssignmentHistory = async () => {
- // const studyHistory = await studyHistoryApi.getStudyHistory(1);
+ //TODO: 수강 중인 스터디 api 호출
+ //const studyId = await myStudyApi.getMyOngoingStudyInfo();
+ // const studyHistory = await studyHistoryApi.getStudyHistory(studyId);
const studyHistories = history;
-
if (studyHistories.length === 0) {
return (
<>
diff --git a/apps/client/app/(afterLogin)/my-assignment/_components/index.ts b/apps/client/app/(afterLogin)/my-study/my-assignment/_components/index.ts
similarity index 100%
rename from apps/client/app/(afterLogin)/my-assignment/_components/index.ts
rename to apps/client/app/(afterLogin)/my-study/my-assignment/_components/index.ts
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/default.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/default.tsx
new file mode 100644
index 00000000..395785b9
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/default.tsx
@@ -0,0 +1,5 @@
+const Default = () => {
+ return null;
+};
+
+export default Default;
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/layout.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/layout.tsx
new file mode 100644
index 00000000..df47c7d9
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/layout.tsx
@@ -0,0 +1,18 @@
+const Layout = ({
+ children,
+ modal,
+}: {
+ children: React.ReactNode;
+ modal: React.ReactNode;
+}) => {
+ return (
+ <>
+
+ {children}
+ {modal}
+
+ >
+ );
+};
+
+export default Layout;
diff --git a/apps/client/app/(afterLogin)/my-assignment/page.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/page.tsx
similarity index 100%
rename from apps/client/app/(afterLogin)/my-assignment/page.tsx
rename to apps/client/app/(afterLogin)/my-study/my-assignment/page.tsx
diff --git a/apps/client/app/(afterLogin)/my-study/my-assignment/repository-url/confirmation/page.tsx b/apps/client/app/(afterLogin)/my-study/my-assignment/repository-url/confirmation/page.tsx
new file mode 100644
index 00000000..8a3c9090
--- /dev/null
+++ b/apps/client/app/(afterLogin)/my-study/my-assignment/repository-url/confirmation/page.tsx
@@ -0,0 +1,8 @@
+import { routePath } from "constants/routePath";
+import { redirect } from "next/navigation";
+
+const RepositoryUrlConfirmationPage = () => {
+ return redirect(routePath["my-assignment"]);
+};
+
+export default RepositoryUrlConfirmationPage;
diff --git a/apps/client/constants/assignmentMockData.ts b/apps/client/constants/assignmentMockData.ts
index b895c887..e867f1b6 100644
--- a/apps/client/constants/assignmentMockData.ts
+++ b/apps/client/constants/assignmentMockData.ts
@@ -27,7 +27,7 @@ export const history: AssignmentHistoryDto[] = [
export const studyDashBoardData: StudyDetailDashboardDto = {
repositoryLink: "",
- isLinkEditable: false,
+ isLinkEditable: true,
submittableAssignments: [
{
studyDetailId: 1,
diff --git a/apps/client/constants/routePath.ts b/apps/client/constants/routePath.ts
index aba26b8e..c4217f62 100644
--- a/apps/client/constants/routePath.ts
+++ b/apps/client/constants/routePath.ts
@@ -2,12 +2,14 @@ export const routePath = {
auth: "/auth",
landing: "/landing",
["my-study"]: "/my-study",
- ["my-assignment"]: "/my-assignment",
+ ["attendance-check"]: "/my-study/attendance-check",
+ ["my-assignment"]: "/my-study/my-assignment",
+ ["my-assignment-repository-url-confirmation"]:
+ "/my-study/my-assignment/repository-url/confirmation",
["study-apply"]: "/study-apply",
["study-application-modal"]: "/study-apply/study-application",
["study-cancellation-modal"]: "/study-apply/study-cancellation",
["auth-error-during-recruitment"]: "/auth-error-during-recruitment",
["auth-error-after-recruitment"]: "/auth-error-after-recruitment",
- ["attendance-check"]: "/my-study/attendance-check",
onboarding: "https://onboarding.gdschongik.com",
} as const;
diff --git a/apps/client/hooks/useMatchedStudyHistoryId.ts b/apps/client/hooks/useMatchedStudyHistoryId.ts
new file mode 100644
index 00000000..afff0ea9
--- /dev/null
+++ b/apps/client/hooks/useMatchedStudyHistoryId.ts
@@ -0,0 +1,33 @@
+"use client";
+
+import { studyDetailApi } from "apis/studyDetailApi";
+import { studyHistoryApi } from "apis/studyHistoryApi";
+import { history, studyDashBoardData } from "constants/assignmentMockData";
+import { useEffect, useState } from "react";
+
+export default function useMatchedStudyHistoryId() {
+ const [matchedStudyHistoryId, setMatchedStudyHistoryId] = useState();
+ useEffect(() => {
+ const fetchData = async () => {
+ //TODO: 수강 중인 스터디 api 호출
+ //const studyId = await myStudyApi.getMyOngoingStudyInfo();
+ //const studyHistories = await studyHistoryApi.getStudyHistory(studyId);
+ const studyHistories = history;
+ // const studyDashboard =
+ // await studyDetailApi.getStudyDetailDashboard(studyId);
+ const studyDashboard = studyDashBoardData;
+ if (studyHistories && studyDashboard) {
+ const submittableWeek = studyDashboard.submittableAssignments[0]?.week;
+ const matchedHistory = studyHistories.find(
+ (item) => item.week === submittableWeek
+ );
+
+ setMatchedStudyHistoryId(matchedHistory?.assignmentHistoryId);
+ }
+ };
+
+ fetchData();
+ }, []);
+
+ return { matchedStudyHistoryId };
+}
diff --git a/apps/client/middleware.ts b/apps/client/middleware.ts
index bea40fba..8f0f5baf 100644
--- a/apps/client/middleware.ts
+++ b/apps/client/middleware.ts
@@ -6,12 +6,7 @@ import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
export const config = {
- matcher: [
- "/my-page/:path*",
- "/my-study/:path*",
- "/study-apply/:path*",
- "/my-assignment/:path*",
- ],
+ matcher: ["/my-page/:path*", "/my-study/:path*", "/study-apply/:path*"],
};
const middleware = async (req: NextRequest) => {
diff --git a/apps/client/types/dtos/studyHistory.ts b/apps/client/types/dtos/studyHistory.ts
index 74f28e46..cfe91e03 100644
--- a/apps/client/types/dtos/studyHistory.ts
+++ b/apps/client/types/dtos/studyHistory.ts
@@ -1,4 +1,7 @@
-import type { AssignmentSubmissionStatusType } from "types/entities/common/assignment";
+import type {
+ AssignmentSubmissionStatusType,
+ SubmissionFailureType,
+} from "types/entities/common/assignment";
export interface AssignmentHistoryDto {
assignmentHistoryId: number;
@@ -7,5 +10,6 @@ export interface AssignmentHistoryDto {
descriptionLink?: string;
submissionLink?: string;
assignmentSubmissionStatus: AssignmentSubmissionStatusType; //TODO: 과제 휴강 여부 추가
+ submissionFailureType?: SubmissionFailureType;
week: number;
}
diff --git a/apps/client/types/entities/myAssignment.ts b/apps/client/types/entities/myAssignment.ts
index 31b42b3c..b52c6f4a 100644
--- a/apps/client/types/entities/myAssignment.ts
+++ b/apps/client/types/entities/myAssignment.ts
@@ -1 +1,4 @@
-export type RepositorySubmissionStatusType = "EDITING" | "SUBMITTED";
+export type RepositorySubmissionStatusType =
+ | "EDITING"
+ | "SUBMITTED"
+ | "EDITING_WITH_WARNING";
diff --git a/packages/ui/src/styles.css b/packages/ui/src/styles.css
index 18f3f9ee..9bbe6b47 100644
--- a/packages/ui/src/styles.css
+++ b/packages/ui/src/styles.css
@@ -803,6 +803,9 @@ progress {
.jc_center:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
justify-content: center;
}
+.flex-d_column:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
+ flex-direction: column;
+}
.top_0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
top: 0;
}