diff --git a/src/api/errors.ts b/src/api/errors.ts index 2bcadf7..dcf3062 100644 --- a/src/api/errors.ts +++ b/src/api/errors.ts @@ -27,6 +27,7 @@ */ export const ErrorCode = { // Global - 기본 에러 + SERVER_ERROR: 'E000', INVALID_ENUM_VALUE: 'E001', INVALID_REQUEST_FORMAT: 'E002', STATUS_ALREADY_SET: 'E003', @@ -110,6 +111,8 @@ export const ErrorCode = { INVALID_MAX_PARTICIPANTS: 'M013', MAX_PARTICIPANTS_LESS_THAN_CURRENT: 'M014', MEETING_DELETE_NOT_ALLOWED: 'M015', + MEETING_JOIN_TIME_EXPIRED: 'M016', + MEETING_UPDATE_TIME_EXPIRED: 'M017', // Topic TOPIC_NOT_FOUND: 'E101', @@ -127,6 +130,8 @@ export const ErrorCode = { MEETING_RETROSPECTIVE_NOT_FOUND: 'R103', RETROSPECTIVE_ALREADY_DELETED: 'R104', NO_ACCESS_RETROSPECTIVE: 'R105', + AI_SUMMARY_NOT_FOUND: 'R106', + RETROSPECTIVE_ALREADY_CREATED: 'R108', // Storage STORAGE_FILE_UPLOAD_FAILED: 'S001', @@ -164,6 +169,7 @@ export type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode] */ export const ErrorMessage: Record = { // Global - 기본 에러 + [ErrorCode.SERVER_ERROR]: '서버 에러가 발생했습니다. 담당자에게 문의 바랍니다.', [ErrorCode.INVALID_ENUM_VALUE]: '유효하지 않은 값입니다.', [ErrorCode.INVALID_REQUEST_FORMAT]: '잘못된 요청 형식입니다.', [ErrorCode.STATUS_ALREADY_SET]: '이미 해당 상태입니다.', @@ -250,6 +256,8 @@ export const ErrorMessage: Record = { [ErrorCode.MAX_PARTICIPANTS_LESS_THAN_CURRENT]: '현재 참가 확정된 인원 수보다 적게 수정할 수 없습니다.', [ErrorCode.MEETING_DELETE_NOT_ALLOWED]: '약속 시작 24시간 이내에는 삭제할 수 없습니다.', + [ErrorCode.MEETING_JOIN_TIME_EXPIRED]: '약속 시작 24시간 이내에는 참가 신청할 수 없습니다.', + [ErrorCode.MEETING_UPDATE_TIME_EXPIRED]: '약속 시작 24시간 이내에는 수정할 수 없습니다.', // Topic [ErrorCode.TOPIC_NOT_FOUND]: '주제를 찾을 수 없습니다.', @@ -267,6 +275,8 @@ export const ErrorMessage: Record = { [ErrorCode.MEETING_RETROSPECTIVE_NOT_FOUND]: '공동 회고 내용을 찾을 수 없습니다.', [ErrorCode.RETROSPECTIVE_ALREADY_DELETED]: '이미 삭제된 개인 회고입니다.', [ErrorCode.NO_ACCESS_RETROSPECTIVE]: '회고에 접근할 권한이 없습니다.', + [ErrorCode.AI_SUMMARY_NOT_FOUND]: 'AI 요약을 찾을 수 없습니다.', + [ErrorCode.RETROSPECTIVE_ALREADY_CREATED]: '이미 약속 회고가 생성되었습니다.', // Storage [ErrorCode.STORAGE_FILE_UPLOAD_FAILED]: '파일 업로드에 실패했습니다.', diff --git a/src/features/meetings/meetings.types.ts b/src/features/meetings/meetings.types.ts index 35381f5..57d4e1e 100644 --- a/src/features/meetings/meetings.types.ts +++ b/src/features/meetings/meetings.types.ts @@ -280,6 +280,7 @@ export interface MyMeetingListItem { meetingStatus: MeetingStatus | 'REJECTED' | 'DONE' myRole: MyMeetingRole progressStatus: MyMeetingProgressStatus + preOpinionTemplateConfirmed: boolean } /** 메인페이지 내 약속 커서 */ diff --git a/src/pages/Home/components/HomeMeetingCard.tsx b/src/pages/Home/components/HomeMeetingCard.tsx index 507be72..e907fa5 100644 --- a/src/pages/Home/components/HomeMeetingCard.tsx +++ b/src/pages/Home/components/HomeMeetingCard.tsx @@ -41,6 +41,7 @@ export default function HomeMeetingCard({ meeting }: HomeMeetingCardProps) { endDateTime, myRole, progressStatus, + preOpinionTemplateConfirmed, } = meeting const status = STATUS_CONFIG[progressStatus] @@ -56,7 +57,7 @@ export default function HomeMeetingCard({ meeting }: HomeMeetingCardProps) { const handleActionClick = (e: MouseEvent) => { e.stopPropagation() - if (isUpcoming) { + if (isUpcoming && preOpinionTemplateConfirmed) { navigate(ROUTES.PRE_OPINIONS(gatheringId, meetingId)) } // TODO: 종료 → 개인 회고 작성 페이지 연결 @@ -110,9 +111,14 @@ export default function HomeMeetingCard({ meeting }: HomeMeetingCardProps) { {/* 액션 버튼 */} - {/* TODO: API 응답에 hasPreOpinionTemplate 필드 추가 후, 템플릿 미제작 시 disabled 처리 */} {isUpcoming && ( - )}