diff --git a/podmate/src/api/userApi.tsx b/podmate/src/api/userApi.tsx index dcc5e04..20ad7dc 100644 --- a/podmate/src/api/userApi.tsx +++ b/podmate/src/api/userApi.tsx @@ -32,7 +32,6 @@ export const getUser = async () => { Authorization: `Bearer ${accessToken}`, }, }); - console.log("res", res.data.result); return res.data.result; } catch {} }; @@ -642,3 +641,25 @@ export const postOrderForm = async (podId: number, items: number[]) => { return null; } }; + +//팟 참여 api +export const postPodJoin = async (podId: number, quantity: number) => { + const accessToken = localStorage.getItem("accessToken"); + try { + const res = await userAxios.post( + `/api/pods/${podId}/join`, + { + quantity: quantity, + }, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + } + ); + return res.data.result; + } catch (error) { + console.error("Failed to fetch pod detail:", error); + throw error; + } +}; diff --git a/podmate/src/components/PodInfoCard/PodInfoCard.tsx b/podmate/src/components/PodInfoCard/PodInfoCard.tsx index c5ab5e8..7aabb9c 100644 --- a/podmate/src/components/PodInfoCard/PodInfoCard.tsx +++ b/podmate/src/components/PodInfoCard/PodInfoCard.tsx @@ -24,7 +24,6 @@ const PodInfoCard = ({ selectedPod, type }: PodInfoCardProps) => { const [podDetail, setPodDetail] = useState(null); const [isLoadingDetail, setIsLoadingDetail] = useState(false); const [isLeader, setIsLeader] = useState(false); - useEffect(() => { const fetchPodDetail = async () => { if (isExpanded && selectedPod.podId && !podDetail) { @@ -78,7 +77,6 @@ const PodInfoCard = ({ selectedPod, type }: PodInfoCardProps) => { } } }; - console.log(isLeader); return ( e.stopPropagation()}> diff --git a/podmate/src/pages/PodJoinPage.tsx b/podmate/src/pages/PodJoinPage.tsx index f563f5e..cffe9fc 100644 --- a/podmate/src/pages/PodJoinPage.tsx +++ b/podmate/src/pages/PodJoinPage.tsx @@ -2,7 +2,7 @@ import { useLocation, useNavigate } from "react-router-dom"; import styled, { keyframes } from "styled-components"; import Header from "../components/Header"; import { useState, useEffect } from "react"; -import { getPodDetail } from "../api/userApi"; +import { getPodDetail, postPodJoin } from "../api/userApi"; import { PodDetail } from "../types/types"; const Container = styled.div` @@ -125,6 +125,61 @@ const InputInfo = styled.div` margin-top: 4px; `; +const ModalOverlay = styled.div` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +`; + +const ModalContent = styled.div` + background: white; + padding: 24px; + border-radius: 12px; + width: 280px; + text-align: center; + animation: ${keyframes` + from { + opacity: 0; + transform: scale(0.8); + } + to { + opacity: 1; + transform: scale(1); + } + `} 0.3s ease-out; +`; + +const ModalTitle = styled.h3` + font-size: 18px; + font-weight: 600; + color: #2f3337; + margin-bottom: 16px; +`; + +const ModalButton = styled.button` + width: 100%; + padding: 12px; + background: #52d4e0; + color: white; + border: none; + border-radius: 8px; + font-size: 16px; + font-weight: 600; + cursor: pointer; + margin-top: 16px; + + &:hover { + background: #33bbff; + } +`; + export default function PodJoinPage() { const location = useLocation(); const navigate = useNavigate(); @@ -134,6 +189,9 @@ export default function PodJoinPage() { const [isLoading, setIsLoading] = useState(true); const [quantity, setQuantity] = useState(0); const [amount, setAmount] = useState(""); + const [showModal, setShowModal] = useState(false); + const [isJoining, setIsJoining] = useState(false); + const [error, setError] = useState(null); useEffect(() => { const fetchPodDetail = async () => { @@ -158,7 +216,7 @@ export default function PodJoinPage() { const getRemainingQuantity = () => { if (!podDetail) return 0; - return Math.floor(getRemainingAmount() / podDetail.unitPrice); + return Math.floor(podDetail.goalAmount - podDetail.currentAmount); }; const isExceedingGoal = () => { @@ -166,15 +224,32 @@ export default function PodJoinPage() { if (pathname.startsWith("/pod/join/mini")) { return Number(amount) > getRemainingAmount(); } else { - return quantity * podDetail.unitPrice > getRemainingAmount(); + return quantity > getRemainingAmount(); } }; - const handleJoin = () => { - if (isExceedingGoal()) { + const handleJoin = async () => { + if (isExceedingGoal() || !podId) { return; } + try { + setIsJoining(true); + setError(null); + + const res = await postPodJoin(podId, quantity); + console.log(res); + setShowModal(true); + } catch (err) { + console.error("Failed to join pod:", err); + setShowModal(true); + } finally { + setIsJoining(false); + } + }; + + const handleModalClose = () => { + setShowModal(false); navigate("/"); }; @@ -257,11 +332,26 @@ export default function PodJoinPage() { - 참여 신청하기 + {isJoining ? "참여 중..." : "참여 신청하기"} + {error && ( + + {error} + + )} + {showModal && ( + + + 신청이 완료되었습니다! + 확인 + + + )} ) : ( <> @@ -316,7 +406,7 @@ export default function PodJoinPage() { {isExceedingGoal() && ( - 목표 금액을 초과했습니다. 남은 수량: {getRemainingQuantity()}개 + 목표 수량을 초과했습니다. 남은 수량: {getRemainingQuantity()}개 )} @@ -324,11 +414,24 @@ export default function PodJoinPage() { - 참여 신청하기 + {isJoining ? "참여 중..." : "참여 신청하기"} + {error && ( + + {error} + + )} + {showModal && ( + + + 신청이 완료되었습니다! + 확인 + + + )} ); } diff --git a/podmate/src/pages/mainPage/Home.tsx b/podmate/src/pages/mainPage/Home.tsx index 09ead66..e183f1f 100644 --- a/podmate/src/pages/mainPage/Home.tsx +++ b/podmate/src/pages/mainPage/Home.tsx @@ -492,16 +492,6 @@ const Home = (): React.ReactElement => { } }} > - {mapState.currentAddress.main && ( - <> - - {mapState.currentAddress.main} - {mapState.currentAddress.sub && ( - {mapState.currentAddress.sub} - )} - - - )} {mapState.selectedPod && ( )}