Skip to content

✨ v1.2.0 - 상세페이지 북마크 #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 11, 2024
6 changes: 3 additions & 3 deletions public/icons/bookmark_black_empty.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/apis/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const getPosePick = (peopleCount: number) =>
publicApi.get<PosePickResponse>(`/pose/pick/${peopleCount}`);

export const getPoseDetail = (poseId: number) =>
publicApi.get<PoseDetailResponse>(`/pose/${poseId}`);
privateApi.get<PoseDetailResponse>(`/pose/${poseId}`);

export const getPoseTalk = () => publicApi.get<PoseTalkResponse>('/pose/talk');

Expand Down
3 changes: 2 additions & 1 deletion src/apis/config/privateApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const privateApi: CustomInstance = axios.create({
privateApi.interceptors.response.use(
(response) => response.data,
(error) => {
const status = error.response.status;
const status = error.response?.status;
console.log('🚀 ~ status:', status);
if (status === ERROR_UNAUTHORIZED || status === ERROR_UNSUPPORTED_MEDIA_TYPE) {
alert('세션이 만료되었어요. 다시 로그인이 필요해요!');
removeClientCookie(COOKIE_ACCESS_TOKEN);
Expand Down
7 changes: 5 additions & 2 deletions src/apis/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import {
FilterTagsResponse,
MyposeCountResponse,
PoseDetailResponse,
PoseFeedContents,
PoseFeedResponse,
PosePickResponse,
Expand All @@ -22,8 +23,10 @@ import {
} from '.';
import { FilterState } from '@/hooks/useFilterState';

export const usePoseDetailQuery = (poseId: number) =>
useQuery(['poseId', poseId], () => getPoseDetail(poseId));
export const usePoseDetailQuery = (
{ poseId }: { poseId: number },
options?: UseQueryOptions<PoseDetailResponse>
) => useQuery<PoseDetailResponse>(['poseId', poseId], () => getPoseDetail(poseId), options);

export const usePosePickQuery = (
peopleCount: number,
Expand Down
16 changes: 3 additions & 13 deletions src/apis/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export interface PoseInfo {
tagAttributes: string;
updatedAt: string;
bookmarkCheck: boolean;
width: number;
height: number;
width?: number;
height?: number;
Comment on lines +12 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

width와 height는 선택 조건으로 바뀐건가요 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네! 백엔드에서 같은 포즈데이터에 대해 상세페이지에서는 width와 height를 보내주지 않고, 피드에서는 보내주는 형태라서 변경했습니다 :) 현재 백엔드에 요청드린 상태인데, 추후에 상세페이지에도 사이즈 정보를 같이 보내주게 바꿔주시면 그때 다시 바꿀 에정입니답

}

// 포즈피드
Expand Down Expand Up @@ -60,17 +60,7 @@ export interface PosePickResponse {
}

export interface PoseDetailResponse {
poseInfo: {
createdAt: string;
frameCount: number;
imageKey: string;
peopleCount: number;
poseId: number;
source: string;
sourceUrl: string;
tagAttributes: string;
updatedAt: string;
};
poseInfo: PoseInfo;
}

export interface PoseTalkResponse {
Expand Down
1 change: 1 addition & 0 deletions src/app/(Main)/MainFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function MainFooter({ children, grow = true }: MainFooterI) {
{isIOS() && <AppDownloadBanner />}
</div>
<div className="h-88" />
{isIOS() && <div className="h-62" />}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS는 높이가 62px 더 필요한가요 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네네 하단에 앱 다운로드 배너가 있어서 해당 배너만큼의 높이가 필요합니다!

</>
);
}
16 changes: 5 additions & 11 deletions src/app/(Main)/mypose/MyposeTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useState } from 'react';

import { useMyposeCountQuery } from '@/apis';
import { COOKIE_ACCESS_TOKEN } from '@/constants';
Expand Down Expand Up @@ -37,27 +36,22 @@ export default function MyposeTab() {
const path = usePathname();
const accesstoken = getClientCookie(COOKIE_ACCESS_TOKEN);

const [countData, setCountData] = useState({ uploadCount: 0, bookmarkCount: 0 });

const query = useMyposeCountQuery({
enabled: accesstoken !== '',
onSuccess: (data) => {
setCountData(data);
},
});
const { data: countData } = useMyposeCountQuery({ enabled: accesstoken !== '' });
const uploadCount = countData === undefined ? 0 : countData.uploadCount;
const bookmarkCount = countData === undefined ? 0 : countData.bookmarkCount;

return (
<div className="h-72 px-20 py-12">
<div className="flex h-full gap-4 rounded-8 bg-divider p-4 ">
<TabItem
key="upload"
title={`${Data.upload.title} ${countData.uploadCount}`}
title={`${Data.upload.title} ${uploadCount}`}
path={Data.upload.path}
current={path === Data.upload.path}
/>
<TabItem
key="bookmark"
title={`${Data.bookmark.title} ${countData.bookmarkCount}`}
title={`${Data.bookmark.title} ${bookmarkCount}`}
path={Data.bookmark.path}
current={path === Data.bookmark.path}
/>
Expand Down
12 changes: 10 additions & 2 deletions src/app/(Sub)/detail/[id]/DetailSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import TagButton from './TagButton';
import { usePoseDetailQuery } from '@/apis';
import { MainFooter } from '@/app/(Main)/MainFooter';
import { PrimaryButton } from '@/components/Button';
import BookmarkButton from '@/components/Feed/BookmarkButton';
import Header from '@/components/Header';
import { Popup } from '@/components/Modal';
import PoseImage from '@/components/Modal/PoseImage';
import { useOverlay } from '@/components/Overlay/useOverlay';
Expand All @@ -20,15 +22,16 @@ interface DetailSectionProps {
}

export default function DetailSection({ poseId }: DetailSectionProps) {
const { data } = usePoseDetailQuery(poseId);
const { data } = usePoseDetailQuery({ poseId });
const { shareKakao } = useKakaoShare();
const { open } = useOverlay();
const pathname = usePathname();

const [isRendered, setIsRendered] = useState(false);

if (!data) return null;
const { imageKey, tagAttributes, source, sourceUrl, peopleCount, frameCount } = data.poseInfo;
const { imageKey, tagAttributes, source, sourceUrl, peopleCount, frameCount, bookmarkCheck } =
data.poseInfo;

const handleShareLink = async () => {
await copy(BASE_SITE_URL + pathname);
Expand All @@ -41,6 +44,11 @@ export default function DetailSection({ poseId }: DetailSectionProps) {

return (
<div>
<Header
close={true}
menu={true}
additional={<BookmarkButton poseId={poseId} isMarked={bookmarkCheck} style="black" />}
/>
{source && <Source source={source} url={sourceUrl} />}
<div className="block">
{isRendered || <div className="h-400 w-screen bg-sub-white" />}
Expand Down
40 changes: 1 addition & 39 deletions src/app/(Sub)/detail/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,11 @@
import { QueryAsyncBoundary } from '@suspensive/react-query';
import { Metadata } from 'next';

import DetailSection from './DetailSection';
import { getPoseDetail } from '@/apis';
import { RejectedFallback } from '@/components/ErrorBoundary';
import Header from '@/components/Header';
import { Loading } from '@/components/Loading';
import { PageAnimation } from '@/components/PageAnimation';
import { HydrationProvider } from '@/components/Provider';
import { OPEN_GRAPH } from '@/constants';

export async function generateMetadata({ params }: { params: { id: string } }): Promise<Metadata> {
const id = parseInt(params.id);
const {
poseInfo: { peopleCount, frameCount, tagAttributes },
} = await getPoseDetail(id);
const description = `${tagAttributes},${frameCount}컷,${peopleCount}인 포즈추천`;

return {
description,
openGraph: {
title: OPEN_GRAPH.detail.title,
description: OPEN_GRAPH.detail.description,
images: [OPEN_GRAPH.detail.image],
},
};
}

export default function DetailPage({ params }: { params: { id: number } }) {
const { id } = params;

return (
<div>
{/* <Header close={true} menu={true} additional={<BookmarkButton style='black'/>} /> */}
<Header close={true} menu={true} />
<QueryAsyncBoundary
rejectedFallback={RejectedFallback}
pendingFallback={<Loading className="h-[calc(100dvh-400px)]" />}
>
<PageAnimation>
<HydrationProvider queryKey={['poseId', id]} queryFn={() => getPoseDetail(id)}>
<DetailSection poseId={id} />
</HydrationProvider>
</PageAnimation>
</QueryAsyncBoundary>
<DetailSection poseId={id} />
</div>
);
}
1 change: 0 additions & 1 deletion src/components/Feed/Photo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ interface PhotoI {
export default function Photo({ data }: PhotoI) {
const { imageKey, source, bookmarkCheck, poseId, width, height } = data;
const [loaded, setLoaded] = useState(false);
console.log(width / height);

return (
<div className="relative mb-16 inline-block w-full rounded-8">
Expand Down
10 changes: 7 additions & 3 deletions src/utils/cookie.client.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { isServer } from './isServer';

export const setClientCookie = (key: string, value: string, options?: { expires?: Date }) => {
document.cookie = `${key}=${value}; path=/; ${
options?.expires ? `expires=${options.expires.toUTCString()}` : ''
}`;
};

export const getClientCookie = (key: string) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${key}=`);
if (isServer) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${key}=`);

return parts.pop()?.split(';').shift();
return parts.pop()?.split(';').shift();
}
};

export const removeClientCookie = (key: string) => {
Expand Down