Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/api/feeds/getWriteInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { apiClient } from '../index';

// 카테고리 및 태그 데이터 타입
export interface CategoryData {
category: string;
tagList: string[];
}

// API 응답 데이터 타입
export interface WriteInfoData {
categoryList: CategoryData[];
}

// API 응답 타입
export interface GetWriteInfoResponse {
isSuccess: boolean;
code: number;
message: string;
data: WriteInfoData;
}

// 새 글 작성을 위한 카테고리 및 태그 조회 API 함수
export const getWriteInfo = async () => {
const response = await apiClient.get<GetWriteInfoResponse>('/feeds/write-info');
return response.data;
};

/*
사용 예시:
const writeInfo = await getWriteInfo();
console.log(writeInfo.data.categoryList); // CategoryData[]

// 카테고리별 태그 접근
writeInfo.data.categoryList.forEach(category => {
console.log(`카테고리: ${category.category}`);
console.log(`태그: ${category.tagList.join(', ')}`);
});
*/
70 changes: 47 additions & 23 deletions src/components/createpost/TagSelectionSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { Section, SectionTitle } from '../../pages/group/CommonSection.styled';
import {
TagContainer,
Expand All @@ -13,28 +13,42 @@ import {
TagCount,
} from './TagSelectionSection.styled';
import closeIcon from '../../assets/post/close.svg';
import { getWriteInfo, type CategoryData } from '@/api/feeds/getWriteInfo';

interface TagSelectionSectionProps {
selectedTags: string[];
onTagToggle: (tag: string) => void;
}

// 상위 장르와 하위 태그 매핑
const genreTagsMap: Record<string, string[]> = {
문학: ['소설', '시', '에세이', '인문학', '철학'],
'과학·IT': ['기술', '과학', 'AI', '데이터'],
사회과학: ['정치', '경제', '사회학', '심리학', '역사'],
인문학: ['철학', '역사', '문화', '언어학', '종교'],
예술: ['미술', '음악', '영화', '디자인', '사진'],
};
const TagSelectionSection = ({ selectedTags, onTagToggle }: TagSelectionSectionProps) => {
const [categories, setCategories] = useState<CategoryData[]>([]);
const [selectedCategory, setSelectedCategory] = useState<string>('');
const [loading, setLoading] = useState(true);

const availableGenres = Object.keys(genreTagsMap);
// API에서 카테고리 및 태그 데이터 로드
useEffect(() => {
const loadWriteInfo = async () => {
try {
setLoading(true);
const response = await getWriteInfo();

const TagSelectionSection = ({ selectedTags, onTagToggle }: TagSelectionSectionProps) => {
const [selectedGenre, setSelectedGenre] = useState<string>('문학');
if (response.isSuccess && response.data.categoryList.length > 0) {
setCategories(response.data.categoryList);
// 첫 번째 카테고리를 기본 선택
setSelectedCategory(response.data.categoryList[0].category);
}
} catch (error) {
console.error('카테고리 정보 로드 실패:', error);
} finally {
setLoading(false);
}
};

const handleGenreSelect = (genre: string) => {
setSelectedGenre(genre);
loadWriteInfo();
}, []);

const handleCategorySelect = (category: string) => {
setSelectedCategory(category);
};

const handleTagToggle = (tag: string) => {
Expand All @@ -54,28 +68,38 @@ const TagSelectionSection = ({ selectedTags, onTagToggle }: TagSelectionSectionP
onTagToggle(tag);
};

const currentSubTags = genreTagsMap[selectedGenre] || [];
// 현재 선택된 카테고리의 태그 목록
const currentTags = categories.find(cat => cat.category === selectedCategory)?.tagList || [];

if (loading) {
return (
<Section>
<SectionTitle>태그</SectionTitle>
<TagContainer>
<div>로딩 중...</div>
</TagContainer>
</Section>
);
}

return (
<Section>
<SectionTitle>태그</SectionTitle>
<TagContainer>
{/* 상위 장르 선택 */}
<GenreButtonGroup>
{availableGenres.map(genre => (
{categories.map(categoryData => (
<GenreButton
key={genre}
active={selectedGenre === genre}
onClick={() => handleGenreSelect(genre)}
key={categoryData.category}
active={selectedCategory === categoryData.category}
onClick={() => handleCategorySelect(categoryData.category)}
>
{genre}
{categoryData.category}
</GenreButton>
))}
</GenreButtonGroup>

{/* 하위 태그 그리드 */}
<SubTagGrid>
{currentSubTags.map(tag => (
{currentTags.map(tag => (
<SubTagButton
key={tag}
active={selectedTags.includes(tag)}
Expand Down