Skip to content

Commit

Permalink
Merge pull request #304 from kimsayhi/Next-김세환-sprint10
Browse files Browse the repository at this point in the history
[김세환] sprint10
  • Loading branch information
Taero-Kim authored Aug 19, 2024
2 parents 17844a9 + ee1b6cc commit 7e6a22e
Show file tree
Hide file tree
Showing 37 changed files with 902 additions and 102 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"cSpell.words": ["sortmobile"]
"cSpell.words": ["addboard", "addfile", "sortmobile"]
}
27 changes: 27 additions & 0 deletions apis/addBoard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import axios from "@/lib/axios";

interface Params<T> {
data: T;
token: string;
}

export const postNewArticle = async ({ data, token }: Params<object>) => {
const res = await axios.post("/articles", data, {
headers: { Authorization: `Bearer ${token}` },
});
};

export const postUploadImage = async ({ data, token }: Params<File>) => {
const formData = new FormData();
formData.append("image", data);
try {
const res = await axios.post("/images/upload", formData, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return res.data;
} catch (err) {
console.log(err);
}
};
29 changes: 27 additions & 2 deletions apis/article.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import axios from "@/lib/axios";
import { ArticleQuery } from "@/models/article";
import { ArticleResponse } from "@/models/article";
import {
Article,
ArticleQuery,
CommentResponse,
GetCommentParam,
} from "@/types/article";
import { ArticleResponse } from "@/types/article";

export const getArticleList = async ({
page = 1,
Expand All @@ -16,3 +21,23 @@ export const getArticleList = async ({
const { list, totalCount }: ArticleResponse = res.data;
return { list, totalCount };
};

export const getArticlesById = async (articleId: number) => {
const res = await axios.get(`/articles/${articleId}`);
const { data }: { data: Article } = res;
return data;
};

export const getArticleComment = async ({
articleId,
limit = 5,
cursor,
}: GetCommentParam) => {
const res = await axios.get(
`/articles/${articleId}/comments?limit=${limit}${
cursor ? `&cursor=${cursor}` : ""
}`
);
const { data }: { data: CommentResponse } = res;
return data;
};
24 changes: 24 additions & 0 deletions apis/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import axios from "@/lib/axios";

interface PostArticleCommentParams {
articleId: number;
data: string;
token: string;
}

export const postArticleComment = async ({
articleId,
data,
token,
}: PostArticleCommentParams) => {
try {
const body = {
content: data,
};
const res = await axios.post(`/articles/${articleId}/comments`, body, {
headers: { Authorization: `Bearer ${token}` },
});
} catch (err) {
console.log(err);
}
};
18 changes: 18 additions & 0 deletions apis/signIn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import axios from "@/lib/axios";
import { access } from "fs";

interface AuthData {
email: string;
password: string;
}

interface ResponseData {
accessToken: string;
refreshToken: string;
}

export const postSignIn = async (authData: AuthData) => {
const res = await axios.post("/auth/signIn", authData);
const { accessToken, refreshToken }: ResponseData = res.data;
return { accessToken, refreshToken };
};
51 changes: 51 additions & 0 deletions components/addboard/AddBoardForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Button from "@/components/ui/Button";
import FileInput from "@/components/ui/FileInput";
import Input from "@/components/ui/Input";
import TextArea from "@/components/ui/TextArea";
import useAddBoard from "@/hooks/useAddBoard";

export default function AddBoardForm() {
const {
inputValues,
onChangeInput,
onSubmitForm,
onChangeFileInput,
isInputValid,
} = useAddBoard();
return (
<form className="m-container mt-[70px] pt-4">
<div className="flex justify-between">
<span className="font-bold text-xl">게시글 쓰기</span>
<Button
className="btn w-[74px] h-[42px]"
onClick={onSubmitForm}
activeBtn={isInputValid}
>
등록
</Button>
</div>
<Input
name="title"
placeholder="제목을 입력해주세요"
type="input"
label="*제목"
value={inputValues.title}
onChange={onChangeInput}
/>
<TextArea
name="content"
placeholder="내용을 입력해 주세요"
label="*내용"
value={inputValues.content}
onChange={onChangeInput}
/>
<FileInput
value=""
onChange={onChangeFileInput}
name="image"
label="이미지"
image={inputValues.image}
/>
</form>
);
}
28 changes: 17 additions & 11 deletions components/boards/Article.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Image from "next/image";
import { formatDate } from "@/utils/formatDate";
import type { Article } from "@/models/article";
import type { Article } from "@/types/article";

import icHeart from "@/public/images/ic_heart.svg";
import icProfile from "@/public/images/ic_profile.svg";
import { Dispatch, SetStateAction } from "react";
import Link from "next/link";
interface Props {
articles: Article[];
setTarget: Dispatch<SetStateAction<HTMLLIElement | null>>;
Expand All @@ -18,18 +19,23 @@ export default function Article({ articles, setTarget }: Props) {
<li
ref={index === articles.length - 1 ? setTarget : null}
key={`${article.id}+${index}`}
className=" bg-gray-50 px-2 pb-6 pt-1 mt-5 border-b shadow-md rounded-xl border-gray-200"
className=" bg-gray-50 px-2 pb-6 pt-2 mt-5 border-b shadow-md rounded-xl border-gray-200 h-[136px]"
>
<div className="flex h-full flex-col justify-between">
<Link
href={`/boards/${article.id}`}
className="flex h-full flex-col justify-between"
>
<div className="flex justify-between gap-10">
<div className="font-semibold text-lg">{article.content}</div>
<Image
className="rounded-lg border border-gray-200 max-h-[72px]"
width={72}
height={72}
src={article.image}
alt="게시글 이미지"
/>
{article.image && (
<Image
className="rounded-lg border border-gray-200 max-h-[72px]"
width={72}
height={72}
src={article.image}
alt="게시글 이미지"
/>
)}
</div>
<div className="text-sm gap-2 flex justify-between pt-4">
<Image
Expand All @@ -53,7 +59,7 @@ export default function Article({ articles, setTarget }: Props) {
{article.likeCount}
</span>
</div>
</div>
</Link>
</li>
))}
</ul>
Expand Down
24 changes: 17 additions & 7 deletions components/boards/ArticleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import icGlasses from "@/public/images/ic_glasses.svg";
import icSort from "@/public/images/ic_sort.svg";
import icSortMobile from "@/public/images/ic_sortmobile.svg";
import DropDown from "@/components/ui/DropDown";
import Link from "next/link";

const INIT_ORDERS = {
recent: "최신순",
Expand All @@ -21,7 +22,7 @@ export default function ArticleList() {
const [nowOrderBy, setNowOrderBy] = useState<OrderByType>(INIT_ORDERS.recent);
const [isOpenDropDown, setIsOpenDropDown] = useState(false);

const onClickDropDown = () => {
const toggleDropDown = () => {
setIsOpenDropDown((prev) => !prev);
};

Expand All @@ -32,7 +33,7 @@ export default function ArticleList() {
orderBy: orderBy,
}));
setNowOrderBy(INIT_ORDERS[orderBy]);
setIsOpenDropDown((prev) => !prev);
toggleDropDown();
};

let debounceTimer: NodeJS.Timeout;
Expand All @@ -54,13 +55,22 @@ export default function ArticleList() {
<div className="pt-10">
<div className="flex justify-between ">
<span className="font-bold text-lg">게시글</span>
<button className="btn order-1 h-[42px] w-[88px] font-semibold">
<Link
href="/addboard"
className="btn order-1 h-[42px] w-[88px] font-semibold"
>
글쓰기
</button>
</Link>
</div>
<div className="flex relative pt-6 gap-4">
<div className=" flex basis-72 gap-1.5 rounded-xl bg-slate-100 px-4 py-[9px] grow">
<Image src={icGlasses} width={15} height={15} alt="게시글 검색" />
<Image
src={icGlasses}
className="w-[15px] h-[15px]"
width={15}
height={15}
alt="게시글 검색"
/>
<input
onChange={onChangeKeyword}
placeholder="검색할 상품을 입력해주세요"
Expand All @@ -69,14 +79,14 @@ export default function ArticleList() {
</div>

<button
onClick={onClickDropDown}
onClick={toggleDropDown}
className="flex-center h-[42px] w-[42px] rounded-xl border border-solid border-gray-200 md:hidden"
>
<Image src={icSortMobile} alt="정렬하기" />
</button>

<button
onClick={onClickDropDown}
onClick={toggleDropDown}
className="hidden h-[42px] w-[130px] items-center justify-between rounded-xl border border-solid px-5 py-4 md:flex"
>
<span>{nowOrderBy}</span>
Expand Down
71 changes: 39 additions & 32 deletions components/boards/BestArticle.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Image from "next/image";

import { formatDate } from "@/utils/formatDate";
import { Article } from "@/models/article";
import { Article } from "@/types/article";

import icMedal from "@/public/images/ic_medal.svg";
import icHeart from "@/public/images/ic_heart.svg";
import Link from "next/link";
interface Props {
articles: Article[];
}
Expand All @@ -18,38 +19,44 @@ export default function BestArticle({ articles }: Props) {
key={article.id}
className="grow bg-gray-50 shadow-md h-[198px] lg:h-[169px] px-[22px] pt-[46px] pb-4 relative rounded-lg"
>
<span className="absolute gap-1 flex-center top-0 left-[22px] w-[102px] h-[30px] text-white bg-my-blue rounded-b-2xl">
<Image src={icMedal} alt="베스트 게시글 뱃지" />
Best
</span>
<div className="flex h-full flex-col justify-between">
<div className="flex justify-between gap-10">
<div className="font-semibold text-lg">{article.content}</div>
<Image
className="rounded-lg border border-gray-200 max-h-[72px]"
width={72}
height={72}
src={article.image}
alt="게시글 이미지"
/>
<Link href={`/boards/${article.id}`}>
<span className="absolute gap-1 flex-center top-0 left-[22px] w-[102px] h-[30px] text-white bg-my-blue rounded-b-2xl">
<Image src={icMedal} alt="베스트 게시글 뱃지" />
Best
</span>
<div className="flex h-full flex-col justify-between">
<div className="flex justify-between gap-10">
<div className="font-semibold text-lg">{article.content}</div>
{article.image && (
<Image
className="rounded-lg border border-gray-200 max-h-[72px]"
width={72}
height={72}
src={article.image}
alt="게시글 이미지"
/>
)}
</div>
<div className="text-sm gap-2 flex justify-between">
<span className="text-gray-700">
{article.writer.nickname}
</span>
<span className="flex gap-0.5 grow text-gray-500">
<Image
src={icHeart}
className="mt-[2px]"
width={13.4}
height={11.65}
alt="좋아요"
/>
{article.likeCount}
</span>
<span className="text-gray-400">
{formatDate(article.createdAt)}
</span>
</div>
</div>
<div className="text-sm gap-2 flex justify-between">
<span className="text-gray-700">{article.writer.nickname}</span>
<span className="flex gap-0.5 grow text-gray-500">
<Image
src={icHeart}
className="mt-[2px]"
width={13.4}
height={11.65}
alt="좋아요"
/>
{article.likeCount}
</span>
<span className="text-gray-400">
{formatDate(article.createdAt)}
</span>
</div>
</div>
</Link>
</li>
))}
</ul>
Expand Down
Loading

0 comments on commit 7e6a22e

Please sign in to comment.