From ae6bfebd870f491819589d195fe158c19abbec54 Mon Sep 17 00:00:00 2001 From: HopeFullee Date: Sun, 14 Dec 2025 14:51:51 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A0=95=EB=B3=B4=20=EB=B0=94=EC=9D=B8=EB=94=A9=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20/=20date=20=EC=9C=A0=ED=8B=B8=ED=95=A8?= =?UTF-8?q?=EC=88=98=20refactor=20/=20=EB=94=94=ED=8F=B4=ED=8A=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=83=81=EC=88=98=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- constants/default-images.ts | 6 +++ next.config.ts | 5 +++ src/app/meetup/[groupId]/page.tsx | 4 +- .../meetup/meetup-banner-images/index.tsx | 2 +- .../description-content/index.tsx | 11 ----- .../description-detail/index.tsx | 13 ++++++ .../description-profile/index.tsx | 21 +++++---- .../description-progress/index.tsx | 20 ++++++--- .../description-setting/index.tsx | 12 +++-- .../description-tags/index.tsx | 8 +++- .../description-title/index.tsx | 6 ++- .../description-sections/index.ts | 2 +- .../meetup/meetup-descriptions/index.tsx | 39 ++++++++++++---- .../pages/meetup/meetup-members/index.tsx | 45 ++++++++++--------- .../post-meetup/fields/date-field/index.tsx | 28 +++--------- src/lib/formatDateTime.ts | 38 ++++++++++------ src/types/service/group.ts | 14 +++--- 17 files changed, 162 insertions(+), 112 deletions(-) create mode 100644 constants/default-images.ts delete mode 100644 src/components/pages/meetup/meetup-descriptions/description-sections/description-content/index.tsx create mode 100644 src/components/pages/meetup/meetup-descriptions/description-sections/description-detail/index.tsx diff --git a/constants/default-images.ts b/constants/default-images.ts new file mode 100644 index 00000000..2db1b2e8 --- /dev/null +++ b/constants/default-images.ts @@ -0,0 +1,6 @@ +// 나중에 회원 프로필, 모임 디폴트 시안 나오면 각각 '/public/default-images/' 경로에서 지정 +export const DEFAULT_PROFILE_IMAGE = + 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'; + +export const DEFAULT_GROUP_IMAGE = + 'https://images.unsplash.com/photo-1705599359461-f99dc9e80efa?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'; diff --git a/next.config.ts b/next.config.ts index b882f61f..b7b6d9e3 100644 --- a/next.config.ts +++ b/next.config.ts @@ -14,6 +14,11 @@ const nextConfig: NextConfig = { port: '', pathname: '/**', }, + { + protocol: 'https', + hostname: 'we-go-bucket.s3.ap-northeast-2.amazonaws.com', + pathname: '/**', + }, { protocol: 'https', hostname: 'images.unsplash.com', diff --git a/src/app/meetup/[groupId]/page.tsx b/src/app/meetup/[groupId]/page.tsx index e030095c..ffcac24c 100644 --- a/src/app/meetup/[groupId]/page.tsx +++ b/src/app/meetup/[groupId]/page.tsx @@ -25,8 +25,8 @@ const MeetupDetailPage = ({ params }: Props) => { return (
- - + + { - const hasImages = images.length; + const hasImages = Boolean(images.length); const defaultImageUrl = 'https://images.unsplash.com/photo-1705599359461-f99dc9e80efa?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'; diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/description-content/index.tsx b/src/components/pages/meetup/meetup-descriptions/description-sections/description-content/index.tsx deleted file mode 100644 index 9a35ca65..00000000 --- a/src/components/pages/meetup/meetup-descriptions/description-sections/description-content/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -interface Props { - content: string; -} - -export const DescriptionContent = ({ content }: Props) => { - return ( -
-

{content}

-
- ); -}; diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/description-detail/index.tsx b/src/components/pages/meetup/meetup-descriptions/description-sections/description-detail/index.tsx new file mode 100644 index 00000000..ca871f8e --- /dev/null +++ b/src/components/pages/meetup/meetup-descriptions/description-sections/description-detail/index.tsx @@ -0,0 +1,13 @@ +import { GetGroupDetailsResponse } from '@/types/service/group'; + +interface Props { + detail: GetGroupDetailsResponse['description']; +} + +export const DescriptionDetail = ({ detail }: Props) => { + return ( +
+

{detail}

+
+ ); +}; 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 da3dbe85..a1d46623 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 @@ -1,28 +1,31 @@ import Image from 'next/image'; import Link from 'next/link'; +import { DEFAULT_PROFILE_IMAGE } from 'constants/default-images'; + +import { GetGroupDetailsResponse } from '@/types/service/group'; + interface Props { - profileImage: string; - name: string; - bio: string; + hostInfo: GetGroupDetailsResponse['createdBy']; } -export const DescriptionProfile = ({ profileImage, name, bio }: Props) => { +export const DescriptionProfile = ({ hostInfo: { nickName, profileImage, userId } }: Props) => { return ( -
- +
+ 프로필 사진
-

{name}

-

{bio}

+

{nickName}

+

some dummy bio text

diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/description-progress/index.tsx b/src/components/pages/meetup/meetup-descriptions/description-sections/description-progress/index.tsx index 9cd0435e..6d45ec62 100644 --- a/src/components/pages/meetup/meetup-descriptions/description-sections/description-progress/index.tsx +++ b/src/components/pages/meetup/meetup-descriptions/description-sections/description-progress/index.tsx @@ -1,21 +1,27 @@ +import { formatTimeAgo } from '@/lib/formatDateTime'; +import { GetGroupDetailsResponse } from '@/types/service/group'; + interface Props { progress: { - current: number; - max: number; + maxParticipants: GetGroupDetailsResponse['maxParticipants']; + participantCount: GetGroupDetailsResponse['participantCount']; }; createdAt: string; } -export const DescriptionProgress = ({ progress: { current, max }, createdAt }: Props) => { - const progressRate = Math.ceil((current / max) * 100); +export const DescriptionProgress = ({ + progress: { maxParticipants, participantCount }, + createdAt, +}: Props) => { + const progressRate = Math.ceil((participantCount / maxParticipants) * 100); return ( -
+

참여 인원

- {current}/{max} + {participantCount}/{maxParticipants}
@@ -24,7 +30,7 @@ export const DescriptionProgress = ({ progress: { current, max }, createdAt }: P
-

{createdAt}

+

{formatTimeAgo(createdAt)}

); diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/description-setting/index.tsx b/src/components/pages/meetup/meetup-descriptions/description-sections/description-setting/index.tsx index e29583c1..4bf8d3ce 100644 --- a/src/components/pages/meetup/meetup-descriptions/description-sections/description-setting/index.tsx +++ b/src/components/pages/meetup/meetup-descriptions/description-sections/description-setting/index.tsx @@ -1,12 +1,12 @@ import { Icon } from '@/components/icon'; +import { formatDateTime } from '@/lib/formatDateTime'; +import { GetGroupDetailsResponse } from '@/types/service/group'; interface Props { - location: string; - date: string; - time: string; + setting: Pick; } -export const DescriptionSetting = ({ location, date, time }: Props) => { +export const DescriptionSetting = ({ setting: { location, startTime } }: Props) => { return (
    @@ -16,9 +16,7 @@ export const DescriptionSetting = ({ location, date, time }: Props) => {
  • -

    - {date} - {time} -

    +

    {formatDateTime(startTime)}

diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/description-tags/index.tsx b/src/components/pages/meetup/meetup-descriptions/description-sections/description-tags/index.tsx index d3094526..3648486a 100644 --- a/src/components/pages/meetup/meetup-descriptions/description-sections/description-tags/index.tsx +++ b/src/components/pages/meetup/meetup-descriptions/description-sections/description-tags/index.tsx @@ -1,8 +1,14 @@ +import { GetGroupDetailsResponse } from '@/types/service/group'; + interface Props { - tags: string[]; + tags: GetGroupDetailsResponse['tags']; } export const DescriptionTags = ({ tags }: Props) => { + const hasTags = Boolean(tags.length); + + if (!hasTags) return null; + return (
{tags.map((tag) => ( diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/description-title/index.tsx b/src/components/pages/meetup/meetup-descriptions/description-sections/description-title/index.tsx index 7075b29d..d2dc5434 100644 --- a/src/components/pages/meetup/meetup-descriptions/description-sections/description-title/index.tsx +++ b/src/components/pages/meetup/meetup-descriptions/description-sections/description-title/index.tsx @@ -1,11 +1,13 @@ +import { GetGroupDetailsResponse } from '@/types/service/group'; + interface Props { - title: string; + title: GetGroupDetailsResponse['title']; } export const DescriptionTitle = ({ title }: Props) => { return (
-

{title}

+

{title}

); }; diff --git a/src/components/pages/meetup/meetup-descriptions/description-sections/index.ts b/src/components/pages/meetup/meetup-descriptions/description-sections/index.ts index b7a1881c..6f5ff7ea 100644 --- a/src/components/pages/meetup/meetup-descriptions/description-sections/index.ts +++ b/src/components/pages/meetup/meetup-descriptions/description-sections/index.ts @@ -1,4 +1,4 @@ -export { DescriptionContent } from './description-content'; +export { DescriptionDetail } from './description-detail'; export { DescriptionProfile } from './description-profile'; export { DescriptionProgress } from './description-progress'; export { DescriptionSetting } from './description-setting'; diff --git a/src/components/pages/meetup/meetup-descriptions/index.tsx b/src/components/pages/meetup/meetup-descriptions/index.tsx index 7842dcfe..86fb25ed 100644 --- a/src/components/pages/meetup/meetup-descriptions/index.tsx +++ b/src/components/pages/meetup/meetup-descriptions/index.tsx @@ -1,28 +1,51 @@ -import type { DUMMY_MEETUP_DATA } from '@/app/meetup/[groupId]/page'; import { - DescriptionContent, + DescriptionDetail, DescriptionProfile, DescriptionProgress, DescriptionSetting, DescriptionTags, DescriptionTitle, } from '@/components/pages/meetup/meetup-descriptions/description-sections'; +import { GetGroupDetailsResponse } from '@/types/service/group'; interface Props { - description: typeof DUMMY_MEETUP_DATA.description; + descriptions: Pick< + GetGroupDetailsResponse, + | 'createdBy' + | 'createdAt' + | 'title' + | 'tags' + | 'description' + | 'location' + | 'startTime' + | 'maxParticipants' + | 'participantCount' + >; } export const MeetupDescriptions = ({ - description: { ownerInfo, title, tags, content, setting, progress, createdAt }, + descriptions: { + createdBy, + createdAt, + title, + tags, + description, + location, + startTime, + maxParticipants, + participantCount, + }, }: Props) => { + console.log(participantCount); + return (
- + - - - + + +
); }; diff --git a/src/components/pages/meetup/meetup-members/index.tsx b/src/components/pages/meetup/meetup-members/index.tsx index 54e21539..93f5e19a 100644 --- a/src/components/pages/meetup/meetup-members/index.tsx +++ b/src/components/pages/meetup/meetup-members/index.tsx @@ -7,48 +7,53 @@ import { useState } from 'react'; import clsx from 'clsx'; -import type { DUMMY_MEETUP_DATA } from '@/app/meetup/[groupId]/page'; import { Icon } from '@/components/icon'; +import { AnimateDynamicHeight } from '@/components/shared'; import { Button } from '@/components/ui'; +import { GetGroupDetailsResponse } from '@/types/service/group'; interface Props { - members: typeof DUMMY_MEETUP_DATA.members; + members: GetGroupDetailsResponse['joinedMembers']; } export const MeetupMembers = ({ members }: Props) => { - const [showMore, setShowMore] = useState(false); + const [expand, setExpand] = useState(false); const [coverMember, setCoverMember] = useState(2 < Math.ceil(members.length / 3)); const hasMoreMember = 2 < Math.ceil(members.length / 3); - const onShowMoreClick = () => { - setShowMore((prev) => !prev); + const defaultProfileImageUrl = + 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'; + + const onExpandClick = () => { + setExpand((prev) => !prev); setCoverMember((prev) => !prev); }; return ( -
+

참여자 정보

-
-
    - {members.map(({ name, profileImage }, idx) => ( + +
      + {members.map(({ nickName, profileImage, userId }, idx) => (
    • -
      - +
      + 프로필 사진

      { coverMember && idx === 5 ? 'hidden' : 'block', )} > - {name} + {nickName}

      @@ -71,7 +76,7 @@ export const MeetupMembers = ({ members }: Props) => {
    • ))}
    -
+ {hasMoreMember && (
@@ -79,10 +84,10 @@ export const MeetupMembers = ({ members }: Props) => { className='flex-center h-9 w-auto border-none bg-gray-50 px-4' size='sm' variant='secondary' - onClick={onShowMoreClick} + onClick={onExpandClick} > - {showMore ? '접기' : '더보기'} - + {expand ? '접기' : '더보기'} +
)} diff --git a/src/components/pages/post-meetup/fields/date-field/index.tsx b/src/components/pages/post-meetup/fields/date-field/index.tsx index b62a188f..47070cc2 100644 --- a/src/components/pages/post-meetup/fields/date-field/index.tsx +++ b/src/components/pages/post-meetup/fields/date-field/index.tsx @@ -7,6 +7,7 @@ import { Icon } from '@/components/icon'; import { DatePickerModal } from '@/components/pages/post-meetup/modals/date-picker-modal'; import { Label } from '@/components/ui'; import { useModal } from '@/components/ui'; +import { formatDateTime } from '@/lib/formatDateTime'; interface Props { field: AnyFieldApi; @@ -14,7 +15,9 @@ interface Props { export const MeetupDateField = ({ field }: Props) => { const { open } = useModal(); - const formattedDate = formatDate(new Date(field.state.value), 'YY.MM.DD - HH:mm'); + + const hasValue = Boolean(field.state.value); + const formattedDate = formatDateTime(field.state.value); const onInputClick = () => { open(); @@ -39,31 +42,12 @@ export const MeetupDateField = ({ field }: Props) => {

- {formattedDate ? formattedDate : '날짜와 시간을 선택해주세요'} + {hasValue ? formattedDate : '날짜와 시간을 선택해주세요'}

); }; - -const formatDate = (date: Date, formatString: string) => { - if (isNaN(date.getTime())) return false; - - const year = date.getFullYear().toString().substring(2, 4); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const day = date.getDate().toString().padStart(2, '0'); - const hours = date.getHours().toString().padStart(2, '0'); - const minutes = date.getMinutes().toString().padStart(2, '0'); - const seconds = date.getSeconds().toString().padStart(2, '0'); - - return formatString - .replace(/YY/g, year) - .replace(/MM/g, month) - .replace(/DD/g, day) - .replace(/HH/g, hours) - .replace(/mm/g, minutes) - .replace(/ss/g, seconds); -}; diff --git a/src/lib/formatDateTime.ts b/src/lib/formatDateTime.ts index 8ced9bef..eefd9472 100644 --- a/src/lib/formatDateTime.ts +++ b/src/lib/formatDateTime.ts @@ -7,20 +7,20 @@ export const formatISO = (dateString: string) => { }; export const formatTimeAgo = (isoString: string) => { - const dateInput = new Date(isoString); + const dateInput = new Date(isoString.endsWith('Z') ? isoString : `${isoString}Z`); const dateNow = new Date(); - const diffPerSec = (dateNow.getTime() - dateInput.getTime()) / 1000; - if (diffPerSec < 60) return `${Math.ceil(diffPerSec)}초 전`; + const diffPerSec = Math.floor((dateNow.getTime() - dateInput.getTime()) / 1000); + if (diffPerSec < 60) return `${diffPerSec}초 전`; - const diffPerMin = diffPerSec / 60; - if (diffPerMin < 60) return `${Math.ceil(diffPerMin)}분 전`; + const diffPerMin = Math.floor(diffPerSec / 60); + if (diffPerMin < 60) return `${diffPerMin}분 전`; - const diffPerHour = diffPerMin / 60; - if (diffPerHour < 24) return `${Math.ceil(diffPerHour)}시간 전`; + const diffPerHour = Math.floor(diffPerMin / 60); + if (diffPerHour < 24) return `${diffPerHour}시간 전`; - const diffPerDay = diffPerHour / 30; - if (diffPerDay < 30) return `${Math.ceil(diffPerDay)}일 전`; + const diffPerDay = Math.floor(diffPerHour / 24); + if (diffPerDay < 30) return `${diffPerDay}일 전`; const yearDiff = dateNow.getFullYear() - dateInput.getFullYear(); const monthDiff = dateNow.getMonth() - dateInput.getMonth(); @@ -30,13 +30,25 @@ export const formatTimeAgo = (isoString: string) => { }; // 모임 시작 시간을 Card 컴포넌트용 형식으로 변환 (예: "25. 12. 25 - 19:00") -export const formatDateTime = (startTime: string, _endTime?: string | null): string => { +export const formatDateTime = (startTime: string, customFormat?: string | null): string | null => { const start = new Date(startTime); - const year = start.getFullYear().toString().slice(-2); + + const fullYear = start.getFullYear().toString(); + const shortYear = fullYear.slice(-2); const month = String(start.getMonth() + 1).padStart(2, '0'); const day = String(start.getDate()).padStart(2, '0'); const hours = String(start.getHours()).padStart(2, '0'); const minutes = String(start.getMinutes()).padStart(2, '0'); - - return `${year}. ${month}. ${day} - ${hours}:${minutes}`; + const seconds = String(start.getSeconds()).padStart(2, '0'); + + if (!customFormat) return `${shortYear}. ${month}. ${day} - ${hours}:${minutes}`; + + return customFormat + .replace(/yyyy/g, fullYear) + .replace(/yy/g, shortYear) + .replace(/MM/g, month) + .replace(/dd/g, day) + .replace(/HH/g, hours) + .replace(/mm/g, minutes) + .replace(/ss/g, seconds); }; diff --git a/src/types/service/group.ts b/src/types/service/group.ts index a9150bea..1eb4de89 100644 --- a/src/types/service/group.ts +++ b/src/types/service/group.ts @@ -80,13 +80,11 @@ export interface PreUploadGroupImagePayload { } export interface PreUploadGroupImageResponse { - images: [ - { - sortOrder: number; - imageUrl440x240: string; - imageUrl100x100: string; - }, - ]; + images: { + sortOrder: number; + imageUrl440x240: string; + imageUrl100x100: string; + }[]; } export type CreateGroupImagePayload = PreUploadGroupImageResponse; @@ -121,7 +119,7 @@ export interface CreateGroupResponse { }; createdAt: string; updatedAt: string; - images?: PreUploadGroupImageResponse | null; + images?: CreateGroupImagePayload['images'] | null; } export interface GetGroupDetailsPayload { From f642d6dd5d9369b15d1c9e0803e05f78153823ad Mon Sep 17 00:00:00 2001 From: HopeFullee Date: Sun, 14 Dec 2025 17:07:25 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=83=81=ED=83=9C=EB=B3=84=20(=EC=B0=B8=EC=97=AC?= =?UTF-8?q?=EC=9E=90,=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EB=93=B1)=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=A5=B8=20UI=20=EB=9E=9C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/meetup/[groupId]/page.tsx | 94 +------------------ .../pages/meetup/meetup-buttons/index.tsx | 76 ++++++++------- .../meetup/meetup-descriptions/index.tsx | 2 - .../pages/meetup/meetup-modal/index.tsx | 12 +-- 4 files changed, 50 insertions(+), 134 deletions(-) diff --git a/src/app/meetup/[groupId]/page.tsx b/src/app/meetup/[groupId]/page.tsx index ffcac24c..9a3135e6 100644 --- a/src/app/meetup/[groupId]/page.tsx +++ b/src/app/meetup/[groupId]/page.tsx @@ -27,101 +27,9 @@ const MeetupDetailPage = ({ params }: Props) => { - +
); }; export default MeetupDetailPage; - -// 바인딩 테스트용 더미 데이터임 (무시하세요) -export const DUMMY_MEETUP_DATA = { - bannerImages: [ - 'https://images.unsplash.com/photo-1546512347-3ad629c193c5?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - 'https://images.unsplash.com/photo-1527529482837-4698179dc6ce?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - 'https://plus.unsplash.com/premium_photo-1700554043895-6e87a46a2b21?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - ], - description: { - ownerInfo: { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'Dummy Name', - bio: 'Some Dummy Bio Message', - }, - title: '동탄 호수공원에서 피크닉하실 분 구해요!', - tags: ['동탄2', '피크닉', '노가리'], - content: - '동탄 호수공원에서 가볍게 피그닉 하실 분을 기다리고 있어요! 간단히 먹거리 나누고, 잔디밭에서 편하게 이야기하며 쉬는 느낌의 소규모 모임입니다.\n혼자 오셔도 편하게 어울릴 수 있어요!', - setting: { - location: '화성시 산척동', - date: '25.11.28', - time: '10:00', - }, - progress: { - current: 9, - max: 12, - }, - createdAt: '30분 전', - }, - members: [ - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName01', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName02', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName03', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName04', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName05', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName06', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName07', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName08', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName09', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName10', - }, - { - profileImage: - 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?q=80&w=717&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', - name: 'UserNickName11', - }, - ], -}; diff --git a/src/components/pages/meetup/meetup-buttons/index.tsx b/src/components/pages/meetup/meetup-buttons/index.tsx index f11b1eaa..6bec8640 100644 --- a/src/components/pages/meetup/meetup-buttons/index.tsx +++ b/src/components/pages/meetup/meetup-buttons/index.tsx @@ -2,27 +2,31 @@ import { useRouter } from 'next/navigation'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; + +import Cookies from 'js-cookie'; import { MeetupModal } from '@/components/pages/meetup/meetup-modal'; import { Button } from '@/components/ui/button'; import { useModal } from '@/components/ui/modal'; +import { GetGroupDetailsResponse } from '@/types/service/group'; interface Props { - progress: { - current: number; - max: number; - }; - ownerInfo: { - name: string; - }; - members: { - name: string; - }[]; + conditions: Pick< + GetGroupDetailsResponse, + 'userStatus' | 'createdBy' | 'participantCount' | 'maxParticipants' + >; } -export const MeetupButtons = ({ progress: { current, max }, ownerInfo }: Props) => { - const [isJoined, _] = useState(true); +export const MeetupButtons = ({ + conditions: { + userStatus: { isJoined }, + createdBy, + participantCount, + maxParticipants, + }, +}: Props) => { + const [isHost, setIsHost] = useState(null); const { open } = useModal(); const { push } = useRouter(); @@ -31,36 +35,42 @@ export const MeetupButtons = ({ progress: { current, max }, ownerInfo }: Props) push('/message/id'); }; - // 방 주인이냐 - const isOwner = ownerInfo.name === '본인 계정 닉네임 ㅇㅇ'; + useEffect(() => { + const checkIsHost = () => { + const sessionId = Number(Cookies.get('userId')); + setIsHost(sessionId === createdBy.userId); + }; - // 모임의 참가자라면 -> (모임 탈퇴 + 채팅 입장) 버튼 - // 본인이 생성한 방이면 -> (모임 취소 + 채팅 입장) 버튼 - if (isJoined) { - return ( -
+ checkIsHost(); + }, [createdBy]); + + return ( +
+ {isJoined ? (
-
-
- ); - } - - // 방 주인 아니고 참가자도 아닐때 -> 참여 버튼 - return ( -
- + ) : ( + + )}
); }; diff --git a/src/components/pages/meetup/meetup-descriptions/index.tsx b/src/components/pages/meetup/meetup-descriptions/index.tsx index 86fb25ed..b17c3e1b 100644 --- a/src/components/pages/meetup/meetup-descriptions/index.tsx +++ b/src/components/pages/meetup/meetup-descriptions/index.tsx @@ -36,8 +36,6 @@ export const MeetupDescriptions = ({ participantCount, }, }: Props) => { - console.log(participantCount); - return (
diff --git a/src/components/pages/meetup/meetup-modal/index.tsx b/src/components/pages/meetup/meetup-modal/index.tsx index 7cf1d2cd..d44aeb81 100644 --- a/src/components/pages/meetup/meetup-modal/index.tsx +++ b/src/components/pages/meetup/meetup-modal/index.tsx @@ -24,19 +24,19 @@ export const MeetupModal = ({ type }: Props) => { const { title, description, confirm } = MODAL_MESSAGE[type]; return ( - - {title} - {description} -
+ + {title} + {description} +
); }; diff --git a/src/components/pages/meetup/meetup-buttons/index.tsx b/src/components/pages/meetup/meetup-buttons/index.tsx index 6bec8640..91aa6338 100644 --- a/src/components/pages/meetup/meetup-buttons/index.tsx +++ b/src/components/pages/meetup/meetup-buttons/index.tsx @@ -16,6 +16,7 @@ interface Props { GetGroupDetailsResponse, 'userStatus' | 'createdBy' | 'participantCount' | 'maxParticipants' >; + groupId: string; } export const MeetupButtons = ({ @@ -25,6 +26,7 @@ export const MeetupButtons = ({ participantCount, maxParticipants, }, + groupId, }: Props) => { const [isHost, setIsHost] = useState(null); const { open } = useModal(); @@ -36,12 +38,9 @@ export const MeetupButtons = ({ }; useEffect(() => { - const checkIsHost = () => { - const sessionId = Number(Cookies.get('userId')); - setIsHost(sessionId === createdBy.userId); - }; - - checkIsHost(); + const sessionId = Number(Cookies.get('userId')); + // eslint-disable-next-line react-hooks/set-state-in-effect + setIsHost(sessionId === createdBy.userId); }, [createdBy]); return ( @@ -51,7 +50,9 @@ export const MeetupButtons = ({ @@ -66,7 +67,7 @@ export const MeetupButtons = ({ ) : ( diff --git a/src/components/pages/meetup/meetup-modal/index.tsx b/src/components/pages/meetup/meetup-modal/index.tsx index d44aeb81..fc6daa6f 100644 --- a/src/components/pages/meetup/meetup-modal/index.tsx +++ b/src/components/pages/meetup/meetup-modal/index.tsx @@ -1,66 +1,70 @@ 'use client'; -import { useState } from 'react'; - +import { Button } from '@/components/ui'; import { ModalContent, ModalDescription, ModalTitle, useModal } from '@/components/ui/modal'; +import { useAttendGroup } from '@/hooks/use-group/use-group-attend'; interface Props { - type: 'join' | 'leave' | 'cancel'; + type: 'attend' | 'cancel' | 'delete'; + groupId: string; } -export const MeetupModal = ({ type }: Props) => { +export const MeetupModal = ({ type, groupId }: Props) => { const { close } = useModal(); - const [isPending, setIsPending] = useState(false); + const { mutate: attendMutate, isPending } = useAttendGroup({ groupId }, () => close()); - const handleConfirm = () => { - setIsPending(true); + const { title, description, confirm } = MODAL_MESSAGE[type]; - setTimeout(() => { - setIsPending(false); - close(); - }, 1000); + const handleConfirmClick = () => { + if (type === 'attend') attendMutate(); + else if (type === 'cancel') { + } else if (type === 'delete') { + } }; - const { title, description, confirm } = MODAL_MESSAGE[type]; - return ( {title} {description}
- - +
); }; const MODAL_MESSAGE = { - join: { + attend: { title: '모임에 참여하시겠어요?', description: '참여 후 바로 그룹채팅에 참여할 수 있어요!', confirm: '참여하기', + onConfirm: (attendMutate: () => void) => attendMutate(), }, - leave: { + cancel: { title: '모임을 정말 탈퇴하시겠어요?', description: '탈퇴 시 그룹채팅과 모임 활동이 종료돼요.', confirm: '탈퇴하기', + onConfirm: (cancelMutate: () => void) => cancelMutate(), }, - cancel: { + delete: { title: '모임을 정말 취소하시겠어요?', description: '취소 후에는 다시 복구할 수 없어요.', confirm: '취소하기', + onConfirm: (deleteMutate: () => void) => deleteMutate(), }, }; diff --git a/src/hooks/use-group/use-group-attend/index.ts b/src/hooks/use-group/use-group-attend/index.ts new file mode 100644 index 00000000..e1d3ae89 --- /dev/null +++ b/src/hooks/use-group/use-group-attend/index.ts @@ -0,0 +1,23 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { API } from '@/api'; +import { groupKeys } from '@/lib/query-key/query-key-group'; +import { AttendGroupPayload } from '@/types/service/group'; + +export const useAttendGroup = (payload: AttendGroupPayload, callback: () => void) => { + const queryClient = useQueryClient(); + + const query = useMutation({ + mutationFn: () => API.groupService.attendGroup(payload), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: groupKeys.detail(payload.groupId) }); + callback(); + console.log('모임 참여 성공.'); + }, + onError: (error) => { + console.log('모임 참여 실패.'); + throw error; + }, + }); + return query; +}; diff --git a/src/lib/formatDateTime.ts b/src/lib/formatDateTime.ts index eefd9472..e171ae37 100644 --- a/src/lib/formatDateTime.ts +++ b/src/lib/formatDateTime.ts @@ -30,7 +30,7 @@ export const formatTimeAgo = (isoString: string) => { }; // 모임 시작 시간을 Card 컴포넌트용 형식으로 변환 (예: "25. 12. 25 - 19:00") -export const formatDateTime = (startTime: string, customFormat?: string | null): string | null => { +export const formatDateTime = (startTime: string, customFormat?: string): string => { const start = new Date(startTime); const fullYear = start.getFullYear().toString(); diff --git a/src/types/service/group.ts b/src/types/service/group.ts index 1eb4de89..abfce6b1 100644 --- a/src/types/service/group.ts +++ b/src/types/service/group.ts @@ -163,3 +163,7 @@ export interface GetGroupDetailsResponse { joinedAt: string; }[]; } + +export interface AttendGroupPayload { + groupId: string; +} From 062eeae18386dcd5df75010f63cbb5c9acdbb2c5 Mon Sep 17 00:00:00 2001 From: HopeFullee Date: Sun, 14 Dec 2025 20:15:28 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=83=88?= =?UTF-8?q?=ED=87=B4=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/service/group-service/index.ts | 11 ++++++---- .../pages/meetup/meetup-modal/index.tsx | 10 ++++++--- src/hooks/use-group/use-group-attend/index.ts | 7 +++--- src/hooks/use-group/use-group-cancel/index.ts | 22 +++++++++++++++++++ .../use-group/use-group-get-details/index.ts | 4 ++-- src/types/service/group.ts | 6 +---- 6 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 src/hooks/use-group/use-group-cancel/index.ts diff --git a/src/api/service/group-service/index.ts b/src/api/service/group-service/index.ts index e8fbcd66..5aeea380 100644 --- a/src/api/service/group-service/index.ts +++ b/src/api/service/group-service/index.ts @@ -1,14 +1,13 @@ import { api } from '@/api/core'; import { - AttendGroupPayload, CreateGroupPayload, CreateGroupResponse, - GetGroupDetailsPayload, GetGroupDetailsResponse, GetGroupsPayload, GetGroupsResponse, GetMyGroupsPayload, GetMyGroupsResponse, + GroupIdPayload, PreUploadGroupImagePayload, PreUploadGroupImageResponse, } from '@/types/service/group'; @@ -70,11 +69,15 @@ export const groupServiceRemote = () => ({ return api.post('/groups/create', payload); }, - getGroupDetails: (payload: GetGroupDetailsPayload) => { + getGroupDetails: (payload: GroupIdPayload) => { return api.get(`/groups/${payload.groupId}`); }, - attendGroup: (payload: AttendGroupPayload) => { + attendGroup: (payload: GroupIdPayload) => { return api.post(`/groups/${payload.groupId}/attend`); }, + + cancelGroup: (payload: GroupIdPayload) => { + return api.post(`/groups/${payload.groupId}/cancel`); + }, }); diff --git a/src/components/pages/meetup/meetup-modal/index.tsx b/src/components/pages/meetup/meetup-modal/index.tsx index fc6daa6f..0e0129d8 100644 --- a/src/components/pages/meetup/meetup-modal/index.tsx +++ b/src/components/pages/meetup/meetup-modal/index.tsx @@ -3,6 +3,7 @@ import { Button } from '@/components/ui'; import { ModalContent, ModalDescription, ModalTitle, useModal } from '@/components/ui/modal'; import { useAttendGroup } from '@/hooks/use-group/use-group-attend'; +import { useCancelGroup } from '@/hooks/use-group/use-group-cancel'; interface Props { type: 'attend' | 'cancel' | 'delete'; @@ -11,14 +12,17 @@ interface Props { export const MeetupModal = ({ type, groupId }: Props) => { const { close } = useModal(); - const { mutate: attendMutate, isPending } = useAttendGroup({ groupId }, () => close()); + const { mutate: attendMutate, isPending: isAttending } = useAttendGroup({ groupId }, close); + const { mutate: cancelMutate, isPending: isCanceling } = useCancelGroup({ groupId }, close); const { title, description, confirm } = MODAL_MESSAGE[type]; + const isPending = isAttending || isCanceling; + const handleConfirmClick = () => { if (type === 'attend') attendMutate(); - else if (type === 'cancel') { - } else if (type === 'delete') { + else if (type === 'cancel') cancelMutate(); + else if (type === 'delete') { } }; diff --git a/src/hooks/use-group/use-group-attend/index.ts b/src/hooks/use-group/use-group-attend/index.ts index e1d3ae89..112729e9 100644 --- a/src/hooks/use-group/use-group-attend/index.ts +++ b/src/hooks/use-group/use-group-attend/index.ts @@ -2,9 +2,9 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { API } from '@/api'; import { groupKeys } from '@/lib/query-key/query-key-group'; -import { AttendGroupPayload } from '@/types/service/group'; +import { GroupIdPayload } from '@/types/service/group'; -export const useAttendGroup = (payload: AttendGroupPayload, callback: () => void) => { +export const useAttendGroup = (payload: GroupIdPayload, callback: () => void) => { const queryClient = useQueryClient(); const query = useMutation({ @@ -14,9 +14,8 @@ export const useAttendGroup = (payload: AttendGroupPayload, callback: () => void callback(); console.log('모임 참여 성공.'); }, - onError: (error) => { + onError: () => { console.log('모임 참여 실패.'); - throw error; }, }); return query; diff --git a/src/hooks/use-group/use-group-cancel/index.ts b/src/hooks/use-group/use-group-cancel/index.ts new file mode 100644 index 00000000..f217ca86 --- /dev/null +++ b/src/hooks/use-group/use-group-cancel/index.ts @@ -0,0 +1,22 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { API } from '@/api'; +import { groupKeys } from '@/lib/query-key/query-key-group'; +import { GroupIdPayload } from '@/types/service/group'; + +export const useCancelGroup = (payload: GroupIdPayload, callback: () => void) => { + const queryClient = useQueryClient(); + + const query = useMutation({ + mutationFn: () => API.groupService.cancelGroup(payload), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: groupKeys.detail(payload.groupId) }); + callback(); + console.log('모임 탈퇴 성공.'); + }, + onError: () => { + console.log('모임 탈퇴 실패.'); + }, + }); + return query; +}; diff --git a/src/hooks/use-group/use-group-get-details/index.ts b/src/hooks/use-group/use-group-get-details/index.ts index 6bacbf02..6499b965 100644 --- a/src/hooks/use-group/use-group-get-details/index.ts +++ b/src/hooks/use-group/use-group-get-details/index.ts @@ -2,9 +2,9 @@ import { useQuery } from '@tanstack/react-query'; import { API } from '@/api'; import { groupKeys } from '@/lib/query-key/query-key-group'; -import { GetGroupDetailsPayload } from '@/types/service/group'; +import { GroupIdPayload } from '@/types/service/group'; -export const useGetGroupDetails = (payload: GetGroupDetailsPayload) => { +export const useGetGroupDetails = (payload: GroupIdPayload) => { const query = useQuery({ queryKey: groupKeys.detail(payload.groupId), queryFn: () => API.groupService.getGroupDetails(payload), diff --git a/src/types/service/group.ts b/src/types/service/group.ts index abfce6b1..03a2d8f9 100644 --- a/src/types/service/group.ts +++ b/src/types/service/group.ts @@ -122,10 +122,6 @@ export interface CreateGroupResponse { images?: CreateGroupImagePayload['images'] | null; } -export interface GetGroupDetailsPayload { - groupId: string; -} - export interface GetGroupDetailsResponse { id: number; title: string; @@ -164,6 +160,6 @@ export interface GetGroupDetailsResponse { }[]; } -export interface AttendGroupPayload { +export interface GroupIdPayload { groupId: string; } From 9d6465e9d50a94c6dd8e6ea74025b3de6688fe56 Mon Sep 17 00:00:00 2001 From: HopeFullee Date: Sun, 14 Dec 2025 20:29:20 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/service/group-service/index.ts | 4 ++++ .../pages/meetup/meetup-modal/index.tsx | 15 +++++++++++---- src/hooks/use-group/use-group-delete/index.ts | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 src/hooks/use-group/use-group-delete/index.ts diff --git a/src/api/service/group-service/index.ts b/src/api/service/group-service/index.ts index 5aeea380..d6af4e22 100644 --- a/src/api/service/group-service/index.ts +++ b/src/api/service/group-service/index.ts @@ -80,4 +80,8 @@ export const groupServiceRemote = () => ({ cancelGroup: (payload: GroupIdPayload) => { return api.post(`/groups/${payload.groupId}/cancel`); }, + + deleteGroup: (payload: GroupIdPayload) => { + return api.delete(`/groups/${payload.groupId}`); + }, }); diff --git a/src/components/pages/meetup/meetup-modal/index.tsx b/src/components/pages/meetup/meetup-modal/index.tsx index 0e0129d8..6427a642 100644 --- a/src/components/pages/meetup/meetup-modal/index.tsx +++ b/src/components/pages/meetup/meetup-modal/index.tsx @@ -1,9 +1,12 @@ 'use client'; +import { useRouter } from 'next/navigation'; + import { Button } from '@/components/ui'; import { ModalContent, ModalDescription, ModalTitle, useModal } from '@/components/ui/modal'; import { useAttendGroup } from '@/hooks/use-group/use-group-attend'; import { useCancelGroup } from '@/hooks/use-group/use-group-cancel'; +import { useDeleteGroup } from '@/hooks/use-group/use-group-delete'; interface Props { type: 'attend' | 'cancel' | 'delete'; @@ -11,19 +14,23 @@ interface Props { } export const MeetupModal = ({ type, groupId }: Props) => { + const { replace } = useRouter(); const { close } = useModal(); const { mutate: attendMutate, isPending: isAttending } = useAttendGroup({ groupId }, close); const { mutate: cancelMutate, isPending: isCanceling } = useCancelGroup({ groupId }, close); + const { mutate: deleteMutate, isPending: isDeleting } = useDeleteGroup({ groupId }, () => { + close(); + replace('/'); + }); - const { title, description, confirm } = MODAL_MESSAGE[type]; + const isPending = isAttending || isCanceling || isDeleting; - const isPending = isAttending || isCanceling; + const { title, description, confirm } = MODAL_MESSAGE[type]; const handleConfirmClick = () => { if (type === 'attend') attendMutate(); else if (type === 'cancel') cancelMutate(); - else if (type === 'delete') { - } + else if (type === 'delete') deleteMutate(); }; return ( diff --git a/src/hooks/use-group/use-group-delete/index.ts b/src/hooks/use-group/use-group-delete/index.ts new file mode 100644 index 00000000..224b5d9a --- /dev/null +++ b/src/hooks/use-group/use-group-delete/index.ts @@ -0,0 +1,18 @@ +import { useMutation } from '@tanstack/react-query'; + +import { API } from '@/api'; +import { GroupIdPayload } from '@/types/service/group'; + +export const useDeleteGroup = (payload: GroupIdPayload, callback: () => void) => { + const query = useMutation({ + mutationFn: () => API.groupService.deleteGroup(payload), + onSuccess: async () => { + console.log('모임 삭제 성공.'); + callback(); + }, + onError: () => { + console.log('모임 삭제 실패.'); + }, + }); + return query; +}; From fc146a6bfd1ef3375f00323f2dd2fab9d2a5f3f0 Mon Sep 17 00:00:00 2001 From: HopeFullee Date: Sun, 14 Dec 2025 23:13:59 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20formatDateTime=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=EC=9C=BC=EB=A1=9C=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EB=B9=8C=EB=93=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../schedule/(components)/meeting-list.tsx | 2 +- .../use-group-upload-images/index.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/hooks/use-group/use-group-upload-images/index.ts diff --git a/src/app/schedule/(components)/meeting-list.tsx b/src/app/schedule/(components)/meeting-list.tsx index 5b57880e..5547c84a 100644 --- a/src/app/schedule/(components)/meeting-list.tsx +++ b/src/app/schedule/(components)/meeting-list.tsx @@ -38,7 +38,7 @@ export const MeetingList = ({ {meetings.map((meeting) => ( { + const query = useMutation({ + mutationFn: (payload: PreUploadGroupImagePayload) => { + return API.groupService.uploadGroupImages(payload); + }, + onSuccess: () => { + console.log('이미지 등록 성공'); + }, + onError: () => { + console.log('이미지 등록 실패'); + }, + }); + return query; +};