diff --git a/.eslintrc.js b/.eslintrc.js index 24e3d874..fcb2e1bf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -63,5 +63,5 @@ module.exports = { settings: { 'import/external-module-folders': ['.yarn'], }, - ignorePatters: ['orval.config.js', '**/_generated/**/*'], + ignorePatterns: ['orval.config.js', '**/_generated/**/*'], } diff --git a/apps/next-app/src/components/common/FeedItem/hooks/useReadPost.ts b/apps/next-app/src/components/common/FeedItem/hooks/useReadPost.ts index 6add8124..db6404d0 100644 --- a/apps/next-app/src/components/common/FeedItem/hooks/useReadPost.ts +++ b/apps/next-app/src/components/common/FeedItem/hooks/useReadPost.ts @@ -3,7 +3,7 @@ import produce from 'immer' import { CACHE_KEYS } from 'services/cacheKeys' import { submitViewedPost } from 'services/feeds' -import type { Feed, Post, SubmitViewedPost } from 'types/feeds' +import type { Feed, SubmitViewedPost } from 'types/feeds' import { mergeObjectsByMutate } from 'utils/common' interface PrevDataType { @@ -11,7 +11,8 @@ interface PrevDataType { pageParams: Array } -const useReadPost = (item: Post) => { +// TODO: 인자타입 임시 변경. 추후에 useReadPost 자체를 재작성 해야 함. 기존 인자타입 Post (types/feeds) +const useReadPost = (item: { id: number }) => { const client = useQueryClient() const { mutate: handleRead } = useMutation({ diff --git a/apps/next-app/src/components/common/FeedItem/hooks/useToggleLike.ts b/apps/next-app/src/components/common/FeedItem/hooks/useToggleLike.ts index bbeb1a47..3a714a6c 100644 --- a/apps/next-app/src/components/common/FeedItem/hooks/useToggleLike.ts +++ b/apps/next-app/src/components/common/FeedItem/hooks/useToggleLike.ts @@ -3,9 +3,9 @@ import { useMutation, useQueryClient } from '@tanstack/react-query' import Toast from 'components/common/Toast' import { CACHE_KEYS } from 'services/cacheKeys' import { likePost, unlikePost } from 'services/feeds' -import type { PrivatePost } from 'types/feeds' -const useToggleLike = (item: PrivatePost) => { +// TODO: 추후에 useToggleLike 자체를 재작성해야 함. 임시로 인자 타입 변경 +const useToggleLike = (item: { id: number; isLiked: boolean }) => { const client = useQueryClient() const { mutate: handleLike } = useMutation({ diff --git a/apps/next-app/src/features/post/ui/PostFeedItem/PostFeedItem.style.tsx b/apps/next-app/src/features/post/ui/PostFeedItem/PostFeedItem.style.tsx new file mode 100644 index 00000000..58e1f1df --- /dev/null +++ b/apps/next-app/src/features/post/ui/PostFeedItem/PostFeedItem.style.tsx @@ -0,0 +1,60 @@ +import Image from 'next/image' +import styled from 'styled-components' + +import { ellipsis, getTypographyStyles } from 'styles/fonts' + +export const Container = styled.div` + border-top-right-radius: 32px; + border-top-left-radius: 32px; + border-bottom-right-radius: 32px; + border-bottom-left-radius: 0px; + overflow: hidden; +` + +export const Body = styled.div` + background-color: var(--color-surface-container-lowest); + padding: 20px; + display: flex; + justify-content: space-between; +` + +export const Footer = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 20px 16px; + background-color: var(--color-surface-container-lowest); + border-top: 1px solid var(--color-divider); +` + +export const Title = styled.p` + ${getTypographyStyles('Headline3_B')}; + ${ellipsis(1)}; + color: var(--color-font-primary); +` + +export const Contents = styled.p` + ${getTypographyStyles('Body1_M')}; + ${ellipsis(2)}; + color: var(--color-font-secondary); +` + +export const Thumbnail = styled.img` + object-fit: cover; + border-radius: 16px; +` + +export const ChannelTitle = styled.p` + cursor: pointer; + ${getTypographyStyles('Body2_B')}; + color: var(--color-font-tertiary); +` + +export const SubText = styled.p` + ${getTypographyStyles('Body2_M')}; + color: var(--color-font-tertiary); +` + +export const ImageButton = styled(Image)` + cursor: pointer; +` diff --git a/apps/next-app/src/features/post/ui/PostFeedItem/PostFeedItem.tsx b/apps/next-app/src/features/post/ui/PostFeedItem/PostFeedItem.tsx new file mode 100644 index 00000000..4b05b067 --- /dev/null +++ b/apps/next-app/src/features/post/ui/PostFeedItem/PostFeedItem.tsx @@ -0,0 +1,94 @@ +import { useRouter } from 'next/navigation' + +import Anchor from 'components/common/Anchor' +import { + copyToClipboard, + getDiameterByType, +} from 'components/common/FeedItem/FeedItem.utils' +import useReadPost from 'components/common/FeedItem/hooks/useReadPost' +import useToggleLike from 'components/common/FeedItem/hooks/useToggleLike' +import Flex from 'components/common/Flex' +import LogoIcon from 'components/common/LogoIcon' +import type { UserItemDTO } from 'services/types/_generated/apiDocumentation.schemas' +import { getFormatDate, getWellKnownChannelImg } from 'utils' + +import * as S from './PostFeedItem.style' + +import Icons from 'assets/icons' + +interface Props extends UserItemDTO { + isLoggedIn: boolean +} + +export const PostFeedItem = ({ + id, + title, + channelId, + channelImageUrl, + link, + imageUrl, + description, + channelTitle, + publishedAt, + isLiked, + isLoggedIn, +}: Props) => { + const router = useRouter() + const { handleLike } = useToggleLike({ id, isLiked }) + const { handleRead } = useReadPost({ id }) + + const goToChannelPage = (channelId: number) => { + router.push(`/channels/${channelId}`) + } + + return ( + + + + handleRead(id)}> + {title} + + handleRead(id)}> + {description} + + + {imageUrl && } + + + + + + goToChannelPage(channelId)}> + {channelTitle} + + + {getFormatDate(publishedAt, 'YYYY.MM.DD')} + + + + {isLoggedIn && ( + handleLike(String(id))} + priority + /> + )} + copyToClipboard(String(link))} + priority + /> + + + + ) +} diff --git a/apps/next-app/src/features/post/ui/PostFeedItem/index.ts b/apps/next-app/src/features/post/ui/PostFeedItem/index.ts new file mode 100644 index 00000000..9cb8d438 --- /dev/null +++ b/apps/next-app/src/features/post/ui/PostFeedItem/index.ts @@ -0,0 +1 @@ +export * from './PostFeedItem' diff --git a/apps/next-app/src/types/feeds.ts b/apps/next-app/src/types/feeds.ts index 810a9eef..efb0b01d 100644 --- a/apps/next-app/src/types/feeds.ts +++ b/apps/next-app/src/types/feeds.ts @@ -18,7 +18,7 @@ export interface Post { title: string channelImageUrl: string channelTitle: string - channelId: string + channelId: number } export interface PrivatePost extends Post {