Skip to content

Commit

Permalink
[Feat] 수강 신청,마이 페이지 관련 QA 반영 (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
SeieunYoo authored Aug 31, 2024
1 parent 104548d commit e00284e
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 33 deletions.
5 changes: 3 additions & 2 deletions apps/client/apis/studyApplyApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { fetcher } from "@wow-class/utils";
import { apiPath } from "constants/apiPath";
import { revalidateTime } from "constants/revalidateTime";
import { tags } from "constants/tags";
import type { StudyListApiResponseDto } from "types/dtos/applyStudy";

Expand All @@ -8,8 +9,8 @@ export const studyApplyApi = {
const response = await fetcher.get<StudyListApiResponseDto>(
apiPath.applyStudy,
{
next: { tags: [tags.studyApply] },
cache: "no-store",
next: { tags: [tags.studyApply], revalidate: revalidateTime },
cache: "force-cache",
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@
import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { Modal, Space, Text } from "@wow-class/ui";
import { useModalRoute } from "@wow-class/ui/hooks";
import { studyApplyApi } from "apis/studyApplyApi";
import { tags } from "constants/tags";
import { useEffect, useState } from "react";
import { revalidateTagByName } from "utils/revalidateTagByName";
import Button from "wowds-ui/Button";

const MODAL_CLOSE_TIME = 1000;
const StudyApplication = ({ params }: { params: { studyId: number } }) => {
const studyId = params.studyId;

const [applySuccess, setApplySuccess] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [studyTitle, setStudyTitle] = useState("");

const { onClose } = useModalRoute();
useEffect(() => {
const fetchStudyData = async () => {
const data = await studyApplyApi.getStudyList();
Expand All @@ -27,11 +31,21 @@ const StudyApplication = ({ params }: { params: { studyId: number } }) => {
if (selectedStudy) {
setStudyTitle(selectedStudy.title);
}
setIsLoading(false);
};

fetchStudyData();
}, [studyId]);

useEffect(() => {
if (applySuccess) {
const timer = setTimeout(() => {
onClose();
}, MODAL_CLOSE_TIME);
return () => clearTimeout(timer);
}
}, [applySuccess, onClose]);

const handleClickApplyButton = async () => {
const result = await studyApplyApi.applyStudy(Number(studyId));
if (result.success) {
Expand All @@ -41,6 +55,10 @@ const StudyApplication = ({ params }: { params: { studyId: number } }) => {
}
};

if (isLoading) {
return null;
}

return (
<Modal>
<Flex direction="column" textAlign="center" width="21rem">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@
import { css } from "@styled-system/css";
import { Flex } from "@styled-system/jsx";
import { Modal, Space, Text } from "@wow-class/ui";
import { useModalRoute } from "@wow-class/ui/hooks";
import { studyApplyApi } from "apis/studyApplyApi";
import { tags } from "constants/tags";
import { useEffect, useState } from "react";
import { revalidateTagByName } from "utils/revalidateTagByName";
import Button from "wowds-ui/Button";

const MODAL_CLOSE_TIME = 1000;

const StudyCancel = ({ params }: { params: { studyId: number } }) => {
const studyId = params.studyId;
const [cancelSucces, setCancelSuccess] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [studyTitle, setStudyTitle] = useState("");
const { onClose } = useModalRoute();

useEffect(() => {
const fetchStudyData = async () => {
Expand All @@ -26,11 +31,21 @@ const StudyCancel = ({ params }: { params: { studyId: number } }) => {
if (selectedStudy) {
setStudyTitle(selectedStudy.title);
}
setIsLoading(false);
};

fetchStudyData();
}, [studyId]);

useEffect(() => {
if (cancelSucces) {
const timer = setTimeout(() => {
onClose();
}, MODAL_CLOSE_TIME);
return () => clearTimeout(timer);
}
}, [cancelSucces, onClose]);

const handleClickCancelButton = async () => {
const result = await studyApplyApi.cancelStudyApplication(Number(studyId));

Expand All @@ -41,6 +56,10 @@ const StudyCancel = ({ params }: { params: { studyId: number } }) => {
}
};

if (isLoading) {
return null;
}

return (
<Modal>
<Flex direction="column" textAlign="center" width="21rem">
Expand Down
145 changes: 116 additions & 29 deletions apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { css } from "@styled-system/css";
import { css, cva } from "@styled-system/css";
import { Flex, styled } from "@styled-system/jsx";
import { Table, Text } from "@wow-class/ui";
import { padWithZero, parseISODate } from "@wow-class/utils";
Expand Down Expand Up @@ -49,55 +49,66 @@ const StudyItem = ({ study, appliedStudyId }: StudyItemProps) => {
const isCancelable = appliedStudyId === studyId;
const isNotApplicable = !isApplicable && !isCancelable;
return (
<Table>
<Table className={tableStyle}>
<Flex direction="column" gap="xxs" justifyContent="center" width={334}>
<Flex className={contentStyle} gap="xs">
<Text typo="h3">{title}</Text>
<Tag color={sessionColors[studyType] ?? "green"} variant="solid1">
{studyType}
<Text className={titleStyle} typo="h3">
{title}
</Text>
<Tag
color={curriculumColors[studyType] ?? "green"}
style={tagButtonStyle}
variant="solid1"
>
{tagTexts[studyType]}
</Tag>
</Flex>
<Link href={notionLink ?? ""} target="_blank">
<Text className={introductionLinkTextStyle} color="sub" typo="body2">
{`(${introduction})`}
</Text>
</Link>
{introduction && (
<Link href={notionLink ?? ""} target="_blank">
<Text
className={introductionLinkTextStyle}
color="sub"
typo="body2"
>
{introduction}
</Text>
</Link>
)}
</Flex>
<Text className={textCellStyle}>{mentorName}</Text>
<Text
className={textCellStyle}
style={{ width: "11rem", textAlign: "center" }}
>
{studyTime}
<Text className={textCellStyle({ type: "mentor" })}>
{mentorName} 멘토
</Text>
<Text className={timeCellStyle}>{studyTime}</Text>
<Text className={textCellStyle({ type: "week" })}>
{totalWeek}주 코스
</Text>
<Text className={textCellStyle}>{totalWeek}주 코스</Text>
<Flex direction="column" textAlign="center">
<Text className={textCellStyle}>
{`${openingDate.month}.${openingDate.day} 개강`}
</Text>
<Text
className={dateStyle}
>{`${openingDate.month}.${openingDate.day} 개강`}</Text>
{isCancelable && (
<Text color="error" typo="body3">
<Text className={dateStyle} color="error" typo="body3">
{`${endDate.month}.${endDate.day} 까지 취소 가능`}
</Text>
)}
</Flex>
<styled.div paddingX="24px">
{isApplicable && (
<Link href={`${routePath["study-application-modal"]}/${studyId}`}>
<Button size="sm" variant="solid">
<Button size="sm" style={tagButtonStyle} variant="solid">
수강 신청
</Button>
</Link>
)}
{isCancelable && (
<Link href={`${routePath["study-cancellation-modal"]}/${studyId}`}>
<Button size="sm" variant="solid">
<Button size="sm" style={tagButtonStyle} variant="solid">
신청 취소
</Button>
</Link>
)}
{isNotApplicable && (
<Button disabled size="sm" variant="solid">
<Button disabled size="sm" style={tagButtonStyle} variant="solid">
신청 불가
</Button>
)}
Expand All @@ -106,24 +117,100 @@ const StudyItem = ({ study, appliedStudyId }: StudyItemProps) => {
);
};

const textCellStyle = css({
const tableStyle = css({
justifyContent: "unset",
});

const titleStyle = css({
textOverflow: "ellipsis",
overflow: "hidden",
maxWidth: "210px",
whiteSpace: "nowrap",
});

const dateStyle = css({
width: "118px",
"@media (max-width: 1439px)": {
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
width: "38px",
},
});

const timeCellStyle = css({
paddingX: "28px",
width: "178px",
textAlign: "center",
"@media (max-width: 1439px)": {
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
padding: "0",
},
"@media (max-width: 1199px)": {
display: "none",
},
});
const textCellStyle = cva({
base: {
"@media (max-width: 1439px)": {
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
padding: "0",
width: "38px",
},
},
variants: {
type: {
mentor: {
paddingX: "15px",
"@media (max-width: 1199px)": {
width: "fit-content",
paddingInline: "7.25px",
},
"@media (max-width: 959px)": {
display: "none",
},
},
week: {
paddingX: "28px",
"@media (max-width: 1199px)": {
display: "none",
},
},
},
},
});

const contentStyle = css({
minWidth: "313px",
width: "313px",
});

const introductionLinkTextStyle = css({
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
textDecoration: "underline",
});

const sessionColors: Record<StudyType, ComponentProps<typeof Tag>["color"]> = {
"과제 스터디": "green",
"온라인 커리큘럼": "blue",
"오프라인 커리큘럼": "yellow",
const tagButtonStyle = {
whiteSpace: "nowrap",
};

const tagTexts: Record<StudyType, string> = {
"과제 스터디": "과제 스터디",
"온라인 커리큘럼": "온라인 스터디",
"오프라인 커리큘럼": "오프라인 스터디",
};

const curriculumColors: Record<StudyType, ComponentProps<typeof Tag>["color"]> =
{
"과제 스터디": "green",
"온라인 커리큘럼": "blue",
"오프라인 커리큘럼": "yellow",
};

export default StudyItem;
1 change: 1 addition & 0 deletions apps/client/constants/revalidateTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const revalidateTime = 180;
4 changes: 2 additions & 2 deletions apps/client/types/dtos/applyStudy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export interface StudyList {
studyId: number;
title: string;
studyType: StudyType;
notionLink: string;
introduction: string;
notionLink?: string;
introduction?: string;
mentorName: string;
dayOfWeek: DayOfWeekType;
startTime: Time | null;
Expand Down

0 comments on commit e00284e

Please sign in to comment.