Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions pages/_app.tsx

This file was deleted.

13 changes: 0 additions & 13 deletions pages/_document.tsx

This file was deleted.

13 changes: 0 additions & 13 deletions pages/api/hello.ts

This file was deleted.

114 changes: 0 additions & 114 deletions pages/index.tsx

This file was deleted.

10 changes: 10 additions & 0 deletions public/empty_Icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions src/app/addboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use client";
import AddImage from "@/components/AddImage";
import InputText from "@/components/InputText";
import TextArea from "@/components/TextArea";
import React, { useEffect, useState } from "react";

const Page = () => {
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const [disable, setDisable] = useState(true);
const [buttonColor, setButtonColor] = useState("#9CA3AF");

useEffect(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

title, content로 결정 되는 값들이라면 굳이 useEffect를 쓸 필요 없습니다!

const isDisabled =  !(title && content);
const buttonColor = title && content ? '#3692FF' : '#9CA3AF';

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 버튼을 컴포넌트화 해서 활용했다면 상태 값을 내부에서 좀 더 깔끔하게 다룰 수 있었을 거 같네요 :)

if (title && content !== "") {
setButtonColor("#3692FF");
setDisable(false);
} else {
setButtonColor("#9CA3AF");
setDisable(true);
}
}, [title, content]);

return (
<div className="flex flex-col justify-center lg:px-[360px] md:px-[24px] px-[15px] pb-[130px]">
<div className="flex flex-row items-center justify-between lg:mt-[94px] mt-[86px]">
<span className="text-[20px] font-bold">게시글 쓰기</span>
<button
className={`w-[74px] h-[42px] rounded-lg bg-[${buttonColor}] text-[#F3F4F6] text-[16px] font-semibold`}
disabled={disable}
>
등록
</button>
</div>

<div className="mt-[32px]">
<InputText setTitle={setTitle} />
</div>

<div className="mt-[24px]">
<TextArea setContent={setContent} />
</div>

<div className="mt-[24px]">
<AddImage />
</div>
</div>
);
};

export default Page;
101 changes: 101 additions & 0 deletions src/app/board/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"use client";
import AddComment from "@/components/AddComment";
import Comment from "@/components/Comment";
import useArticleDetails from "@/hooks/useArticleDetails";
import useComment from "@/hooks/useComment";
import Image from "next/image";
import { useParams } from "next/navigation";
import React from "react";
import { BsThreeDotsVertical } from "react-icons/bs";
import { GoHeart } from "react-icons/go";
import { TbArrowBack } from "react-icons/tb";
import Link from "next/link";
import useScroll from "@/hooks/useScroll";
import Loading from "@/components/Loading";

const Page = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

next를 사용하시는 김에 다양한 렌더링을 써보시면 좋을 거 같습니다 :) 특히 상세 페이지의 경우 보통 SEO와 직결되므로 특히 더 고려해 볼 수 있겠죠!

const { id } = useParams();
const { articleDetails } = useArticleDetails(id as string);
const { comments, nextCursor, setComment, setNextCursor } = useComment({
id: id as string,
});
const { loading } = useScroll({
nextCursor,
setComment,
setNextCursor,
id: id as string,
});

const formattedDate = articleDetails?.createdAt
? new Date(articleDetails.createdAt)
.toLocaleDateString("ko-KR", {
year: "numeric",
month: "2-digit",
day: "2-digit",
})
.replace(/\.$/, "")
: "";

