Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

글 상세 페이지(API 추가 전) #14

Merged
merged 9 commits into from
Apr 8, 2024
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
1 change: 0 additions & 1 deletion src/app/provider/global-styled-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { createGlobalStyle } from "styled-components";

export const GlobalStyle = createGlobalStyle`
html, body, div, span, applet, object, iframe,
p, blockquote, pre,
Expand Down
5 changes: 5 additions & 0 deletions src/app/router/router.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createBrowserRouter } from "react-router-dom";

import { QuestionPage } from "~/pages/question";
import { QuestionDetailPage } from "~/pages/question-detail-page/question-detail-page";
import QuestionWritePage from "~/pages/question/question-write.page";
import { ReumiPage } from "~/pages/reumi";
import { RootPage } from "~/pages/root";
Expand All @@ -12,6 +13,10 @@ export const router = createBrowserRouter([
path: ROUTE.root,
element: <RootPage />,
},
{
path: ROUTE.questionDetail,
element: <QuestionDetailPage />,
},
{
path: ROUTE.question,
element: <QuestionPage />,
Expand Down
2 changes: 1 addition & 1 deletion src/entities/comment/model/comment-upload.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export interface CommentUpload {
}

export interface CommentUploadResponse {
createAt: string;
createdAt: string;
id: number;
content: string;
likeCount: number;
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];
},
};
35 changes: 35 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,35 @@
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;
}
export interface ProfileHeaderProps {
userProfile: {
userName: string;
questionCount: number;
answerCount: number;
};
viewCount: number;
commnetCount: number;
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;
};
45 changes: 45 additions & 0 deletions src/entities/question-detail-page/ui/question-detail-body.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import styled from "styled-components";

interface QuestionDetailBodyProps {
content: string;
purpose: string;
code: string;
}

// 스타일
const QuestionTextContainer = styled.div`
border: 1px solid #000;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
`;
const QuestionTextTitle = styled.h2`
border-bottom: 1px solid #000;
padding-bottom: 10px;
line-height: 30px;
font-weight: 600;
font-size: ${({ theme }) => theme.fontSize.headline6};
`;
const QuestionTextContant = styled.div`
padding-top: 20px;
font-size: ${({ theme }) => theme.fontSize.body2};
`;

export const QuestionDetailBody = ({ content, purpose, code }: QuestionDetailBodyProps) => {
return (
<>
<QuestionTextContainer>
<QuestionTextTitle>목적</QuestionTextTitle>
<QuestionTextContant>{purpose}</QuestionTextContant>
</QuestionTextContainer>
<QuestionTextContainer>
<QuestionTextTitle>질문</QuestionTextTitle>
<QuestionTextContant>{content}</QuestionTextContant>
</QuestionTextContainer>
<QuestionTextContainer>
<QuestionTextTitle>Code&lt;&gt;</QuestionTextTitle>
<QuestionTextContant>{code}</QuestionTextContant>
</QuestionTextContainer>
</>
);
};
100 changes: 100 additions & 0 deletions src/entities/question-detail-page/ui/question-detail-profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import styled, { css } from "styled-components";

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

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

const ProfileHeaderData: ProfileHeaderProps = {
userProfile: {
userName: "Sky",
questionCount: 14,
answerCount: 10,
},
viewCount: 23,
commnetCount: 15,
likeCount: 42,
};
// 스타일
const Flex = css`
display: flex;
`;
const QuestionDetailProfile = styled.div`
padding: 10px 20px;
color: #fff;
font-size: ${({ theme }) => theme.fontSize.body2};
${Flex}
justify-content: space-between;
margin-bottom: 25px;
background-color: ${({ theme }) => theme.colors.tabBar};
`;
const HeaderProfile = styled.div`
${Flex}
`;
const Profile = styled.div`
${Flex}
line-height: 30px;
margin-right: 20px;
`;
const ProfileImg = styled.p`
margin-right: 10px;
width: 30px;
height: 30px;
border-radius: 50px;
background-color: pink;
`;
const UserCount = styled.div`
line-height: 30px;
font-size: ${({ theme }) => theme.fontSize.caption};
color: ${({ theme }) => theme.colors.secondary};
`;
const HeaderCount = styled.div`
${Flex}
`;
const Count = styled.div`
${Flex}
margin-left: 15px;
line-height: 30px;
`;
const Icons = styled.p`
height: 30px;
padding-top: 3px;
box-sizing: border-box;
margin-right: 5px;
`;

export const QuestionDetailPfofile = () => {
return (
<QuestionDetailProfile>
<HeaderProfile>
<Profile>
<ProfileImg></ProfileImg>
<p className="user-name">{ProfileHeaderData.userProfile.userName}</p>
</Profile>
<UserCount>
질문횟수: {ProfileHeaderData.userProfile.questionCount}회/답변횟수:{" "}
{ProfileHeaderData.userProfile.answerCount}회
</UserCount>
</HeaderProfile>
<HeaderCount>
<Count>
<Icons>
<Icon.View />
</Icons>
<p>{ProfileHeaderData.viewCount}</p>
</Count>
<Count>
<Icons>
<Icon.Review />
</Icons>
<p>{ProfileHeaderData.commnetCount}</p>
</Count>
<Count>
<Icons>
<Icon.Like />
</Icons>
<p>{ProfileHeaderData.likeCount}</p>
</Count>
</HeaderCount>
</QuestionDetailProfile>
);
};
51 changes: 51 additions & 0 deletions src/entities/question-detail-page/ui/question-detail-title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import styled from "styled-components";

interface QuestionDetailTypeProps {
title: string;
categories: string[];
githubUrl: string;
}

// 스타일
const QuestionTitle = styled.p`
font-size: ${({ theme }) => theme.fontSize.subtitle1};
margin-bottom: 25px;
`;
const QuestionCodeLink = styled.div`
display: flex;
justify-content: space-between;
margin-bottom: 25px;
`;
const QuestionCodeType = styled.p`
color: ${({ theme }) => theme.colors.main};
font-size: ${({ theme }) => theme.fontSize.subtitle2};
`;
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 = ({ title, categories, githubUrl }: QuestionDetailTypeProps) => {
return (
<div className="question-detail-title">
<QuestionTitle>{title}</QuestionTitle>
<QuestionCodeLink>
<QuestionCodeType>
{categories.map((category, index) => (
<span key={index}>{category}</span>
))}
</QuestionCodeType>
<QuestionGitLinkBtn href={githubUrl} target="_blank">
Github Link
</QuestionGitLinkBtn>
</QuestionCodeLink>
</div>
);
};
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
1 change: 1 addition & 0 deletions src/pages/question-detail-page/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./question-detail-page";
Loading
Loading