Skip to content

Commit

Permalink
feat: 디스커션 페이지 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
ymj07168 committed Oct 25, 2024
1 parent fd9373c commit d29a4b6
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/Routers.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const Routers = () => {
{/* 챌린지 문제토론 페이지 - */}
<Route
element={<DiscussionPage />}
path="/challenges/:challengeId/discussion/:discussionId"
path="/challenges/:challengeId/problems/:problemId"
/>
{/* 마이페이지 */}
<Route element={<MyPage />} path="/mypage" />
Expand Down
33 changes: 33 additions & 0 deletions src/api/challenge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import client from "./client";
import { getCookie } from "./cookie";

const token = getCookie("accessToken");

// 문제 댓글 조회
export const getProblemComments = async ({
challengeId,
problemId,
pageSize = 0,
}) => {
return await client.get(
`/api/challenges/${challengeId}/problems/${problemId}?page=${pageSize}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
};

// 문제 댓글 조회
export const postProblemComment = async ({ problemId, content }) => {
return await client.post(
`/api/problem_comment`,
{ problemId: problemId, content: content },
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
};
17 changes: 9 additions & 8 deletions src/components/challenge/Comment.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from "react";
import { Button } from "@mui/material";

export const Comment = () => {
export const Comment = ({ nickname, content, createdAt, profileImage }) => {
const formattedDate = new Date(createdAt).toLocaleDateString("ko-KR", {
year: "numeric",
month: "long",
day: "numeric",
});
return (
<div>
<div className="flex flex-row items-center my-2">
Expand All @@ -11,13 +15,10 @@ export const Comment = () => {
alt=""
/>
<div className="flex flex-col px-4">
<div className="text-xl font-bold mx-1">
이거 어떻게 풀어요? 힌트 주세요
</div>
<div className="text-xl font-bold mx-1">{content}</div>
<div flex flex-row>
<span className="text-lg mx-1 mr-10">고채린</span>
<span className="text-lg mx-3 mr-10 ">2024-10-20</span>
<span className="text-lg mx-3 mr-10">댓글 10</span>
<span className="text-lg mx-1 mr-10">{nickname}</span>
<span className="text-lg mx-3 mr-10 ">{formattedDate}</span>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/challenge/DiscussionHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ export const DiscussionHeader = () => {
};
return (
<div>
<Button
{/* <Button
variant="contained"
sx={{ color: "white", backgroundColor: "black" }}
>
챌린지로 돌아가기
</Button>
</Button> */}

<div className="my-2">
<span className="text-lg mx-4 mr-10">백준</span>
Expand Down
55 changes: 30 additions & 25 deletions src/components/challenge/ProblemCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { Button } from "@mui/material";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import { faMedal } from "@fortawesome/free-solid-svg-icons";
import { useNavigate, useParams } from "react-router-dom";

const ProblemCard = ({problemId,title, site, siteKinds, level}
const ProblemCard = ({ problemId, title, site, siteKinds, level }) => {
console.log(site);

const { challengeId } = useParams();
const navigate = useNavigate();


) => {
console.log(site)

return (
<div className="relative flex min-h-30 justify-between h-full py-5 px-3 my-5 border-2 p-2 rounded-lg shadow-sm">
<div className="flex flex-row justify-between w-5/6">
Expand All @@ -26,18 +27,18 @@ const ProblemCard = ({problemId,title, site, siteKinds, level}
variant="outlined"
color="success"
style={{ borderRadius: "1rem" }}

onClick={() => window.open(site)}

>

문제링크
</Button>
<Button
className="my-2"
variant="contained"
color="success"
style={{ borderRadius: "1rem" }}
onClick={() =>
navigate(`/challenges/${challengeId}/problems/${problemId}`)
}
>
토론방
</Button>
Expand All @@ -46,24 +47,28 @@ const ProblemCard = ({problemId,title, site, siteKinds, level}
</div>

<div className="absolute top-0 right-5">
{level === "Hard" && <FontAwesomeIcon
icon={faMedal}
style={{ color: "#FFD43B" }}
className="fa-4x"
/>}
{level === "Medium" && <FontAwesomeIcon
icon={faMedal}
style={{ color: "#C4BFBA" }}
className="fa-4x"
/>}
{level === "Easy" && <FontAwesomeIcon
icon={faMedal}
style={{ color: "#A6370F" }}
className="fa-4x"
/>}

{level === "Hard" && (
<FontAwesomeIcon
icon={faMedal}
style={{ color: "#FFD43B" }}
className="fa-4x"
/>
)}
{level === "Medium" && (
<FontAwesomeIcon
icon={faMedal}
style={{ color: "#C4BFBA" }}
className="fa-4x"
/>
)}
{level === "Easy" && (
<FontAwesomeIcon
icon={faMedal}
style={{ color: "#A6370F" }}
className="fa-4x"
/>
)}
</div>

</div>
);
};
Expand Down
25 changes: 25 additions & 0 deletions src/hooks/useGetProblemComments.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useQuery } from "@tanstack/react-query";
import { getProblemComments } from "../api/challenge";

export const useGetProblemComments = ({ challengeId, problemId }) => {
const queryKey = ["tilDetail", [challengeId, problemId]];

const queryFn = async () => {
if (challengeId && problemId) {
const response = await getProblemComments({
challengeId: challengeId,
problemId: problemId,
});
return response.data;
}
throw new Error("Missing parameters");
};

const { isLoading, isError, data, error, isSuccess, refetch } = useQuery({
queryKey,
queryFn,
enabled: !!challengeId && !!problemId,
});

return { isLoading, isError, data, error, isSuccess, refetch };
};
98 changes: 88 additions & 10 deletions src/pages/DiscussionPage.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,98 @@
import React from "react";
import React, { useState } from "react";
import Header from "../components/common/Header";
import PageContainer from "../components/common/PageContainer";
import { DiscussionHeader } from "../components/challenge/DiscussionHeader";
import { Comment } from "../components/challenge/Comment";
import { useGetProblemComments } from "../hooks/useGetProblemComments";
import { useParams } from "react-router-dom";
import { Button, Chip, TextField } from "@mui/material";
import { postProblemComment } from "../api/challenge";
import PostComment from "../components/postdetail/PostComment";
import { Tag } from "@mui/icons-material";

const DiscussionPage = () => {
const { challengeId, problemId } = useParams();
const { data, refetch } = useGetProblemComments({
challengeId: challengeId,
problemId: problemId,
});

const [newComment, setNewComment] = useState("");

const handlePostProblemComment = () => {
postProblemComment({
challengeId: challengeId,
problemId: problemId,
content: newComment,
}).then((res) => {
console.log(res);
refetch();
setNewComment("");
});
};

return (
<>
<Header />
<PageContainer className="xl:px-[150px] lg:px-[100px] md:px-50 sm:px-10">
<DiscussionHeader />
<Comment />
<Comment />
<Comment />
<Comment />
<Comment />
<PageContainer className="xl:px-[150px] lg:px-[100px] md:px-50 sm:px-10 mt-5">
<div className="flex flex-row gap-3 mb-5">
<Chip
icon={<Tag />}
label={data?.problemTitle}
variant="outlined"
color="success"
sx={{
padding: "10px",
"& .MuiChip-label": {
fontSize: "24px !important", // Chip 내 레이블에 대한 폰트 크기 설정
fontWeight: 600,
},
}}
/>
<Chip
icon={<Tag />}
label={data?.siteKinds}
variant="outlined"
color="success"
sx={{
padding: "10px",
"& .MuiChip-label": {
fontSize: "24px !important", // Chip 내 레이블에 대한 폰트 크기 설정
fontWeight: 600,
},
}}
/>
</div>
<div className="flex flex-col w-full gap-2">
<div className="self-start text-2xl font-semibold">
{data?.problemCommentsList?.content.length || 0}개의 댓글
</div>
<TextField
value={newComment}
multiline
rows={5}
placeholder="댓글을 작성하세요"
onChange={(e) => setNewComment(e.target.value)}
/>
<Button
variant="contained"
color="success"
sx={{
alignSelf: "end",
}}
onClick={handlePostProblemComment}
>
댓글 작성
</Button>
</div>
{data?.problemCommentsList?.content.map((item) => (
<PostComment
id={item.id}
key={item.id}
writerNickname={item.nickname}
writerProfileImage={item.profileImage}
createdAt={item.createdAt}
content={item.content}
/>
))}
</PageContainer>
</>
);
Expand Down
8 changes: 4 additions & 4 deletions src/pages/MainPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ const MainPage = () => {
};

useEffect(() => {
// setCookie(
// "accessToken",
// "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiTUVNQkVSIiwicHJvZmlsZUltYWdlIjoiaHR0cDovL2sua2FrYW9jZG4ubmV0L2RuL2RmQVd6Zy9idHNKbjdtWWZmby9jN2FncWtvY1lONDVmN3hIQjIxc3ZLL2ltZ182NDB4NjQwLmpwZyIsImVtYWlsIjoieW1qMDcxNjhAbmF2ZXIuY29tIiwic29jaWFsIjoia2FrYW8iLCJuYW1lIjoi7J207Zqo7JuQIiwiaWF0IjoxNzI5ODI0NTk1LCJleHAiOjE3Mjk4NjA1OTV9.aLplzRNPNM18uJIp1Yu9KNK6c8bhY0iOkou9qPP_I_Q"
// );
setCookie(
"accessToken",
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiTUVNQkVSIiwicHJvZmlsZUltYWdlIjoiaHR0cDovL2sua2FrYW9jZG4ubmV0L2RuL2RmQVd6Zy9idHNKbjdtWWZmby9jN2FncWtvY1lONDVmN3hIQjIxc3ZLL2ltZ182NDB4NjQwLmpwZyIsImVtYWlsIjoieW1qMDcxNjhAbmF2ZXIuY29tIiwic29jaWFsIjoia2FrYW8iLCJuYW1lIjoi7J207Zqo7JuQIiwiaWF0IjoxNzI5ODU3MDcwLCJleHAiOjE3Mjk4OTMwNzB9.uD3VVT-RnGA5Q2DKgQ0Lkq7KXV641LfSOO9v6oirW7w"
);
getTIL({ pageNumber: pageNumber }).then((res) => setPostsData(res.data));
getChallenges({ pageSize: 0 }).then((res) =>
setChallenges(res.data.content)
Expand Down

0 comments on commit d29a4b6

Please sign in to comment.