diff --git a/src/apis/recruit.js b/src/apis/recruit.js index fc72434..aa2e5e1 100644 --- a/src/apis/recruit.js +++ b/src/apis/recruit.js @@ -7,6 +7,12 @@ import instance from './instance'; */ export const submitRecruit = (data) => instance.post('/api/v1/visitor/applicantMembers', data); +/** + * 신입 부원 모집 공고 조회 + * @returns {Promise} + */ +export const getMainRecruitment = () => instance.get('/api/v1/visitor/main/recruitment'); + /** * (관리자) 지원자 목록 조회 * @returns {Promise} diff --git a/src/components/recruit/RecruitCompleteCard.jsx b/src/components/recruit/RecruitCompleteCard.jsx index c81b91a..c0f7d4b 100644 --- a/src/components/recruit/RecruitCompleteCard.jsx +++ b/src/components/recruit/RecruitCompleteCard.jsx @@ -1,8 +1,81 @@ +import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; +import { getMainRecruitment } from '@/apis/recruit'; import { ROUTES } from '@/constants/routes'; -function RecruitCompleteCard() { +const COMPLETE_MESSAGE = '회장의 연락을 통해 면접 일정이 조정될 예정이오니, 잠시 기다려 주세요.'; + +const EMPTY_RECRUITMENT_NOTICE = '모집 공고 정보를 불러오지 못했습니다.'; + +const formatKoreanDate = (dateText, shouldIncludeYear = true) => { + if (typeof dateText !== 'string') return ''; + + const [year, month, day] = dateText.split('-'); + if (!year || !month || !day) return dateText; + + const formattedMonth = Number(month); + const formattedDay = Number(day); + if (Number.isNaN(formattedMonth) || Number.isNaN(formattedDay)) return dateText; + + const monthDayText = `${formattedMonth}월 ${formattedDay}일`; + + return shouldIncludeYear ? `${year}년 ${monthDayText}` : monthDayText; +}; + +const createDateRangeText = (startDate, endDate) => { + if (typeof startDate !== 'string' && typeof endDate !== 'string') return ''; + if (typeof startDate !== 'string') return formatKoreanDate(endDate); + if (typeof endDate !== 'string' || startDate === endDate) return formatKoreanDate(startDate); + + const startYear = startDate.split('-')[0]; + const endYear = endDate.split('-')[0]; + const shouldShowEndYear = startYear !== endYear; + + return `${formatKoreanDate(startDate)} ~ ${formatKoreanDate(endDate, shouldShowEndYear)}`; +}; + +const RecruitCompleteCard = () => { + const [recruitment, setRecruitment] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [hasRecruitmentError, setHasRecruitmentError] = useState(false); + + useEffect(() => { + let isMounted = true; + + const fetchMainRecruitment = async () => { + try { + const response = await getMainRecruitment(); + if (!isMounted) return; + + setRecruitment(response.data?.data ?? null); + setHasRecruitmentError(false); + } catch (error) { + if (!isMounted) return; + + console.error('[RecruitCompleteCard] 모집 공고 조회 실패', error); + setHasRecruitmentError(true); + } finally { + if (isMounted) { + setIsLoading(false); + } + } + }; + + fetchMainRecruitment(); + + return () => { + isMounted = false; + }; + }, []); + + const interviewPeriod = createDateRangeText( + recruitment?.interviewStart, + recruitment?.interviewEnd + ); + const notificationDate = formatKoreanDate(recruitment?.notificationDate); + const contactText = [recruitment?.bossName, recruitment?.contactNumber].filter(Boolean).join(' '); + return (
- 면접 기간: - 2026년 4월 6일 ~ 4월 7일 -
-- 합격 통보: - 2026년 4월 7일 예정{' '} - - (해당 일정은 변동될 수 있습니다.) - -
-- 면접 장소: - 3-511호 ONE 동아리방 -
- -- 회장의 연락을 통해 면접 일정이 조정될 예정이오니, 잠시 기다려 주세요. -
-문의: 회장 최예은 010-1111-1111
+ {isLoading &&모집 공고 정보를 불러오는 중입니다.
} + + {!isLoading && hasRecruitmentError && ( ++ {EMPTY_RECRUITMENT_NOTICE} +
+ )} + + {!isLoading && !hasRecruitmentError && recruitment && ( + <> + {interviewPeriod && ( ++ 면접 기간: + {interviewPeriod} +
+ )} + {notificationDate && ( ++ 합격 통보: + {notificationDate} 예정{' '} + + (해당 일정은 변동될 수 있습니다.) + +
+ )} + {recruitment.roomLocation && ( ++ 면접 장소: + {recruitment.roomLocation} +
+ )} + > + )} + +{COMPLETE_MESSAGE}
+ {contactText &&문의: 회장 {contactText}
}