Skip to content

Commit

Permalink
refactor: member page
Browse files Browse the repository at this point in the history
  • Loading branch information
stakbucks committed Apr 7, 2024
1 parent 20f5c10 commit f6b2f3b
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 116 deletions.
12 changes: 0 additions & 12 deletions src/app/(routes)/member/[memberId]/character-create-link.tsx

This file was deleted.

34 changes: 34 additions & 0 deletions src/app/(routes)/member/[memberId]/characters-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use client';

import FixedBottomArea from '@/components/fixed-bottom-area';
import CTAButton from '@/components/ui/cta-button';
import { Member } from '@/services/auth/getMember';
import { useCharactersQuery } from '@/store/query/useCharactersQuery';
import { Characters } from './characters';
import { Header } from './header';
import { MemberData } from './member-data';

type Props = {
memberId: Member['memberId'];
};

export function CharactersContainer({ memberId }: Props) {
const {
data: { characters, cheerCount, memberNickname, isMe, joinDays, memoCount },
} = useCharactersQuery(memberId);

const isMyPage = isMe;

return (
<>
<div className="flex flex-1 flex-col">
<Header cheerCount={cheerCount} memberNickname={memberNickname} isMyPage={isMyPage} />
<MemberData joinDays={joinDays} memoCount={memoCount} />
<Characters isMyPage={isMyPage} characters={characters} />
</div>
{!isMyPage && (
<FixedBottomArea contents={<CTAButton as={'Link'} href="/" text="내 캐릭터 만들러 가기" />} />
)}
</>
);
}
36 changes: 36 additions & 0 deletions src/app/(routes)/member/[memberId]/characters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { GetCharactersResponse } from '@/services/character/getCharacters';
import CharacterCard from './character-card';
import CharacterCreateButton from './character-create-button';

type Props = {
isMyPage: boolean;
characters: GetCharactersResponse['characters'];
};

const MAXIMUM_CHARACTER = 6;

export function Characters({ characters, isMyPage }: Props) {
const showCharacterCreateButton = isMyPage && characters.length < MAXIMUM_CHARACTER;

return (
<section className="flex-1 bg-[#F6F8FC] px-6 pb-[90px]">
<h2 className="mb-[10px] pt-5 text-[20px] font-bold leading-[32px] text-[#494E59]">성장 기록지</h2>
<div className="grid grid-cols-2 gap-3">
{characters?.map((character, i) => {
if (isMyPage)
return (
<CharacterCard
key={character.id}
component="link"
href={`/character/${character.id}`}
character={character}
order={i}
/>
);
return <CharacterCard order={i} key={character.id} component="div" character={character} />;
})}
{showCharacterCreateButton && <CharacterCreateButton />}
</div>
</section>
);
}
20 changes: 20 additions & 0 deletions src/app/(routes)/member/[memberId]/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { LikeButton, LikeButtonWithTooltip } from './like-button';
import { GetCharactersResponse } from '@/services/character/getCharacters';

type Props = {
isMyPage: boolean;
} & Pick<GetCharactersResponse, 'memberNickname' | 'cheerCount'>;

export function Header({ isMyPage, memberNickname, cheerCount }: Props) {
const headerText = `${memberNickname}의 도감 `;
return (
<header className="flex items-center justify-between py-5 pl-6 pr-7">
<h1 className="text-bold24 text-[#494E59]">{headerText}</h1>
{isMyPage ? (
<LikeButton component="div" cheerCount={cheerCount} />
) : (
<LikeButtonWithTooltip component="button" cheerCount={cheerCount ?? 0} />
)}
</header>
);
}
49 changes: 49 additions & 0 deletions src/app/(routes)/member/[memberId]/member-data.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import EggImage from '@/assets/images/egg.png';
import PencilImage from '@/assets/images/pencil.png';
import { GetCharactersResponse } from '@/services/character/getCharacters';
import Image from 'next/image';

