Skip to content

Commit

Permalink
feat : 블로그 페이지 Suspense 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
f0rever0 committed Nov 6, 2023
1 parent 74598ac commit 3a7434d
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 73 deletions.
53 changes: 10 additions & 43 deletions src/views/BlogPage/BlogPage.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { css } from '@emotion/react';
import { Suspense } from 'react';
import PageLayout from '@src/components/common/PageLayout';
import useStorage from '@src/hooks/useStorage';
import { activeGenerationCategoryList } from '@src/lib/constants/tabs';
import { PartCategoryType } from '@src/lib/types/blog';
import BlogPostSkeletonUI from '@src/views/BlogPage/components/BlogPostSkeletonUI';
import { OvalSpinner } from '@src/views/ProjectPage/components';
import BlogPostList from './components/BlogPostList';
import BlogTab from './components/BlogTab';
import { BlogTabType } from './components/BlogTab/types';
import { useGetResponse } from './hooks/queries/useGetResponse';
import useInfiniteScroll from './hooks/useInfiniteScroll';
import * as S from './style';

export default function BlogPage() {
const [selectedTab, setSelectedTab] = useStorage(
Expand All @@ -29,17 +26,7 @@ export default function BlogPage() {
PartCategoryType.ALL,
);

const { response, hasNextPage, fetchNextPage, isFetching } = useGetResponse(
selectedTab,
selectedMajorCategory,
selectedSubCategory,
);
const { ref } = useInfiniteScroll(fetchNextPage);

const showTotalPostList = () => {
setMajorCategory(activeGenerationCategoryList[0]);
setSubCategory(PartCategoryType.ALL);
};
const selected = { selectedTab, selectedMajorCategory, selectedSubCategory };

return (
<PageLayout
Expand All @@ -50,38 +37,18 @@ export default function BlogPage() {
`}
>
<BlogTab
selectedTab={selectedTab}
selected={selected}
setSelectedTab={setSelectedTab}
selectedMajorCategory={selectedMajorCategory}
setMajorCategory={setMajorCategory}
selectedSubCategory={selectedSubCategory}
setSubCategory={setSubCategory}
/>
{!response ? (
<BlogPostSkeletonUI />
) : (
<>
{response.length === 0 ? (
<S.EmptyBlogPostListWrapper>
<S.EmptyBlogPostList>
{`아직 올라온 ${selectedTab === 'article' ? '아티클이' : '활동후기가'} 없어요`}
</S.EmptyBlogPostList>
<S.Total onClick={showTotalPostList}>{`${
selectedTab === 'article' ? '아티클' : '활동후기'
} 전체 보기`}</S.Total>
</S.EmptyBlogPostListWrapper>
) : (
<>
<BlogPostList selectedTap={selectedTab} blogPostList={response} />
{(hasNextPage || isFetching) && (
<S.SpinnerWrapper ref={hasNextPage ? ref : undefined}>
<OvalSpinner />
</S.SpinnerWrapper>
)}
</>
)}
</>
)}
<Suspense fallback={<BlogPostSkeletonUI />}>
<BlogPostList
selected={selected}
setMajorCategory={setMajorCategory}
setSubCategory={setSubCategory}
/>
</Suspense>
</PageLayout>
);
}
6 changes: 3 additions & 3 deletions src/views/BlogPage/components/BlogPost/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import DefaultProfileImage from '@src/views/BlogPage/components/BlogPost/Default
import * as S from './style';

interface HeaderProps {
selectedTap: string;
selectedTab: string;
blogPost: BlogPostType;
}

export default function Header({ selectedTap, blogPost }: HeaderProps) {
export default function Header({ selectedTab, blogPost }: HeaderProps) {
return (
<S.Header>
{selectedTap === 'article' ? (
{selectedTab === 'article' ? (
<>
<S.Profile>
{blogPost.authorProfileImageUrl ? (
Expand Down
10 changes: 5 additions & 5 deletions src/views/BlogPage/components/BlogPost/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import * as S from './style';
const TWO_LINE_TITLE_HEIGHT = 72;

interface BlogPostProps {
selectedTap: string;
selectedTab: string;
blogPost: BlogPostType;
}

export default function BlogPost({ selectedTap, blogPost }: BlogPostProps) {
export default function BlogPost({ selectedTab, blogPost }: BlogPostProps) {
const titleRef = useRef<HTMLDivElement>(null);
const [descriptionLine, setDescriptionLine] = useState(1);
const [error, setError] = useState(false);
Expand All @@ -33,12 +33,12 @@ export default function BlogPost({ selectedTap, blogPost }: BlogPostProps) {
return (
<S.BlogPost
onClick={() => {
track(`click_${selectedTap}_detail`);
track(`click_${selectedTab}_detail`);
window.open(blogPost.url);
}}
>
<div>
<Header selectedTap={selectedTap} blogPost={blogPost} />
<Header selectedTab={selectedTab} blogPost={blogPost} />
<S.Body>
<S.Title ref={titleRef}>{blogPost.title}</S.Title>
<S.Description descriptionLine={descriptionLine}>{blogPost.description}</S.Description>
Expand All @@ -65,7 +65,7 @@ export default function BlogPost({ selectedTap, blogPost }: BlogPostProps) {
placeholder="blur"
blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mPU0zOtBwACNQES9P3nGQAAAABJRU5ErkJggg=="
/>
{selectedTap === 'article' && <Like blogPost={blogPost} />}
{selectedTab === 'article' && <Like blogPost={blogPost} />}
</S.ThumbnailWrapper>
</S.BlogPost>
);
Expand Down
54 changes: 45 additions & 9 deletions src/views/BlogPage/components/BlogPostList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,54 @@
import type { BlogPostType } from '@src/lib/types/blog';
import type { PartCategoryType } from '@src/lib/types/blog';
import BlogPost from '@src/views/BlogPage/components/BlogPost';
import { OvalSpinner } from '@src/views/ProjectPage/components';
import { useGetResponse } from '../../hooks/queries/useGetResponse';
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
import { selectedType } from '../BlogTab/types';
import EmptyBlogPostList from '../EmptyBlogPostList';
import * as S from './style';

interface BlogPostListProps {
selectedTap: string; // review || article
blogPostList: BlogPostType[];
selected: selectedType;
setMajorCategory: (newValue: number) => void;
setSubCategory: (newValue: PartCategoryType) => void;
}

export default function BlogPostList({ selectedTap, blogPostList }: BlogPostListProps) {
export default function BlogPostList({
selected,
setMajorCategory,
setSubCategory,
}: BlogPostListProps) {
const { selectedTab, selectedMajorCategory, selectedSubCategory } = selected;

const { response, hasNextPage, fetchNextPage, isFetching } = useGetResponse(
selectedTab,
selectedMajorCategory,
selectedSubCategory,
);
const { ref } = useInfiniteScroll(fetchNextPage);

return (
<S.BlogPostList>
{blogPostList?.map((blogPost) => (
<BlogPost key={blogPost.id} blogPost={blogPost} selectedTap={selectedTap} />
))}
</S.BlogPostList>
<>
{response?.length == 0 ? (
<EmptyBlogPostList
selectedTab={selectedTab}
setMajorCategory={setMajorCategory}
setSubCategory={setSubCategory}
/>
) : (
<>
<S.BlogPostList>
{response?.map((blogPost) => (
<BlogPost key={blogPost.id} blogPost={blogPost} selectedTab={selectedTab} />
))}
</S.BlogPostList>
{(hasNextPage || isFetching) && (
<S.SpinnerWrapper ref={hasNextPage ? ref : undefined}>
<OvalSpinner />
</S.SpinnerWrapper>
)}
</>
)}
</>
);
}
7 changes: 7 additions & 0 deletions src/views/BlogPage/components/BlogPostList/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ export const BlogPostList = styled.div`
gap: 36px;
}
`;

export const SpinnerWrapper = styled.section`
display: flex;
justify-content: center;
align-items: center;
margin: 50px 0;
`;
11 changes: 5 additions & 6 deletions src/views/BlogPage/components/BlogTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@ import {
import { PartCategoryType } from '@src/lib/types/blog';
import * as S from './style';
import { BlogTabMap, BlogTabType } from './types';
import { selectedType } from './types';

interface BlogTanProps {
selectedTab: BlogTabType;
selected: selectedType;
setSelectedTab: (newValue: BlogTabType) => void;
selectedMajorCategory: number;
setMajorCategory: (newValue: number) => void;
selectedSubCategory: PartCategoryType;
setSubCategory: (newValue: PartCategoryType) => void;
}
export default function BlogTab({
selectedTab,
selected,
setSelectedTab,
selectedMajorCategory,
setMajorCategory,
selectedSubCategory,
setSubCategory,
}: BlogTanProps) {
const { selectedTab, selectedMajorCategory, selectedSubCategory } = selected;

const blogTabList: BlogTabMap = {
review: {
title: '활동후기',
Expand Down
8 changes: 8 additions & 0 deletions src/views/BlogPage/components/BlogTab/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { PartCategoryType } from '@src/lib/types/blog';

export enum BlogTabType {
REVIEW = 'review',
ARTICLE = 'article',
Expand All @@ -9,3 +11,9 @@ type BlogTabContent = {
};

export type BlogTabMap = Record<BlogTabType, BlogTabContent>;

export type selectedType = {
selectedTab: BlogTabType;
selectedMajorCategory: number;
selectedSubCategory: PartCategoryType;
};
31 changes: 31 additions & 0 deletions src/views/BlogPage/components/EmptyBlogPostList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { activeGenerationCategoryList } from '@src/lib/constants/tabs';
import { PartCategoryType } from '@src/lib/types/blog';
import { BlogTabType } from '../BlogTab/types';
import * as S from './style';

interface EmptyBlogPostListProps {
selectedTab: BlogTabType;
setMajorCategory: (newValue: number) => void;
setSubCategory: (newValue: PartCategoryType) => void;
}
export default function EmptyBlogPostList({
selectedTab,
setMajorCategory,
setSubCategory,
}: EmptyBlogPostListProps) {
const showTotalPostList = () => {
setMajorCategory(activeGenerationCategoryList[0]);
setSubCategory(PartCategoryType.ALL);
};

return (
<S.EmptyBlogPostListWrapper>
<S.EmptyBlogPostList>
{`아직 올라온 ${selectedTab === 'article' ? '아티클이' : '활동후기가'} 없어요`}
</S.EmptyBlogPostList>
<S.Total onClick={showTotalPostList}>{`${
selectedTab === 'article' ? '아티클' : '활동후기'
} 전체 보기`}</S.Total>
</S.EmptyBlogPostListWrapper>
);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import styled from '@emotion/styled';
import { colors } from '@sopt-makers/colors';

export const SpinnerWrapper = styled.section`
display: flex;
justify-content: center;
align-items: center;
margin: 50px 0;
`;

export const EmptyBlogPostListWrapper = styled.section`
display: flex;
flex-direction: column;
Expand Down

0 comments on commit 3a7434d

Please sign in to comment.