Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
[FE] refactor: categories, writings ๋ถ„๋ฆฌ (#236)
Browse files Browse the repository at this point in the history
* refactor: `categories`, 'writings' ๋ถ„๋ฆฌ

* refactor: `categories` ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๋•Œ ์นดํ…Œ๊ณ ๋ฆฌ ํ—ค๋”๋Š” ๋ณด์ด๊ฒŒ ์ˆ˜์ •

* refactor: `useCategoryWritings` -> `useWritings`

* feat: `CategoryItem` ๊ตฌํ˜„

* refactor: CategorySection ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ

* chore: isValidCategoryName ํŒŒ์ผ ๊ฒฝ๋กœ ์ˆ˜์ •

* chore: merge
  • Loading branch information
jeonjeunghoon authored Aug 11, 2023
1 parent e1fd86b commit fc53c73
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 246 deletions.
136 changes: 0 additions & 136 deletions frontend/src/components/Category/CategorySection/CategorySection.tsx

This file was deleted.

This file was deleted.

This file was deleted.

89 changes: 89 additions & 0 deletions frontend/src/components/Category/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { KeyboardEventHandler } from 'react';
import { styled } from 'styled-components';
import useCategoryInput from '../useCategoryInput';
import { useCategoryMutation } from '../useCategoryMutation';
import { isValidCategoryName } from '../isValidCategoryName';
import Input from 'components/@common/Input/Input';
import { PlusCircleIcon } from 'assets/icons';

const Header = () => {
const {
inputRef,
escapeInput: escapeAddCategory,
isInputOpen,
openInput,
resetInput,
isError,
setIsError,
} = useCategoryInput('');
const { addCategory } = useCategoryMutation();

const requestAddCategory: KeyboardEventHandler<HTMLInputElement> = async (e) => {
if (e.key !== 'Enter') return;

const categoryName = e.currentTarget.value.trim();

if (!isValidCategoryName(categoryName)) {
setIsError(true);
return;
}

resetInput();
addCategory({ categoryName: categoryName });
};

return (
<S.Header>
<S.Title>์นดํ…Œ๊ณ ๋ฆฌ</S.Title>
{isInputOpen ? (
<Input
type='text'
variant='underlined'
size='small'
placeholder='Add category ...'
ref={inputRef}
isError={isError}
onBlur={resetInput}
onKeyDown={escapeAddCategory}
onKeyUp={requestAddCategory}
/>
) : (
<S.Button onClick={openInput} aria-label='์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€ ์ž…๋ ฅ ์ฐฝ ์—ด๊ธฐ'>
<PlusCircleIcon width={12} height={12} />
</S.Button>
)}
</S.Header>
);
};

export default Header;

const S = {
Header: styled.header`
display: flex;
justify-content: space-between;
align-items: center;
height: 2.8rem;
font-size: 1.2rem;
font-weight: 400;
padding-right: 0.8rem;
`,

Title: styled.h1`
color: ${({ theme }) => theme.color.gray8};
cursor: default;
`,

Button: styled.button`
display: flex;
justify-content: center;
align-items: center;
width: 2rem;
height: 2.4rem;
border-radius: 8px;
&:hover {
background-color: ${({ theme }) => theme.color.gray5};
}
`,
};
34 changes: 34 additions & 0 deletions frontend/src/components/Category/Item/Item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Accordion from 'components/@common/Accordion/Accordion';
import { useState } from 'react';
import Category from '../Category/Category';
import WritingList from '../WritingList/WritingList';

type Props = {
categoryId: number;
categoryName: string;
isDefaultCategory: boolean;
};

const Item = ({ categoryId, categoryName, isDefaultCategory }: Props) => {
const [isOpen, setIsOpen] = useState(false);

return (
<Accordion.Item key={categoryId}>
<Accordion.Title
onIconClick={() => setIsOpen((prev) => !prev)}
aria-label={`${categoryName} ์นดํ…Œ๊ณ ๋ฆฌ ์™ผ์ชฝ ์‚ฌ์ด๋“œ๋ฐ”์—์„œ ์—ด๊ธฐ`}
>
<Category
categoryId={categoryId}
categoryName={categoryName}
isDefaultCategory={isDefaultCategory}
/>
</Accordion.Title>
<Accordion.Panel>
<WritingList categoryId={categoryId} isOpen={isOpen} />
</Accordion.Panel>
</Accordion.Item>
);
};

export default Item;
28 changes: 28 additions & 0 deletions frontend/src/components/Category/List/List.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Accordion from 'components/@common/Accordion/Accordion';
import { useCategories } from './useCategories';
import Item from '../Item/Item';

const List = () => {
const { categories } = useCategories();

return (
<>
{categories ? (
<Accordion>
{categories.map((category, index) => {
return (
<Item
key={category.id}
categoryId={category.id}
categoryName={category.categoryName}
isDefaultCategory={Boolean(index === 0)}
/>
);
})}
</Accordion>
) : null}
</>
);
};

export default List;
8 changes: 8 additions & 0 deletions frontend/src/components/Category/List/useCategories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useQuery } from '@tanstack/react-query';
import { getCategories } from 'apis/category';

export const useCategories = () => {
const { data } = useQuery(['categories'], getCategories);

return { categories: data ? data.categories : null };
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Meta, StoryObj } from '@storybook/react';
import CategorySection from './CategorySection';
import Section from './Section';

const meta: Meta<typeof CategorySection> = {
title: 'CategorySection',
component: CategorySection,
const meta: Meta<typeof Section> = {
title: 'Section',
component: Section,
};

export default meta;
Expand Down
Loading

0 comments on commit fc53c73

Please sign in to comment.