diff --git a/packages/adminPage/build.js b/packages/adminPage/build.js index 806d1130..ba07dbb8 100644 --- a/packages/adminPage/build.js +++ b/packages/adminPage/build.js @@ -17,7 +17,7 @@ const buildUrl = [ "events/[id]", "comments", "comments/[id]", - "users" + "users", ]; async function copyFolder(src, dest) { diff --git a/packages/adminPage/src/features/eventDetail/drawButton/DrawButton.jsx b/packages/adminPage/src/features/eventDetail/drawButton/DrawButton.jsx index bb11692e..90061937 100644 --- a/packages/adminPage/src/features/eventDetail/drawButton/DrawButton.jsx +++ b/packages/adminPage/src/features/eventDetail/drawButton/DrawButton.jsx @@ -1,9 +1,9 @@ +import { useState, useEffect, useRef } from "react"; import { useParams } from "react-router-dom"; import { fetchServer } from "@common/dataFetch/fetchServer.js"; -import { useQuery, useMutation } from "@common/dataFetch/getQuery.js"; + import Button from "@common/components/Button.jsx"; import openModal from "@common/modal/openModal.js"; - import AlertModal from "@admin/modals/AlertModal.jsx"; import DrawResultModal from "./DrawResultModal.jsx"; @@ -12,17 +12,8 @@ import Suspense from "@common/components/Suspense.jsx"; import Spinner from "@common/components/Spinner.jsx"; import DelaySkeleton from "@common/components/DelaySkeleton.jsx"; -function DrawButton() { - const { eventId } = useParams(); - const drawResultData = useQuery( - `event-detail-draw-result-${eventId}`, - () => { - return fetchServer(`/api/v1/admin/draw/${eventId}/winners`); - }, - { deferred: true }, - ); - - const resultModal = ( +function ResultModalContainer({ eventId }) { + return (
에러남
}> ); +} - const mutate = useMutation( - `event-detail-draw-result-${eventId}`, - () => fetchServer(`/api/v1/admin/draw/${eventId}/draw`, { method: "post" }), - { - onSuccess: () => openModal(resultModal), - onFail: () => - openModal(), - }, - ); +function DrawButton() { + const { eventId } = useParams(); + const [drawState, setDrawState] = useState("BEFORE_END"); + const interval = useRef(null); + const timeout = useRef(null); - if (drawResultData.length === 0) - return ( - - ); - return ( - - ); + useEffect(() => { + fetchServer(`/api/v1/admin/draw/${eventId}/status`) + .then(({ status }) => setDrawState(status)) + .catch(() => { + setDrawState("ERROR"); + }); + }, [eventId]); + + useEffect(() => { + return () => { + clearInterval(interval.current); + clearTimeout(timeout.current); + }; + }, []); + + async function onSubmit() { + function shortPooling() { + fetchServer(`/api/v1/admin/draw/${eventId}/status`) + .then(({ status }) => { + setDrawState(status); + if (status !== "IS_DRAWING") { + clearInterval(interval.current); + } + }) + .catch(() => { + setDrawState("ERROR"); + clearInterval(interval.current); + }); + } + + try { + await fetchServer(`/api/v1/admin/draw/${eventId}/draw`, { method: "post" }); + setDrawState("IS_DRAWING"); + openModal(); + timeout.current = setTimeout(() => { + shortPooling(); + interval.current = setInterval(shortPooling, 5000); + }, 500); + } catch { + openModal(); + } + } + + switch (drawState) { + case "BEFORE_END": + return null; + case "AVAILABLE": + return ( + + ); + case "IS_DRAWING": + return ( +
추첨 진행중...
+ ); + case "COMPLETE": + return ( + + ); + default: + return
에러
; + } } export default DrawButton; diff --git a/packages/adminPage/src/features/eventDetail/drawButton/mock.js b/packages/adminPage/src/features/eventDetail/drawButton/mock.js index 7051ea75..6b12b6a2 100644 --- a/packages/adminPage/src/features/eventDetail/drawButton/mock.js +++ b/packages/adminPage/src/features/eventDetail/drawButton/mock.js @@ -2,6 +2,7 @@ import { http, HttpResponse } from "msw"; import getRandomString from "@common/mock/getRandomString.js"; let result = []; +let status = "AVAILABLE"; function makeDrawComplete() { const newResult = []; @@ -24,11 +25,16 @@ function makeDrawComplete() { const handlers = [ http.post("/api/v1/admin/draw/:eventId/draw", () => { result = makeDrawComplete(); + status = "IS_DRAWING"; + setTimeout(() => (status = "COMPLETE"), 3000); return new HttpResponse(null, { status: 201 }); }), http.get("/api/v1/admin/draw/:eventId/winners", () => { return HttpResponse.json(result); }), + http.get("/api/v1/admin/draw/:eventId/status", () => { + return HttpResponse.json({ status }); + }), ]; export default handlers; diff --git a/packages/adminPage/src/features/eventList/DeleteButton.jsx b/packages/adminPage/src/features/eventList/DeleteButton.jsx index 7b4fca1a..8c35224c 100644 --- a/packages/adminPage/src/features/eventList/DeleteButton.jsx +++ b/packages/adminPage/src/features/eventList/DeleteButton.jsx @@ -1,4 +1,4 @@ -import { fetchServer } from "@common/dataFetch/fetchServer.js"; +import { fetchServer, HTTPError } from "@common/dataFetch/fetchServer.js"; import { useMutation } from "@common/dataFetch/getQuery.js"; import ConfirmModal from "@admin/modals/ConfirmModal.jsx"; import AlertModal from "@admin/modals/AlertModal.jsx"; @@ -17,9 +17,23 @@ function DeleteButton({ selected, reset }) { }), { onSuccess: () => { - openModal(); + openModal(); reset(); }, + onError: async (e) => { + if (e instanceof HTTPError && e.status === 400) { + return openModal( + , + ); + } + if (e instanceof HTTPError && e.status === 404) { + return openModal(); + } + return openModal(); + }, }, ); const deleteConfirmModal = ( diff --git a/packages/adminPage/src/features/eventList/mock.js b/packages/adminPage/src/features/eventList/mock.js index e51ba264..caecd856 100644 --- a/packages/adminPage/src/features/eventList/mock.js +++ b/packages/adminPage/src/features/eventList/mock.js @@ -91,6 +91,15 @@ const handlers = [ size, }); }), + http.delete("/api/v1/admin/events/:id", async ({ params }) => { + const { id } = params; + + const index = dummyData.findIndex(({ eventId }) => eventId === id); + if (index === -1) return HttpResponse.json(false); + dummyData.splice(index, 1); + + return HttpResponse.json(true); + }), http.delete("/api/v1/admin/events", async ({ request }) => { const { eventIds } = await request.json(); diff --git a/packages/adminPage/src/features/eventList/table/SearchResultItem.jsx b/packages/adminPage/src/features/eventList/table/SearchResultItem.jsx index 0e39e7e3..b5c010b8 100644 --- a/packages/adminPage/src/features/eventList/table/SearchResultItem.jsx +++ b/packages/adminPage/src/features/eventList/table/SearchResultItem.jsx @@ -1,16 +1,18 @@ import { Link } from "react-router-dom"; import tableTemplateCol from "./tableStyle.js"; -import EventStatus from "@admin/serverTime/EventStatus.js"; +import { useEventStatus } from "@admin/serverTime/EventStatus.js"; import Button from "@common/components/Button.jsx"; import Checkbox from "@common/components/Checkbox.jsx"; import { formatDate } from "@common/utils.js"; function SearchResultItem({ eventId, name, startTime, endTime, eventType, checked, setCheck }) { + const eventStatus = useEventStatus(startTime, endTime); + return (