From ecc8da00c642cd32e93ee75ad462a1c5ae1e417c Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 00:47:48 +0900 Subject: [PATCH 01/12] =?UTF-8?q?refactor:=20Main=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=ED=8C=8C=EC=9D=BC=20=EC=9C=84=EC=B9=98=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/{Main.tsx => Main/index.tsx} | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) rename src/pages/{Main.tsx => Main/index.tsx} (92%) diff --git a/src/pages/Main.tsx b/src/pages/Main/index.tsx similarity index 92% rename from src/pages/Main.tsx rename to src/pages/Main/index.tsx index 5c5e260..e820d7b 100644 --- a/src/pages/Main.tsx +++ b/src/pages/Main/index.tsx @@ -72,10 +72,10 @@ export default function Main() {
setShowSidebar(true)} />
-
+
-

+

지금까지 {Math.max(mainData?.writtenLetterNumber || 0, messages.length)}개의
메시지가 모였어요 💌 @@ -86,7 +86,7 @@ export default function Main() { 도시에 불이 켜져요

-
+
navigate('/write')} > - 메시지 작성하기 + 메시지 작성하기
@@ -123,9 +123,9 @@ export default function Main() { )} onClick={() => navigate('/write')} > - 메시지 작성하기 + 메시지 작성하기 -
+
{messages.map((message, index) => ( Date: Sun, 20 Apr 2025 00:50:09 +0900 Subject: [PATCH 02/12] =?UTF-8?q?refactor:=20Main=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=82=B4=EC=97=90=EC=84=9C=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{containers/Main => pages/Main/components}/Header.tsx | 0 .../Main => pages/Main/components}/NoticeSection.tsx | 2 +- src/{ => pages/Main}/components/TopButton.tsx | 0 src/pages/Main/index.tsx | 6 +++--- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/{containers/Main => pages/Main/components}/Header.tsx (100%) rename src/{containers/Main => pages/Main/components}/NoticeSection.tsx (96%) rename src/{ => pages/Main}/components/TopButton.tsx (100%) diff --git a/src/containers/Main/Header.tsx b/src/pages/Main/components/Header.tsx similarity index 100% rename from src/containers/Main/Header.tsx rename to src/pages/Main/components/Header.tsx diff --git a/src/containers/Main/NoticeSection.tsx b/src/pages/Main/components/NoticeSection.tsx similarity index 96% rename from src/containers/Main/NoticeSection.tsx rename to src/pages/Main/components/NoticeSection.tsx index 540e3eb..a9394b4 100644 --- a/src/containers/Main/NoticeSection.tsx +++ b/src/pages/Main/components/NoticeSection.tsx @@ -50,7 +50,7 @@ export default function NoticeSection({ notices }: NoticeSectionProps) { return (
-

공지

+

공지

Date: Sun, 20 Apr 2025 00:53:45 +0900 Subject: [PATCH 03/12] =?UTF-8?q?refactor:=20Message=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Main/components/MessageList.tsx | 29 +++++++++++++++++++++++ src/pages/Main/index.tsx | 28 ++++++++++------------ 2 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 src/pages/Main/components/MessageList.tsx diff --git a/src/pages/Main/components/MessageList.tsx b/src/pages/Main/components/MessageList.tsx new file mode 100644 index 0000000..3c5a3a3 --- /dev/null +++ b/src/pages/Main/components/MessageList.tsx @@ -0,0 +1,29 @@ +import MessageCard from '@/components/MessageCard' + +interface MessageListProps { + messages: MessageType[] + hasNextPage: boolean + observerRef: (node?: Element | null) => void + setActiveMessage: (message: MessageType) => void +} + +export default function MessageList({ + messages, + hasNextPage, + observerRef, + setActiveMessage, +}: MessageListProps) { + return ( +
+ {messages.map((message, index) => ( + setActiveMessage(message)} + /> + ))} + {messages.length > 0 && hasNextPage &&
} +
+ ) +} diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index 0cfa375..6564bbb 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -1,4 +1,3 @@ -import MessageCard from '@/components/MessageCard' import SolidButton from '@/components/SolidButton' import TopButton from './components/TopButton' import Header from './components/Header' @@ -7,15 +6,16 @@ import useBodyBackgroundColor from '@/hooks/useBodyBackgroundColor' import { useMainData } from '@/hooks/useMainData' import { useGetMessages } from '@/hooks/useMessage' import Sidebar from '@/layouts/Sidebar' -import { useEffect, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import { useInView } from 'react-intersection-observer' import { useLocation, useNavigate } from 'react-router-dom' import { twMerge } from 'tailwind-merge' import MessageModal from '@/components/MessageModal' import { extractImgLink } from '@/utils/extractImgLink' import { PencilIcon } from '@/assets/icons' +import MessageList from './components/MessageList' -export default function Main() { +export default function MainPage() { const [showFade, setShowFade] = useState(false) const [showSidebar, setShowSidebar] = useState(false) const [activeMessage, setActiveMessage] = useState() @@ -37,7 +37,10 @@ export default function Main() { refetch: messagesRefetch, } = useGetMessages() - const messages = data?.pages.flatMap((page) => page.openedLetters ?? []) ?? [] + const messages = useMemo( + () => data?.pages.flatMap((page) => page.openedLetters ?? []) ?? [], + [data?.pages] + ) useEffect(() => { const handleScroll = () => { @@ -125,17 +128,12 @@ export default function Main() { > 메시지 작성하기 -
- {messages.map((message, index) => ( - setActiveMessage(message)} - /> - ))} - {messages.length > 0 && hasNextPage &&
} -
+
From 98e3f571fa67b2f449f44fb2caf2696583fa5bee Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 00:56:47 +0900 Subject: [PATCH 04/12] =?UTF-8?q?refactor:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1=20=EB=B2=84=ED=8A=BC=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Main/components/WriteMessageButton.tsx | 34 +++++++++++++++++++ src/pages/Main/index.tsx | 33 +++--------------- 2 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 src/pages/Main/components/WriteMessageButton.tsx diff --git a/src/pages/Main/components/WriteMessageButton.tsx b/src/pages/Main/components/WriteMessageButton.tsx new file mode 100644 index 0000000..2ef0646 --- /dev/null +++ b/src/pages/Main/components/WriteMessageButton.tsx @@ -0,0 +1,34 @@ +import { PencilIcon } from '@/assets/icons' +import SolidButton from '@/components/SolidButton' +import { Link } from 'react-router-dom' +import { twMerge } from 'tailwind-merge' + +interface WriteMessageButtonProps { + isVisible: boolean + isFixed?: boolean + buttonRef?: (node?: Element | null) => void +} + +const WriteMessageButton = ({ isVisible, isFixed = false, buttonRef }: WriteMessageButtonProps) => { + const className = isFixed + ? twMerge( + 'fixed bottom-[100px] left-1/2 z-50 -translate-x-1/2 rounded-full py-4 transition-opacity duration-200', + isVisible ? 'pointer-events-none opacity-0' : 'opacity-100' + ) + : 'relative z-10 py-4 mx-auto rounded-full' + + return ( +
+ + + 메시지 작성하기 + + + {!isFixed && ( +
+ )} +
+ ) +} + +export default WriteMessageButton diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index 6564bbb..8bfe76d 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -1,4 +1,3 @@ -import SolidButton from '@/components/SolidButton' import TopButton from './components/TopButton' import Header from './components/Header' import NoticeSection from './components/NoticeSection' @@ -8,12 +7,12 @@ import { useGetMessages } from '@/hooks/useMessage' import Sidebar from '@/layouts/Sidebar' import { useEffect, useMemo, useState } from 'react' import { useInView } from 'react-intersection-observer' -import { useLocation, useNavigate } from 'react-router-dom' +import { useLocation } from 'react-router-dom' import { twMerge } from 'tailwind-merge' import MessageModal from '@/components/MessageModal' import { extractImgLink } from '@/utils/extractImgLink' -import { PencilIcon } from '@/assets/icons' import MessageList from './components/MessageList' +import WriteMessageButton from './components/WriteMessageButton' export default function MainPage() { const [showFade, setShowFade] = useState(false) @@ -21,10 +20,9 @@ export default function MainPage() { const [activeMessage, setActiveMessage] = useState() const [ref, inView] = useInView() const [buttonRef, isButtonVisible] = useInView({ - rootMargin: '-40px 0px 100%', + rootMargin: '-50px 0px 100%', threshold: 0, }) - const navigate = useNavigate() const location = useLocation() useBodyBackgroundColor('#14192F') @@ -99,35 +97,14 @@ export default function MainPage() {
-
- navigate('/write')} - > - 메시지 작성하기 - -
-
+ +
- navigate('/write')} - > - 메시지 작성하기 - Date: Sun, 20 Apr 2025 00:59:26 +0900 Subject: [PATCH 05/12] =?UTF-8?q?refactor:=20useScrollFade=20=ED=9B=85=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useScrollFade.ts | 17 +++++++++++++++++ src/pages/Main/index.tsx | 20 +++++--------------- 2 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 src/hooks/useScrollFade.ts diff --git a/src/hooks/useScrollFade.ts b/src/hooks/useScrollFade.ts new file mode 100644 index 0000000..5e879b7 --- /dev/null +++ b/src/hooks/useScrollFade.ts @@ -0,0 +1,17 @@ +import { useEffect, useState } from 'react' + +export const useScrollFade = (targetPosition: number = 430) => { + const [showFade, setShowFade] = useState(false) + + useEffect(() => { + const handleScroll = () => { + const scrollPosition = window.scrollY + setShowFade(scrollPosition > targetPosition) + } + + window.addEventListener('scroll', handleScroll) + return () => window.removeEventListener('scroll', handleScroll) + }, [targetPosition]) + + return showFade +} diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index 8bfe76d..059c61c 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -13,9 +13,9 @@ import MessageModal from '@/components/MessageModal' import { extractImgLink } from '@/utils/extractImgLink' import MessageList from './components/MessageList' import WriteMessageButton from './components/WriteMessageButton' +import { useScrollFade } from '@/hooks/useScrollFade' export default function MainPage() { - const [showFade, setShowFade] = useState(false) const [showSidebar, setShowSidebar] = useState(false) const [activeMessage, setActiveMessage] = useState() const [ref, inView] = useInView() @@ -23,7 +23,8 @@ export default function MainPage() { rootMargin: '-50px 0px 100%', threshold: 0, }) - const location = useLocation() + const { state } = useLocation() + const showFade = useScrollFade() useBodyBackgroundColor('#14192F') const { data: mainData, refetch: mainDataRefetch } = useMainData() @@ -40,17 +41,6 @@ export default function MainPage() { [data?.pages] ) - useEffect(() => { - const handleScroll = () => { - const scrollPosition = window.scrollY - const targetPosition = 430 - setShowFade(scrollPosition > targetPosition) - } - - window.addEventListener('scroll', handleScroll) - return () => window.removeEventListener('scroll', handleScroll) - }, []) - useEffect(() => { if (inView && hasNextPage && !isFetchingNextPage) { fetchNextPage() @@ -58,11 +48,11 @@ export default function MainPage() { }, [inView, hasNextPage, isFetchingNextPage, fetchNextPage]) useEffect(() => { - if (location.state && location.state.from === 'write') { + if (state?.from === 'write') { mainDataRefetch() messagesRefetch() } - }, [location]) + }, [state?.from]) return ( <> From 6f911f3677e9f76150320a047a1ce61e62beb38d Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 01:01:14 +0900 Subject: [PATCH 06/12] =?UTF-8?q?refactor:=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Main/components/CityBackground.tsx | 22 ++++++++++++++++++++ src/pages/Main/index.tsx | 18 +++++++--------- 2 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 src/pages/Main/components/CityBackground.tsx diff --git a/src/pages/Main/components/CityBackground.tsx b/src/pages/Main/components/CityBackground.tsx new file mode 100644 index 0000000..d8acafa --- /dev/null +++ b/src/pages/Main/components/CityBackground.tsx @@ -0,0 +1,22 @@ +import { extractImgLink } from '@/utils/extractImgLink' + +interface CityBackgroundProps { + messageCount: number +} + +const CityBackground = ({ messageCount }: CityBackgroundProps) => { + return ( +
+
+ 배경 이미지 +
+
+
+ ) +} + +export default CityBackground diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index 059c61c..e066600 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -10,10 +10,10 @@ import { useInView } from 'react-intersection-observer' import { useLocation } from 'react-router-dom' import { twMerge } from 'tailwind-merge' import MessageModal from '@/components/MessageModal' -import { extractImgLink } from '@/utils/extractImgLink' import MessageList from './components/MessageList' import WriteMessageButton from './components/WriteMessageButton' import { useScrollFade } from '@/hooks/useScrollFade' +import CityBackground from './components/CityBackground' export default function MainPage() { const [showSidebar, setShowSidebar] = useState(false) @@ -41,6 +41,11 @@ export default function MainPage() { [data?.pages] ) + const messageCount = useMemo( + () => Math.max(mainData?.writtenLetterNumber || 0, messages.length), + [mainData?.writtenLetterNumber, messages.length] + ) + useEffect(() => { if (inView && hasNextPage && !isFetchingNextPage) { fetchNextPage() @@ -77,16 +82,7 @@ export default function MainPage() { 도시에 불이 켜져요

-
-
- 배경 이미지 -
-
-
+
Date: Sun, 20 Apr 2025 01:05:33 +0900 Subject: [PATCH 07/12] =?UTF-8?q?refactor:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=ED=95=A8=EC=88=98=20=EC=9E=AC?= =?UTF-8?q?=EC=84=B1=EC=84=B1=20=EA=B4=80=EB=A0=A8=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Main/components/MessageCounter.tsx | 22 ++++++++++++++ src/pages/Main/index.tsx | 30 +++++++++----------- 2 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 src/pages/Main/components/MessageCounter.tsx diff --git a/src/pages/Main/components/MessageCounter.tsx b/src/pages/Main/components/MessageCounter.tsx new file mode 100644 index 0000000..f073632 --- /dev/null +++ b/src/pages/Main/components/MessageCounter.tsx @@ -0,0 +1,22 @@ +interface MessageCounterProps { + messageCount: number +} + +const MessageCounter = ({ messageCount }: MessageCounterProps) => { + return ( +
+

+ 지금까지 {messageCount}개의 +
+ 메시지가 모였어요 💌 +

+

+ 전체 메시지가 쌓일수록 +
+ 도시에 불이 켜져요 +

+
+ ) +} + +export default MessageCounter diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index e066600..58f80b3 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -5,7 +5,7 @@ import useBodyBackgroundColor from '@/hooks/useBodyBackgroundColor' import { useMainData } from '@/hooks/useMainData' import { useGetMessages } from '@/hooks/useMessage' import Sidebar from '@/layouts/Sidebar' -import { useEffect, useMemo, useState } from 'react' +import { useCallback, useEffect, useMemo, useState } from 'react' import { useInView } from 'react-intersection-observer' import { useLocation } from 'react-router-dom' import { twMerge } from 'tailwind-merge' @@ -14,6 +14,7 @@ import MessageList from './components/MessageList' import WriteMessageButton from './components/WriteMessageButton' import { useScrollFade } from '@/hooks/useScrollFade' import CityBackground from './components/CityBackground' +import MessageCounter from './components/MessageCounter' export default function MainPage() { const [showSidebar, setShowSidebar] = useState(false) @@ -46,6 +47,14 @@ export default function MainPage() { [mainData?.writtenLetterNumber, messages.length] ) + const handleSidebarToggle = useCallback(() => { + setShowSidebar(true) + }, []) + + const handleCloseModal = useCallback(() => { + setActiveMessage(undefined) + }, []) + useEffect(() => { if (inView && hasNextPage && !isFetchingNextPage) { fetchNextPage() @@ -61,27 +70,14 @@ export default function MainPage() { return ( <> - {activeMessage && ( - setActiveMessage(undefined)} /> - )} + {activeMessage && } -
setShowSidebar(true)} /> +
-
-

- 지금까지 {Math.max(mainData?.writtenLetterNumber || 0, messages.length)}개의 -
- 메시지가 모였어요 💌 -

-

- 전체 메시지가 쌓일수록 -
- 도시에 불이 켜져요 -

-
+ From 6352250b01964aea481f5282d2e73208508eb9f9 Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 01:11:05 +0900 Subject: [PATCH 08/12] =?UTF-8?q?refactor:=20=EC=BA=90=EC=8B=B1=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=83=81=EC=88=98=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/cache.ts | 2 ++ src/hooks/useMainData.ts | 5 +++-- src/hooks/useMessage.ts | 13 +++++++------ src/hooks/useNews.tsx | 5 +++-- src/hooks/useNotices.ts | 9 +++++---- src/hooks/useShare..ts | 5 +++-- 6 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 src/constants/cache.ts diff --git a/src/constants/cache.ts b/src/constants/cache.ts new file mode 100644 index 0000000..91f949f --- /dev/null +++ b/src/constants/cache.ts @@ -0,0 +1,2 @@ +export const CACHE_TIME = 1000 * 60 * 60 // 1시간 +export const STALE_TIME = 1000 * 60 * 5 // 5분 diff --git a/src/hooks/useMainData.ts b/src/hooks/useMainData.ts index 496af01..4093f29 100644 --- a/src/hooks/useMainData.ts +++ b/src/hooks/useMainData.ts @@ -1,11 +1,12 @@ import { getMainData } from '@/apis/message' +import { CACHE_TIME, STALE_TIME } from '@/constants/cache' import { useQuery } from '@tanstack/react-query' export const useMainData = () => { return useQuery({ queryKey: ['main-data'], queryFn: () => getMainData(), - staleTime: 1000 * 60 * 5, // 5분 - gcTime: 1000 * 60 * 60, // 1시간 + staleTime: STALE_TIME, + gcTime: CACHE_TIME, }) } diff --git a/src/hooks/useMessage.ts b/src/hooks/useMessage.ts index ea73366..00af8a7 100644 --- a/src/hooks/useMessage.ts +++ b/src/hooks/useMessage.ts @@ -1,4 +1,5 @@ import { getMessages, getMyMessageDetail, getMyMessages } from '@/apis/message' +import { CACHE_TIME, STALE_TIME } from '@/constants/cache' import { useInfiniteQuery, useQuery } from '@tanstack/react-query' const MESSAGE_SIZE = 10 @@ -14,8 +15,8 @@ export const useGetMessages = () => { return allPages.length }, initialPageParam: 0, - staleTime: 1000 * 60 * 5, // 5분 - gcTime: 1000 * 60 * 60, // 1시간 + staleTime: STALE_TIME, + gcTime: CACHE_TIME, }) } @@ -23,8 +24,8 @@ export const useGetMyMessages = () => { return useQuery({ queryKey: ['my-messages'], queryFn: () => getMyMessages(), - staleTime: 1000 * 60 * 5, // 5분 - gcTime: 1000 * 60 * 60, // 1시간 + staleTime: STALE_TIME, + gcTime: CACHE_TIME, }) } @@ -32,8 +33,8 @@ export const useGetMyMessageDetail = (id: string) => { return useQuery({ queryKey: ['my-message-detail', id], queryFn: () => getMyMessageDetail(id), - staleTime: 1000 * 60 * 5, // 5분 - gcTime: 1000 * 60 * 60, // 1시간 + staleTime: STALE_TIME, + gcTime: CACHE_TIME, retry: 0, }) } diff --git a/src/hooks/useNews.tsx b/src/hooks/useNews.tsx index 8b7579a..7ec78d9 100644 --- a/src/hooks/useNews.tsx +++ b/src/hooks/useNews.tsx @@ -1,4 +1,5 @@ import { getNews } from '@/apis/news' +import { CACHE_TIME, STALE_TIME } from '@/constants/cache' import { useInfiniteQuery } from '@tanstack/react-query' const NEWS_SIZE = 10 @@ -14,7 +15,7 @@ export const useGetNews = () => { return allPages.length }, initialPageParam: 0, - staleTime: 1000 * 60 * 5, // 5분 - gcTime: 1000 * 60 * 60, // 1시간 + staleTime: STALE_TIME, + gcTime: CACHE_TIME, }) } diff --git a/src/hooks/useNotices.ts b/src/hooks/useNotices.ts index 7b3f7e1..fa7cf93 100644 --- a/src/hooks/useNotices.ts +++ b/src/hooks/useNotices.ts @@ -1,4 +1,5 @@ import { getNoticeById, getNotices } from '@/apis/notice' +import { CACHE_TIME, STALE_TIME } from '@/constants/cache' import { useInfiniteQuery, useQuery } from '@tanstack/react-query' export const useGetNotices = (size: number) => { @@ -12,8 +13,8 @@ export const useGetNotices = (size: number) => { return allPages.length // 다음 페이지 번호 }, initialPageParam: 0, - staleTime: 1000 * 60 * 5, // 5분 - gcTime: 1000 * 60 * 60, // 1시간 + staleTime: STALE_TIME, + gcTime: CACHE_TIME, }) } @@ -21,7 +22,7 @@ export const useGetNoticeById = (id: string) => { return useQuery({ queryKey: ['notice', id], queryFn: () => getNoticeById(id), - staleTime: 1000 * 60 * 60, // 1시간 - gcTime: 1000 * 60 * 60 * 2, // 2시간 + staleTime: CACHE_TIME, + gcTime: CACHE_TIME * 2, }) } diff --git a/src/hooks/useShare..ts b/src/hooks/useShare..ts index 26e0079..1f5f964 100644 --- a/src/hooks/useShare..ts +++ b/src/hooks/useShare..ts @@ -1,11 +1,12 @@ import { getSharing } from '@/apis/share' +import { CACHE_TIME, STALE_TIME } from '@/constants/cache' import { useQuery } from '@tanstack/react-query' export const useGetSharing = () => { return useQuery({ queryKey: ['sharing'], queryFn: () => getSharing(), - staleTime: 1000 * 60 * 5, // 5분 - gcTime: 1000 * 60 * 60, // 1시간 + staleTime: STALE_TIME, + gcTime: CACHE_TIME, }) } From 072e889ffa147fe76e16c3f23230a6ab124a5453 Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 21:53:35 +0900 Subject: [PATCH 09/12] =?UTF-8?q?refactor:=20api=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message.ts | 50 ++++++++++++++++++---------------------- src/pages/Main/index.tsx | 27 ++++++++++++++++++++-- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/apis/message.ts b/src/apis/message.ts index 7298ba0..656f237 100644 --- a/src/apis/message.ts +++ b/src/apis/message.ts @@ -1,39 +1,33 @@ import { client } from './client' export const getMessages = async (page: number, size: number) => { - try { - const { - data: { data }, - } = await client.get('/mainPage/letter', { - params: { - page, - size, - }, - }) - return data - } catch (error) { - if (error instanceof Error) { - console.error(error.message) - } + const { + data: { data }, + } = await client.get('/mainPage/letter', { + params: { + page, + size, + }, + }) + if (!data) { + throw new Error('No messages received from server') } + return data } export const getMainData = async () => { - try { - const { - data: { data }, - } = await client.get('/mainPage', { - params: { - page: 0, - size: 1, - }, - }) - return data - } catch (error) { - if (error instanceof Error) { - console.error(error.message) - } + const { + data: { data }, + } = await client.get('/mainPage', { + params: { + page: 0, + size: 1, + }, + }) + if (!data) { + throw new Error('No main data received from server') } + return data } export const getSearchResult = async (keyword: string, target: string) => { diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index 58f80b3..984e360 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -15,6 +15,7 @@ import WriteMessageButton from './components/WriteMessageButton' import { useScrollFade } from '@/hooks/useScrollFade' import CityBackground from './components/CityBackground' import MessageCounter from './components/MessageCounter' +import SolidButton from '@/components/SolidButton' export default function MainPage() { const [showSidebar, setShowSidebar] = useState(false) @@ -28,13 +29,14 @@ export default function MainPage() { const showFade = useScrollFade() useBodyBackgroundColor('#14192F') - const { data: mainData, refetch: mainDataRefetch } = useMainData() + const { data: mainData, refetch: mainDataRefetch, isError: isMainDataError } = useMainData() const { data, fetchNextPage, hasNextPage, isFetchingNextPage, refetch: messagesRefetch, + isError: isMessagesError, } = useGetMessages() const messages = useMemo( @@ -68,6 +70,27 @@ export default function MainPage() { } }, [state?.from]) + if (isMainDataError || isMessagesError) { + return ( +
+
+

데이터를 불러오는데 실패했습니다.

+ { + mainDataRefetch() + messagesRefetch() + }} + > + 다시 시도하기 + +
+
+ ) + } + return ( <> {activeMessage && } @@ -75,7 +98,7 @@ export default function MainPage() {
-
+
From e2982c5d2b93bc67a53ecfe2fa55d2c8792b009e Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 22:28:04 +0900 Subject: [PATCH 10/12] =?UTF-8?q?feat:=20query=20=EB=B0=8F=20mutation=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=8B=9C,=20Sentry=EC=97=90=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.tsx | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 49374d4..4448caa 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,7 @@ import { createRoot } from 'react-dom/client' import App from '@/App' import '@/styles/index.css' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query' import * as Sentry from '@sentry/react' import { browserTracingIntegration, replayIntegration } from '@sentry/react' @@ -16,7 +16,30 @@ Sentry.init({ tracePropagationTargets: ['localhost', import.meta.env.VITE_API_URL], }) -const queryClient = new QueryClient() +const queryClient = new QueryClient({ + queryCache: new QueryCache({ + onError: (error) => { + if (error instanceof Error) { + Sentry.captureException(error) + } else { + Sentry.captureMessage('Unknown Query Error', { + extra: { error }, + }) + } + }, + }), + mutationCache: new MutationCache({ + onError: (error) => { + if (error instanceof Error) { + Sentry.captureException(error) + } else { + Sentry.captureMessage('Unknown Mutation Error', { + extra: { error }, + }) + } + }, + }), +}) createRoot(document.getElementById('root')!).render( From 39e9319a0c1f157255dc3ed161739f0cb73dc3b1 Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 23:08:13 +0900 Subject: [PATCH 11/12] =?UTF-8?q?chore:=20=EC=9E=AC=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=EB=B0=8F=20refetch=20=EA=B4=80=EB=A0=A8=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main.tsx b/src/main.tsx index 4448caa..5980a89 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -17,6 +17,12 @@ Sentry.init({ }) const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + refetchOnWindowFocus: false, + }, + }, queryCache: new QueryCache({ onError: (error) => { if (error instanceof Error) { From f22763e98f99669a05decf39251e769be26338c5 Mon Sep 17 00:00:00 2001 From: AAminha Date: Sun, 20 Apr 2025 23:29:36 +0900 Subject: [PATCH 12/12] =?UTF-8?q?design:=20=EA=B3=B5=ED=86=B5=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/AuthCallback/index.tsx | 2 +- src/pages/Login/index.tsx | 6 +++--- src/styles/utilities.css | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pages/AuthCallback/index.tsx b/src/pages/AuthCallback/index.tsx index 1bbc7e2..6d98cd7 100644 --- a/src/pages/AuthCallback/index.tsx +++ b/src/pages/AuthCallback/index.tsx @@ -17,7 +17,7 @@ export default function AuthCallback() { if (error) { return ( -
+

{error}

diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx index 3fbea1e..925fe67 100644 --- a/src/pages/Login/index.tsx +++ b/src/pages/Login/index.tsx @@ -22,9 +22,9 @@ export default function LoginPage() { return ( <> setIsOpen(false)} /> -
-
-
+
+
+
{ diff --git a/src/styles/utilities.css b/src/styles/utilities.css index f977bb9..7cb2b14 100644 --- a/src/styles/utilities.css +++ b/src/styles/utilities.css @@ -15,7 +15,6 @@ display: flex; flex-direction: column; align-items: center; - justify-content: space-between; width: 100%; flex-grow: 1; }