Skip to content

Commit

Permalink
API 연결 및 type수정, reactquery 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
Leedo02 committed Apr 8, 2024
1 parent a70da1d commit 51b8e12
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 77 deletions.
2 changes: 1 addition & 1 deletion src/app/router/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const router = createBrowserRouter([
element: <RootPage />,
},
{
path: ROUTE.detail,
path: ROUTE.questionDetail,
element: <QuestionDetailPage />,
},
{
Expand Down
3 changes: 3 additions & 0 deletions src/entities/question-detail-page/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./ui/question-detail-body";
export * from "./ui/question-detail-profile";
export * from "./ui/question-detail-title";
14 changes: 14 additions & 0 deletions src/entities/question-detail-page/model/question-detail-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ENV } from "~/shared/environment";

export const DETAIL_ENDPOINT = {
default: `${ENV.baseUrl}/api/question/detail`,
finalDetail: (id: string) => {
return `${DETAIL_ENDPOINT.default}/${id}`;
},
};
export const DETAIL_KEY = {
default: [`detail`],
finalDetail: (id: string) => {
return [...DETAIL_KEY.default, id];
},
};
18 changes: 0 additions & 18 deletions src/entities/question-detail-page/model/question-detail-type.ts

This file was deleted.

25 changes: 25 additions & 0 deletions src/entities/question-detail-page/model/question-detail.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export interface QuestionDetailType {
id: number;
title: string;
githubUrl: string;
content: string;
code: string;
purpose: string;
likeCount: number;
viewCount: number;
createdAt: string;
categories: Category[];
comments: Comment[];
}
export interface Category {
id: number;
name: string;
count: number;
}

export interface Comment {
id: number;
content: string;
createdAt: string;
likeCount: number;
}
18 changes: 18 additions & 0 deletions src/entities/question-detail-page/model/use-detail-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { UseQueryResult, useQuery } from "@tanstack/react-query";

import { DETAIL_ENDPOINT, DETAIL_KEY } from "./question-detail-key";
import { QuestionDetailType } from "./question-detail.type";

export const useDetailQuery = (id: string): UseQueryResult<QuestionDetailType> => {
const Detail = useQuery<QuestionDetailType>({
queryKey: DETAIL_KEY.finalDetail(id),
queryFn: async () => {
const response = await fetch(DETAIL_ENDPOINT.finalDetail(id));
if (!response.ok) {
throw new Error("Failed to fetch question detail");
}
return await response.json();
},
});
return Detail;
};
55 changes: 18 additions & 37 deletions src/entities/question-detail-page/ui/question-detail-body.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,11 @@
import styled from "styled-components";

import { QuestionBodyProps } from "../model/question-detail-type";
interface QuestionDetailBodyProps {
content: string;
purpose: string;
code: string;
}

const QuestionBodyData: QuestionBodyProps = {
questionTitle: ["목적", "질문", "Code<>"],
questionText: [
"Lorem ipsum dolor sit amet consectetur. Faucibus a non etiam sit nunc imperdiet nisl nulla blandit. Sit facilisi eget et iaculis praesent. Nisl leo non est justo congue. Amet accumsan egestas morbi augue quisque duis vitae quam ac.",
"Lorem ipsum dolor sit amet consectetur. Faucibus a non etiam sit nunc imperdiet nisl nulla blandit. Sit facilisi eget et iaculis praesent. Nisl leo non est justo congue. Amet accumsan egestas morbi augue quisque duis vitae quam ac.Lorem ipsum dolor sit amet consectetur. Faucibus a non etiam sit nunc imperdiet nisl nulla blandit. Sit facilisi eget et iaculis praesent. Nisl leo non est justo congue. Amet accumsan egestas morbi augue quisque duis vitae quam ac.Lorem ipsum dolor sit amet consectetur. Faucibus a non etiam sit nunc imperdiet nisl nulla blandit. Sit facilisi eget et iaculis praesent. Nisl leo non est justo congue. Amet accumsan egestas morbi augue quisque duis vitae quam ac.",
`print('
오늘부터 지지관계에서 벗어나
르미와(과) 나는 한몸으로 일체가 된다.
르미에 대한 공격은 나에 대한 공격으로 간주한다.
세상에 70억명의 르미 팬이 있다면, 나는 그들 중 한 명일 것이다.
세상에 1억명의 르미 팬이 있다면., 나 또한 그들 중 한 명일 것이다.
세상에 천만 명의 르미 팬이 있다면, 나는 여전히 그들 중 한 명일 것이다.
세상에 백 명의 르미 팬이 있다면, 나는 아직도 그들 중 한 명일 것이다.
세상에 한 명의 르미 팬이 있다면, 그 사람은 아마도 나일 것이다.
세상에 단 한 명의 르미 팬도 없다면, 나는 그제서야 이 세상에 없는 것이다.
르미, 나의 사랑.
르미, 나의 빛.
르미, 나의 어둠.
르미, 나의 삶.
르미, 나의 기쁨.
르미, 나의 슬픔.
르미, 나의 안식.
르미, 나의 영혼.
르미, 나.
')`,
],
};
// 스타일
const QuestionTextContainer = styled.div`
border: 1px solid #000;
Expand All @@ -50,15 +25,21 @@ const QuestionTextContant = styled.div`
font-size: ${({ theme }) => theme.fontSize.body2};
`;

export const QuestionDetailBody = () => {
export const QuestionDetailBody = ({ content, purpose, code }: QuestionDetailBodyProps) => {
return (
<>
{QuestionBodyData.questionTitle.map((title, index) => (
<QuestionTextContainer key={index}>
<QuestionTextTitle>{title}</QuestionTextTitle>
<QuestionTextContant>{QuestionBodyData.questionText[index]}</QuestionTextContant>
</QuestionTextContainer>
))}
<QuestionTextContainer>
<QuestionTextTitle>목적</QuestionTextTitle>
<QuestionTextContant>{purpose}</QuestionTextContant>
</QuestionTextContainer>
<QuestionTextContainer>
<QuestionTextTitle>질문</QuestionTextTitle>
<QuestionTextContant>{content}</QuestionTextContant>
</QuestionTextContainer>
<QuestionTextContainer>
<QuestionTextTitle>Code&lt;&gt;</QuestionTextTitle>
<QuestionTextContant>{code}</QuestionTextContant>
</QuestionTextContainer>
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled, { css } from "styled-components";

import { ProfileHeaderProps } from "~/entities/question-detail-page/model/question-detail-type";
import { ProfileHeaderProps } from "~/entities/question-detail-page/model/question-detail.type";

Check failure on line 3 in src/entities/question-detail-page/ui/question-detail-profile.tsx

View workflow job for this annotation

GitHub Actions / test-build

Module '"~/entities/question-detail-page/model/question-detail.type"' has no exported member 'ProfileHeaderProps'.

import { Icon } from "~/shared/icons";

Expand Down
25 changes: 15 additions & 10 deletions src/entities/question-detail-page/ui/question-detail-title.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import styled from "styled-components";

import { QuestionTitleProps } from "../model/question-detail-type";

const QuestionTitleData: QuestionTitleProps = {
title: "Lorem ipsum dolor sit amet consectetur.",
codetype: ["HTML", "CSS"],
};
interface QuestionDetailTypeProps {
title: string;
categories: string[];
githubUrl: string;
}

// 스타일
const QuestionTitle = styled.p`
Expand All @@ -24,22 +23,28 @@ const QuestionCodeType = styled.p`
const QuestionGitLinkBtn = styled.a`
cursor: pointer;
line-height: 30px;
color: #000;
text-decoration: none;
font-size: ${({ theme }) => theme.fontSize.button};
border: none;
border-radius: 10px;
padding: 0 18px;
background-color: ${({ theme }) => theme.colors.secondary};
`;

export const QuestionDetailTitle = () => {
export const QuestionDetailTitle = ({ title, categories, githubUrl }: QuestionDetailTypeProps) => {
return (
<div className="question-detail-title">
<QuestionTitle>{QuestionTitleData.title}</QuestionTitle>
<QuestionTitle>{title}</QuestionTitle>
<QuestionCodeLink>
<QuestionCodeType>
{QuestionTitleData.codetype[0]}/{QuestionTitleData.codetype[1]}
{categories.map((category, index) => (
<span key={index}>{category}</span>
))}
</QuestionCodeType>
<QuestionGitLinkBtn>Github Link</QuestionGitLinkBtn>
<QuestionGitLinkBtn href={githubUrl} target="_blank">
Github Link
</QuestionGitLinkBtn>
</QuestionCodeLink>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions src/entities/question-header/ui/question-header.ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const ProfileImage = styled.img`

const ProfileName = styled.div`
font-size: ${(props) => props.theme.fontSize.body2};
color: #fff;
`;

const QuestionAndAnswerCount = styled.div`
Expand Down
60 changes: 52 additions & 8 deletions src/pages/question-detail-page/question-detail-page.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,73 @@
import { useParams } from "react-router-dom";
import styled from "styled-components";

import { CommentByQuestionAnswer } from "~/entities/comment";
import { useDetailQuery } from "~/entities/question-detail-page/model/use-detail-query";
import { QuestionDetailBody } from "~/entities/question-detail-page/ui/question-detail-body";
import { QuestionDetailPfofile } from "~/entities/question-detail-page/ui/question-detail-profile";
import { QuestionDetailTitle } from "~/entities/question-detail-page/ui/question-detail-title";
import { QuestionHeader } from "~/entities/question-header";

// 스타일
const QuestionDetailContainer = styled.div`
color: #000;
line-height: 1.2em;
border-radius: 15px;
background-color: #fff;
`;
const QuestionTextContainer = styled.div`
padding: 25px 20px;
`;
const QuestionBox = styled.div`
width: 768px;
margin-left: auto;
margin-right: auto;
box-sizing: border-box;
padding: 20px;
background: rgb(42, 39, 49);
background: linear-gradient(60deg, rgba(42, 39, 49, 1) 0%, rgba(137, 128, 155, 1) 35%, rgba(42, 39, 49, 1) 100%);
border-radius: 28px;
`;

export const QuestionDetailPage = () => {
const { id } = useParams();

const { isError, isLoading, data } = useDetailQuery(id as string);
console.log(data);

if (isError) {
alert("Error from 하늘");
}
if (isLoading) {
return <div>Loading...</div>;
}

// Title영역
const title = data?.title || "";
const categories = data?.categories.map((category) => category.name) || [];
const githubUrl = data?.githubUrl || "";
// Body 영역
const { content = "", purpose = "", code = "" } = data || {};
const questionDetailBodyProps = {
content,
purpose,
code,
};
return (
<>
<QuestionDetailContainer>
<QuestionDetailPfofile />
<QuestionTextContainer>
<QuestionDetailTitle />
<QuestionDetailBody />
</QuestionTextContainer>
</QuestionDetailContainer>
<QuestionBox>
<QuestionDetailContainer>
<QuestionHeader
viewCount={data?.viewCount as number}
likeCount={data?.likeCount as number}
comments={data?.comments.length as number}
/>
<QuestionTextContainer>
<QuestionDetailTitle title={title} categories={categories} githubUrl={githubUrl} />
<QuestionDetailBody {...questionDetailBodyProps} />
</QuestionTextContainer>
</QuestionDetailContainer>
<CommentByQuestionAnswer />

Check failure on line 69 in src/pages/question-detail-page/question-detail-page.tsx

View workflow job for this annotation

GitHub Actions / test-build

Property 'comment' is missing in type '{}' but required in type 'CommentByQuestionAnswerProps'.
</QuestionBox>
</>
);
};
4 changes: 2 additions & 2 deletions src/widgets/question-list/ui/question-list.ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ export const QuestionList = () => {
return (
<Container>
<QuestionListContainer>
{data.length === 0 && <div>검색 결과가 없습니다.</div>}
{data.map(({ id, title, likeCount, viewCount, categories, commentCount, createdAt }) => (
{data?.length === 0 && <div>검색 결과가 없습니다.</div>}
{data && data.map(({ id, title, likeCount, viewCount, categories, commentCount, createdAt }) => (
<Question
key={id}
title={title}
Expand Down

0 comments on commit 51b8e12

Please sign in to comment.