Skip to content

Commit

Permalink
feature-065: 하위 카테고리 태그 가져오는 API 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
gs0428 committed Feb 14, 2024
1 parent 7bc75cf commit c572859
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 31 deletions.
6 changes: 6 additions & 0 deletions src/apis/category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export const getCategories = async () => {
return response.data;
};

// 카테고리 별 태그 가져오는 API
export const getCategoryTags = async (categoryId: string) => {
const response = await axiosInstance.get(`/category/${categoryId}/`);
return response.data;
};

// 카테고리 이동1 API
export const putSubToOtherTop = async (
categoryId: number,
Expand Down
2 changes: 1 addition & 1 deletion src/apis/videos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const getRecentVideos = async (): Promise<
};

export const getVideoById = async (
videoId: number,
videoId: string,
): Promise<APIResponse<Record<'videos', IVideoProps[]>>> => {
const response = await axiosInstance.get(`/videos/${videoId}/get`);
return response.data;
Expand Down
3 changes: 2 additions & 1 deletion src/components/category/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CategorySelectBox } from '@/components/SummaryPage/SummaryDetailBox/Cat
import { categoryState } from '@/stores/category';

import * as CardStyles from '@/styles/category/Card.style';
import Chip from '../common/chip/Chip';

interface ICardProps {
mode: 'default' | 'category' | 'recommend';
Expand Down Expand Up @@ -65,7 +66,7 @@ const Card: React.FC<ICardProps> = ({
<CardStyles.Summary>{video.description}</CardStyles.Summary>
<CardStyles.ChipWrap>
{video.tag.map((tag) => (
<CardStyles.Chip key={tag.name}>{`# ${tag.name}`}</CardStyles.Chip>
<Chip key={tag.name} name={tag.name} />
))}
</CardStyles.ChipWrap>
</CardStyles.Content>
Expand Down
23 changes: 23 additions & 0 deletions src/components/common/chip/Chip.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import theme from '@/styles/theme';
import styled from 'styled-components';

export const ChipContainer = styled.div`
cursor: pointer;
margin-right: 18px;
margin-bottom: 18px;
padding: 3px 9.5px;
background-color: ${theme.color.gray100};
border-radius: 8px;
color: ${theme.color.gray400};
${theme.typography.Caption1};
&.light {
border: 1px solid ${theme.color.gray200};
background-color: ${theme.color.white};
}
&.selected {
border-color: ${theme.color.gray300};
background-color: ${theme.color.gray100};
}
`;
19 changes: 19 additions & 0 deletions src/components/common/chip/Chip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ChipContainer } from './Chip.style';

interface IChipProps {
name: string;
light?: boolean;
selected?: boolean;
onSelectTag?: (name: string) => void;
}

const Chip = ({ name, light, selected, onSelectTag }: IChipProps) => {
return (
<ChipContainer
className={`${light && 'light'} ${selected && 'selected'}`}
onClick={() => onSelectTag && onSelectTag(name)}
>{`# ${name}`}</ChipContainer>
);
};

export default Chip;
60 changes: 41 additions & 19 deletions src/pages/CategoryPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,38 @@ import * as CategoryPageStyles from '@/styles/category/index.style';
import Card from '@/components/category/Card';
import { useRecoilValue } from 'recoil';
import { categoryState } from '@/stores/category';
import { ISubFolderProps } from 'types/category';
import { ISubFolderProps, ITagProps } from 'types/category';
import EmptyCard from '@/components/category/EmptyCard';
import { deleteVideos, getRecentVideos, getVideoById } from '@/apis/videos';
import { IVideoProps } from 'types/videos';
import { sortVideos } from '@/utils/sortVideos';
import { CardContainer } from '@/styles/category/Card.style';
import { CategorySelectBox } from '@/components/SummaryPage/SummaryDetailBox/CategorySelectBox';
import Chip from '@/components/common/chip/Chip';
import { getCategoryTags } from '@/apis/category';

const CategoryPage = () => {
const params = useParams();
const [name, setName] = useState('');
const [menus, setMenus] = useState<ISubFolderProps[]>([]);
const [menus, setMenus] = useState<ISubFolderProps[] | ITagProps[]>([]);
const [videos, setVideos] = useState<IVideoProps[]>([]);
const [recentRegisterMode, setRecentRegisterMode] = useState(false);
const [checkedVideos, setCheckedVideos] = useState<number[]>([]);
const [selectedTags, setSelectedTags] = useState<string[]>([]);
const categories = useRecoilValue(categoryState);

const [selectedCategoryId, setSelectedCategoryId] = useState(
categories.length ? categories[0].categoryId : -1,
);

const onSelectTag = (name: string) => {
if (selectedTags.includes(name)) {
setSelectedTags(selectedTags.filter((tag) => tag !== name));
} else {
setSelectedTags([...selectedTags, name]);
}
};

const handleSelectCategory = (categoryId: number) => {
setSelectedCategoryId(categoryId);
};
Expand All @@ -45,33 +56,31 @@ const CategoryPage = () => {
.then((res) => {
setVideos(res.result.videos);
setName('최근 읽은 영상');
setMenus([]);
})
.catch((err) => console.log(err));
} else if (!params.sub_folder) {
getVideoById(Number(params.top_folder)).then((res) => {
getVideoById(params.top_folder).then((res) => {
const index = categories.findIndex(
(category) => category.categoryId === Number(params.top_folder),
);
if (!res.isSuccess) {
setName(categories[index].name);
setMenus([]);
setVideos([]);
return;
}
setName(categories[index].name);
setMenus(categories[index].subFolders);
setVideos(res.isSuccess ? res.result.videos : []);
});
} else {
getVideoById(Number(params.sub_folder)).then((res) => {
getVideoById(params.sub_folder).then((res) => {
const index = categories.findIndex(
(category) => category.categoryId === Number(params.top_folder),
);
const subIndex = categories[index].subFolders.findIndex(
(subFolder) => subFolder.categoryId === Number(params.sub_folder),
);
getCategoryTags(params.sub_folder!).then((res) =>
setMenus(res.result.tags),
);
setName(categories[index].subFolders[subIndex].name);
setMenus([]);

setVideos(res.isSuccess ? res.result.videos : []);
});
}
Expand Down Expand Up @@ -147,14 +156,27 @@ const CategoryPage = () => {
</CategoryPageStyles.SelectModeWrap>
) : (
<>
<div>
{menus.map((menu) => (
<CategoryPageStyles.Menu
to={`/category/${menu.topCategoryId}/${menu.categoryId}`}
key={`${menu.name}-${menu.categoryId}`}
>
{menu.name}
</CategoryPageStyles.Menu>
<div style={{ display: 'flex' }}>
{menus.map((menu: ISubFolderProps | ITagProps) => (
<>
{'tag_id' in menu && (
<Chip
key={menu.tag_id}
name={menu.name}
light
selected={selectedTags.includes(menu.name)}
onSelectTag={onSelectTag}
/>
)}
{!('tag_id' in menu) && (
<CategoryPageStyles.Menu
to={`/category/${menu.topCategoryId}/${menu.categoryId}`}
key={`${menu.name}-${menu.categoryId}`}
>
{menu.name}
</CategoryPageStyles.Menu>
)}
</>
))}
</div>
<CategoryPageStyles.ModeWrap onClick={toggleRecentRegisterMode}>
Expand Down
10 changes: 0 additions & 10 deletions src/styles/category/Card.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,3 @@ export const DropdownWrap = styled.div`
}
}
`;

export const Chip = styled.div`
margin-right: 18px;
margin-bottom: 18px;
padding: 3px 9.5px;
background-color: ${theme.color.gray100};
border-radius: 8px;
color: ${theme.color.gray400};
${theme.typography.Caption1};
`;
5 changes: 5 additions & 0 deletions types/category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ export interface ISelectedCategoryProps {
name: string;
categoryId: number;
}

export interface ITagProps {
tag_id: number;
name: string;
}

0 comments on commit c572859

Please sign in to comment.