Skip to content

Commit

Permalink
Merge pull request #267 from myong39/Next-서미영-sprint10
Browse files Browse the repository at this point in the history
[서미영] Sprint10
  • Loading branch information
dev-kjy authored Jul 22, 2024
2 parents 34a748e + ceda62f commit ff9959e
Show file tree
Hide file tree
Showing 42 changed files with 1,391 additions and 127 deletions.
100 changes: 100 additions & 0 deletions components/board/BoardDetailArticle.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
@mixin font-style($size, $weight, $lineHeight, $color) {
font-size: $size;
font-weight: $weight;
color: $color;
line-height: $lineHeight;
}

.freeboard-detail-main {
width: 1200px;
margin: 0 auto;
padding: 32px 0;
}

.board-detail-article-section {
display: flex;
flex-direction: column;
justify-content: center;
margin-bottom: 32px;
}

.title-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;

h1 {
@include font-style(20px, 700, 32px, var(--gray800));
}

img {
width: 24px;
height: 24px;
}
}

.content-wrapper {
display: flex;
align-items: center;
}

.user-wrapper {
display: flex;
align-items: center;

img {
width: 40px;
height: 40px;
margin-right: 16px;
}

h3 {
@include font-style(14px, 500, 24px, var(--gray600));
margin-right: 8px;
}

span {
@include font-style(14px, 400, 24px, var(--gray400));
}
}

.favorite-wrapper {
display: flex;
align-items: center;
padding: 4px 12px;
border: 1px solid var(--gray200);
border-radius: 35px;
gap: 3px;

img {
width: 32px;
height: 32px;
}

span {
@include font-style(16px, 500, 26px, var(--gray500));
}
}

.vertical-divider {
border-left: 1px solid var(--gray200);
width: 0;
height: 40px;
margin: 0 32px;
}

.horizontal-divider {
border-top: 1px solid var(--gray200);
width: 100%;
height: 0px;
margin: 16px 0 24px;
}

.content {
@include font-style(18px, 400, 26px, var(--gray800));
}

.comment {
margin-top: 40px;
}
41 changes: 41 additions & 0 deletions components/board/BoardDetailArticle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Article } from "@/types/articleTypes";
import styles from "./BoardDetailArticle.module.scss";
import defalutProfleImg from "@/public/images/icons/ic_user.svg";
import kebabImg from "@/public/images/icons/ic_kebab.svg";
import favoriteImg from "@/public/images/icons/ic_heart.svg";
import { getFormatTime } from "@/utils/Utils";

export default function BoardDetailArticle({
article: {
title,
content,
writer: { nickname },
likeCount,
createdAt,
},
}: {
article: Article;
}) {
return (
<section className={styles["board-detail-article-section"]}>
<div className={styles["title-wrapper"]}>
<h1>{title}</h1>
<img src={kebabImg.src} />
</div>
<div className={styles["content-wrapper"]}>
<div className={styles["user-wrapper"]}>
<img src={defalutProfleImg.src} />
<h3>{nickname}</h3>
<span>{getFormatTime(createdAt, false)}</span>
</div>
<span className={styles["vertical-divider"]}></span>
<div className={styles["favorite-wrapper"]}>
<img src={favoriteImg.src} />
<span>{likeCount}</span>
</div>
</div>
<span className={styles["horizontal-divider"]}></span>
<span className={styles.content}>{content}</span>
</section>
);
}
25 changes: 25 additions & 0 deletions components/board/BoardDetailConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { CommentObject } from "@/types/articleTypes";
import emptyImg from "@/public/images/icons/Img_reply_empty.svg";
import { FieldInfo } from "@/types/registerTypes";

export const commentInfo: CommentObject = {
comments: [],
content: "아직 댓글이 없어요,\n지금 댓글을 달아보세요!",
imgUrl: {
src: emptyImg.src,
alt: "빈 코멘트",
},
};

export enum FIELDTYPE {
TITLE = "댓글달기",
}

