diff --git a/src/api/service/group-service/index.ts b/src/api/service/group-service/index.ts index 1dd79a48..cf6d754b 100644 --- a/src/api/service/group-service/index.ts +++ b/src/api/service/group-service/index.ts @@ -1,4 +1,4 @@ -import { api, apiV2 } from '@/api/core'; +import { apiV2 } from '@/api/core'; import { CreateGroupPayload, CreateGroupResponse, @@ -12,7 +12,7 @@ import { } from '@/types/service/group'; export const groupServiceRemote = () => ({ - // 모임 목록 조회 (GET /groups) + // 모임 목록 조회 (GET /api/v2/groups) getGroups: async (payload: GetGroupsPayload): Promise => { const params = new URLSearchParams(); if (payload.keyword) { @@ -23,9 +23,9 @@ export const groupServiceRemote = () => ({ } params.append('size', payload.size.toString()); - return api.get(`/groups?${params.toString()}`); + return apiV2.get(`/groups?${params.toString()}`); }, - // 내 모임 목록 조회 (GET /groups/me) :스케줄러 페이지 + // 내 모임 목록 조회 (GET /api/v2/groups/me) :스케줄러 페이지 getMyGroups: async (payload: GetMyGroupsPayload): Promise => { const params = new URLSearchParams(); params.append('type', payload.type); @@ -34,7 +34,7 @@ export const groupServiceRemote = () => ({ } params.append('size', payload.size.toString()); - return api.get(`/groups/me?${params.toString()}`); + return apiV2.get(`/groups/me?${params.toString()}`); }, // 모임 이미지 사전 업로드 (POST /groups/images/upload) - multipart/form-data diff --git a/src/app/page.tsx b/src/app/page.tsx index 6efde57e..ca37a650 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -31,7 +31,7 @@ export default async function HomePage({ searchParams }: HomePageProps) { return ( <> - ; + ); } diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/description-profile/index.tsx b/src/components/pages/meetup/meetup-descriptions/description-sections/description-profile/index.tsx index 8a960ec2..fe3b4440 100644 --- a/src/components/pages/meetup/meetup-descriptions/description-sections/description-profile/index.tsx +++ b/src/components/pages/meetup/meetup-descriptions/description-sections/description-profile/index.tsx @@ -24,7 +24,7 @@ export const DescriptionProfile = ({ alt='프로필 사진' draggable={false} height={40} - src={profileImage} + src={profileImage ?? ''} />
diff --git a/src/components/pages/meetup/meetup-members/index.tsx b/src/components/pages/meetup/meetup-members/index.tsx index 7ce056b7..7e21d0f1 100644 --- a/src/components/pages/meetup/meetup-members/index.tsx +++ b/src/components/pages/meetup/meetup-members/index.tsx @@ -48,7 +48,7 @@ export const MeetupMembers = ({ members }: Props) => { alt='프로필 사진' draggable={false} height={64} - src={profileImage} + src={profileImage ?? ''} />

; diff --git a/src/types/service/group.ts b/src/types/service/group.ts index 331c11cf..66e06114 100644 --- a/src/types/service/group.ts +++ b/src/types/service/group.ts @@ -1,30 +1,63 @@ -// 모임 목록 조회 응답 (GET /api/v1/groups) +// Group V2 공통 타입 +export type GroupV2Status = 'RECRUITING' | 'FULL' | 'CLOSED' | 'CANCELLED' | 'FINISHED'; + +export type GroupV2JoinPolicy = 'FREE' | 'APPROVAL_REQUIRED'; + +export type GroupV2ListFilter = 'ACTIVE' | 'ARCHIVED' | 'ALL'; + +export type GroupUserV2Status = 'ATTEND' | 'LEFT' | 'KICKED' | 'BANNED' | 'PENDING' | 'REJECTED'; + +export interface GroupV2Membership { + groupUserId: number; + role: 'HOST' | 'MANAGER' | 'MEMBER'; + status: GroupUserV2Status; + joinedAt: string; + leftAt: string | null; +} + +// 모임 목록 조회 응답 (GET /api/v2/groups, GET /api/v2/groups/me) export interface GroupListItemResponse { id: number; title: string; + // v2 추가 필드 + joinPolicy: GroupV2JoinPolicy; + status: GroupV2Status; + location: string; locationDetail?: string | null; startTime: string; // ISO 8601 형식: "2026-12-25T19:00:00" endTime?: string | null; // ISO 8601 형식: "2026-12-25T21:00:00" - images: string[]; + images: string[]; // CARD_440_240 URL 배열 (최대 3개) tags: string[]; description: string; participantCount: number; maxParticipants: number; + // v2 추가 필드 + remainingSeats: number; + joinable: boolean; + createdBy: { userId: number; nickName: string; profileImage: string | null; + profileMessage?: string | null; }; createdAt: string; // ISO 8601 형식 updatedAt: string; // ISO 8601 형식 + + // /api/v2/groups/me 에서만 내려오는 필드 (목록에서는 선택적) + myMembership?: GroupV2Membership | null; } -// 모임 목록 조회 요청 파라미터 +// 모임 목록 조회 요청 파라미터 (GET /api/v2/groups) export interface GetGroupsPayload { keyword?: string; cursor?: number; size: number; + // v2 필터 옵션들 (선택) + filter?: GroupV2ListFilter; + includeStatuses?: GroupV2Status[]; + excludeStatuses?: GroupV2Status[]; } // 모임 목록 조회 응답 @@ -33,11 +66,16 @@ export interface GetGroupsResponse { nextCursor: number | null; } -// 내 모임 목록 조회 요청 파라미터 (GET /api/v1/groups/me) +// 내 모임 목록 조회 요청 파라미터 (GET /api/v2/groups/me) export interface GetMyGroupsPayload { type: 'current' | 'myPost' | 'past'; cursor?: number; size: number; + // v2 필터 옵션들 (선택) + filter?: GroupV2ListFilter; + includeStatuses?: GroupV2Status[]; + excludeStatuses?: GroupV2Status[]; + myStatuses?: GroupUserV2Status[]; } // 내 모임 목록 조회 응답 @@ -101,13 +139,15 @@ export interface CreateGroupPayload { imageKey: string; sortOrder: number; }[]; - joinPolicy: 'FREE' | 'APPROVE'; + // v2 기준: FREE / APPROVAL_REQUIRED + joinPolicy: GroupV2JoinPolicy; } export interface CreateGroupResponse { id: number; title: string; - status: 'RECRUITING' | 'FULL' | 'FINISHED'; + // v2 상태 타입 + status: GroupV2Status; address: { location: string; locationDetail: string; @@ -123,16 +163,10 @@ export interface CreateGroupResponse { createdBy: { userId: number; nickName: string; - profileImage: string; - profileMessage: string; + profileImage: string | null; + profileMessage: string | null; }; - myMembership?: { - groupUserId: number; - role: 'HOST' | 'MEMBER'; - status: 'ATTEND' | 'LEFT'; - joinedAt: string; - leftAt: string; - } | null; + myMembership?: GroupV2Membership | null; images: { groupImageId: number; imageKey: string; @@ -151,19 +185,20 @@ export interface CreateGroupResponse { export interface GetGroupDetailsResponse { id: number; title: string; - status: 'RECRUITING' | 'FULL' | 'FINISHED'; + status: GroupV2Status; address: { location: string; locationDetail: string; }; startTime: string; - endTime: string; + endTime?: string | null; images: { groupImageId: number; imageKey: string; sortOrder: number; variants: { variantId: number; + // v2 이미지 타입 type: 'CARD_440_240' | 'THUMBNAIL_100_100'; width: number; height: number; @@ -178,26 +213,20 @@ export interface GetGroupDetailsResponse { createdBy: { userId: number; nickName: string; - profileImage: string; - profileMessage: string; + profileImage: string | null; + profileMessage: string | null; }; createdAt: string; updatedAt: string; - myMembership?: { - groupUserId: number; - role: 'HOST' | 'MEMBER'; - status: 'ATTEND' | 'LEFT'; - joinedAt: string; - leftAt: string; - } | null; + myMembership?: GroupV2Membership | null; joinedMembers: { - userId: 0; - groupRole: 'HOST' | 'MEMBER'; - status: 'ATTEND' | 'LEFT'; + userId: number; + role: 'HOST' | 'MANAGER' | 'MEMBER'; + status: GroupUserV2Status; nickName: string; - profileImage: string; + profileImage: string | null; joinedAt: string; - leftAt: string; + leftAt: string | null; }[]; }