Skip to content

Commit

Permalink
Skeleton 애니메이션 변경, pr&issue 템플릿 변경, 글 수정 및 다중선택 컴포넌트 관련 버그 해결 (#312)
Browse files Browse the repository at this point in the history
* docs: (#302) 일정 추정 및 소요 시간 항목 추가

* refactor: (#271) 불필요한 props 제거

* fix: (#271) 글 수정 시 mock 데이터가 뜨는 오류 해결

* design: (#271) 제목, 내용 input css 수정

* feat: (#281) 다중선택 컴포넌트 외부 영역 선택 시 DropDown이 닫히도록 구현

* refactor: (#91) pulse animation을 wave로 변경 및 animation 관련 코드 theme으로 분리

* refactor: (#91) story 이름 수정, Skeleton 사용하는 파일에서 props 추가

* design: (#91) 스켈레톤 각 Box의 height 단위 px에서 vh 로 변경
  • Loading branch information
inyeong-kang authored Aug 11, 2023
1 parent 3c23d0f commit 1fc4dc7
Show file tree
Hide file tree
Showing 18 changed files with 149 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ about: 기능 이슈 관련 템플릿
title: ''
labels: ''
assignees: ''

---

## ✨ 추가 기능

<!-- 어떤 기능을 개발 -->

## 📆 일정 추정

<!-- 기능 구현에 소요되는 시간, 구현 시작/종료일 등 -->

## 📃 세부 사항

<!-- 사용할 기술, 패턴 등
Expand Down
4 changes: 4 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ close: #

수행할 작업을 1~2줄 사이로 요약해주세요.

## ⏰ 소요 시간

기능 구현에 소요된 시간을 적어주세요. (추정했던 시간과 다르다면 이유도 함께)

## 🔎 작업 상세 설명

주요 기능 및 로직에 관해 설명해주세요.
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/PostForm/PostForm.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,20 @@ const MOCK_DATA: PostInfo = {
};

export const NewPost = () => {
const { mutate, isError, error } = useCreatePost();
const { mutate } = useCreatePost();
return (
<>
<PostForm mutate={mutate} isError={isError} error={error} />
<PostForm mutate={mutate} />
</>
);
};

export const OldPost = () => {
const examplePostId = 1;
const { mutate, isError, error } = useEditPost(examplePostId);
const { mutate } = useEditPost(examplePostId);
return (
<>
<PostForm data={MOCK_DATA} mutate={mutate} isError={isError} error={error} />
<PostForm data={MOCK_DATA} mutate={mutate} />
</>
);
};
4 changes: 1 addition & 3 deletions frontend/src/components/PostForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ import * as S from './style';
interface PostFormProps extends HTMLAttributes<HTMLFormElement> {
data?: PostInfo;
mutate: UseMutateFunction<any, unknown, FormData, unknown>;
isError: boolean;
error: unknown;
}

const MAX_TITLE_LENGTH = 100;
const MAX_CONTENT_LENGTH = 1000;
const CATEGORY_COUNT_LIMIT = 3;

export default function PostForm({ data, mutate, isError, error }: PostFormProps) {
export default function PostForm({ data, mutate }: PostFormProps) {
const {
title,
content,
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/components/PostForm/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,20 @@ export const LeftSide = styled.div<{ $hasImage: boolean }>`
`;

export const Title = styled.input`
border: 1px solid #e6e6e6;
border-radius: 6px;
padding: 10px;
margin-top: 10px;
color: gray;
font: var(--text-title);
&:focus {
outline: none !important;
border-color: var(--slate);
}
@media (min-width: ${theme.breakpoint.md}) {
font-size: 2.4rem;
}
Expand All @@ -80,7 +88,10 @@ export const Title = styled.input`

export const Content = styled.textarea`
min-height: 300px;
border: 1px solid #e6e6e6;
border-radius: 6px;
padding: 10px;
margin-top: 7px;
margin-bottom: 10px;
color: gray;
Expand All @@ -90,6 +101,11 @@ export const Content = styled.textarea`
font: var(--text-caption);
font-family: 'Raleway', sans-serif;
&:focus {
outline: none !important;
border-color: var(--slate);
}
@media (min-width: ${theme.breakpoint.md}) {
font-size: 1.8rem;
line-height: 2.4rem;
Expand Down
40 changes: 20 additions & 20 deletions frontend/src/components/common/Layout/Layout.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,33 @@ type Story = StoryObj<typeof Layout>;
export const VisibleCategory: Story = {
render: () => (
<Layout isSidebarVisible={true}>
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
</Layout>
),
};

export const HiddenCategory: Story = {
render: () => (
<Layout isSidebarVisible={false}>
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
<Skeleton isLarge={false} />
</Layout>
),
};
22 changes: 18 additions & 4 deletions frontend/src/components/common/MultiSelect/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Option } from './types';

import { useState, MouseEvent } from 'react';
import React, { useState, useEffect, useRef } from 'react';

import OptionCancelButton from '@components/optionList/WritingVoteOptionList/WritingVoteOption/OptionCancelButton';

Expand All @@ -25,6 +25,7 @@ export default function MultiSelect({
placeholder = '여러 개의 옵션을 선택해주세요',
}: MultiSelectProps) {
const [isOpen, setIsOpen] = useState(false);
const wrapperRef = useRef<HTMLDivElement>(null);

const filteredOptionList = optionList.filter(
option => !selectedOptionList.some(selected => selected.id === option.id)
Expand All @@ -34,16 +35,29 @@ export default function MultiSelect({
setIsOpen(!isOpen);
};

const handleOutsideClick = (event: MouseEvent) => {
if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};

useEffect(() => {
document.addEventListener('click', handleOutsideClick);
return () => {
document.removeEventListener('click', handleOutsideClick);
};
}, []);

return (
<S.Container>
<S.Wrapper onClick={handleToggleWrapper}>
<S.Wrapper ref={wrapperRef} onClick={handleToggleWrapper}>
<S.SelectedOptionListContainer>
{selectedOptionList.length === 0 && <span>{placeholder} </span>}
{selectedOptionList.map(({ id, name }) => (
<S.SelectedOption key={id} onClick={(e: MouseEvent) => e.stopPropagation()}>
<S.SelectedOption key={id} onClick={(e: React.MouseEvent) => e.stopPropagation()}>
<span>{name}</span>
<OptionCancelButton
onClick={(e: MouseEvent) => {
onClick={(e: React.MouseEvent) => {
e.stopPropagation();
handleOptionDelete(id);
}}
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/components/common/Skeleton/Skeleton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ const meta: Meta<typeof Skeleton> = {
export default meta;
type Story = StoryObj<typeof Skeleton>;

export const Default: Story = {
render: () => <Skeleton />,
export const FirstBoxLarge: Story = {
render: () => <Skeleton isLarge={true} />,
};

export const FirstBoxSmall: Story = {
render: () => <Skeleton isLarge={false} />,
};
10 changes: 6 additions & 4 deletions frontend/src/components/common/Skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';

import * as S from './style';

export default function Skeleton() {
interface SkeletonProps {
isLarge: boolean;
}

export default function Skeleton({ isLarge }: SkeletonProps) {
return (
<S.Container>
<S.FirstBox />
<S.FirstBox $isLarge={isLarge} />
<S.SecondBox />
<S.ThirdBox />
</S.Container>
Expand Down
37 changes: 13 additions & 24 deletions frontend/src/components/common/Skeleton/style.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import { keyframes, styled } from 'styled-components';
import { styled } from 'styled-components';

import { theme } from '@styles/theme';

const skeletonGradient = keyframes`
0% {
background-color: rgba(165, 165, 165, 0.1);
}
50% {
background-color: rgba(165, 165, 165, 0.3);
}
100% {
background-color: rgba(165, 165, 165, 0.1);
}
`;

export const Container = styled.div`
display: flex;
flex-direction: column;
Expand All @@ -29,30 +15,33 @@ export const Container = styled.div`
const Box = styled.div`
border-radius: 4px;
-webkit-animation: ${skeletonGradient} 1.8s infinite ease-in-out;
animation: ${skeletonGradient} 1.8s infinite ease-in-out;
background-color: #eee;
background: linear-gradient(110deg, #ececec 8%, #f5f5f5 18%, #ececec 33%);
background-size: 200% 100%;
animation: 1.7s ${theme.animation.skeletonGradientWave} linear infinite;
`;

export const FirstBox = styled(Box)`
height: 110px;
export const FirstBox = styled(Box)<{ $isLarge: boolean }>`
height: ${props => (props.$isLarge ? '40vh' : '30vh')};
@media (min-width: ${theme.breakpoint.sm}) {
height: 140px;
height: ${props => (props.$isLarge ? '44vh' : '34vh')};
}
`;

export const SecondBox = styled(Box)`
height: 20px;
height: 4vh;
@media (min-width: ${theme.breakpoint.sm}) {
height: 30px;
height: 6vh;
}
`;

export const ThirdBox = styled(Box)`
height: 10px;
height: 2vh;
@media (min-width: ${theme.breakpoint.sm}) {
height: 15px;
height: 4vh;
}
`;
2 changes: 1 addition & 1 deletion frontend/src/components/post/PostList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export default function PostList() {
})}
</React.Fragment>
))}
{isFetchingNextPage && <Skeleton />}
{isFetchingNextPage && <Skeleton isLarge={false} />}
</S.PostListContainer>
</S.Container>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/post/PostListPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default function PostListPage() {
</Drawer>
</S.DrawerWrapper>
<ErrorBoundary fallback={<div>에러발생</div>}>
<Suspense fallback={<Skeleton />}>
<Suspense fallback={<Skeleton isLarge={true} />}>
<PostList />
</Suspense>
</ErrorBoundary>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/hooks/query/post/useEditPost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { QUERY_KEY } from '@constants/queryKey';

export const useEditPost = (postId: number) => {
const queryClient = useQueryClient();
const { mutate, isLoading, isError, error } = useMutation(
const { mutate, isLoading, isSuccess, isError, error } = useMutation(
(updatedPost: FormData) => editPost(postId, updatedPost),
{
onSuccess: () => {
Expand All @@ -18,5 +18,5 @@ export const useEditPost = (postId: number) => {
}
);

return { mutate, isLoading, isError, error };
return { mutate, isLoading, isSuccess, isError, error };
};
3 changes: 0 additions & 3 deletions frontend/src/hooks/query/post/usePostDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ export const usePostDetail = (isGuest: boolean, postId: number) => {
onSuccess: data => {
return data;
},
onError: error => {
window.console.error(error);
},
}
);

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/post/CreatePost/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function CreatePost() {

return (
<Layout isSidebarVisible={false}>
<PostForm mutate={mutate} isError={isError} error={error} />
<PostForm mutate={mutate} />
</Layout>
);
}
Loading

0 comments on commit 1fc4dc7

Please sign in to comment.