Skip to content

Commit

Permalink
Merge pull request #62 from teamViNO/feature-063
Browse files Browse the repository at this point in the history
feature-063: 카테고리 드롭다운 리팩토링
  • Loading branch information
whistleJs authored Feb 13, 2024
2 parents 8598973 + ffb9085 commit f06c34b
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
import { Dropdown } from '@/styles/SummaryPage';

import DropdownItem from './DropdownItem';
import { useRecoilValue } from 'recoil';
import { categoryState } from '@/stores/category';
import React from 'react';
import { ISelectedCategoryProps } from 'types/category';

// 임시 타입
interface Item {
id: number;
text: string;
items?: Item[];
interface ICategoryDropdownProp {
setSelectedCategory: React.Dispatch<
React.SetStateAction<ISelectedCategoryProps>
>;
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
}

type Props = {
categoryList: Item[];
};

const CategoryDropdown = ({ categoryList }: Props) => {
const CategoryDropdown = ({
setSelectedCategory,
setIsOpen,
}: ICategoryDropdownProp) => {
const categories = useRecoilValue(categoryState);
return (
<Dropdown onClick={(e) => e.stopPropagation()}>
<ul>
{categoryList.map((category) => (
<DropdownItem key={category.id} category={category} />
{categories.map((category) => (
<DropdownItem
key={category.categoryId}
category={category}
setSelectedCategory={setSelectedCategory}
setIsOpen={setIsOpen}
/>
))}
</ul>
</Dropdown>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,81 @@
import { useState } from 'react';

import DownIcon from '@/assets/icons/down.svg?react';
import { IFolderProps, ISelectedCategoryProps } from 'types/category';
import { DropdownTopCategoryName } from '@/styles/SummaryPage';

// 임시 타입
interface Item {
id: number;
text: string;
items?: Item[];
interface ICategoryDropdownProp {
category: IFolderProps;
setSelectedCategory: React.Dispatch<
React.SetStateAction<ISelectedCategoryProps>
>;
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
}

type Props = {
category: Item;
};
interface IItemClickProps {
name: string;
categoryId: number;
}

const DropdownItem = ({ category }: Props) => {
const DropdownItem = ({
category,
setSelectedCategory,
setIsOpen,
}: ICategoryDropdownProp) => {
const [isShow, setIsShow] = useState(false);

const dynamicStyles = {
icon: {
transform: isShow ? 'rotateZ(180deg)' : 'rotateZ(0deg)',
},
subCategory: {
height: isShow ? (category.items?.length || 0) * 46 : 0,
height: isShow ? (category.subFolders.length || 0) * 46 : 0,
},
};

const handleItemClick = async (id: number) => {
const handleItemClick = async ({ name, categoryId }: IItemClickProps) => {
setSelectedCategory({
name,
categoryId,
});
// API 요청
console.log(id);
console.log('API 요청');
setIsOpen(false);
};

return (
<>
<li onClick={() => setIsShow(!isShow)}>
<DownIcon width={18} height={18} style={dynamicStyles.icon} />

{category.text}
<li>
<DownIcon
width={18}
height={18}
style={dynamicStyles.icon}
onClick={() => setIsShow(!isShow)}
/>
<DropdownTopCategoryName
onClick={() =>
handleItemClick({
name: category.name,
categoryId: category.categoryId,
})
}
>
{category.name}
</DropdownTopCategoryName>
</li>

<ul style={dynamicStyles.subCategory}>
{category.items?.map((subCategory) => (
{category.subFolders.map((subFolder) => (
<li
key={subCategory.id}
onClick={() => handleItemClick(subCategory.id)}
key={subFolder.categoryId}
onClick={() =>
handleItemClick({
name: subFolder.name,
categoryId: subFolder.categoryId,
})
}
>
{subCategory.text}
{subFolder.name}
</li>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,13 @@ import OpenFileIcon from '@/assets/icons/open-file.svg?react';
import useOutsideClick from '@/hooks/useOutsideClick';

import { CategoryDropdown } from './CategoryDropdown';
import { ISelectedCategoryProps } from 'types/category';

const CategorySelectBox = () => {
const categoryList = [
{
id: 1,
text: '기획',
items: [
{ id: 2, text: '마케팅' },
{ id: 3, text: '트렌드' },
{ id: 4, text: '기업' },
{ id: 5, text: '용어' },
],
},
{
id: 6,
text: '디자인',
items: [
{ id: 7, text: 'AAA' },
{ id: 8, text: 'BBB' },
{ id: 9, text: 'CCC' },
{ id: 10, text: 'DDD' },
],
},
];

const [isLogin] = useState(true);
const [isOpen, setIsOpen] = useState(false);
const [selectedCategory, setSelectedCategory] =
useState<ISelectedCategoryProps>({ name: '', categoryId: 0 });

// 다른 영역 클릭 시 dropdown 안보여지게 하기
const [ref] = useOutsideClick<HTMLDivElement>(() => {
Expand All @@ -44,24 +24,34 @@ const CategorySelectBox = () => {

setIsOpen(!isOpen);
};

return (
<div ref={ref} style={{ display: 'flex', gap: 8 }} onClick={handleBoxClick}>
<div style={{ position: 'relative', flex: '1 1 auto' }}>
<div className="select-box">
<span>
{isLogin
? '어떤 카테고리에 넣을까요?'
? selectedCategory.name
? selectedCategory.name
: '어떤 카테고리에 넣을까요?'
: '로그인하고 요약한 영상을 아카이빙해요!'}
</span>

<DownIcon width={18} height={18} />
</div>

{isOpen && <CategoryDropdown categoryList={categoryList} />}
{isOpen && (
<CategoryDropdown
setSelectedCategory={setSelectedCategory}
setIsOpen={setIsOpen}
/>
)}
</div>

<span className={`icon-button ${!isLogin && 'disabled'}`}>
<span
className={`icon-button ${!isLogin && 'disabled'} ${
selectedCategory.name ? 'selected' : 'not-selected'
}`}
>
<OpenFileIcon width={28} height={28} />
</span>
</div>
Expand Down
17 changes: 16 additions & 1 deletion src/styles/SummaryPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,16 @@ export const DetailBox = styled.div`
width: 40px;
height: 40px;
border-radius: 8px;
background-color: ${(props) => props.theme.color.gray200};
cursor: pointer;
&.selected {
background-color: ${(props) => props.theme.color.green400};
}
&.not-selected {
background-color: ${(props) => props.theme.color.gray200};
}
&.disabled svg {
& path:nth-of-type(1) {
fill: ${(props) => props.theme.color.gray300};
Expand Down Expand Up @@ -489,3 +496,11 @@ export const ModalContainer = styled(BlurBackground)`
}
}
`;

export const DropdownTopCategoryName = styled.span`
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
`;
5 changes: 5 additions & 0 deletions types/category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ export interface IFolderProps {
topCategoryId: null;
subFolders: ISubFolderProps[];
}

export interface ISelectedCategoryProps {
name: string;
categoryId: number;
}

0 comments on commit f06c34b

Please sign in to comment.