From 0ec4c1a66146410253d61b5198b541b7b434a1b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=98=88=EC=A7=80?= Date: Mon, 11 Nov 2024 18:59:45 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Feat=20:=20=ED=8C=90=EB=A7=A4=EC=A4=91,=20?= =?UTF-8?q?=ED=8C=90=EB=A7=A4=EC=99=84=EB=A3=8C=20api=20=EC=97=B0=EA=B2=B0?= =?UTF-8?q?=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/request.tsx | 1 + src/app/totalItem/userItem/[...slug]/page.tsx | 452 +++++++++--------- .../totalItem/user/SellingOrSold.tsx | 118 ----- .../totalItem/user/SellingProduct.tsx | 122 +++++ src/components/totalItem/user/SoldProduct.tsx | 120 +++++ 5 files changed, 479 insertions(+), 334 deletions(-) delete mode 100644 src/components/totalItem/user/SellingOrSold.tsx create mode 100644 src/components/totalItem/user/SellingProduct.tsx create mode 100644 src/components/totalItem/user/SoldProduct.tsx diff --git a/src/api/request.tsx b/src/api/request.tsx index 2a1f8b4..714d559 100644 --- a/src/api/request.tsx +++ b/src/api/request.tsx @@ -140,6 +140,7 @@ export const getClothingSalesDetails = async ( method: "GET", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${process.env.API_TOKEN}`, }, } ); diff --git a/src/app/totalItem/userItem/[...slug]/page.tsx b/src/app/totalItem/userItem/[...slug]/page.tsx index 6162896..9b9ef0b 100644 --- a/src/app/totalItem/userItem/[...slug]/page.tsx +++ b/src/app/totalItem/userItem/[...slug]/page.tsx @@ -1,219 +1,239 @@ -'use client'; -import MainTitle from '@/components/titles/MainTitle'; -import { useState, useEffect } from 'react'; -import { getClothingSalesDetails, getUserInfo } from '@/api/request'; -import classNames from 'classnames'; -import { useRouter } from 'next/navigation'; -import { useSearchParams } from 'next/navigation'; -import { usePathname } from 'next/navigation'; -import { ClothingSalesItemStatus } from '@/interface/interface'; -import { it } from 'node:test'; -import item from '@/app/item/page'; -import SellingOrSold from '@/components/totalItem/user/SellingOrSold'; -import RejectedProduct from '@/components/totalItem/user/RejectedProduct'; -import ExpiredProduct from '@/components/totalItem/user/ExpiredProduct'; -import KGProduct from '@/components/totalItem/user/KGProduct'; +"use client"; +import MainTitle from "@/components/titles/MainTitle"; +import { useState, useEffect } from "react"; +import { getClothingSalesDetails, getUserInfo } from "@/api/request"; +import classNames from "classnames"; +import { useRouter } from "next/navigation"; +import { useSearchParams } from "next/navigation"; +import { usePathname } from "next/navigation"; +import { ClothingSalesItemStatus } from "@/interface/interface"; +import { it } from "node:test"; +import item from "@/app/item/page"; +import SellingProduct from "@/components/totalItem/user/SellingProduct"; +import RejectedProduct from "@/components/totalItem/user/RejectedProduct"; +import ExpiredProduct from "@/components/totalItem/user/ExpiredProduct"; +import KGProduct from "@/components/totalItem/user/KGProduct"; +import SoldProduct from "@/components/totalItem/user/SoldProduct"; export default function Page() { - const path = usePathname().split('/'); - - const clothingSalesId = Number(path[3]); - //const clothingSalesCount = Number(path[4]); - - // 상태별 totalElements를 저장할 state - const [totalElements, setTotalElements] = useState({ - selling: 0, - soldOut: 0, - rejected: 0, - sellingEnd: 0, - kgSell: 0, - }); - - const [state, setState] = useState('selling'); - const [items, setItems] = useState(null); - const [user, setUser] = useState(null); - const [selectedButtons, setSelectedButtons] = useState([ - true, - false, - false, - false, - false, - ]); - - const handleButtonClick = (index: number) => { - const updatedButtons = selectedButtons.map((_, i) => i === index); - setSelectedButtons(updatedButtons); - - // 버튼 인덱스에 따라 상태값을 변경 - switch (index) { - case 0: - setState('selling'); - break; - case 1: - setState('sold-out'); - break; - case 2: - setState('rejected'); - break; - case 3: - setState('selling-end'); - break; - case 4: - setState('kg-sell'); - break; - default: - setState('selling'); - } - }; - - // 여러 상태의 API 호출을 병렬로 처리하고, 모두 완료된 후 상태 업데이트 - const fetchTotalElementsForAllStates = async () => { - console.log('fetchTotalElementsForAllStates called'); - const states = [ - 'selling', - 'sold-out', - 'rejected', - 'selling-end', - 'kg-sell', - ]; - - try { - // 모든 상태에 대해 API 요청을 병렬로 처리 - const responses = await Promise.all( - states.map((status) => - getClothingSalesDetails(clothingSalesId, status, '0', '4') - ) - ); - console.log('API Responses:', responses); // 응답값 디버깅 - - const totalElementsResult = { - selling: responses[0]?.result?.totalElements || 0, - soldOut: responses[1]?.result?.totalElements || 0, - rejected: responses[2]?.result?.totalElements || 0, - sellingEnd: responses[3]?.result?.totalElements || 0, - kgSell: responses[4]?.result?.totalElements || 0, - }; - console.log('Total Elements:', totalElementsResult); // 디버깅 - // 상태 업데이트 - setTotalElements(totalElementsResult); - } catch (error) { - console.error('Error fetching total elements:', error); - } - }; - - // 선택된 상태에 따라 아이템 로드 - const fetchItemsForSelectedState = async () => { - const result = await getClothingSalesDetails( - clothingSalesId, - state, - '0', - '4' - ); - setItems(result); - }; - - useEffect(() => { - fetchTotalElementsForAllStates(); // 처음에 전체 상태의 totalElements 불러오기 - }, []); - - useEffect(() => { - fetchItemsForSelectedState(); // 선택된 상태의 아이템 불러오기 - }, [state]); - - useEffect(() => { - const fetchUser = async () => { - const userInfo = await getUserInfo(clothingSalesId); - setUser(userInfo?.result); - }; - fetchUser(); - }, []); - - return ( -
-
- -
-
-
이름
-
{user?.name}
- -
코드
-
{user?.code}
- -
주소
-
- {user?.address} -
- -
번호
-
- {user?.phoneNumber} -
-
-
- - { -
-
- {[ - '판매 중', - '판매 완료', - '리젝 상품', - '만료 상품', - 'KG 매입', - ].map((title, index) => ( -
handleButtonClick(index)} - > -
- {title} -
-
- {/* 상태에 따른 totalElements 표시 */} - {index === 0 && totalElements.selling} - {index === 1 && totalElements.soldOut} - {index === 2 && totalElements.rejected} - {index === 3 && totalElements.sellingEnd} - {index === 4 && totalElements.kgSell} -
-
- - - -
-
- ))} -
- {/* */} -
- {selectedButtons[0] && } - {selectedButtons[1] && } - {selectedButtons[2] && } - {selectedButtons[3] && } - {selectedButtons[4] && } -
-
- } -
-
- ); + const path = usePathname().split("/"); + + const clothingSalesId = Number(path[3]); + //const clothingSalesCount = Number(path[4]); + + // 상태별 totalElements를 저장할 state + const [totalElements, setTotalElements] = useState({ + selling: 0, + soldOut: 0, + rejected: 0, + sellingEnd: 0, + kgSell: 0, + }); + + const [state, setState] = useState("selling"); + const [items, setItems] = useState(null); + const [user, setUser] = useState(null); + const [selectedButtons, setSelectedButtons] = useState([ + true, + false, + false, + false, + false, + ]); + + const handleButtonClick = (index: number) => { + const updatedButtons = selectedButtons.map((_, i) => i === index); + setSelectedButtons(updatedButtons); + + // 버튼 인덱스에 따라 상태값을 변경 + switch (index) { + case 0: + setState("selling"); + break; + case 1: + setState("sold-out"); + break; + case 2: + setState("rejected"); + break; + case 3: + setState("selling-end"); + break; + case 4: + setState("kg-sell"); + break; + default: + setState("selling"); + } + }; + + const fetchTotalElementsForAllStates = async () => { + console.log("fetchTotalElementsForAllStates called"); + console.log("clothingSalesId:", clothingSalesId); // 디버깅을 위해 추가 + + const states = [ + "selling", + "sold-out", + "rejected", + "selling-end", + "kg-sell", + ]; + + try { + // 모든 상태에 대해 API 요청을 병렬로 처리 + const responses = await Promise.all( + states.map(async (status) => { + try { + const response = await getClothingSalesDetails( + clothingSalesId, + status, + "0", + "4" + ); + return response; + } catch (error) { + console.error(`Error fetching data for status "${status}":`, error); + throw error; // 에러가 있으면 해당 상태의 요청을 실패로 처리 + } + }) + ); + + console.log("API Responses:", responses); // 응답값 디버깅 + + const totalElementsResult = { + selling: responses[0]?.result?.totalElements || 0, + soldOut: responses[1]?.result?.totalElements || 0, + rejected: responses[2]?.result?.totalElements || 0, + sellingEnd: responses[3]?.result?.totalElements || 0, + kgSell: responses[4]?.result?.totalElements || 0, + }; + console.log("Total Elements:", totalElementsResult); // 디버깅 + + // 상태 업데이트 + setTotalElements(totalElementsResult); + } catch (error) { + console.error("Error fetching total elements:", error); + } + }; + + // 선택된 상태에 따라 아이템 로드 + const fetchItemsForSelectedState = async () => { + try { + const result = await getClothingSalesDetails( + clothingSalesId, // path 파라미터 + state, // path 파라미터 (productState) + "0", // query 파라미터 (page) + "4" // query 파라미터 (size) + ); + setItems(result); + console.log("result", result); + } catch (error) { + console.error("Error fetching items for selected state:", error); + } + }; + + useEffect(() => { + fetchTotalElementsForAllStates(); // 처음에 전체 상태의 totalElements 불러오기 + }, []); + + useEffect(() => { + fetchItemsForSelectedState(); // 선택된 상태의 아이템 불러오기 + }, [state]); + + useEffect(() => { + const fetchUser = async () => { + const userInfo = await getUserInfo(clothingSalesId); + setUser(userInfo?.result); + }; + fetchUser(); + }, []); + + return ( +
+
+ +
+
+
이름
+
{user?.name}
+ +
코드
+
{user?.code}
+ +
주소
+
+ {user?.address} +
+ +
번호
+
+ {user?.phoneNumber} +
+
+
+ + { +
+
+ {[ + "판매 중", + "판매 완료", + "리젝 상품", + "만료 상품", + "KG 매입", + ].map((title, index) => ( +
handleButtonClick(index)} + > +
+ {title} +
+
+ {/* 상태에 따른 totalElements 표시 */} + {index === 0 && totalElements.selling} + {index === 1 && totalElements.soldOut} + {index === 2 && totalElements.rejected} + {index === 3 && totalElements.sellingEnd} + {index === 4 && totalElements.kgSell} +
+
+ + + +
+
+ ))} +
+ {/* */} +
+ {selectedButtons[0] && } + {selectedButtons[1] && } + {selectedButtons[2] && } + {selectedButtons[3] && } + {selectedButtons[4] && } +
+
+ } +
+
+ ); } diff --git a/src/components/totalItem/user/SellingOrSold.tsx b/src/components/totalItem/user/SellingOrSold.tsx deleted file mode 100644 index 3297c20..0000000 --- a/src/components/totalItem/user/SellingOrSold.tsx +++ /dev/null @@ -1,118 +0,0 @@ -'use client'; -import { useState, useEffect } from 'react'; -import { ClothingSalesItemStatus } from '@/interface/interface'; - -export default function SellingOrSold({ items }: any) { - const [view, setView] = useState<{ [key: string]: boolean }>({}); - const [userItems, setUserItems] = useState([]); - - useEffect(() => { - if (items?.clothing?.result?.content) { - setUserItems(items.clothing.result.content); - } - }, [items]); - - const handleClickOutside = (event: any) => { - if ( - Object.values(view).some(Boolean) && - !event.target.closest('.dropdown-container') - ) { - setView({}); - } - }; - - const toggleDropdown = (id: string) => { - setView((prevView) => ({ - ...prevView, - [id]: !prevView[id], - })); - }; - - useEffect(() => { - document.addEventListener('click', handleClickOutside); - return () => { - document.removeEventListener('click', handleClickOutside); - }; - }, [view]); - - return ( -
-
-
-
- 전체 {userItems?.length ?? 0}개 -
-
-
-
-
상품 코드
-
상품명
-
등급
-
판매기간
-
판매금액
-
정산금
-
수수료
-
상태
-
-
- - {userItems?.map((item) => ( -
-
-
{item.productCode}
-
-
-
{item.productName}
-
-
{item.grade}
-
{item.salesPeriod}
-
{item.salesPrice}
-
{item.settlementPrice}
-
{item.fee}
- -
    toggleDropdown(item.productCode)} - > -
    -
    {item.isReturned ? '반품' : '판매 중'}
    -
    - {view[item.productCode] ? ( - - - - ) : ( - - - - )} -
    -
    -
-
-
-
- ))} -
-
-
- ); -} diff --git a/src/components/totalItem/user/SellingProduct.tsx b/src/components/totalItem/user/SellingProduct.tsx new file mode 100644 index 0000000..d34d1c5 --- /dev/null +++ b/src/components/totalItem/user/SellingProduct.tsx @@ -0,0 +1,122 @@ +"use client"; +import { useState, useEffect, use } from "react"; +import { ClothingSalesItemStatus } from "@/interface/interface"; + +export default function SellingProduct({ clothing }: any) { + const [view, setView] = useState<{ [key: string]: boolean }>({}); + const [userItems, setUserItems] = useState([]); + + useEffect(() => { + if (clothing?.result?.content) { + setUserItems(clothing.result.content); + } + }, [clothing]); + + console.log("Sellingitems", clothing); + + console.log("userItems", userItems); + + const handleClickOutside = (event: any) => { + if ( + Object.values(view).some(Boolean) && + !event.target.closest(".dropdown-container") + ) { + setView({}); + } + }; + + const toggleDropdown = (id: string) => { + setView((prevView) => ({ + ...prevView, + [id]: !prevView[id], + })); + }; + + useEffect(() => { + document.addEventListener("click", handleClickOutside); + return () => { + document.removeEventListener("click", handleClickOutside); + }; + }, [view]); + + return ( +
+
+
+
+ 전체 {userItems?.length ?? 0}개 +
+
+
+
+
상품 코드
+
상품명
+
등급
+
판매기간
+
판매금액
+
정산금
+
수수료
+
상태
+
+
+ + {userItems?.map((item) => ( +
+
+
{item.productCode}
+
+
+
{item.productName}
+
+
{item.grade}
+
{item.salesPeriod}
+
{item.salesPrice}
+
{item.settlementPrice}
+
{item.fee}
+ +
    toggleDropdown(item.productCode)} + > +
    +
    {item.isReturned ? "반품" : "판매 중"}
    +
    + {view[item.productCode] ? ( + + + + ) : ( + + + + )} +
    +
    +
+
+
+
+ ))} +
+
+
+ ); +} diff --git a/src/components/totalItem/user/SoldProduct.tsx b/src/components/totalItem/user/SoldProduct.tsx new file mode 100644 index 0000000..e4a19a1 --- /dev/null +++ b/src/components/totalItem/user/SoldProduct.tsx @@ -0,0 +1,120 @@ +"use client"; +import { useState, useEffect } from "react"; +import { ClothingSalesItemStatus } from "@/interface/interface"; + +export default function SoldProduct({ clothing }: any) { + const [view, setView] = useState<{ [key: string]: boolean }>({}); + const [userItems, setUserItems] = useState([]); + + useEffect(() => { + if (clothing?.result?.content) { + setUserItems(clothing.result.content); + } + }, [clothing]); + + console.log("Solditems", clothing); + + const handleClickOutside = (event: any) => { + if ( + Object.values(view).some(Boolean) && + !event.target.closest(".dropdown-container") + ) { + setView({}); + } + }; + + const toggleDropdown = (id: string) => { + setView((prevView) => ({ + ...prevView, + [id]: !prevView[id], + })); + }; + + useEffect(() => { + document.addEventListener("click", handleClickOutside); + return () => { + document.removeEventListener("click", handleClickOutside); + }; + }, [view]); + + return ( +
+
+
+
+ 전체 {userItems?.length ?? 0}개 +
+
+
+
+
상품 코드
+
상품명
+
등급
+
판매기간
+
판매금액
+
정산금
+
수수료
+
상태
+
+
+ + {userItems?.map((item) => ( +
+
+
{item.productCode}
+
+
+
{item.productName}
+
+
{item.grade}
+
{item.salesPeriod}
+
{item.salesPrice}
+
{item.settlementPrice}
+
{item.fee}
+ +
    toggleDropdown(item.productCode)} + > +
    +
    {item.isReturned ? "반품" : "판매 중"}
    +
    + {view[item.productCode] ? ( + + + + ) : ( + + + + )} +
    +
    +
+
+
+
+ ))} +
+
+
+ ); +} From 9739f3998485e9eb487cc58fb91b4e35ec4fb755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=98=88=EC=A7=80?= Date: Mon, 11 Nov 2024 19:13:28 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Chore=20:=20=EB=A6=AC=EC=A0=9D=20=EC=83=81?= =?UTF-8?q?=ED=92=88,=20=EB=A7=8C=EB=A3=8C=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=84=A0=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../totalItem/user/ExpiredProduct.tsx | 182 ++++++++---------- .../totalItem/user/RejectedProduct.tsx | 179 +++++++---------- 2 files changed, 149 insertions(+), 212 deletions(-) diff --git a/src/components/totalItem/user/ExpiredProduct.tsx b/src/components/totalItem/user/ExpiredProduct.tsx index b314232..99f3abd 100644 --- a/src/components/totalItem/user/ExpiredProduct.tsx +++ b/src/components/totalItem/user/ExpiredProduct.tsx @@ -1,115 +1,83 @@ -'use client'; -import { useState, useEffect } from 'react'; -import { ClothingSalesItemStatus } from '@/interface/interface'; +"use client"; +import { useState, useEffect } from "react"; +import { ClothingSalesItemStatus } from "@/interface/interface"; -export default function ExpiredProduct({ items }: any) { - const [view, setView] = useState<{ [key: string]: boolean }>({}); - const [userItems, setUserItems] = useState([]); +export default function ExpiredProduct({ expiredItems }: any) { + const [view, setView] = useState<{ [key: string]: boolean }>({}); + const [userItems, setUserItems] = useState([]); - useEffect(() => { - if (items?.clothing?.result?.content) { - setUserItems(items.clothing.result.content); - } - }, [items]); + useEffect(() => { + if (expiredItems?.result?.content) { + setUserItems(expiredItems.result.content); + } + }, [expiredItems]); - const handleClickOutside = (event: any) => { - if ( - Object.values(view).some(Boolean) && - !event.target.closest('.dropdown-container') - ) { - setView({}); - } - }; + const handleClickOutside = (event: any) => { + if ( + Object.values(view).some(Boolean) && + !event.target.closest(".dropdown-container") + ) { + setView({}); + } + }; - const toggleDropdown = (id: string) => { - setView((prevView) => ({ - ...prevView, - [id]: !prevView[id], - })); - }; + const toggleDropdown = (id: string) => { + setView((prevView) => ({ + ...prevView, + [id]: !prevView[id], + })); + }; - useEffect(() => { - document.addEventListener('click', handleClickOutside); - return () => { - document.removeEventListener('click', handleClickOutside); - }; - }, [view]); + useEffect(() => { + document.addEventListener("click", handleClickOutside); + return () => { + document.removeEventListener("click", handleClickOutside); + }; + }, [view]); - return ( -
-
-
-
- 전체 {userItems?.length ?? 0}개 -
-
- 일괄 반송 완료 -
-
-
-
-
상품 코드
-
상품명
-
등급
-
선정일
-
상태
-
-
+ return ( +
+
+
+
+ 전체 {userItems?.length ?? 0}개 +
+
+ 일괄 반송 완료 +
+
+
+
+
상품 코드
+
상품명
+
등급
+
신청일
+
상태
+
+
- {userItems?.map((item) => ( -
-
-
{item.productCode}
-
-
-
{item.productName}
-
-
{item.grade}
-
{item.grade}
- -
    toggleDropdown(item.productCode)} - > -
    -
    {item.isReturned ? '반품' : '판매 중'}
    -
    - {view[item.productCode] ? ( - - - - ) : ( - - - - )} -
    -
    -
-
-
-
- ))} -
-
-
- ); + {userItems?.map((item) => ( +
+
+
{item.productCode}
+
+
+
{item.productName}
+
+
{item.grade}
+ 신청일 추가 +
    toggleDropdown(item.productCode)} + > + 상태 드롭다운 추가 +
+
+
+
+ ))} +
+
+
+ ); } diff --git a/src/components/totalItem/user/RejectedProduct.tsx b/src/components/totalItem/user/RejectedProduct.tsx index f56a8a6..ae7a428 100644 --- a/src/components/totalItem/user/RejectedProduct.tsx +++ b/src/components/totalItem/user/RejectedProduct.tsx @@ -1,113 +1,82 @@ -'use client'; -import { useState, useEffect } from 'react'; -import { ClothingSalesItemStatus } from '@/interface/interface'; +"use client"; +import { useState, useEffect } from "react"; +import { ClothingSalesItemStatus } from "@/interface/interface"; -export default function RejectedProduct({ items }: any) { - const [view, setView] = useState<{ [key: string]: boolean }>({}); - const [userItems, setUserItems] = useState([]); +export default function RejectedProduct({ rejectedItems }: any) { + const [view, setView] = useState<{ [key: string]: boolean }>({}); + const [userItems, setUserItems] = useState([]); - useEffect(() => { - if (items?.clothing?.result?.content) { - setUserItems(items.clothing.result.content); - } - }, [items]); + useEffect(() => { + if (rejectedItems?.result?.content) { + setUserItems(rejectedItems?.result.content); + } + }, [rejectedItems]); - const handleClickOutside = (event: any) => { - if ( - Object.values(view).some(Boolean) && - !event.target.closest('.dropdown-container') - ) { - setView({}); - } - }; + const handleClickOutside = (event: any) => { + if ( + Object.values(view).some(Boolean) && + !event.target.closest(".dropdown-container") + ) { + setView({}); + } + }; - const toggleDropdown = (id: string) => { - setView((prevView) => ({ - ...prevView, - [id]: !prevView[id], - })); - }; + const toggleDropdown = (id: string) => { + setView((prevView) => ({ + ...prevView, + [id]: !prevView[id], + })); + }; - useEffect(() => { - document.addEventListener('click', handleClickOutside); - return () => { - document.removeEventListener('click', handleClickOutside); - }; - }, [view]); + useEffect(() => { + document.addEventListener("click", handleClickOutside); + return () => { + document.removeEventListener("click", handleClickOutside); + }; + }, [view]); - return ( -
-
-
-
- 전체 {userItems?.length ?? 0}개 -
-
- 일괄 반송 완료 -
-
-
-
-
상품 코드
-
상품명
-
선정일
-
상태
-
-
+ return ( +
+
+
+
+ 전체 {userItems?.length ?? 0}개 +
+
+ 일괄 반송 완료 +
+
+
+
+
상품 코드
+
상품명
+
신청일
+
상태
+
+
- {userItems?.map((item) => ( -
-
-
{item.productCode}
-
-
-
{item.productName}
-
-
{item.grade}
- -
    toggleDropdown(item.productCode)} - > -
    -
    {item.isReturned ? '반품' : '판매 중'}
    -
    - {view[item.productCode] ? ( - - - - ) : ( - - - - )} -
    -
    -
-
-
-
- ))} -
-
-
- ); + {userItems?.map((item) => ( +
+
+
{item.productCode}
+
+
+
{item.productName}
+
+ {/*
{item.grade}
*/} + 신청일 추가 +
    toggleDropdown(item.productCode)} + > + 상태 드롭 다운 추가 +
+
+
+
+ ))} +
+
+
+ ); }