Skip to content

Commit

Permalink
Merge pull request #28 from f-lab-edu/feature/feed-component
Browse files Browse the repository at this point in the history
[feat] 피드 컴포넌트 UI 개발
  • Loading branch information
lee1nna authored Nov 5, 2024
2 parents 2f3076e + 9767b5a commit 6e344fe
Show file tree
Hide file tree
Showing 38 changed files with 822 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.image_wrap {
position: relative;
width: 630px;
height: 500px;

img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Slide from '../Slide';
import styles from './BasicFeedContent.module.scss';

type BasicFeedContentProps = {
images: string[];
};

const BasicFeedContent = ({ images }: BasicFeedContentProps) => {
return (
<Slide>
{images.map((image) => {
return (
<div className={styles.image_wrap}>
<img src={image} alt="feed_image" />
</div>
);
})}
</Slide>
);
};

export default BasicFeedContent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@use '../../../../styles/helpers/index' as *;

@mixin flag_icon {
position: absolute;
width: 24px;
height: 24px;
}

.debate_wrap {
position: relative;
width: 630px;
height: 500px;
@include flex-column;

.blue_area {
width: 100%;
height: 50%;
background-color: rgba(43, 89, 195, 0.3);
font-weight: bold;
@include flex-center;

svg {
@include flag_icon;
top: 15px;
left: 15px;
}
}

.red_area {
width: 100%;
height: 50%;
background-color: rgba(211, 101, 130, 0.3);
font-weight: bold;
@include flex-center;

svg {
@include flag_icon;
top: calc(50% + 15px);
left: 15px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import BlueFlag from '@/assets/icons/blue_flag.svg';
import RedFlag from '@/assets/icons/red_flag.svg';
import Typo from '@/components/common/Typo';
import { Post } from '../../types/feed';
import styles from './DebateFeedContent.module.scss';

type DebateFeedContentProps = {
debate: Post;
};

const DebateFeedContent = ({ debate }: DebateFeedContentProps) => {
return (
<div className={styles.debate_wrap}>
<div className={styles.blue_area}>
<Typo as="div" fontSize="body-32" textAlign="center">
{debate?.options?.[0].optionContent}
</Typo>
<BlueFlag />
</div>
<div className={styles.red_area}>
<Typo as="div" fontSize="body-32" textAlign="center">
{debate?.options?.[1].optionContent}
</Typo>
<RedFlag />
</div>
</div>
);
};

export default DebateFeedContent;
9 changes: 9 additions & 0 deletions src/app/(MainLayout)/components/Feed/Feed.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@use '../../../../styles/helpers/index' as *;

.feed_container {
width: 630px;
height: auto;
min-height: 800px;
border-radius: 15px;
box-shadow: 3px 3px 10px 0px rgba(0, 0, 0, 0.25);
}
21 changes: 21 additions & 0 deletions src/app/(MainLayout)/components/Feed/Feed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styles from './Feed.module.scss';
import FeedTop from '../FeedTop/FeedTop';
import { MainFeed } from '../../types/feed';
import FeedBottom from '../FeedBottom/FeedBottom';
import FeedCenter from '../FeedCenter/FeedCenter';

type FeedProps = {
feed: MainFeed;
};

const Feed = ({ feed }: FeedProps) => {
return (
<div className={styles.feed_container}>
<FeedTop feed={feed} />
<FeedCenter post={feed.post} />
<FeedBottom feed={feed} />
</div>
);
};

export default Feed;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@use '../../../../styles/helpers/index' as *;

.feed_bottom {
padding: 15px 20px;
background-color: $COLOR_WHITE;
}
19 changes: 19 additions & 0 deletions src/app/(MainLayout)/components/FeedBottom/FeedBottom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MainFeed } from '../../types/feed';
import FeedContentBox from '../FeedContentBox/FeedContentBox';
import FeedCountBox from '../FeedCountBox/FeedCountBox';
import styles from './FeedBottom.module.scss';

type FeedBottomProps = {
feed: MainFeed;
};

const FeedBottom = ({ feed }: FeedBottomProps) => {
return (
<div className={styles.feed_bottom}>
<FeedCountBox post={feed.post} />
<FeedContentBox feed={feed} />
</div>
);
};

export default FeedBottom;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@use '../../../../styles/helpers/index' as *;

.feed_center {
height: 500px;
background-color: rgba(238, 238, 238, 1);
}
27 changes: 27 additions & 0 deletions src/app/(MainLayout)/components/FeedCenter/FeedCenter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Post } from '../../types/feed';
import BasicFeedContent from '../BasicFeedContent/BasicFeedContent';
import DebateFeedContent from '../DebateFeedContent/DebateFeedContent';
import styles from './FeedCenter.module.scss';

const MOCK_IMAGE_URL = [
'https://flexible.img.hani.co.kr/flexible/normal/960/960/imgdb/resize/2019/0121/00501111_20190121.JPG',
'https://www.fitpetmall.com/wp-content/uploads/2023/10/shutterstock_1938687109-1.png',
'https://health.chosun.com/site/data/img_dir/2024/06/07/2024060701516_0.jpg',
];

type FeedCenterProps = {
post: Post;
};

const FeedCenter = ({ post }: FeedCenterProps) => {
return (
<div className={styles.feed_center}>
{post.postType === 'BASIC' && (
<BasicFeedContent images={MOCK_IMAGE_URL} />
)}
{post.postType === 'DEBATE' && <DebateFeedContent debate={post} />}
</div>
);
};

export default FeedCenter;
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const FeedCommentWriteInput = ({
className={styles.submit_button}
onClick={submitHandler}
disabled={disabled}
/>
>
게시
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@use '../../../../styles/helpers/index' as *;

.username_box {
margin-top: 16px;
margin-bottom: 12px;
@include flex-start-center;

.username {
font-size: 16px;
font-weight: bold;
margin-right: 10px;
white-space: nowrap;
}
}

.content_wrapper {
display: flex;

.content_box {
position: relative;
font-size: 16px;
color: $COLOR_GRAY_2;
// max-height: 50px;
line-height: 24px;

.more {
cursor: pointer;
background-color: $COLOR_WHITE;
font-weight: bold;
float: right;
display: flex;
align-items: flex-end;
height: 100%;
shape-outside: inset(calc(100% - 24px) 0 0 0);
}
}
}

.hashtag_box {
margin-top: 30px;
display: flex;
gap: 10px;

.hashtag {
font-size: 14px;
color: $COLOR_GRAY_4;
}
}

.two_ellipsis {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
56 changes: 56 additions & 0 deletions src/app/(MainLayout)/components/FeedContentBox/FeedContentBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use client';

import { useRouter } from 'next/navigation';
import Typo from '@/components/common/Typo';
import { compactTimeFormatter } from '@/utils/formatter';
import clsx from 'clsx';
import { MainFeed } from '../../types/feed';
import styles from './FeedContentBox.module.scss';

type FeedContentBoxProps = {
feed: MainFeed;
};
const FeedContentBox = ({ feed }: FeedContentBoxProps) => {
const router = useRouter();

const onClickMoreButton = () => {
if (feed.post.postType === 'BASIC') {
router.push('?cf=1');
}
if (feed.post.postType === 'DEBATE') {
router.push('?df=1');
}
};

return (
<>
<div className={styles.username_box}>
<span className={styles.username}>{feed.basicUser.userName}</span>
<Typo as="span" fontSize="body-14" color="gray-4">
{compactTimeFormatter(feed.post.createdAt)}
</Typo>
</div>
<div className={styles.content_wrapper}>
<div className={clsx(styles.content_box, styles.two_ellipsis)}>
<span
className={styles.more}
onClick={onClickMoreButton}
aria-hidden="true"
>
더보기
</span>
{feed.post.content}
</div>
</div>
<div className={styles.hashtag_box}>
{feed.post.hashTagNames.map((hashtag) => (
<span key={hashtag} className={styles.hashtag}>
{hashtag}
</span>
))}
</div>
</>
);
};

export default FeedContentBox;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@use '../../../../styles/helpers/index' as *;

.count_box {
@include flex-start-center;
font-size: 20px;
color: $COLOR_GRAY_2;

svg {
cursor: pointer;
}

.like_count {
margin: 0 15px 0 5px;
}

.comment_count {
margin-left: 5px;
}
}
40 changes: 40 additions & 0 deletions src/app/(MainLayout)/components/FeedCountBox/FeedCountBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client';

import { useRouter } from 'next/navigation';
import MessageIcon from '@/assets/icons/message.svg';
import { digitNumberFormatter } from '@/utils/formatter';
import { Post } from '../../types/feed';
import LikeButton from '../LikeButton';
import styles from './FeedCountBox.module.scss';

type FeedCountBoxProps = {
post: Post;
};

const FeedCountBox = ({ post }: FeedCountBoxProps) => {
const router = useRouter();

const onClickMessageIcon = () => {
if (post.postType === 'BASIC') {
router.push('?cf=1');
}
if (post.postType === 'DEBATE') {
router.push('?df=1');
}
};

return (
<div className={styles.count_box}>
<LikeButton isLike={false} size="medium" postId={post.postId} />
<div className={styles.like_count}>
{digitNumberFormatter(post.likeCount)}
</div>
<MessageIcon onClick={onClickMessageIcon} />
<span className={styles.comment_count}>
{digitNumberFormatter(post.commentCount)}
</span>
</div>
);
};

export default FeedCountBox;
Loading

0 comments on commit 6e344fe

Please sign in to comment.