export const fields: { [id: string]: FieldInfo } = {
[FIELDTYPE.TITLE]: {
id: FIELDTYPE.TITLE,
name: FIELDTYPE.TITLE,
type: "input",
placeholder: "댓글을 입력해주세요",
},
};
11 changes: 6 additions & 5 deletions components/boards/AllArticleItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@ import { ArticleProp } from "@/types/articleTypes";
import styles from "./Freeboard.module.scss";
import favoriteImg from "@/public/images/icons/ic_heart.svg";
import { getFormatTime } from "@/utils/Utils";
import noImg from "@/public/images/icons/no_img.svg";

export default function AllArticleItem({
article: { createdAt, image, likeCount, title, writer },
}: ArticleProp) {
const titleImage = image ? image : noImg.src;

return (
<div className={styles["all-card"]}>
<div className={styles["content-wrapper"]}>
<div className={styles["title-wrapper"]}>
<h2 className={styles["card-title"]}>{title}</h2>
{image && (
<div className={styles["item-box"]}>
<img className={styles.item} src={image} alt="대표 이미지" />
</div>
)}
<div className={styles["item-box"]}>
<img className={styles.item} src={titleImage} alt="대표 이미지" />
</div>
</div>
<div className={styles["writer-wrapper"]}>
<div className={styles["nickname-wrapper"]}>
Expand Down
22 changes: 17 additions & 5 deletions components/boards/AllArticleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,32 @@ import AllArticleItem from "./AllArticleItem";
import { Article, ArticleApiData } from "@/types/articleTypes";
import SearchInput from "@/components/layout/SearchInput";
import Button from "@/components/layout/Button";
import Dropdown from "@/components/layout/Dropdown";
import Link from "next/link";
import { getArticle } from "@/lib/articleApi";
import { useRouter } from "next/router";
import SortDropdown from "../layout/Dropdown/SortDropdown";
import {
defaultOrderType,
ORDER_TYPE_ENUM,
orderTypeKeysKR,
orderTypeKR,
orderTypeUS,
} from "@/constants/orderConstants";

export default function AllArticleList({
initialArticles,
}: {
initialArticles: Article[];
}) {
const [articles, setArticles] = useState(initialArticles);
const [orderBy, setOrderBy] = useState<ArticleApiData["orderBy"]>("recent");
const [orderBy, setOrderBy] = useState(ORDER_TYPE_ENUM.RECENT);
const items = orderTypeKeysKR;

const router = useRouter();
const keyword = router.query.q;

const handleOrderChange = (option: string) => {
if (option === "recent" || option === "like") setOrderBy(option);
setOrderBy(orderTypeUS[option as keyof typeof orderTypeUS]);
};

const fetchData = async ({ orderBy, pageSize, keyword }: ArticleApiData) => {
Expand Down Expand Up @@ -58,11 +66,15 @@ export default function AllArticleList({
<section className={styles["all-article"]}>
<div className={styles["all-title-wrapper"]}>
<h1 className={styles.title}>게시글</h1>
<Button>글쓰기</Button>
<Button href="/addboard">글쓰기</Button>
</div>
<div className={styles["search-wrapper"]}>
<SearchInput onSortBySearch={handleSortBySearch} />
<Dropdown onOrderChange={handleOrderChange} />
<SortDropdown
onOrderChange={handleOrderChange}
items={items}
defaultOrderType={orderTypeKR[defaultOrderType]}
/>
</div>
{articles.length
? articles.map((article) => (
Expand Down
11 changes: 6 additions & 5 deletions components/boards/BestArticleItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@ import badgeImg from "@/public/images/icons/img_badge.svg";
import favoriteImg from "@/public/images/icons/ic_heart.svg";
import { ArticleProp } from "@/types/articleTypes";
import { getFormatTime } from "@/utils/Utils";
import noImg from "@/public/images/icons/no_img.svg";

export default function BestArticleItem({
article: { createdAt, image, likeCount, title, writer },
}: ArticleProp) {
const titleImage = image ? image : noImg.src;

return (
<div className={styles["best-card"]}>
<img className={styles.badge} src={badgeImg.src} alt="Best 뱃지" />
<div className={styles["content-wrapper"]}>
<div className={styles["title-wrapper"]}>
<h2 className={styles["card-title"]}>{title}</h2>
{image && (
<div className={styles["item-box"]}>
<img className={styles.item} src={image} alt="대표 이미지" />
</div>
)}
<div className={styles["item-box"]}>
<img className={styles.item} src={titleImage} alt="대표 이미지" />
</div>
</div>
<div className={styles["writer-wrapper"]}>
<div className={styles["nickname-wrapper"]}>
Expand Down
10 changes: 5 additions & 5 deletions components/boards/BestArticleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { getArticle } from "@/lib/articleApi";
import { Article, ArticleApiData } from "@/types/articleTypes";
import Link from "next/link";
import useDeviceType from "@/hooks/useDeviceType";
import { DeviceTypePageSize } from "@/types/articleTypes";
import { DeviceTypePageSize } from "@/constants/deviceSizesConstants";
import { ORDER_TYPE_ENUM } from "@/constants/orderConstants";

const ORDERBY = "like";
const { MOBILE_PAGE_SIZE, TABLET_PAGE_SIZE, DESKTOP_PAGE_SIZE } =
DeviceTypePageSize;

export default function BestArticleList() {
const [articles, setArticles] = useState<Article[]>([]);
const { isMobile, isTablet } = useDeviceType();
const { MOBILE_PAGE_SIZE, TABLET_PAGE_SIZE, DESKTOP_PAGE_SIZE } =
DeviceTypePageSize;

const pageSize = isTablet
? TABLET_PAGE_SIZE
Expand All @@ -32,7 +32,7 @@ export default function BestArticleList() {
};

useEffect(() => {
fetchData({ orderBy: ORDERBY, pageSize: pageSize });
fetchData({ orderBy: ORDER_TYPE_ENUM.LIKE, pageSize: pageSize });
}, [pageSize]);

return (
Expand Down
22 changes: 18 additions & 4 deletions components/layout/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import { ReactNode } from "react";
import styles from "./Button.module.scss";
import Link from "next/link";
import { ButtonProps } from "@/types/commonTypes";

export default function Button({
href = "",
children,
disabled = false,
}: ButtonProps) {
if (!href) {
return (
<button className={styles.button} disabled={disabled}>
{children}
</button>
);
}

export default function Button({ children }: { children: ReactNode }) {
return (
<Link href="">
<button className={styles.button}>{children}</button>
<Link href={href}>
<button className={styles.button} disabled={disabled}>
{children}
</button>
</Link>
);
}
43 changes: 43 additions & 0 deletions components/layout/Comment.tsx/Comment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react";
import kebabImg from "@/public/images/icons/ic_kebab.svg";
import { getFormatTime, getElapsedTime } from "@/utils/Utils";
import { CommentType } from "@/types/articleTypes";
import styles from "./Commtent.module.scss";
import defaultProfileImg from "@/public/images/icons/ic_user.svg";

export default function Comment({
comment: {
content,
writer: { image, nickname },
createdAt,
},
}: {
comment: CommentType;
}) {
const elapsedTime = getElapsedTime(createdAt);
const formattedTime = getFormatTime(createdAt);
const profileImg = image ? image : defaultProfileImg.src;

return (
<div className={styles.comment}>
<div className={styles["comment-content-Wrapper"]}>
<p>{content}</p>
<img
className={styles["kebab-image"]}
src={kebabImg.src}
alt="더보기"
/>
</div>
<div className={styles["writer-wrapper"]}>
<img src={profileImg} alt={`${nickname}의 프로필 사진`} />
<div className={styles["nickname-wrapper"]}>
<h3>{nickname}</h3>
<h4>
{formattedTime} {`(${elapsedTime})`}
</h4>
</div>
</div>
<div className={styles["horizontal-divider"]}></div>
</div>
);
}
Loading

0 comments on commit ff9959e

Please sign in to comment.