diff --git a/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx b/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx index 0cb1fd3..53f2c0a 100644 --- a/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx +++ b/src/app/(layout)/archive/_components/ArchiveCardGrid/index.tsx @@ -4,6 +4,10 @@ import { useState, useEffect } from 'react'; import Card from '@/components/ui/Card'; import { useModalStore } from '@/stores/useModalStore'; import { TagType } from '@/types'; +import { useTemplatesLikes } from '@/hooks/template/useTemplateLikes'; +import { useRecentlyUsedTemplates } from '@/hooks/template/useRecentlyUsedTemplates'; +import { useFolderDetail } from '@/hooks/folder/useFolderDetail'; +import { Template } from '@/services/template/getTemplates'; interface ArchiveCardGridProps { selectedFolderId: string; @@ -11,65 +15,65 @@ interface ArchiveCardGridProps { sortType: 'popular' | 'latest'; } -// 템플릿 데이터 타입 정의 -interface TemplateData { - id: string; - templateId: number; - title: string; - description: string; - tags: string[]; - likes: number; - content: string; - folderId: string; -} - -// 폴더별 더미 데이터 -const folderData: Record = { - '1': Array.from({ length: 32 }, (_, index) => ({ - id: `fav_${index + 1}`, - templateId: index + 1, - title: `찜한 템플릿 ${index + 1}`, - description: - '찜한 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', - tags: ['인사말', '자기소개'], - likes: 150 + index, - content: `찜한 템플릿 ${index + 1}의 내용입니다.\n\n안녕하세요 잘 부탁드립니다.`, - folderId: '1', - })), - '2': Array.from({ length: 5 }, (_, index) => ({ - id: `recent_${index + 1}`, - templateId: 100 + index + 1, - title: `최근 사용한 템플릿 ${index + 1}`, - description: - '최근에 사용한 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', - tags: ['감사글', '공지글'], - likes: 80 + index, - content: `최근 사용한 템플릿 ${index + 1}의 내용입니다.\n\n감사합니다.`, - folderId: '2', - })), - '3': Array.from({ length: 8 }, (_, index) => ({ - id: `user1_${index + 1}`, - templateId: 200 + index + 1, - title: `사용자 폴더1 템플릿 ${index + 1}`, - description: - '사용자가 만든 폴더의 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', - tags: ['부탁글', '제안글'], - likes: 60 + index, - content: `사용자 폴더1 템플릿 ${index + 1}의 내용입니다.\n\n잘 부탁드립니다.`, - folderId: '3', - })), - '4': Array.from({ length: 3 }, (_, index) => ({ - id: `user2_${index + 1}`, - templateId: 300 + index + 1, - title: `사용자 폴더2 템플릿 ${index + 1}`, - description: - '사용자가 만든 폴더의 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', - tags: ['후기작성', '소셜글'], - likes: 40 + index, - content: `사용자 폴더2 템플릿 ${index + 1}의 내용입니다.\n\n감사합니다.`, - folderId: '4', - })), -}; +// 템플릿 데이터 타입 정의 (현재 사용되지 않음 - API 타입으로 대체됨) +// interface TemplateData { +// id: string; +// templateId: number; +// title: string; +// description: string; +// tags: string[]; +// likes: number; +// content: string; +// folderId: string; +// } + +// 폴더별 더미 데이터 (현재 사용되지 않음 - API 연동으로 대체됨) +// const folderData: Record = { +// '1': Array.from({ length: 32 }, (_, index) => ({ +// id: `fav_${index + 1}`, +// templateId: index + 1, +// title: `찜한 템플릿 ${index + 1}`, +// description: +// '찜한 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', +// tags: ['인사말', '자기소개'], +// likes: 150 + index, +// content: `찜한 템플릿 ${index + 1}의 내용입니다.\n\n안녕하세요 잘 부탁드립니다.`, +// folderId: '1', +// })), +// '2': Array.from({ length: 5 }, (_, index) => ({ +// id: `recent_${index + 1}`, +// templateId: 100 + index + 1, +// title: `최근 사용한 템플릿 ${index + 1}`, +// description: +// '최근에 사용한 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', +// tags: ['감사글', '공지글'], +// likes: 80 + index, +// content: `최근 사용한 템플릿 ${index + 1}의 내용입니다.\n\n감사합니다.`, +// folderId: '2', +// })), +// '3': Array.from({ length: 8 }, (_, index) => ({ +// id: `user1_${index + 1}`, +// templateId: 200 + index + 1, +// title: `사용자 폴더1 템플릿 ${index + 1}`, +// description: +// '사용자가 만든 폴더의 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', +// tags: ['부탁글', '제안글'], +// likes: 60 + index, +// content: `사용자 폴더1 템플릿 ${index + 1}의 내용입니다.\n\n잘 부탁드립니다.`, +// folderId: '3', +// })), +// '4': Array.from({ length: 3 }, (_, index) => ({ +// id: `user2_${index + 1}`, +// templateId: 300 + index + 1, +// title: `사용자 폴더2 템플릿 ${index + 1}`, +// description: +// '사용자가 만든 폴더의 템플릿입니다. 글로우업 글쓰기 서비스는 여러 상황에서 사용자의 글쓰기 경험을 돕고자 합니다.', +// tags: ['후기작성', '소셜글'], +// likes: 40 + index, +// content: `사용자 폴더2 템플릿 ${index + 1}의 내용입니다.\n\n감사합니다.`, +// folderId: '4', +// })), +// }; export default function ArchiveCardGrid({ selectedFolderId, @@ -80,6 +84,46 @@ export default function ArchiveCardGrid({ const [isLoading, setIsLoading] = useState(false); const { openModal, currentModal } = useModalStore(); + // 폴더별 데이터 API 연동 + const isLikes = selectedFolderId === '1'; + const isRecent = selectedFolderId === '2'; + const folderIdNum = Number(selectedFolderId); + + const { data: likesData } = useTemplatesLikes(); + const { data: recentData } = useRecentlyUsedTemplates(); + const { data: folderDetailData } = useFolderDetail( + !isLikes && !isRecent && !isNaN(folderIdNum) ? folderIdNum : 0, + ); + + // 템플릿 데이터 추출 + let templates: Template[] = []; + if (isLikes) { + templates = likesData?.templates ?? []; + } else if (isRecent) { + templates = recentData?.templates ?? []; + } else if (folderDetailData) { + templates = folderDetailData.templates ?? []; + } + + // 태그 필터링 + let filteredTemplates: Template[] = templates; + if (selectedTag) { + filteredTemplates = templates.filter((card) => + card.tags.some((tag: string) => tag === selectedTag), + ); + } + + // 정렬 + if (sortType === 'popular') { + filteredTemplates = [...filteredTemplates].sort((a, b) => b.likeCount - a.likeCount); + } else { + filteredTemplates = [...filteredTemplates].sort((a, b) => b.templateId - a.templateId); + } + + // 페이징 + const displayedCards = filteredTemplates.slice(0, visibleCards); + const hasMoreCards = visibleCards < filteredTemplates.length; + // 컴포넌트 마운트 시와 모달이 닫힐 때만 카드 클릭 상태 초기화 useEffect(() => { // 모달이 닫힐 때만 카드 클릭 상태를 초기화 @@ -93,26 +137,6 @@ export default function ArchiveCardGrid({ setVisibleCards(15); }, [selectedFolderId]); - // 현재 폴더의 데이터 가져오기 - const getCurrentFolderData = () => { - const data = folderData[selectedFolderId] || []; - - // 태그 필터링 - let filteredData = data; - if (selectedTag) { - filteredData = data.filter((card) => card.tags.some((tag: string) => tag === selectedTag)); - } - - // 정렬 - if (sortType === 'popular') { - filteredData.sort((a, b) => b.likes - a.likes); - } else { - filteredData.sort((a, b) => b.templateId - a.templateId); // 최신순 (ID 기준) - } - - return filteredData; - }; - const handleLoadMore = () => { setIsLoading(true); // 더 불러오기 로직 (추후 API 연결) @@ -123,7 +147,7 @@ export default function ArchiveCardGrid({ }; // 모달 열기 핸들러 - 카드 클릭 시 모달 연결을 위한 상태 처리 - const handleCardClick = (templateId: number, cardData: TemplateData) => { + const handleCardClick = (templateId: number, cardData: Template) => { console.log('카드 클릭:', { templateId, folderId: selectedFolderId, @@ -138,22 +162,18 @@ export default function ArchiveCardGrid({ }); }; - const currentData = getCurrentFolderData(); - const displayedCards = currentData.slice(0, visibleCards); - const hasMoreCards = visibleCards < currentData.length; - return (
{/* 카드 그리드 - 3열로 배치 */}
{displayedCards.map((card) => ( handleCardClick(card.templateId, card)} className="cursor-pointer transition-all duration-200 hover:scale-[1.02] hover:shadow-lg" /> diff --git a/src/app/(layout)/archive/_components/ArchiveSidebar/index.tsx b/src/app/(layout)/archive/_components/ArchiveSidebar/index.tsx index c7d445f..7d39eed 100644 --- a/src/app/(layout)/archive/_components/ArchiveSidebar/index.tsx +++ b/src/app/(layout)/archive/_components/ArchiveSidebar/index.tsx @@ -5,6 +5,9 @@ import { useRouter } from 'next/navigation'; import ArchiveFolderStatus from '../ArchiveFolderStatus'; import ArchiveFolderInput from '../ArchiveFolderInput'; import ArchiveModalWarning from '../ArchiveModalWarning'; +import { useFolders } from '@/hooks/folder/useFolders'; +import { useCreateFolder } from '@/hooks/folder/useCreateFolder'; +import { useDeleteFolder } from '@/hooks/folder/useDeleteFolder'; interface ArchiveSidebarProps { selectedFolderId: string; @@ -15,19 +18,27 @@ export default function ArchiveSidebar({ selectedFolderId, onFolderSelect }: Arc const router = useRouter(); const [isCreatingFolder, setIsCreatingFolder] = useState(false); const [deleteModalOpen, setDeleteModalOpen] = useState(false); - const [folderToDelete, setFolderToDelete] = useState(null); - - // 테스트용 더미 데이터 - const [folders, setFolders] = useState([ - { id: '1', name: '찜한 템플릿', templateCount: 32 }, - { id: '2', name: '최근 사용한 템플릿', templateCount: 5 }, - { id: '3', name: '사용자 폴더1', templateCount: 8 }, - { id: '4', name: '사용자 폴더2', templateCount: 3 }, - ]); - - const handleFolderClick = (folderId: string) => { - onFolderSelect(folderId); - console.log('폴더 선택:', folderId); + const [folderToDelete, setFolderToDelete] = useState(null); + + // 폴더 목록 API 연동 + const { data: foldersData } = useFolders(); + const createFolderMutation = useCreateFolder(); + const deleteFolderMutation = useDeleteFolder(); + + // 찜한 템플릿, 최근 사용한 템플릿은 고정 + const fixedFolders = [ + { id: 1, name: '찜한 템플릿' }, + { id: 2, name: '최근 사용한 템플릿' }, + ]; + + // 폴더 목록 합치기 + const folders = [ + ...fixedFolders, + ...(foldersData?.folders?.map((f) => ({ id: f.folderId, name: f.name })) || []), + ]; + + const handleFolderClick = (folderId: number) => { + onFolderSelect(folderId.toString()); }; const handleFolderDoubleClick = (folderId: string) => { @@ -39,19 +50,15 @@ export default function ArchiveSidebar({ selectedFolderId, onFolderSelect }: Arc }; const handleFolderSave = (folderName: string) => { - console.log('폴더 저장:', folderName); - // 새 폴더를 목록에 추가 - const newFolder = { - id: Date.now().toString(), - name: folderName, - templateCount: 0, - }; - setFolders((prev) => [...prev, newFolder]); - setIsCreatingFolder(false); + createFolderMutation.mutate( + { name: folderName }, + { + onSuccess: () => setIsCreatingFolder(false), + }, + ); }; const handleFolderCancel = () => { - console.log('폴더 생성 취소'); setIsCreatingFolder(false); }; @@ -59,19 +66,21 @@ export default function ArchiveSidebar({ selectedFolderId, onFolderSelect }: Arc router.push('/explore'); }; - const handleDeleteClick = (folderId: string) => { + const handleDeleteClick = (folderId: number) => { setFolderToDelete(folderId); setDeleteModalOpen(true); }; const handleDeleteConfirm = () => { if (folderToDelete) { - setFolders((prev) => prev.filter((folder) => folder.id !== folderToDelete)); - console.log('폴더 삭제:', folderToDelete); - // 삭제된 폴더가 현재 선택된 폴더라면 기본 폴더로 변경 - if (selectedFolderId === folderToDelete) { - onFolderSelect('1'); // 찜한 템플릿으로 변경 - } + deleteFolderMutation.mutate(folderToDelete, { + onSuccess: () => { + // 삭제된 폴더가 현재 선택된 폴더라면 기본 폴더로 변경 + if (selectedFolderId === folderToDelete.toString()) { + onFolderSelect('1'); + } + }, + }); } setDeleteModalOpen(false); setFolderToDelete(null); @@ -88,17 +97,17 @@ export default function ArchiveSidebar({ selectedFolderId, onFolderSelect }: Arc style={{ width: '312px', height: '640px' }} >
- {/* 기존 폴더들 */} + {/* 폴더 목록 */} {folders.map((folder) => ( handleFolderClick(folder.id)} + onDoubleClick={() => handleFolderDoubleClick(folder.id.toString())} + onDelete={() => handleDeleteClick(folder.id)} /> ))} @@ -117,6 +126,7 @@ export default function ArchiveSidebar({ selectedFolderId, onFolderSelect }: Arc diff --git a/src/app/(layout)/archive/page.tsx b/src/app/(layout)/archive/page.tsx index 62892b5..975c828 100644 --- a/src/app/(layout)/archive/page.tsx +++ b/src/app/(layout)/archive/page.tsx @@ -4,10 +4,12 @@ import { useState } from 'react'; import ArchiveSidebar from './_components/ArchiveSidebar'; import ArchiveContent from './_components/ArchiveContent'; import { Button } from '@/components/ui/Button'; +import { useRouter } from 'next/navigation'; export default function ArchivePage() { // 기본값을 "찜한 템플릿" (id: '1')으로 설정 const [selectedFolderId, setSelectedFolderId] = useState('1'); + const router = useRouter(); return (
@@ -16,7 +18,12 @@ export default function ArchivePage() { {/* 페이지 제목과 새 템플릿 만들기 버튼 */}

보관함

-
diff --git a/src/app/(layout)/explore/page.tsx b/src/app/(layout)/explore/page.tsx index 4a199b3..d6ee909 100644 --- a/src/app/(layout)/explore/page.tsx +++ b/src/app/(layout)/explore/page.tsx @@ -25,7 +25,8 @@ export default function ExplorePage() { const [recommendTemplates, setRecommendTemplates] = useState([]); const [allTemplates, setAllTemplates] = useState([]); const [totalPages, setTotalPages] = useState(0); - const { currentModal, openModal, closeModal } = useModalStore(); + const { openModal } = useModalStore(); + const [userName, setUserName] = useState('사용자'); const tagOptions: TagType[] = [ '인사말', @@ -69,6 +70,57 @@ export default function ExplorePage() { fetchRecommendTemplates(); }, []); + // 사용자 이름 로드 및 설정 + useEffect(() => { + const token = localStorage.getItem('token'); + console.log('Loaded token:', token); + if (token) { + try { + const payloadBase64Url = token.split('.')[1]; + console.log('Payload Base64URL (raw from token):', payloadBase64Url); + + if (payloadBase64Url) { + // Base64URL을 표준 Base64로 변환 + let base64 = payloadBase64Url.replace(/-/g, '+').replace(/_/g, '/'); + while (base64.length % 4) { + base64 += '='; + } + console.log('Payload Base64 (after B64URL to B64 conversion):', base64); + + const binaryString = atob(base64); // 변환된 base64 문자열 사용 + console.log('Decoded Binary String (raw from atob):', binaryString); + + // 바이너리 문자열을 Uint8Array로 변환 + const bytes = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + + // Uint8Array를 UTF-8 문자열로 디코딩 + const decodedPayloadUtf8 = new TextDecoder('utf-8').decode(bytes); + console.log('Decoded Payload (UTF-8 string):', decodedPayloadUtf8); + + const parsedPayload = JSON.parse(decodedPayloadUtf8); + console.log('Parsed Payload (JS object):', parsedPayload); + + if (parsedPayload && parsedPayload.name) { + setUserName(parsedPayload.name); + console.log('User name set to state:', parsedPayload.name); + + localStorage.setItem('user', JSON.stringify({ name: parsedPayload.name })); + console.log('User object saved to localStorage:', { name: parsedPayload.name }); + } else { + console.log('Name not found in parsed payload or payload is null'); + } + } else { + console.log('payloadBase64Url is undefined or empty'); + } + } catch (error) { + console.error('토큰 디코딩, 사용자 이름 추출 또는 로컬 스토리지 저장 실패:', error); + } + } + }, []); + // 전체 템플릿 데이터 가져오기 useEffect(() => { const fetchTemplates = async () => { @@ -209,7 +261,7 @@ export default function ExplorePage() {

- AI가 [username]님을 위해 추천한 맞춤형 템플릿을 사용해 보세요! + AI가 {userName}님을 위해 추천한 맞춤형 템플릿을 사용해 보세요!

diff --git a/src/app/(layout)/mypage/_components/MypageData.tsx b/src/app/(layout)/mypage/_components/MypageData.tsx index 3c4d0ce..b987838 100644 --- a/src/app/(layout)/mypage/_components/MypageData.tsx +++ b/src/app/(layout)/mypage/_components/MypageData.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import Image from 'next/image'; import IconEdit from '@/assets/icons/icon-edit.svg'; @@ -13,6 +13,21 @@ interface MypageDataProps { export default function MypageData({ profileImage, nickname, onNicknameChange }: MypageDataProps) { const [currentNickname, setCurrentNickname] = useState(nickname); + useEffect(() => { + const userStr = localStorage.getItem('user'); + if (userStr) { + try { + const userData = JSON.parse(userStr); + if (userData.name) { + setCurrentNickname(userData.name); + onNicknameChange(userData.name); + } + } catch (error) { + console.error('Failed to parse user data:', error); + } + } + }, []); + const handleNicknameChange = (e: React.ChangeEvent) => { const newNickname = e.target.value; setCurrentNickname(newNickname); diff --git a/src/app/(layout)/mypage/page.tsx b/src/app/(layout)/mypage/page.tsx index c430b0d..7bd149f 100644 --- a/src/app/(layout)/mypage/page.tsx +++ b/src/app/(layout)/mypage/page.tsx @@ -1,14 +1,28 @@ 'use client'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import MypageData from './_components/MypageData'; import MypageGlow from './_components/MypageGlow'; import MypageCancelAccount from './_components/MypageCancelAccount'; export default function MyPage() { - const [nickname, setNickname] = useState('사용자닉네임'); + const [nickname, setNickname] = useState(''); const glowScore = 1213; + useEffect(() => { + const userStr = localStorage.getItem('user'); + if (userStr) { + try { + const userData = JSON.parse(userStr); + if (userData.name) { + setNickname(userData.name); + } + } catch (error) { + console.error('Failed to parse user data:', error); + } + } + }, []); + const handleNicknameChange = (newNickname: string) => { setNickname(newNickname); }; diff --git a/src/hooks/folder/useCreateFolder.ts b/src/hooks/folder/useCreateFolder.ts new file mode 100644 index 0000000..328b22f --- /dev/null +++ b/src/hooks/folder/useCreateFolder.ts @@ -0,0 +1,12 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { createFolder, CreateFolderRequest } from '@/services/folders/createFolder'; + +export const useCreateFolder = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (data: CreateFolderRequest) => createFolder(data), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['folders'] }); + }, + }); +}; diff --git a/src/hooks/folder/useDeleteFolder.ts b/src/hooks/folder/useDeleteFolder.ts new file mode 100644 index 0000000..14a88d8 --- /dev/null +++ b/src/hooks/folder/useDeleteFolder.ts @@ -0,0 +1,12 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { deleteFolder } from '@/services/folders/deleteFolder'; + +export const useDeleteFolder = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (folderId: number) => deleteFolder(folderId), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['folders'] }); + }, + }); +}; diff --git a/src/hooks/folder/useFolderDetail.ts b/src/hooks/folder/useFolderDetail.ts new file mode 100644 index 0000000..09fd6e9 --- /dev/null +++ b/src/hooks/folder/useFolderDetail.ts @@ -0,0 +1,10 @@ +import { useQuery } from '@tanstack/react-query'; +import { getFolderDetail } from '@/services/folders/getFolderDetail'; + +export const useFolderDetail = (folderId: number) => { + return useQuery({ + queryKey: ['folder', folderId], + queryFn: () => getFolderDetail(folderId), + enabled: !!folderId, + }); +}; diff --git a/src/hooks/folder/useFolders.ts b/src/hooks/folder/useFolders.ts new file mode 100644 index 0000000..32cc45a --- /dev/null +++ b/src/hooks/folder/useFolders.ts @@ -0,0 +1,9 @@ +import { useQuery } from '@tanstack/react-query'; +import { getFolders } from '@/services/folders/getFolders'; + +export const useFolders = () => { + return useQuery({ + queryKey: ['folders'], + queryFn: getFolders, + }); +}; diff --git a/src/hooks/template/useRecentlyUsedTemplates.ts b/src/hooks/template/useRecentlyUsedTemplates.ts new file mode 100644 index 0000000..e990778 --- /dev/null +++ b/src/hooks/template/useRecentlyUsedTemplates.ts @@ -0,0 +1,9 @@ +import { useQuery } from '@tanstack/react-query'; +import { getRecentlyUsedTemplates } from '@/services/template/getRecentlyUsedTemplates'; + +export const useRecentlyUsedTemplates = () => { + return useQuery({ + queryKey: ['templates', 'recently-used'], + queryFn: getRecentlyUsedTemplates, + }); +}; diff --git a/src/services/folders/createFolder.ts b/src/services/folders/createFolder.ts new file mode 100644 index 0000000..18e5a52 --- /dev/null +++ b/src/services/folders/createFolder.ts @@ -0,0 +1,14 @@ +import { customFetch } from '@/utils/customFetch'; +import { Folder } from './getFolders'; + +export interface CreateFolderRequest { + name: string; +} + +export const createFolder = async (payload: CreateFolderRequest): Promise => { + const data = await customFetch(`/folders`, { + method: 'POST', + body: JSON.stringify(payload), + }); + return data ?? null; +}; diff --git a/src/services/folders/deleteFolder.ts b/src/services/folders/deleteFolder.ts new file mode 100644 index 0000000..5baccb2 --- /dev/null +++ b/src/services/folders/deleteFolder.ts @@ -0,0 +1,7 @@ +import { customFetch } from '@/utils/customFetch'; + +export const deleteFolder = async (folderId: number): Promise => { + await customFetch(`/folders/${folderId}`, { + method: 'DELETE', + }); +}; diff --git a/src/services/folders/getFolderDetail.ts b/src/services/folders/getFolderDetail.ts new file mode 100644 index 0000000..69ca89c --- /dev/null +++ b/src/services/folders/getFolderDetail.ts @@ -0,0 +1,13 @@ +import { customFetch } from '@/utils/customFetch'; +import { Folder } from './getFolders'; +import { Template } from '@/services/template/getTemplates'; + +export interface FolderDetailResponse { + folder: Folder; + templates: Template[]; +} + +export const getFolderDetail = async (folderId: number): Promise => { + const data = await customFetch(`/folders/${folderId}`); + return data ?? null; +}; diff --git a/src/services/template/getRecentlyUsedTemplates.ts b/src/services/template/getRecentlyUsedTemplates.ts new file mode 100644 index 0000000..778cbf6 --- /dev/null +++ b/src/services/template/getRecentlyUsedTemplates.ts @@ -0,0 +1,13 @@ +import { customFetch } from '@/utils/customFetch'; +import { Template } from './getTemplates'; + +interface GetRecentlyUsedTemplatesResponse { + templates: Template[]; + totalPage: number; +} + +export const getRecentlyUsedTemplates = + async (): Promise => { + const data = await customFetch(`/templates/me/recently-used`); + return data ?? null; + };