Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/nori-dongsan/nori-client
Browse files Browse the repository at this point in the history
…into develop
  • Loading branch information
Brokyeom committed Jul 21, 2022
2 parents 12f0667 + 8e78eee commit c0bfb19
Show file tree
Hide file tree
Showing 22 changed files with 317 additions and 146 deletions.
45 changes: 45 additions & 0 deletions community.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 댓글
export interface ReplyData {
author: boolean;
userNickname?: string;
content: string;
createdAt: string;
}
// 커뮤니티 데이터
export interface CommunityData {
id: string;
author: boolean;
category: string;
title: string;
content: string;
userNickname: string;
replyCount: number;
createdAt: string;
image?: string;
imageList: string[];
replyList: ReplyData[];
}
// 커뮤니티 게시글 작성 post body
export interface PostCommunityBody {
category: string;
title: string;
content: string;
imageList?: FormData;
}
// 커뮤니티 댓글
export interface PostCommentBody {
boardId?: string;
content: string;
}

export interface GetCommunityList {
communityList: CommunityData[];
isLoading: boolean;
isError: string;
}
// 커뮤니티 글 작성 이미지 데이터
export interface ImgData {
id: number;
src: string;
file: File;
}
4 changes: 3 additions & 1 deletion components/common/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ export default function Header() {
onChange={handleInputValue}
/>
<Link href="/viewProduct">
<IcSearchIcon onClick={handleClick} />
<a>
<IcSearchIcon onClick={handleClick} />
</a>
</Link>
</StSearchBar>
<StMenu>
Expand Down
74 changes: 64 additions & 10 deletions components/common/WriteHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import styled from '@emotion/styled';
import { IcWriteHeaderLogo } from '../../public/assets/icons';
import Link from 'next/link';
import { useRecoilState } from 'recoil';
import { newPostInfoState } from '../../core/atom';
import { postCommunity } from '../../core/api/community';
import { isChangeInfoState, newPostInfoState } from '../../core/atom';
import { postCommunity, putCommunity } from '../../core/api/community';
import { useRouter } from 'next/router';
import { PutCommunityBody } from '../../types/community';

export default function WriteHeader() {
const [newPostInfo, setNewPostInfo] = useRecoilState(newPostInfoState);
const [isChangeCommunity, setIsChangeCommunity] =
useRecoilState(isChangeInfoState);
const router = useRouter();
const { pathname } = useRouter();
const { pathname, query } = useRouter();

const handleRegister = async () => {
const { title, content } = newPostInfo;
Expand All @@ -27,20 +30,71 @@ export default function WriteHeader() {
router.push(`/community/${data.id}`);
};

const handleCancel = () => {
const val = confirm(
'수정을 취소하시겠습니까? 작성하던 내용은 모두 삭제됩니다.',
);

if (val) {
router.push(`/community/${query.cid}`);
}
};

const handleUpdate = async () => {
const { category, title, content, imageList } = newPostInfo;
const {
isChangeCategory,
isChangeTitle,
isChangeContent,
isChangeImageList,
} = isChangeCommunity;
const updatePostInfo: PutCommunityBody = {};

if (isChangeCategory) updatePostInfo.category = category;
if (isChangeTitle) updatePostInfo.title = title;
if (isChangeContent) updatePostInfo.content = content;
if (isChangeImageList) updatePostInfo.imageList = imageList;

if (updatePostInfo.title === '' || updatePostInfo.content === '') {
alert('내용을 입력해주세요.');
return;
}

const data = await putCommunity(String(query.cid), updatePostInfo);
setNewPostInfo({
category: '후기',
title: '',
content: '',
});
setIsChangeCommunity({
isChangeCategory: false,
isChangeTitle: false,
isChangeContent: false,
isChangeImageList: false,
});
router.push(`/community/${data.id}`);
};

return (
<StWriteHeaderWrapper>
<Link href="/community">
<a>
<IcWriteHeaderLogo />
</a>
</Link>
{pathname === '/community' ? (
{pathname === '/write/[cid]' ? (
<StModifyBlock>
<StCancleBtn>취소</StCancleBtn>
<StWriteBtn>수정완료</StWriteBtn>
<StCancleBtn isMargin={false} onClick={handleCancel}>
취소
</StCancleBtn>
<StWriteBtn isMargin={false} onClick={handleUpdate}>
수정완료
</StWriteBtn>
</StModifyBlock>
) : (
<StWriteBtn>등록하기</StWriteBtn>
<StWriteBtn isMargin={true} onClick={handleRegister}>
등록하기
</StWriteBtn>
)}
</StWriteHeaderWrapper>
);
Expand All @@ -53,7 +107,7 @@ const StWriteHeaderWrapper = styled.section`
position: sticky;
top: -3.2em;
width: 192rem;
width: 100%;
height: 11.4rem;
padding-top: 4.2rem;
Expand All @@ -63,12 +117,12 @@ const StWriteHeaderWrapper = styled.section`
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08);
`;
const StWriteBtn = styled.a`
const StWriteBtn = styled.a<{ isMargin: boolean }>`
display: flex;
justify-content: center;
align-items: center;
margin-left: 11.4rem;
margin-left: ${({ isMargin }) => (isMargin ? '11.4rem' : '0rem')};
width: 10rem;
height: 4.2rem;
Expand Down
1 change: 0 additions & 1 deletion components/community/CommunityFloatingBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import Link from 'next/link';
import { IcWriteBtn, IcTopBtn } from '../../public/assets/icons';
Expand Down
1 change: 0 additions & 1 deletion components/main/ToyPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { MainToyData } from '../../types/toy';
export default function ToyPreview(props: MainToyData) {
const { image, month, price, siteName, siteUrl, title } = props;
const [isMark, setIsMark] = useState(false);
console.log(image);
const handleToySite = (e: React.MouseEvent<HTMLElement>) => {
if (!(e.target instanceof SVGElement)) window.open(siteUrl);
};
Expand Down
48 changes: 28 additions & 20 deletions components/viewProduct/FilterDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ export default function FilterDropdown(props: FilterDropdownProps) {
};

return (
<StDropdownWrapper isDrop={isDrop} isExcept={isExcept}>
<StDropdownWrapper
isDrop={isDrop}
isExcept={isExcept}
className={`${
isDrop ? 'slide-fade-in-dropdown' : 'slide-fade-out-dropdown'
}`}
>
{categoryKey === '장난감 종류' && toyKindList.length !== 0
? toyKindList.map((tagText: string, elementIdx: number) => {
return (
Expand Down Expand Up @@ -135,8 +141,6 @@ const StFilterElement = styled.p`
width: 15.2rem;
height: 2rem;
// color: {({ checked, theme: { colors } }) =>
// checked ? colors.black : colors.gray008};
${({ theme }) => theme.fonts.b5_14_medium_140};
`;
const StDropdownWrapper = styled.div<{ isExcept: boolean; isDrop: boolean }>`
Expand Down Expand Up @@ -172,36 +176,40 @@ const StDropdownWrapper = styled.div<{ isExcept: boolean; isDrop: boolean }>`
theme.colors.gray002}; /*스크롤바 뒷 배경 색상*/
}
// @keyframes slide-fade-in-dropdown-animation {
// 0% {
// transform: translateY(-1rem);
// }
@keyframes slide-fade-in-dropdown-animation {
0% {
max-height: 14.8rem;
overflow: hidden;
opacity: 1;
}
100% {
opacity: 0;
max-height: 0;
overflow: hidden;
}
}
// 100% {
// transform: translateY(0);
// }
// }
/* fade out */
@keyframes slide-fade-out-dropdown-animation {
0% {
transform: translateY(0);
opacity: 0;
max-height: 0;
overflow: hidden;
}
100% {
transform: translateY(-100%);
opacity: 1;
max-height: 14.8rem;
overflow: hidden;
}
}
animation: ${({ isDrop }) =>
isDrop
? 'slide-fade-in-dropdown-animation 0.4s ease'
: 'slide-fade-out-dropdown-animation 0.4s ease'};
// .slide-fade-out-dropdown {
// animation: slide-fade-out-dropdown-animation 0.4s ease;
// animation-fill-mode: forwards;
// }
? 'slide-fade-in-dropdown-animation 0.2s ease-out'
: 'slide-fade-out-dropdown-animation 0.2s ease-out'};
`;
// display `-객체의 노출여부/표현방식--`
// ( justify-content / align-items)
Expand Down
57 changes: 30 additions & 27 deletions components/viewProduct/ProductFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from '@emotion/styled';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import {
checkedItemsState,
Expand All @@ -19,54 +19,57 @@ export default function ProductFilter() {
false,
false,
]);

const [visibilityAnimation, setVisibilityAnimation] = useState<boolean[]>([
false,
false,
false,
false,
false,
]);
const filterListData = Object.values(filterlist.filterList);
const filterListKeys = Object.keys(filterlist.filterList);
const [checkedItems, setcheckedItems] =
useRecoilState<Set<number>[]>(checkedItemsState);
const toyKindList = useRecoilValue<string[]>(toyKindState);
const [repeat, setRepeat] = useState<any>(null);
const handleDropdown = (idx: number) => {
if (visibility[idx]) {
let timeoutId = repeat;
window.clearTimeout(timeoutId);
setRepeat(null);
setVisibilityAnimation({
...visibilityAnimation,
[idx]: true,
});
} else {
setRepeat(
setTimeout(() => {
setVisibilityAnimation({
...visibilityAnimation,
[idx]: false,
});
}, 190),
);
}
setVisibility({
...visibility,
[idx]: !visibility[idx],
});
};

//const [repeat, setRepeat] = useState<null | number | void | string>();
// const handleDrop = (idx: number) => {
// if (visibility[idx]) {
// clearTimeout(repeat);
// setRepeat(null);
// setVisibility({
// ...visibility,
// [idx]: !visibility[idx],
// });
// } else {
// setRepeat(
// setTimeout(() => {
// setVisibility({
// ...visibility,
// [0]: !visibility[0],
// });
// return 0;
// }, 400),
// );
// }
// };

return (
<StFilterWrapper>
{filterListKeys.map((title: string, idx: number) => (
<StFilterSection isDrop={visibility[idx]} key={title}>
<StFilterSection isDrop={visibilityAnimation[idx]} key={title}>
<StFilterTitle
onClick={() => {
handleDropdown(idx);
}}
>
<h2>{title}</h2>
{visibility[idx] ? <IcClose /> : <IcOpen />}
{visibilityAnimation[idx] ? <IcClose /> : <IcOpen />}
</StFilterTitle>
{visibility[idx] && (
{visibilityAnimation[idx] && (
<FilterDropdown
categoryInfo={filterListData[idx]}
categoryIdx={idx}
Expand Down
Loading

0 comments on commit c0bfb19

Please sign in to comment.