Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/api/service/group-service/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { api, apiV2 } from '@/api/core';
import { apiV2 } from '@/api/core';
import {
CreateGroupPayload,
CreateGroupResponse,
Expand All @@ -12,7 +12,7 @@ import {
} from '@/types/service/group';

export const groupServiceRemote = () => ({
// 모임 목록 조회 (GET /groups)
// 모임 목록 조회 (GET /api/v2/groups)
getGroups: async (payload: GetGroupsPayload): Promise<GetGroupsResponse> => {
const params = new URLSearchParams();
if (payload.keyword) {
Expand All @@ -23,9 +23,9 @@ export const groupServiceRemote = () => ({
}
params.append('size', payload.size.toString());

return api.get<GetGroupsResponse>(`/groups?${params.toString()}`);
return apiV2.get<GetGroupsResponse>(`/groups?${params.toString()}`);
},
// 내 모임 목록 조회 (GET /groups/me) :스케줄러 페이지
// 내 모임 목록 조회 (GET /api/v2/groups/me) :스케줄러 페이지
getMyGroups: async (payload: GetMyGroupsPayload): Promise<GetMyGroupsResponse> => {
const params = new URLSearchParams();
params.append('type', payload.type);
Expand All @@ -34,7 +34,7 @@ export const groupServiceRemote = () => ({
}
params.append('size', payload.size.toString());

return api.get<GetMyGroupsResponse>(`/groups/me?${params.toString()}`);
return apiV2.get<GetMyGroupsResponse>(`/groups/me?${params.toString()}`);
},

// 모임 이미지 사전 업로드 (POST /groups/images/upload) - multipart/form-data
Expand Down
2 changes: 1 addition & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default async function HomePage({ searchParams }: HomePageProps) {
return (
<>
<GroupSearchBar />
<GroupList initialData={initialData} initialKeyword={keyword} />;
<GroupList initialData={initialData} initialKeyword={keyword} />
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const DescriptionProfile = ({
alt='프로필 사진'
draggable={false}
height={40}
src={profileImage}
src={profileImage ?? ''}
/>

<div className='flex flex-col justify-center *:line-clamp-1'>
Expand Down
2 changes: 1 addition & 1 deletion src/components/pages/meetup/meetup-members/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const MeetupMembers = ({ members }: Props) => {
alt='프로필 사진'
draggable={false}
height={64}
src={profileImage}
src={profileImage ?? ''}
/>
</Link>
<p
Expand Down
2 changes: 1 addition & 1 deletion src/lib/schema/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const createGroupSchema = z.object({
}),
)
.optional(),
joinPolicy: z.union([z.literal('FREE'), z.literal('APPROVE')]),
joinPolicy: z.union([z.literal('FREE'), z.literal('APPROVAL_REQUIRED')]),
});

export type CreateGroupFormValues = z.infer<typeof createGroupSchema>;
91 changes: 60 additions & 31 deletions src/types/service/group.ts
Original file line number Diff line number Diff line change
@@ -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[];
}

// 모임 목록 조회 응답
Expand All @@ -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[];
}

// 내 모임 목록 조회 응답
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}[];
}

Expand Down