type Props = Pick<GetCharactersResponse, 'joinDays' | 'memoCount'>;
export function MemberData({ joinDays, memoCount }: Props) {
return (
<section className="mb-5 px-6">
<h2 className="mb-[10px] pt-5 text-[20px] font-bold leading-[32px] text-[#494E59]">성장과정</h2>
<div className="flex justify-between gap-[10px] pb-[6px]">
<div className="flex flex-1 items-center justify-between rounded-xl bg-[#F6F8FC] px-5 py-[18px]">
<div>
<div className="text-[12px] font-medium leading-[18px] text-[#8B92A0]">성장한지</div>
<div className="text-[20px] font-bold leading-[30px] text-[#2777EA]">{joinDays}</div>
</div>
<div className="flex h-[50px] w-[50px] rounded-lg bg-white">
<Image
alt=""
objectFit="cover"
priority
width={50}
height={50}
src={EggImage}
className="rounded-lg"
/>
</div>
</div>
<div className="flex flex-1 items-center justify-between rounded-xl bg-[#F6F8FC] px-5 py-[18px]">
<div>
<div className="text-[12px] font-medium leading-[18px] text-[#8B92A0]">총 메모</div>
<div className="text-[20px] font-bold leading-[30px] text-[#2777EA]">{memoCount}</div>
</div>
<div className="flex h-[50px] w-[50px] rounded-lg bg-white">
<Image
alt=""
objectFit="cover"
priority
width={50}
height={50}
src={PencilImage}
className="rounded-lg"
/>
</div>
</div>
</div>
</section>
);
}
116 changes: 13 additions & 103 deletions src/app/(routes)/member/[memberId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,112 +1,22 @@
import EggImage from '@/assets/images/egg.png';
import PencilImage from '@/assets/images/pencil.png';
import { PageContainer } from '@/components/ui';
import A2HS from '@/hooks/useA2HS';
import getMember from '@/services/auth/getMember';
import getCharacters from '@/services/character/getCharacters';
import { cookies } from 'next/headers';
import Image from 'next/image';
import CharacterCard from './character-card';
import CharacterCreateButton from './character-create-button';
import CharacterCreateLink from './character-create-link';
import { LikeButton, LikeButtonWithTooltip } from './like-button';
import PageContainerV2 from '@/components/page-container-v2/page-container-v2';
import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query';
import { charactersQueryOptions } from '@/store/query/useCharactersQuery';
import { CharactersContainer } from './characters-container';

const MAXIMUM_CHARACTER = 6;
export default async function Home({ params: { memberId } }: { params: { memberId: number } }) {
const accessToken = `${cookies().get('accessToken')?.value}`;

export default async function Home({ params: { memberId } }: { params: { memberId: string } }) {
const accessToken = cookies().get('accessToken')?.value;

const characters = await getCharacters({
memberId: Number(memberId),
accessToken,
});

const isMyPage = characters?.isMe;
const headerText = `${characters?.memberNickname}의 도감 `;
const showCharacterCreateButton = isMyPage && characters.characters.length < MAXIMUM_CHARACTER;
const queryClient = new QueryClient();
const { isMe } = await queryClient.fetchQuery(charactersQueryOptions(accessToken, memberId));

return (
<PageContainerV2 hasNavigator={characters?.isMe}>
<div className="flex flex-1 flex-col">
<header className="flex items-center justify-between py-5 pl-6 pr-7">
<h1 className="text-bold24 text-[#494E59]">{headerText}</h1>
{isMyPage ? (
<LikeButton component="div" cheerCount={characters.cheerCount} />
) : (
<LikeButtonWithTooltip component="button" cheerCount={characters?.cheerCount ?? 0} />
)}
</header>
<section className="mb-5 px-6">
<h2 className="mb-[10px] pt-5 text-[20px] font-bold leading-[32px] text-[#494E59]">성장과정</h2>
<div className="flex justify-between gap-[10px] pb-[6px]">
<div className="flex flex-1 items-center justify-between rounded-xl bg-[#F6F8FC] px-5 py-[18px]">
<div>
<div className="text-[12px] font-medium leading-[18px] text-[#8B92A0]">성장한지</div>
<div className="text-[20px] font-bold leading-[30px] text-[#2777EA]">
{characters?.joinDays}
</div>
</div>
<div className="flex h-[50px] w-[50px] rounded-lg bg-white">
<Image
alt=""
objectFit="cover"
priority
width={50}
height={50}
src={EggImage}
className="rounded-lg"
/>
</div>
</div>
<div className="flex flex-1 items-center justify-between rounded-xl bg-[#F6F8FC] px-5 py-[18px]">
<div>
<div className="text-[12px] font-medium leading-[18px] text-[#8B92A0]">총 메모</div>
<div className="text-[20px] font-bold leading-[30px] text-[#2777EA]">
{characters?.memoCount}
</div>
</div>
<div className="flex h-[50px] w-[50px] rounded-lg bg-white">
<Image
alt=""
objectFit="cover"
priority
width={50}
height={50}
src={PencilImage}
className="rounded-lg"
/>
</div>
</div>
</div>
</section>
<section className="flex-1 bg-[#F6F8FC] px-6 pb-[90px]">
<h2 className="mb-[10px] pt-5 text-[20px] font-bold leading-[32px] text-[#494E59]">성장 기록지</h2>
<div className="grid grid-cols-2 gap-3">
{characters?.characters?.map((character, i) => {
if (isMyPage)
return (
<CharacterCard
key={character.id}
component="link"
href={`/character/${character.id}`}
character={character}
order={i}
/>
);
return <CharacterCard order={i} key={character.id} component="div" character={character} />;
})}
{showCharacterCreateButton && <CharacterCreateButton />}
</div>
</section>
</div>

{!isMyPage && (
<div className="fixed bottom-0 left-0 right-0 z-10 flex justify-center py-4">
<CharacterCreateLink />
</div>
)}
<A2HS />
</PageContainerV2>
<HydrationBoundary state={dehydrate(queryClient)}>
<PageContainerV2 hasNavigator={isMe}>
<CharactersContainer memberId={memberId} />
<A2HS />
</PageContainerV2>
</HydrationBoundary>
);
}
2 changes: 1 addition & 1 deletion src/services/character/getCharacters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type GetCharactersRequest = {
accessToken?: string;
};

export default async function getCharacters(request: GetCharactersRequest): Promise<GetCharactersResponse | undefined> {
export default async function getCharacters(request: GetCharactersRequest): Promise<GetCharactersResponse> {
try {
const res = await fetch(
`${process.env.NEXT_PUBLIC_SERVER_BASE_URL}/api/v1/character/member/${request.memberId}`,
Expand Down
19 changes: 19 additions & 0 deletions src/store/query/useCharactersQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Member } from '@/services/auth/getMember';
import getCharacters, { GetCharactersResponse } from '@/services/character/getCharacters';
import { BasicSuspenseQueryOptions } from '@/types/query';
import { useSuspenseQuery } from '@tanstack/react-query';
import { getCookie } from 'cookies-next';

export const charactersQueryOptions = (
accessToken: string,
memberId: Member['memberId'],
): BasicSuspenseQueryOptions<GetCharactersResponse> => ({
queryKey: ['characters', memberId],
queryFn: () => getCharacters({ memberId, accessToken }),
});

export function useCharactersQuery(memberId: Member['memberId']) {
return useSuspenseQuery({
...charactersQueryOptions(`${getCookie('accessToken')}`, memberId),
});
}

0 comments on commit f6b2f3b

Please sign in to comment.