diff --git a/apps/client/apis/studyApplyApi.ts b/apps/client/apis/studyApplyApi.ts index 973de4df..280e2b9e 100644 --- a/apps/client/apis/studyApplyApi.ts +++ b/apps/client/apis/studyApplyApi.ts @@ -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"; @@ -8,8 +9,8 @@ export const studyApplyApi = { const response = await fetcher.get( apiPath.applyStudy, { - next: { tags: [tags.studyApply] }, - cache: "no-store", + next: { tags: [tags.studyApply], revalidate: revalidateTime }, + cache: "force-cache", } ); diff --git a/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-application/[studyId]/page.tsx b/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-application/[studyId]/page.tsx index 7a8a949c..42cb0100 100644 --- a/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-application/[studyId]/page.tsx +++ b/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-application/[studyId]/page.tsx @@ -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(); @@ -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) { @@ -41,6 +55,10 @@ const StudyApplication = ({ params }: { params: { studyId: number } }) => { } }; + if (isLoading) { + return null; + } + return ( diff --git a/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx b/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx index 9ce3087c..68ff33bb 100644 --- a/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx +++ b/apps/client/app/(afterLogin)/study-apply/@modal/(.)study-cancellation/[studyId]/page.tsx @@ -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 () => { @@ -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)); @@ -41,6 +56,10 @@ const StudyCancel = ({ params }: { params: { studyId: number } }) => { } }; + if (isLoading) { + return null; + } + return ( diff --git a/apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx b/apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx index dcd560a0..f62aef0f 100644 --- a/apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx +++ b/apps/client/app/(afterLogin)/study-apply/_components/StudyItem.tsx @@ -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"; @@ -49,34 +49,45 @@ const StudyItem = ({ study, appliedStudyId }: StudyItemProps) => { const isCancelable = appliedStudyId === studyId; const isNotApplicable = !isApplicable && !isCancelable; return ( - +
- {title} - - {studyType} + + {title} + + + {tagTexts[studyType]} - - - {`(${introduction})`} - - + {introduction && ( + + + {introduction} + + + )} - {mentorName} - - {studyTime} + + {mentorName} 멘토 + + {studyTime} + + {totalWeek}주 코스 - {totalWeek}주 코스 - - {`${openingDate.month}.${openingDate.day} 개강`} - + {`${openingDate.month}.${openingDate.day} 개강`} {isCancelable && ( - + {`${endDate.month}.${endDate.day} 까지 취소 가능`} )} @@ -84,20 +95,20 @@ const StudyItem = ({ study, appliedStudyId }: StudyItemProps) => { {isApplicable && ( - )} {isCancelable && ( - )} {isNotApplicable && ( - )} @@ -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["color"]> = { - "과제 스터디": "green", - "온라인 커리큘럼": "blue", - "오프라인 커리큘럼": "yellow", +const tagButtonStyle = { + whiteSpace: "nowrap", +}; + +const tagTexts: Record = { + "과제 스터디": "과제 스터디", + "온라인 커리큘럼": "온라인 스터디", + "오프라인 커리큘럼": "오프라인 스터디", }; +const curriculumColors: Record["color"]> = + { + "과제 스터디": "green", + "온라인 커리큘럼": "blue", + "오프라인 커리큘럼": "yellow", + }; + export default StudyItem; diff --git a/apps/client/constants/revalidateTime.ts b/apps/client/constants/revalidateTime.ts new file mode 100644 index 00000000..63665588 --- /dev/null +++ b/apps/client/constants/revalidateTime.ts @@ -0,0 +1 @@ +export const revalidateTime = 180; diff --git a/apps/client/types/dtos/applyStudy.ts b/apps/client/types/dtos/applyStudy.ts index cbf8f85e..ec01cda5 100644 --- a/apps/client/types/dtos/applyStudy.ts +++ b/apps/client/types/dtos/applyStudy.ts @@ -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;