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

[ CommunityForm ] 댓글 mocking 구현 / 상세페이지 이동 구현 #122

Merged
merged 5 commits into from
Jul 20, 2022
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
2 changes: 1 addition & 1 deletion components/common/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function Header() {
</p>
</StTopLink>
<StHeaderContents>
<Link href="/main">
<Link href="/">
<a>
<IcNoriHeaderLogo />
</a>
Expand Down
88 changes: 88 additions & 0 deletions components/common/PageNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import styled from '@emotion/styled';
import { css } from '@emotion/react';
import {
IcLeftArrow,
IcLeftArrowFill,
IcRightArrow,
IcRightArrowFill,
} from '../../public/assets/icons';

interface PageNavigationProps {
currentPage: number;
lastPage: number;
handleCurrentPage: (nextPage: number) => void;
}

export default function PageNavigation(props: PageNavigationProps) {
const { currentPage, lastPage, handleCurrentPage } = props;

const pageArray =
currentPage % 5 === 0
? new Array(5)
.fill(0)
.map((_, idx) => (Math.floor(currentPage / 5) - 1) * 5 + idx + 1)
: lastPage > Math.ceil(currentPage / 5) * 5
? new Array(5)
.fill(0)
.map((_, idx) => Math.floor(currentPage / 5) * 5 + idx + 1)
: new Array(lastPage - Math.floor(currentPage / 5) * 5)
.fill(0)
.map((_, idx) => Math.floor(currentPage / 5) * 5 + idx + 1);

const handlePreviousGroupPage = () => {
handleCurrentPage(pageArray[0] - 1);
};
const handleNextGroupPage = () => {
handleCurrentPage(pageArray[pageArray.length - 1] + 1);
};

const handlePageNumber = (e: React.MouseEvent<HTMLAnchorElement>) => {
const target = e.target as HTMLAnchorElement;
handleCurrentPage(Number(target.innerHTML));
};
return (
<StNavigationWrapper>
{Math.floor(currentPage / 5) >= 1 && currentPage !== 5 ? (
<IcLeftArrowFill onClick={handlePreviousGroupPage} />
) : (
<IcLeftArrow />
)}
{pageArray.map((page) => (
<StPageNumberA
key={page}
isCurrent={page === currentPage}
onClick={() => handleCurrentPage(page)}
>
{page}
</StPageNumberA>
))}
{lastPage > Math.ceil(currentPage / 5) * 5 ? (
<IcRightArrowFill onClick={handleNextGroupPage} />
) : (
<IcRightArrow />
)}
</StNavigationWrapper>
);
}

const StNavigationWrapper = styled.nav`
display: flex;
justify-content: space-around;
align-items: center;

width: 22.2rem;
margin-bottom: 12rem;

cursor: pointer;
`;
const StPageNumberA = styled.a<{ isCurrent: boolean }>`
${({ isCurrent }) =>
isCurrent
? css`
color: #1db981;
`
: css`
color: #787878;
`};
${({ theme }) => theme.fonts.b3_16_medium_140}
`;
1 change: 1 addition & 0 deletions components/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as Error404 } from './Error404';
export { default as Header } from './Header';
export { default as Footer } from './Footer';
export { default as WriteHeader } from './WriteHeader';
export { default as PageNavigation } from './PageNavigation';
1 change: 1 addition & 0 deletions components/community/CommunityList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default function CommunityList(props: CommunityListProps) {
<StCommunityListWrapper>
{contentsList.map((content, idx) => (
<ContentCard
id={content.id}
key={idx}
category={content.category}
title={content.title}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import styled from '@emotion/styled';
import { IcReply, IcHeart, IcDot } from '../../public/assets/icons';
import CommunityCategory from './CommunityCategory';
import Router from 'next/router';
import { useRouter } from 'next/router';
import Link from 'next/link';

interface ContentInfoProps {
id: string;
category: string;
title: string;
content: string;
Expand All @@ -13,15 +17,27 @@ interface ContentInfoProps {
}

export default function ContentCard(props: ContentInfoProps) {
const { category, title, content, userNickname, replyCount, createdAt, img } =
props;
const {
id,
category,
title,
content,
userNickname,
replyCount,
createdAt,
img,
} = props;

return (
<StContentsCardWrapper>
<StContentInfo>
<CommunityCategory category={category} />
<h1>{title}</h1>
<p>{content}</p>
<StMainInfo
onClick={() => Router.push({ pathname: `/community/${id}` })}
>
<h1>{title}</h1>
<p>{content}</p>
</StMainInfo>
<StWriteInfo>
<span>{userNickname}</span>
<IcDot />
Expand All @@ -41,7 +57,7 @@ export default function ContentCard(props: ContentInfoProps) {

const StContentsCardWrapper = styled.div`
display: flex;
flex-direction: row;
/* flex-direction: ; */

margin-bottom: 4.8rem;
padding-bottom: 4.5rem;
Expand All @@ -52,13 +68,17 @@ const StContentsCardWrapper = styled.div`
border-bottom: 0.1rem solid ${({ theme }) => theme.colors.gray005};

h1 {
width: 92.3rem;
margin-top: 1.6rem;
margin-bottom: 0.7rem;

${({ theme }) => theme.fonts.b9_24_medium_150}

cursor: pointer;
}

p {
width: 72.5rem;
margin-bottom: 2.7rem;

display: -webkit-box;
Expand All @@ -68,21 +88,25 @@ const StContentsCardWrapper = styled.div`

color: ${({ theme }) => theme.colors.gray009};
${({ theme }) => theme.fonts.t6_17_regular_140}

cursor: pointer;
}
`;
const StMainInfo = styled.article``;
const StContentInfo = styled.section`
margin-right: 4.9rem;
display: flex;
flex-direction: column;

width: auto;
width: 72.5rem;
`;
const StContentImg = styled.img`
width: 21.6rem;
height: 21.6rem;

object-fit: cover;
width: 21.8rem;
height: 21.8rem;

border: 0.1rem solid ${({ theme }) => theme.colors.gray005};
border-radius: 0.5rem;

object-fit: cover;
`;
const StWriteInfo = styled.div`
display: flex;
Expand Down
11 changes: 9 additions & 2 deletions components/community/ReplyContent.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import styled from '@emotion/styled';
import { IcReplyWriteIcon } from '../../public/assets/icons';
import { useState } from 'react';

interface ReplyContentProps {
author: boolean;
userNickname?: string;
content: string;
createdAt: string;
}

export default function ReplyContent(props: ReplyContentProps) {
const { userNickname, content, createdAt } = props;
const { userNickname, content, createdAt, author } = props;

return (
<StReplyContentWrapper>
<StReplyInfo>
<p>{userNickname}</p>
{author && <IcReplyWriteIcon />}
</StReplyInfo>
<StReplyContents>
<p>{content}</p>
<span>{createdAt} · 신고</span>
<span>
{createdAt} · {author ? '삭제' : '신고'}
</span>
</StReplyContents>
</StReplyContentWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,55 @@
import styled from '@emotion/styled';
import ReplyContent from '../community/ReplyContent';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { postReply } from '../../core/api/community';
import {
CommunityData,
PostCommentBody,
ReplyData,
} from '../../types/community';
import ReplyContent from './ReplyContent';
import { useRouter } from 'next/router';

interface ReplyListProps {
cid: string;
replyList: ReplyData[];
}

export default function Reply() {
export default function ReplyList(props: ReplyListProps) {
const router = useRouter();
const { replyList, cid } = props;
const [inputColor, setInputColor] = useState<boolean>(false);
const [replyText, setReplyText] = useState<string>('');
const [newReplyInfo, setNewReplyInfo] = useState<PostCommentBody>({
boardId: '',
content: '',
});

const handleInputText = (e: React.ChangeEvent<HTMLInputElement>) => {
setReplyText(e.target.value);
setNewReplyInfo({ ...newReplyInfo, content: e.target.value });
};

const handleInputColor = () => {
setInputColor(replyText.length !== 0);
};

const handleReplyregister = async () => {
const { content } = newReplyInfo;
if (content === '') {
alert('내용을 입력해주세요.');
return;
}

const data = await postReply(newReplyInfo);
setNewReplyInfo({
boardId: `${cid}`,
content: replyText,
});
router.push(`/community/${data.id}`);
};

return (
<StReplyWrapper>
<>
<StReplyTitle>
<h1>댓글</h1>
<p>23</p>
Expand All @@ -29,37 +63,25 @@ export default function Reply() {
onChange={handleInputText}
/>
</StInputContent>
<StInputBtn inputColor={inputColor}>입력</StInputBtn>
<StInputBtn inputColor={inputColor} onClick={handleReplyregister}>
입력
</StInputBtn>
</StInputForm>
<ReplyContent
userNickname="희지맘"
createdAt="2022.07.13"
content="저희는 4개월 때부터 학습용 완구 썼어요!"
/>
<ReplyContent
userNickname="희지맘"
createdAt="2022.07.13"
content="저희는 4개월 때부터 학습용 완구 썼어요!"
/>
<ReplyContent
userNickname="희지맘"
createdAt="2022.07.13"
content="저희는 4개월 때부터 학습용 완구 썼어요!"
/>
<ReplyContent
userNickname="희지맘"
createdAt="2022.07.13"
content="저희는 4개월 때부터 학습용 완구 썼어요!"
/>
</StReplyWrapper>
<StReplyWrapper>
{replyList.map((reply, idx) => (
<ReplyContent
key={idx}
author={reply.author}
userNickname={reply.userNickname}
content={reply.content}
createdAt={reply.createdAt}
/>
))}
</StReplyWrapper>
</>
);
}

const StReplyWrapper = styled.section`
display: flex;
flex-direction: column;
justify-content: flex-start;
`;
const StReplyTitle = styled.article`
display: flex;
flex-direction: row;
Expand Down Expand Up @@ -136,3 +158,8 @@ const StInputBtn = styled.span<{ inputColor: boolean }>`

cursor: pointer;
`;
const StReplyWrapper = styled.section`
display: flex;
flex-direction: column;
justify-content: flex-start;
`;
2 changes: 1 addition & 1 deletion components/community/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { default as ReplyContent } from './ReplyContent';
export { default as CommunityList } from './CommunityList';
export { default as Reply } from './Reply';
export { default as CommunityFloatingBtn } from './CommunityFloatingBtn';
export { default as replyList } from './ReplyList';
Loading