diff --git a/admin/src/components/Toast/index.tsx b/admin/src/components/Toast/index.tsx new file mode 100644 index 00000000..2921a452 --- /dev/null +++ b/admin/src/components/Toast/index.tsx @@ -0,0 +1,16 @@ +interface ToastProps { + message: string; + isVisible: boolean; +} + +export default function Toast({ message, isVisible }: ToastProps) { + return ( +
+ {message} +
+ ); +} diff --git a/admin/src/hooks/useFetch.ts b/admin/src/hooks/useFetch.ts index db697c6a..7ba15c33 100644 --- a/admin/src/hooks/useFetch.ts +++ b/admin/src/hooks/useFetch.ts @@ -6,6 +6,9 @@ export default function useFetch(fetch: (params: P) => Promise) const [isError, setIsError] = useState(false); const fetchData = async (params?: P) => { + setIsError(false); + setIsSuccess(false); + try { const data = await fetch(params as P); setData(data); diff --git a/admin/src/hooks/useInfiniteFetch.ts b/admin/src/hooks/useInfiniteFetch.ts index d9d57c5c..89394f2b 100644 --- a/admin/src/hooks/useInfiniteFetch.ts +++ b/admin/src/hooks/useInfiniteFetch.ts @@ -36,6 +36,8 @@ export default function useInfiniteFetch({ if (!hasNextPage || isLoading || currentPageParam === undefined) return; setIsLoading(true); + setIsError(false); + setIsSuccess(false); try { const lastPage = await fetch(currentPageParam); const nextPageParam = getNextPageParam(currentPageParam, lastPage); diff --git a/admin/src/hooks/useToast.tsx b/admin/src/hooks/useToast.tsx new file mode 100644 index 00000000..dabd5c10 --- /dev/null +++ b/admin/src/hooks/useToast.tsx @@ -0,0 +1,24 @@ +import { useCallback, useEffect, useState } from "react"; +import Toast from "../components/Toast"; + +export default function useToast(message: string, duration: number = 3000) { + const [visible, setVisible] = useState(false); + + const showToast = useCallback(() => { + setVisible(true); + }, []); + + useEffect(() => { + if (visible) { + const timer = setTimeout(() => { + setVisible(false); + }, duration); + + return () => clearTimeout(timer); + } + }, [visible, duration]); + + const ToastComponent = ; + + return { showToast, ToastComponent }; +} diff --git a/admin/src/pages/Lottery/index.tsx b/admin/src/pages/Lottery/index.tsx index f129f82d..d5d23332 100644 --- a/admin/src/pages/Lottery/index.tsx +++ b/admin/src/pages/Lottery/index.tsx @@ -9,6 +9,7 @@ import TimePicker from "@/components/TimePicker"; import { STATUS_MAP } from "@/constants/common"; import { LOTTERY_HEADER } from "@/constants/lottery"; import useFetch from "@/hooks/useFetch"; +import useToast from "@/hooks/useToast"; import { LotteryEventType } from "@/types/lottery"; import { PutLotteryResponse } from "@/types/lotteryApi"; import { getDateDifference } from "@/utils/getDateDifference"; @@ -16,6 +17,8 @@ import { getDateDifference } from "@/utils/getDateDifference"; export default function Lottery() { const navigate = useNavigate(); + const { showToast, ToastComponent } = useToast("수정 사항이 반영되었습니다!"); + const lotteryData = useLoaderData() as LotteryEventType[]; const [lottery, setLottery] = useState({} as LotteryEventType); @@ -35,7 +38,7 @@ export default function Lottery() { }, []); useEffect(() => { if (isSuccessPostLottery) { - // TODO: toast 메시지 + showToast(); } }, [isSuccessPostLottery]); @@ -103,6 +106,8 @@ export default function Lottery() { 수정사항 업데이트 + + {ToastComponent} ); }