diff --git a/index.html b/index.html index 0d56746..e983fec 100644 --- a/index.html +++ b/index.html @@ -2,6 +2,7 @@
+ diff --git a/package-lock.json b/package-lock.json index 525a00d..4926afc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7918,6 +7918,12 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "license": "MIT" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -9580,9 +9586,9 @@ } }, "node_modules/vite": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", - "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", + "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, "license": "MIT", "dependencies": { diff --git a/src/api/fetchYouTubeVideoData.ts b/src/api/fetchYouTubeVideoData.ts index e60d135..72c9c05 100644 --- a/src/api/fetchYouTubeVideoData.ts +++ b/src/api/fetchYouTubeVideoData.ts @@ -1,20 +1,25 @@ export const fetchYouTubeVideoData = async (videoId: string) => { const apiKey = import.meta.env.VITE_YOUTUBE_API_KEY; - const response = await fetch( - `https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id=${videoId}&key=${apiKey}`, - ); + try { + const response = await fetch( + `https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id=${videoId}&key=${apiKey}`, + ); - if (!response.ok) { - throw new Error('비디오 정보를 가져오는데 실패했습니다.'); - } + if (!response.ok) { + throw new Error('비디오 정보를 가져오는데 실패했습니다. status:' + response.status); + } - const data = await response.json(); - const videoDetails = data.items[0]; + const data = await response.json(); + const videoDetails = data.items[0]; - return { - title: videoDetails.snippet.title, - creator: videoDetails.snippet.channelTitle, - uploadDate: videoDetails.snippet.publishedAt, - views: videoDetails.statistics.viewCount, - }; + return { + title: videoDetails.snippet.title, + creator: videoDetails.snippet.channelTitle, + uploadDate: videoDetails.snippet.publishedAt, + views: videoDetails.statistics.viewCount, + }; + } catch (error) { + console.error(error); + throw new Error('비디오 정보를 가져오는데 실패했습니다.'); + } }; diff --git a/src/components/comment/CommentActions.tsx b/src/components/comment/CommentActions.tsx deleted file mode 100644 index dd86f79..0000000 --- a/src/components/comment/CommentActions.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { css } from '@emotion/react'; - -interface CommentActionsProps { - onEdit: () => void; - onDelete: () => void; -} - -const CommentActions: React.FC플리 선택
-플레이리스트를 찾을 수 없습니다.
; + return null; } const userModel: UserModel = { @@ -53,43 +40,24 @@ const PlaylistDetailPage = () => { photoURL: playlistUser?.photoURL ?? '', subscriptions: playlistUser?.subscriptions ?? [], }; - - const handleVideoSelect = (videoId: string) => { - setSelectedVideoId(videoId); - }; - - const handleCompleteClick = () => { - if (selectedVideoId) { - navigate(`/post/add/newPost?pli=${playlistId}&videoId=${selectedVideoId}`); - } - }; + const handleBackClick = () => navigate('/playlist'); const isOwner = user?.uid === playlist?.userId; return ( <> -본 서비스는 구글 로그인을 통해 사용자의 이름, email 주소, 프로필 이미지를 수집하며, 수집된 diff --git a/src/pages/Profile.tsx b/src/pages/Profile.tsx index 0b05397..36cb50f 100644 --- a/src/pages/Profile.tsx +++ b/src/pages/Profile.tsx @@ -1,6 +1,7 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import { css } from '@emotion/react'; +import { useQueryClient } from '@tanstack/react-query'; import { HiOutlinePencil, HiOutlinePlay, HiOutlineHeart } from 'react-icons/hi2'; import { useNavigate, useParams } from 'react-router-dom'; @@ -14,11 +15,11 @@ import Playlists from '@/components/playlist/Playlists'; import Post from '@/components/post/Post'; import { PATH } from '@/constants/path'; import { useAuth } from '@/hooks/useAuth'; -import { useLikedPosts } from '@/hooks/useLikedPosts'; // 좋아요한 포스트를 가져오는 훅 +import { useLikedPosts } from '@/hooks/useLikedPosts'; import { useUserPlaylists } from '@/hooks/usePlaylists'; import { useAddPlaylist } from '@/hooks/usePostPlaylist'; import { useUserData } from '@/hooks/useUserData'; -import { useUserPosts } from '@/hooks/useUserPosts'; // 사용자 포스트를 가져오는 훅 +import { useUserPosts } from '@/hooks/useUserPosts'; import ProfileInfo from '../components/profile/ProfileInfo'; @@ -39,6 +40,7 @@ const ProfilePage: React.FC = () => { const { userPosts, loadingPosts, error: userPostsError } = useUserPosts(userId || ''); const { likedPosts, loadingLikedPosts, error: likedPostsError } = useLikedPosts(userId || ''); const addPlaylistMutation = useAddPlaylist(); + const queryClient = useQueryClient(); useEffect(() => { if (currentUser && userData) { @@ -46,6 +48,18 @@ const ProfilePage: React.FC = () => { } }, [currentUser, userData]); + const handleTabChange = useCallback( + (tabId: string) => { + setActiveTab(tabId); + if (tabId === 'likes') { + queryClient.invalidateQueries({ queryKey: ['likedPosts', userId] }); + } else if (tabId === 'post') { + queryClient.invalidateQueries({ queryKey: ['posts', userId] }); + } + }, + [userId, queryClient], + ); + const handleSettingsClick = () => { navigate(PATH.SETTINGS); }; @@ -93,7 +107,7 @@ const ProfilePage: React.FC = () => { onFollowToggle={handleFollowToggle} />
Please log in to view your playlists.
; @@ -70,70 +114,86 @@ const SelectPliPage = () => { const filteredPlaylists = myPlaylists?.filter((playlist) => playlist.videos.length > 0) || []; - if (videoId) { - return ( - <> -지원
본 서비스는 사용자가 유튜브 영상의 링크와 함께 게시글을 작성할 수 있는 소셜 네트워크
diff --git a/src/stores/modalStore.ts b/src/stores/modalStore.ts
new file mode 100644
index 0000000..eb8954d
--- /dev/null
+++ b/src/stores/modalStore.ts
@@ -0,0 +1,21 @@
+import create from 'zustand';
+
+type ModalStore = {
+ openModals: string[];
+ openModal: (modalType: string) => void;
+ closeModal: (modalType: string) => void;
+ closeAllModals: () => void;
+ isAnyModalOpen: () => boolean;
+};
+
+export const useModalStore = create