return (
<div className="flex flex-col lg:px-[360px] md:px-[24px] px-[16px] ">
<div className="flex flex-row justify-between items-center mt-[95px]">
<span className="text-[20px] font-bold">{articleDetails?.title}</span>
<BsThreeDotsVertical size={24} color="#9CA3AF" />
</div>

<div className="flex flex-row items-center mt-[16px]">
<div className=" relative w-[40px] h-[40px] rounded-full bg-gray-400">
<Image fill src="/profile.svg" alt="profile" />
</div>
<span className="text-[14px] font-medium ml-[16px]">
{articleDetails?.writer.nickname}
</span>
<span className="text-[14px] text-[#9CA3AF] font-normal ml-[8px]">
{formattedDate}
</span>

<div className="w-[1px] h-[40px] bg-[#D1D5DB] mx-[32px]" />

<div className="flex flex-row items-center justify-center w-[87px] h-[40px] rounded-4xl border-[1px] border-[#E5E7EB]">
<GoHeart size={32} color="#6B7280" />
<span className="text-[16px] font-medium ml-[4px]">
{articleDetails?.likeCount}
</span>
</div>
</div>

<div className="border-[0.5px] border-[#E5E7EB] mt-[16px] mb-[24px]"></div>

<span className="text-[18px] font-normal">{articleDetails?.content}</span>

<AddComment />

{comments.length > 0 ? (
comments.map((comment, index) => (
<Comment comment={comment} key={index} />
))
) : (
<div className="flex flex-col items-center justify-center mt-[40px]">
<Image width={140} height={140} alt="Empty" src="/empty_Icon.svg" />
<span className="text-[16px] text-[#9CA3AF] font-normal mt-[16px]">
아직 댓글이 없어요, 지금 댓글을 달아보세요!
</span>
</div>
)}

{loading && <Loading />}

<div className="mt-[64px] mb-[95px] flex flex-row justify-center">
<Link
href="/boards"
className="flex flex-row items-center justify-center bg-[#3692FF] w-[240px] h-[48px] rounded-[40px] text-[#F3F4F6] text-[18px] font-semibold"
>
목록으로 돌아가기
<TbArrowBack className="ml-[8px]" size={24} color="#FFFFFF" />
</Link>
</div>
</div>
);
};

export default Page;
42 changes: 18 additions & 24 deletions src/app/boards/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"use client";
import Article from "@/components/Article";
import BestArticle from "@/components/BestArticle";
import Loading from "@/components/Loading";
import Search from "@/components/Search";
import useArticle, { Articles } from "@/hooks/useArticle";
import useArticle from "@/hooks/useArticle";
import useBestArticle from "@/hooks/useBestArticle";
import { motion } from "framer-motion";
import { Articles } from "@/types/article";
import Link from "next/link";
import { useState } from "react";

export default function Boards() {
Expand All @@ -16,24 +18,28 @@ export default function Boards() {
basis,
});

console.log(articleResults);
return (
<div className="flex flex-col justify-center lg:px-[360px] lg:pt-[24px] md:px-[24px] md:pt-[24px] px-[16px] pt-[16px]">
<div className="flex flex-col items-start">
<div className="flex flex-col justify-center lg:px-[360px] md:px-[24px] md:pt-[24px] px-[16px] pt-[16px]">
<div className="flex flex-col items-start lg:mt-[94px] md:mt-[94px] mt-[84px]">
<span className="text-[20px] font-bold mb-[24px]">베스트 게시글</span>
<div className="flex flex-row">
{bestArticles.map((article, index) => (
<BestArticle key={index} article={article} />
<Link href={`/board/${article.id}`} key={index}>
<BestArticle key={index} article={article} />
</Link>
))}
</div>
</div>

<div className=" mt-[40px] flex flex-col">
<div className="flex flex-row justify-between">
<span className="text-[20px] font-bold mb-[24px]">게시글</span>
<button className="w-[88px] h-[42px] rounded-lg bg-[#3692FF] text-[#FFFFFF] text-[16px] font-semibold cursor-pointer">
<Link
href="/addboard"
className="w-[88px] h-[42px] rounded-lg bg-[#3692FF] text-[#FFFFFF] text-[16px] font-semibold cursor-pointer flex items-center justify-center"
>
글쓰기
</button>
</Link>
</div>

<Search
Expand All @@ -45,25 +51,13 @@ export default function Boards() {
/>

{articleResults?.map((article, index) => (
<Article key={index} article={article} />
<Link key={index} href={`/board/${article.id}`}>
<Article key={index} article={article} />
</Link>
))}
</div>

{loading ?? (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5, ease: "easeInOut" }}
className="flex justify-center mt-[30px]"
>
<motion.div
initial={{ rotate: 0 }}
animate={{ rotate: 360 }}
transition={{ ease: "linear", duration: 1, repeat: Infinity }}
className="w-[30px] h-[30px] border-[#F3F4F6] border-[3px] rounded-full border-t-transparent"
/>
</motion.div>
)}
{loading ?? <Loading />}
</div>
);
}
Loading
Loading