Skip to content

Commit

Permalink
[Chore] 나의 스터디 페이지 QA 반영 (#128)
Browse files Browse the repository at this point in the history
* fix: 출석체크 에러 상태 반영 못하는 부분 수정

* fix: 출석 번호 trim 추가

* fix: 출석번호 textarea 줄바꿈 금지

* chore: 메타데이터 타이틀 수정

* design: 제출한 과제 확인 버튼 줄바꿈 안 되도록 수정

* chore: 오늘의 할 일 과제 박스 버튼 비활성화 상태 삭제

* chore: 오늘의 할 일 맨 마지막에 도달 시 캐러셀 버튼 안 보이도록 수정

* chore: 출석체크 모달에서 api fetch 대신 query parameter로 처리하도록 수정

* design: 출석번호 textfield placeholder ui 변경

* chore: 출석 성공한 경우 error 상태 리셋

* chore: 나의 과제 페이지로 이동 시에는 외부 탭으로 열리지 않도록 수정

* chore: 스터디 기본 정보 api 호출 시 cache 속성 no-store로 가져오게 수정
  • Loading branch information
ghdtjgus76 authored Sep 4, 2024
1 parent ae4405a commit bd12241
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 94 deletions.
6 changes: 3 additions & 3 deletions apps/client/apis/myStudyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const myStudyApi = {
`${apiPath.basicStudyInfo}/${studyId}`,
{
next: { tags: [tags.basicStudyInfo] },
cache: "force-cache",
cache: "no-store",
}
);

Expand All @@ -44,9 +44,9 @@ export const myStudyApi = {

return response.data;
},
checkAttendance: async (studyId: number, attendanceNumber: string) => {
checkAttendance: async (studyDetailId: number, attendanceNumber: string) => {
const response = await fetcher.post(
`${apiPath.studyDetails}/${studyId}/${apiPath.attend}`,
`${apiPath.studyDetails}/${studyDetailId}/${apiPath.attend}`,
{
attendanceNumber,
}
Expand Down
2 changes: 1 addition & 1 deletion apps/client/app/(afterLogin)/my-page/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Metadata } from "next";

export const metadata: Metadata = {
title: "마이페이지",
title: "마이 페이지",
};

const Layout = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { useModalRoute } from "@wow-class/ui/hooks";
import { parseISODate } from "@wow-class/utils";
import { myStudyApi } from "apis/myStudyApi";
import { tags } from "constants/tags";
import useFetchAttendanceCheckModalInfoData from "hooks/useFetchAttendanceCheckModalInfoData";
import useAttendanceCheckSearchParams from "hooks/useAttendanceCheckSearchParams";
import Image from "next/image";
import type { KeyboardEventHandler } from "react";
import { useState } from "react";
import { revalidateTagByName } from "utils/revalidateTagByName";
import { validateAttendanceNumber } from "utils/validateAttendanceNumber";
Expand All @@ -22,9 +23,8 @@ const AttendanceCheckModal = () => {

const { onClose } = useModalRoute();

const {
studyInfo: { currentWeek, studyDetailId, studyName, deadLine },
} = useFetchAttendanceCheckModalInfoData();
const { studyDetailId, studyName, deadLine, currentWeek } =
useAttendanceCheckSearchParams();

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

Expand All @@ -48,11 +48,17 @@ const AttendanceCheckModal = () => {
};

const handleClickAttendanceCheckButton = async () => {
if (!isAttendanceNumberValid(attendanceNumber)) {
const trimmedAttendanceNumber = attendanceNumber.trim();

if (!isAttendanceNumberValid(trimmedAttendanceNumber)) {
return setError(true);
}

const success = await checkAttendance(studyDetailId, attendanceNumber);
const success = await checkAttendance(
+studyDetailId,
trimmedAttendanceNumber
);

if (!success) {
return setError(true);
}
Expand All @@ -62,12 +68,19 @@ const AttendanceCheckModal = () => {

const handleAttendanceSuccess = () => {
setAttended(true);
setError(false);
revalidateTagByName(tags.dailyTask);
setTimeout(() => {
onClose();
}, 500);
};

const handleKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
}
};

return (
<Modal>
{attended ? (
Expand Down Expand Up @@ -136,9 +149,12 @@ const AttendanceCheckModal = () => {
error={error}
helperText={error ? textfieldHelperText : ""}
label="출결번호 입력"
placeholder="Ex. 0000"
placeholder="ex) 0000"
style={textfieldStyle}
value={attendanceNumber}
textareaProps={{
onKeyDown: handleKeyDown,
}}
onChange={handleChangeAttendanceNumber}
/>
<Button
Expand Down Expand Up @@ -172,6 +188,7 @@ const attendanceCheckDescriptionStyle = css({
const textfieldStyle = {
height: "89px",
marginBottom: "20px",
whiteSpace: "nowrap",
};

const attendanceCompleteTitleStyle = css({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ const AssignmentStatusBox = ({
</Flex>
<Button
asProp={Link}
disabled={assignmentSubmissionStatus !== "NOT_SUBMITTED"}
href={routePath["my-assignment"]}
size="lg"
style={assignmentButtonStyle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { Text } from "@wow-class/ui";
import { padWithZero, parseISODate } from "@wow-class/utils";
import { myStudyApi } from "apis/myStudyApi";
import { attendanceStatusMap } from "constants/attendanceStatusMap";
import { routePath } from "constants/routePath";
import Link from "next/link";
Expand All @@ -12,15 +13,28 @@ import Tag from "wowds-ui/Tag";

interface AttendanceStatusBoxProps {
week: number;
studyDetailId: number;
attendanceStatus: AttendanceStatusType;
deadLine: string;
}

const AttendanceStatusBox = ({
const AttendanceStatusBox = async ({
week,
attendanceStatus,
studyDetailId,
deadLine,
}: AttendanceStatusBoxProps) => {
const myOngoingStudyInfoResponse = await myStudyApi.getMyOngoingStudyInfo();

if (!myOngoingStudyInfoResponse?.studyId) {
return null;
}

const basicStudyInfoResponse = await myStudyApi.getBasicStudyInfo(
myOngoingStudyInfoResponse?.studyId
);
const studyName = basicStudyInfoResponse?.title;

const {
year: startYear,
month: startMonth,
Expand Down Expand Up @@ -63,7 +77,7 @@ const AttendanceStatusBox = ({
<Button
asProp={Link}
disabled={attendanceStatus === "ATTENDED"}
href={`${routePath["attendance-check"]}`}
href={`${routePath["attendance-check"]}?study-detail-id=${studyDetailId}&week=${week}&study-name=${studyName}&deadline=${deadLine}`}
size="lg"
style={attendanceButtonStyle}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,16 @@
import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import useHorizontalScroll from "hooks/useHorizontalScroll";
import useScrollCarouselButtonVisibility from "hooks/useScrollCarouselButtonVisibility";
import Image from "next/image";
import { type PropsWithChildren, useEffect, useState } from "react";
import { type PropsWithChildren } from "react";

const DailyTaskCarousel = ({ children }: PropsWithChildren) => {
const [showRightButton, setShowRightButton] = useState(false);

const itemWidth = 386;

const { containerRef, handleScroll } = useHorizontalScroll();

useEffect(() => {
if (containerRef.current) {
const containerWidth = containerRef.current.offsetWidth;
const totalChildrenWidth = Array.from(containerRef.current.children)
.map((child) => (child as HTMLElement).offsetWidth)
.reduce((acc, width) => acc + width, 0);

if (totalChildrenWidth > containerWidth) {
setShowRightButton(true);
}
}
}, [containerRef]);
const showRightButton = useScrollCarouselButtonVisibility(containerRef);

const handleClickScrollRightButton = () => {
if (containerRef.current) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ const DailyTaskItem = ({
attendanceStatus,
assignmentTitle,
assignmentSubmissionStatus,
studyDetailId,
} = dailyTask;

return todoType === "ATTENDANCE" ? (
<AttendanceStatusBox
attendanceStatus={attendanceStatus || "NOT_ATTENDED"}
deadLine={deadLine}
key={index}
studyDetailId={studyDetailId}
week={week}
/>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,19 @@ const StudyCurriculum = async () => {
curriculumStatus === "CANCELLED" ? "ATTENDED" : attendanceStatus
];

const assignmentButtonText =
assignmentSubmissionStatus === "SUCCESS"
? "제출한 과제 확인"
: "과제 제출하기";
const isAssignmentSubmissionSuccess =
assignmentSubmissionStatus === "SUCCESS";
const assignmentButtonText = isAssignmentSubmissionSuccess
? "제출한 과제 확인"
: "과제 제출하기";
const assignmentButtonHref =
submissionLink ?? routePath["my-assignment"] ?? "";
const assignmentButtonTargetProp = isAssignmentSubmissionSuccess
? "_blank"
: "_self";
const assignmentButtonVariant = isAssignmentSubmissionSuccess
? "outline"
: "solid";

const isCurrentWeek = getIsCurrentWeek(startDate, endDate);

Expand Down Expand Up @@ -143,12 +150,8 @@ const StudyCurriculum = async () => {
href={assignmentButtonHref}
size="sm"
style={assignmentButtonStyle}
target="_blank"
variant={
assignmentSubmissionStatus === "SUCCESS"
? "outline"
: "solid"
}
target={assignmentButtonTargetProp}
variant={assignmentButtonVariant}
>
{assignmentButtonText}
</Button>
Expand Down Expand Up @@ -198,6 +201,7 @@ const rightColStyle = css({
const assignmentButtonStyle = {
minWidth: "131px",
margin: "21px 25px",
whiteSpace: "nowrap",
};

const weekContainerStyle = css({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Metadata } from "next";

export const metadata: Metadata = {
title: "나의 과제 | GDSC Hongik 스터디 서비스, 와우클래스",
title: "나의 과제 | 와우클래스",
};

const Layout = ({ children }: { children: React.ReactNode }) => {
Expand Down
10 changes: 5 additions & 5 deletions apps/client/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ import { JotaiProvider } from "../components/JotaiProvider";

export const metadata: Metadata = {
title: {
default: "와우 클래스 | GDSC Hongik 스터디 서비스",
template: "%s | 와우 클래스",
default: "와우클래스 | GDSC Hongik 스터디 서비스",
template: "%s | 와우클래스",
},
description:
"와우클래스는 GDSC Hongik이 제공하는 스터디 관리 플랫폼입니다. 이 서비스는 정규 스터디 과제 제출, 출석 체크 등 전반적인 스터디 활동을 효율적으로 관리할 수 있는 기능을 제공합니다.",
openGraph: {
title: "와우 클래스 | GDSC Hongik 스터디 서비스",
title: "와우클래스 | GDSC Hongik 스터디 서비스",
description:
"와우클래스는 GDSC Hongik이 제공하는 스터디 관리 플랫폼입니다. 이 서비스는 정규 스터디 과제 제출, 출석 체크 등 전반적인 스터디 활동을 효율적으로 관리할 수 있는 기능을 제공합니다.",
images: ["/images/og-image.png"],
siteName: "와우 클래스 | GDSC Hongik 스터디 서비스",
siteName: "와우클래스 | GDSC Hongik 스터디 서비스",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "와우 클래스 | GDSC Hongik 스터디 서비스",
title: "와우클래스 | GDSC Hongik 스터디 서비스",
description:
"와우클래스는 GDSC Hongik이 제공하는 스터디 관리 플랫폼입니다. 이 서비스는 정규 스터디 과제 제출, 출석 체크 등 전반적인 스터디 활동을 효율적으로 관리할 수 있는 기능을 제공합니다.",
images: ["/images/og-image.png"],
Expand Down
14 changes: 14 additions & 0 deletions apps/client/hooks/useAttendanceCheckSearchParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useSearchParams } from "next/navigation";

const useAttendanceCheckSearchParams = () => {
const searchParams = useSearchParams();

const studyDetailId = searchParams.get("study-detail-id") || "0";
const studyName = searchParams.get("study-name");
const deadLine = searchParams.get("deadline") || "";
const currentWeek = searchParams.get("week");

return { studyDetailId, studyName, deadLine, currentWeek };
};

export default useAttendanceCheckSearchParams;
49 changes: 0 additions & 49 deletions apps/client/hooks/useFetchAttendanceCheckModalInfoData.ts

This file was deleted.

Loading

0 comments on commit bd12241

Please sign in to comment.