Skip to content

Commit

Permalink
Merge pull request #282 from gloddy-dev/feature/281-refactoring-group…
Browse files Browse the repository at this point in the history
…-member-page

Feature : 모임 멤버 조회 페이지 리팩토링
  • Loading branch information
kangju2000 authored Aug 30, 2023
2 parents 432e633 + dd7a5ad commit f263c60
Show file tree
Hide file tree
Showing 39 changed files with 382 additions and 153 deletions.
4 changes: 4 additions & 0 deletions public/icons/16/hood.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/icons/16/mate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/icons/16/soulmate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion src/apis/groups/apis.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import privateApi from '../config/privateApi';

import type {
AppliesResponse,
Article,
ArticleRequest,
ArticlesResponse,
CommentRequest,
CommentsReponse,
CreateGroupRequest,
CreateGroupResponse,
GroupDetailResponse,
GroupMembersResponse,
GroupsResponse,
Expand All @@ -22,7 +24,7 @@ export const getGroupDetail = (groupId: number) => {
};

export const postCreateGroup = (CreateGroupData: CreateGroupRequest) => {
return privateApi.post('/group-create', CreateGroupData);
return privateApi.post<CreateGroupResponse>('/group-create', CreateGroupData);
};

export const getArticles = (groupId: number, page: number) => {
Expand Down Expand Up @@ -60,3 +62,7 @@ export const getGroupMembers = (groupId: number) => {
export const getNotice = (groupId: number) => {
return privateApi.get<Notice[]>(`/groups/${groupId}/articles/notice`);
};

export const getApplies = (groupId: number) => {
return privateApi.get<AppliesResponse>(`/groups/${groupId}/applies`);
};
1 change: 1 addition & 0 deletions src/apis/groups/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export const Keys = Object.freeze({
getComments: (groupId: number, articleId: number) => ['getComments', groupId, articleId],
getGroupMembers: (groupId: number) => ['getGroupMembers', groupId],
getNotice: (groupId: number) => ['getNotice', groupId],
getApplies: (groupId: number) => ['getApplies', groupId],
});
7 changes: 6 additions & 1 deletion src/apis/groups/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';

export const usePostCreateGroup = () => {
return useMutation(postCreateGroup);
const router = useRouter();
return useMutation(postCreateGroup, {
onSuccess: (data) => {
router.push(`/grouping/${data.groupId}`);
},
});
};

export const usePostArticle = (groupId: number) => {
Expand Down
5 changes: 5 additions & 0 deletions src/apis/groups/queries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
getApplies,
getArticle,
getArticles,
getComments,
Expand Down Expand Up @@ -63,3 +64,7 @@ export const useGetGroupMembers = (groupId: number) => {
export const useGetNotice = (groupId: number) => {
return useSuspenseQuery(Keys.getNotice(groupId), () => getNotice(groupId));
};

export const useGetApplies = (groupId: number) => {
return useSuspenseQuery(Keys.getApplies(groupId), () => getApplies(groupId));
};
31 changes: 27 additions & 4 deletions src/apis/groups/type.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { ReliabilityType } from '@/types';

export interface Grouping {
groupId: number;
imageUrl: string;
title: string;
content: string;
memberCount: number;
maxUser: number;
maxMemberCount: number;
maxUser: number; // 삭제 예정
place: string;
meetDate: string; // '2021-08-01'
startTime: string; // '19:00'
Expand Down Expand Up @@ -59,11 +62,15 @@ export interface CreateGroupRequest {
endTime: string;
placeName: string;
placeAddress: string;
placeLatitude: string;
placeLongitude: string;
place_latitude: string;
place_longitude: string;
maxUser: number;
}

export interface CreateGroupResponse {
groupId: number;
}

export interface ArticleRequest {
groupId: number;
article: Pick<Article, 'content' | 'notice' | 'images'>;
Expand Down Expand Up @@ -93,7 +100,7 @@ export interface GroupMember {
userId: number;
nickName: string;
imageUrl: string;
reliabilityLevel: string; // TODO: 리터럴로 변경
reliabilityLevel: ReliabilityType;
}

export interface GroupMembersResponse {
Expand All @@ -104,3 +111,19 @@ export interface Notice {
noticeId: number;
content: string;
}

export interface Apply {
userId: number;
userNickname: string;
userImageUrl: string;
reliabilityLevel: ReliabilityType;
introduce: string;
reason: string;
}

export interface ApplyRequest extends Pick<Apply, 'introduce' | 'reason'> {}

export interface AppliesResponse {
totalCount: number;
applies: Apply[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ArticleHeader from './components/ArticleHeader.client';
import CommentForm from './components/CommentForm';
import { Keys, getArticle } from '@/apis/groups';
import { RejectedFallback } from '@/components/common/ErrorBoundary';
import { HydrationProvider } from '@/components/common/Provider/HydrationProvider';
import { HydrationProvider } from '@/components/common/Provider';
import { Spacing } from '@/components/common/Spacing';
import { QueryAsyncBoundary } from '@suspensive/react-query';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useGetGroupDetail } from '@/apis/groups';
import { BottomFixedDiv } from '@/components/BottomFixedDiv';
import { Button, ButtonGroup, FloatAddButton } from '@/components/Button';
import { Spacing } from '@/components/common/Spacing';
import { Divider } from '@/components/Divider';
import { Tabs } from '@/components/Tabs';
import Link from 'next/link';

Expand All @@ -21,9 +22,10 @@ export default function GroupingDetail({ groupId }: GroupingDetailProps) {
const { myGroup } = groupDetailData;

return (
<main className="bg-white">
<>
<GroupingHeader />
<TopSection />
<Divider />
<Tabs>
<Tabs.List>
<Tabs.Tab value="detail" text="상세정보" />
Expand Down Expand Up @@ -60,6 +62,6 @@ export default function GroupingDetail({ groupId }: GroupingDetailProps) {
</Button>
</ButtonGroup>
)}
</main>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import { Flex } from '@/components/Layout';
import { useNumberParams } from '@/hooks/useNumberParams';
import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/navigation';

export default function GroupingHeader() {
const { groupId } = useNumberParams<['groupId']>();
const router = useRouter();

const { data: groupDetailData } = useGetGroupDetail(groupId);
const { title, isCaptain } = groupDetailData;
Expand All @@ -20,9 +18,11 @@ export default function GroupingHeader() {
<Header className="px-4">
<Header.Left>
<Flex align="center">
<IconButton size="large" onClick={() => router.back()}>
<Image src="/icons/24/arrow_back.svg" alt="back" width={24} height={24} />
</IconButton>
<Link href="/grouping">
<IconButton size="large">
<Image src="/icons/24/arrow_back.svg" alt="back" width={24} height={24} />
</IconButton>
</Link>
<p>{title}</p>
</Flex>
</Header.Left>
Expand All @@ -35,9 +35,6 @@ export default function GroupingHeader() {
</IconButton>
</Link>
)}
<IconButton size="large" onClick={() => console.log('더보기')}>
<Image src="/icons/24/more.svg" alt="more" width={24} height={24} />
</IconButton>
</Flex>
</Header.Right>
</Header>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
import { useGetGroupDetail } from '@/apis/groups';
import { Spacing } from '@/components/common/Spacing';
import { useNumberParams } from '@/hooks/useNumberParams';
import { useShowMore } from '@/hooks/useShowMore';
import Image from 'next/image';

export default function TopSection() {
const { groupId } = useNumberParams<['groupId']>();
const { contentRef, toggleShowFullText, shouldShowButton, showFullText } = useShowMore({
maxLines: 6,
});

const { data: groupDetailData } = useGetGroupDetail(groupId);
const { imageUrl, title, content } = groupDetailData;
Expand All @@ -19,7 +23,18 @@ export default function TopSection() {
<div className="px-20">
<h4 className="text-h4 text-sign-cto">{title}</h4>
<Spacing size={8} />
<p className="text-paragraph-2 text-sign-secondary">{content}</p>
<div ref={contentRef} className="text-paragraph-2 text-sign-secondary">
{showFullText ? content : content.split('\n').slice(0, 6).join('\n')}
</div>
<Spacing size={4} />
{shouldShowButton && (
<button
className="p-2 text-subtitle-2 text-sign-sub"
onClick={() => toggleShowFullText()}
>
{showFullText ? '접기' : '더보기'}
</button>
)}
</div>
<Spacing size={20} />
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@

import { useGetGroupDetail } from '@/apis/groups';
import { Spacing } from '@/components/common/Spacing';
import { Toast } from '@/components/Modal';
import { useModal } from '@/hooks/useModal';
import { useNumberParams } from '@/hooks/useNumberParams';
import Image from 'next/image';
import { Map, MapMarker } from 'react-kakao-maps-sdk';

export default function LocationSection() {
const { groupId } = useNumberParams<['groupId']>();
const { data: groupDetailData } = useGetGroupDetail(groupId);
const { place, placeLatitude, placeLongitude } = groupDetailData;
const { place, placeLatitude, placeLongitude, placeAddress } = groupDetailData;

const { open } = useModal({ delay: 2000 });

const handleClipboardClick = () => {
navigator.clipboard
.writeText(placeAddress)
.then(() => open(<Toast>주소가 복사되었습니다.</Toast>))
.catch(() => open(<Toast>주소 복사에 실패했습니다.</Toast>));
};

return (
<section>
Expand All @@ -22,31 +33,31 @@ export default function LocationSection() {
width={24}
height={24}
className="absolute right-12 top-12 z-10"
onClick={() => console.log('복사')}
onClick={handleClipboardClick}
/>
<Map
center={{
lat: +placeLatitude,
lng: +placeLongitude,
lat: +placeLatitude || 37.595706,
lng: +placeLongitude || 127.052574,
}}
className="aspect-video rounded-t-8"
level={4}
draggable={false}
>
<MapMarker
position={{
lat: +placeLatitude,
lng: +placeLongitude,
lat: +placeLatitude || 37.595706,
lng: +placeLongitude || 127.052574,
}}
/>
</Map>
<div className="p-16">
<p>
<span className="text-subtitle-2 text-sign-primary">경희회관</span>{' '}
<span className="text-caption text-sign-sub">호프, 요리주점</span>
<span className="text-subtitle-2">{place || '경희회관'}</span>
{/* <span className="pl-4 text-caption text-sign-sub">호프, 요리주점</span> */}
</p>
<Spacing size={2} />
<p className="text-paragraph-2 text-sign-secondary">{place}</p>
<p className="text-paragraph-2 text-sign-secondary">{placeAddress}</p>
</div>
</div>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function MemberSection() {
const pathname = usePathname();

const { data: groupDetailData } = useGetGroupDetail(groupId);
const { maxUser, memberCount } = groupDetailData;
const { memberCount, maxMemberCount } = groupDetailData;

const { data: groupMembersData } = useGetGroupMembers(groupId);
const { groupMembers } = groupMembersData;
Expand All @@ -22,7 +22,7 @@ export default function MemberSection() {
<section>
<div className="flex items-center justify-between">
<p className="pl-4 text-subtitle-3 text-sign-secondary">
모임 멤버 ({memberCount}/{maxUser})
모임 멤버 ({memberCount}/{maxMemberCount})
</p>
<div
className="flex cursor-pointer items-center text-caption text-sign-caption"
Expand All @@ -35,7 +35,12 @@ export default function MemberSection() {
<Spacing size={20} />
<div className="flex items-center gap-16 overflow-x-scroll">
{groupMembers.map((member) => (
<Avatar key={member.userId} imageUrl={member.imageUrl} iconVariant="education">
<Avatar
key={member.userId}
imageUrl={member.imageUrl ?? '/dummy_avatar.png'}
iconVariant="education"
onClick={() => router.push(`${pathname}/members`)}
>
<Avatar.Name isCaptain={member.isCaptain}>{member.nickName}</Avatar.Name>
</Avatar>
))}
Expand Down
Loading

0 comments on commit f263c60

Please sign in to comment.