Skip to content

Commit

Permalink
아티클 상세 페이지 개발 (#107)
Browse files Browse the repository at this point in the history
* fix: codegen 설정을 바꾸고 경로 수정

* chore: 대/소문자 이슈 제거

* chore: dayjs 설치

* ui fix: `Avatar` 스타일 변경

* [tailwind-config] feat: `text-` 접두어 스타일 build시 포함하도록 설정 추가

* feat: `article-tag-list` 클릭 가능/불가능 분기 처리 추가

* feat: 유저 un/follow 및 토글 버튼 추가

* feat: axios instance 분리 및 return 값 추상화

* fix: `ReactQueryStreamedHydration` wrapper 제거

* refactor: 일관된 반응형 className 분리 및 재사용

* feat: comment 관련 컴포넌트 추가

* refactor: `getLastPage`함수 분리

* fix: 좋아요 버튼을 토글로 변경

* fix: 유저 프로필 아바타 변경

* feat: ssr을 이용해 article 페이지 구현

* feat: 코멘트 로그인 유도 ui 추가

* fix: 사용하지 않는 dependency 제거

* feat: 페이지네이션 구현
  • Loading branch information
ludacirs authored Sep 14, 2023
1 parent b956672 commit 68d7634
Show file tree
Hide file tree
Showing 77 changed files with 1,916 additions and 15,398 deletions.
20 changes: 13 additions & 7 deletions apps/realworld/orval.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { defineConfig } from "orval";
import { defineConfig } from 'orval';

export default defineConfig({
myproject: {
realworld: {
output: {
mode: "single",
target: "src/shared/api/realworld/apis.ts",
schemas: "src/shared/api/realworld/models",
client: "react-query",
mode: 'tags-split',
target: 'src/shared/api/realworld/endpoints',
schemas: 'src/shared/api/realworld/models',
client: 'react-query',
prettier: true,
clean: true,
mock: true,
override: {
mutator: {
path: 'src/shared/api/realworld/axios/axiosInstance.ts',
name: 'axiosInstance',
},
},
},
input: {
target: "./realworld.json",
target: './realworld.json',
},
},
});
2 changes: 1 addition & 1 deletion apps/realworld/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
"@packages/ui": "*",
"@tanstack/eslint-plugin-query": "^4.34.1",
"@tanstack/react-query": "^4.33.0",
"@tanstack/react-query-next-experimental": "^5.0.0-alpha.80",
"@types/node": "20.5.7",
"@types/react": "18.2.21",
"@types/react-dom": "18.2.7",
"autoprefixer": "^10.4.15",
"axios": "^1.5.0",
"dayjs": "^1.11.9",
"eslint": "8.48.0",
"eslint-config-next": "13.4.19",
"next": "13.4.19",
Expand Down
62 changes: 62 additions & 0 deletions apps/realworld/src/app/article/[slug]/article.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use client';

import { InduceSignIn } from '@/entities/comment';
import { ArticleTagList } from '@/entities/tag';
import { UserProfileAvatar } from '@/entities/user';
import { useGetArticle } from '@/shared/api/realworld/endpoints/articles/articles';
import { useGetArticleComments } from '@/shared/api/realworld/endpoints/comments/comments';
import { responsiveWidth } from '@/shared/css/responsive-width';
import { ArticleFavoriteToggleButton } from '@/widgets/article';
import { UserCommentList } from '@/widgets/comment';
import { UserFollowToggleButton } from '@/widgets/user';

const Article = ({ slug }: { slug: string }) => {
const { data: articleResponse } = useGetArticle(slug, { query: { staleTime: 1000 } });
const { data: commentsResponse } = useGetArticleComments(slug, { query: { staleTime: 1000 } });
const { author, body, createdAt, favorited, favoritesCount, tagList, title } = articleResponse?.article!;
const commentList = commentsResponse?.comments!;
const formattedBody = body.replaceAll('\\n', '\n');

return (
<div className="flex flex-col justify-center w-full">
<div className="flex justify-center p-32 mb-32 text-white bg-gray1800">
<div className={`flex flex-col gap-16 ${responsiveWidth}`}>
<h1 className="font-bold text-[3.5rem] [text-shadow:_0_1px_3px_rgb(0_0_0_/0.3)] leading-none">{title}</h1>
<div className="flex items-center gap-24">
<UserProfileAvatar author={author} createdAt={createdAt} usernameColor="text-white" />
<div className="flex gap-8 button-group">
<UserFollowToggleButton following={author.following} username={author.username} />
<ArticleFavoriteToggleButton favorited={favorited} slug={slug} favoritesCount={favoritesCount} />
</div>
</div>
</div>
</div>

<div className={`w-full flex justify-center items-center flex-col`}>
<div className={`flex flex-col gap-32 ${responsiveWidth} `}>
<p className="whitespace-pre-line">{formattedBody}</p>

<ArticleTagList tagList={tagList} />
</div>

<div className={`w-full h-1 my-32 bg-gray1000 ${responsiveWidth}`} />

<div className="flex flex-col gap-32">
<div className="flex items-center justify-center gap-24">
<UserProfileAvatar author={author} createdAt={createdAt} />
<div className="flex gap-8 button-group">
<UserFollowToggleButton following={author.following} username={author.username} />
<ArticleFavoriteToggleButton favorited={favorited} slug={slug} favoritesCount={favoritesCount} />
</div>
</div>
<InduceSignIn />
<div className="w-728 max-desktop:w-595 max-tablet:w-544">
<UserCommentList commentList={commentList} />
</div>
</div>
</div>
</div>
);
};

export default Article;
27 changes: 27 additions & 0 deletions apps/realworld/src/app/article/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { getArticle, getGetArticleQueryKey } from '@/shared/api/realworld/endpoints/articles/articles';
import getQueryClient from '@/shared/utils/reactQueryClient';
import { dehydrate, Hydrate } from '@tanstack/react-query';
import Article from './article';
import { getArticleComments, getGetArticleCommentsQueryKey } from '@/shared/api/realworld/endpoints/comments/comments';

const HydratedArticle = async ({ params }: { params: { slug: string } }) => {
const { slug } = params;
const queryClient = getQueryClient();
await Promise.all([
queryClient.prefetchQuery(getGetArticleQueryKey(slug), () => getArticle(slug), {
staleTime: 1000,
}),
queryClient.prefetchQuery(getGetArticleCommentsQueryKey(slug), () => getArticleComments(slug), { staleTime: 1000 }),
]);
const dehydratedState = dehydrate(queryClient);

return (
<Hydrate state={dehydratedState}>
<div className="flex ">
<Article slug={slug} />
</div>
</Hydrate>
);
};

export default HydratedArticle;
162 changes: 0 additions & 162 deletions apps/realworld/src/app/article/page.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion apps/realworld/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { PopularTags } from '@/widgets/tags';
import { FeedToggle } from '@/widgets/tab';
import { ArticleList } from '@/widgets/article';
import { responsiveWidth } from '@/shared/css/responsive-width';

export default function Home() {
return (
Expand All @@ -12,7 +13,7 @@ export default function Home() {
</div>
</div>

<div className="w-[calc(100%_-_30px)] mx-auto max-w-1140 max-desktop:max-w-940 max-tablet:max-w-720 ">
<div className={`w-[calc(100%_-_30px)] mx-auto ${responsiveWidth}`}>
<div className="flex gap-30">
<div className="flex-[0_0_75%]">
<FeedToggle />
Expand Down
Loading

0 comments on commit 68d7634

Please sign in to comment.