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
21 changes: 2 additions & 19 deletions src/app/group/[groupId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,14 @@ const GroupDetailPage = ({ params }: Props) => {

if (!data) return null;

const {
images,
status,
joinPolicy,
myMembership,
joinedMembers,
participantCount,
maxParticipants,
} = data;
const { images, status, joinPolicy, myMembership, joinedMembers } = data;

return (
<div>
<GroupBannerImages images={images} />
<GroupDescriptions descriptions={data} />
<GroupMembers isHost={myMembership?.role === 'HOST'} members={joinedMembers} />
<GroupButtons
conditions={{
isHost: myMembership?.role === 'HOST',
isJoined: myMembership?.status === 'ATTEND',
isPast: status === 'FINISHED',
isPending: myMembership?.status === 'PENDING',
isFreeGroup: joinPolicy === 'FREE',
isAttendDisabled: participantCount >= maxParticipants || status === 'FINISHED',
}}
/>
<GroupButtons statuses={{ status, myMembership, joinPolicy }} />
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Button } from '@/components/ui';

export const FinishedButton = () => {
return <Button disabled={true}>모임 마감</Button>;
};
64 changes: 20 additions & 44 deletions src/components/pages/group/group-buttons/index.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,34 @@
'use client';

// import { useRouter } from 'next/navigation';

import { GroupModal } from '@/components/pages/group/group-modal';
import { Button } from '@/components/ui/button';
import { useModal } from '@/components/ui/modal';
import { FinishedButton } from '@/components/pages/group/group-buttons/finished-button';
import { JoiningButton } from '@/components/pages/group/group-buttons/joining-button';
import { MembersButton } from '@/components/pages/group/group-buttons/members-button';
import { PendingButton } from '@/components/pages/group/group-buttons/pending-button';
import { GetGroupDetailsResponse } from '@/types/service/group';

interface Props {
conditions: {
isJoined: boolean;
isHost: boolean;
isPast: boolean;
isPending: boolean;
isAttendDisabled: boolean;
isFreeGroup: boolean;
};
statuses: Pick<GetGroupDetailsResponse, 'status' | 'myMembership' | 'joinPolicy'>;
}

export const GroupButtons = ({
conditions: { isJoined, isHost, isPast, isFreeGroup, isAttendDisabled },
}: Props) => {
const { open } = useModal();
// const { push } = useRouter();
export const GroupButtons = ({ statuses: { status, myMembership, joinPolicy } }: Props) => {
const isMember = myMembership?.status === 'ATTEND' && status !== 'FINISHED';

const isPending = myMembership?.status === 'PENDING' && status !== 'FINISHED';

const isFinished = status === 'FINISHED';

// 그룹 채팅방 아이디 추가해야됨
const onEnterChatClick = () => {
alert('채팅 파업');
// push('/message/id');
};
const canJoin = !isMember && !isPending && !isFinished;

return (
<div className='sticky bottom-[56px] border-t-1 border-gray-200 bg-white px-4 py-3'>
{isJoined ? (
<div className='flex gap-[10px]'>
<Button
className='flex-[1.2]'
disabled={isPast}
variant='tertiary'
onClick={() => open(<GroupModal type={isHost ? 'delete' : 'leave'} />)}
>
{isHost ? '모임 취소' : '모임 탈퇴'}
</Button>
<Button className='flex-2' disabled={isPast} onClick={onEnterChatClick}>
채팅 입장
</Button>
</div>
) : (
<Button
disabled={isAttendDisabled}
onClick={() => open(<GroupModal type={isFreeGroup ? 'attend' : 'approval'} />)}
>
{isFreeGroup ? '참여하기' : '참여 신청하기'}
</Button>
{canJoin && (
<JoiningButton
conditions={{ isGroupFull: status === 'FULL', isFreeGroup: joinPolicy === 'FREE' }}
/>
)}
{isPending && <PendingButton />}
{isMember && <MembersButton conditions={{ isHost: myMembership.role === 'HOST' }} />}
{isFinished && <FinishedButton />}
</div>
);
};
23 changes: 23 additions & 0 deletions src/components/pages/group/group-buttons/joining-button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { GroupModal } from '@/components/pages/group/group-modal';
import { Button } from '@/components/ui';
import { useModal } from '@/components/ui';

interface Props {
conditions: {
isGroupFull: boolean;
isFreeGroup: boolean;
};
}

export const JoiningButton = ({ conditions: { isGroupFull, isFreeGroup } }: Props) => {
const { open } = useModal();

return (
<Button
disabled={isGroupFull}
onClick={() => open(<GroupModal type={isFreeGroup ? 'attend' : 'approval'} />)}
>
{isFreeGroup ? '참여하기' : '참여 신청하기'}
</Button>
);
};
36 changes: 36 additions & 0 deletions src/components/pages/group/group-buttons/members-button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// import { useRouter } from 'next/navigation';

import { GroupModal } from '@/components/pages/group/group-modal';
import { Button, useModal } from '@/components/ui';

interface Props {
conditions: {
isHost: boolean;
};
}

export const MembersButton = ({ conditions: { isHost } }: Props) => {
const { open } = useModal();
// const { push } = useRouter();

// 그룹 채팅방 아이디 추가해야됨
const onEnterChatClick = () => {
alert('채팅 파업');
// push('/message/id');
};

return (
<div className='flex gap-[10px]'>
<Button
className='flex-[1.2]'
variant='tertiary'
onClick={() => open(<GroupModal type={isHost ? 'delete' : 'leave'} />)}
>
{isHost ? '모임 취소' : '모임 탈퇴'}
</Button>
<Button className='flex-2' onClick={onEnterChatClick}>
채팅 입장
</Button>
</div>
);
};
22 changes: 22 additions & 0 deletions src/components/pages/group/group-buttons/pending-button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GroupModal } from '@/components/pages/group/group-modal';
import { Button } from '@/components/ui';
import { useModal } from '@/components/ui';

export const PendingButton = () => {
const { open } = useModal();

return (
<div className='flex gap-[10px]'>
<Button
className='flex-[1.2]'
variant='tertiary'
onClick={() => open(<GroupModal type='pending' />)}
>
신청 취소
</Button>
<Button className='flex-2' disabled={true}>
대기중
</Button>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import Link from 'next/link';

import { ImageWithFallback } from '@/components/ui';
import { PendingBadge } from '@/components/ui';
import { GetGroupDetailsResponse } from '@/types/service/group';

interface Props {
hostInfo: GetGroupDetailsResponse['createdBy'];
groupId: number;
conditions: {
isHost: boolean;
isPast: boolean;
isPending: boolean;
isFinished: boolean;
};
groupId: number;
}

export const DescriptionProfile = ({
hostInfo: { userId, nickName, profileImage, profileMessage },
conditions: { isHost, isPast },
conditions: { isHost, isPending, isFinished },
groupId,
}: Props) => {
const isEditable = isHost && !isFinished;

return (
<div className='flex-between w-full select-none'>
<Link href={`/profile/${userId}`} className='flex gap-3'>
Expand All @@ -33,8 +37,9 @@ export const DescriptionProfile = ({
{profileMessage && <p className='text-text-xs-regular text-gray-600'>{profileMessage}</p>}
</div>
</Link>
{isPast && <p className='text-text-xs-semibold pr-1 text-gray-500'>모임 마감</p>}
{isHost && !isPast && (
{isFinished && <p className='text-text-xs-semibold pr-1 text-gray-500'>모임 마감</p>}
{isPending && <PendingBadge children={'대기중'} variant='md' />}
{isEditable && (
<Link
href={`/create-group/${groupId}`}
className='text-text-xs-semibold text-mint-500 pr-1'
Expand Down
6 changes: 5 additions & 1 deletion src/components/pages/group/group-descriptions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ export const GroupDescriptions = ({
return (
<section className='bg-white px-5 pt-6 pb-4'>
<DescriptionProfile
conditions={{ isHost: myMembership?.role === 'HOST', isPast: status === 'FINISHED' }}
conditions={{
isHost: myMembership?.role === 'HOST',
isPending: myMembership?.status === 'PENDING',
isFinished: status === 'FINISHED',
}}
groupId={id}
hostInfo={createdBy}
/>
Expand Down
8 changes: 7 additions & 1 deletion src/components/pages/group/group-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useKickGroupMember } from '@/hooks/use-group/use-group-kick';
import { useLeaveGroup } from '@/hooks/use-group/use-group-leave';
import { AttendGroupPayload } from '@/types/service/group';

type ModalType = 'attend' | 'approval' | 'leave' | 'delete' | 'kick';
type ModalType = 'attend' | 'approval' | 'pending' | 'leave' | 'delete' | 'kick';

interface BaseProps {
type: Exclude<ModalType, 'kick'>;
Expand Down Expand Up @@ -46,6 +46,7 @@ export const GroupModal = (props: Props) => {
const mutateByType = {
attend: () => attendMutate(undefined),
approval: (message: AttendGroupPayload) => attendMutate(message),
pending: () => leaveMutate(),
leave: () => leaveMutate(),
delete: async () => {
await deleteMutate();
Expand Down Expand Up @@ -88,6 +89,11 @@ const MODAL_CONTENTS = {
description: '참여 신청 메세지',
confirmMessage: '신청하기',
}),
pending: () => ({
title: '참여 신청을 취소하시겠어요?',
description: '조금만 더 기다려 보는건 어떨까요?',
confirmMessage: '취소하기',
}),
leave: () => ({
title: '모임을 정말 탈퇴하시겠어요?',
description: '탈퇴 시 그룹채팅과 모임 활동이 종료돼요.',
Expand Down