From 9353a6e5dd9f6e6acf76557b6d9fd533ecb3c836 Mon Sep 17 00:00:00 2001 From: gaeun220 Date: Mon, 10 Feb 2025 16:24:16 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EC=8B=A0=EC=B2=AD=20=ED=8F=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Conflicts: # frontend/src/app/groups/[groupId]/ClientPage.tsx --- .../app/groups/[groupId]/apply/ClientPage.tsx | 110 ++++++++++++++++++ .../src/app/groups/[groupId]/apply/page.tsx | 11 ++ 2 files changed, 121 insertions(+) create mode 100644 frontend/src/app/groups/[groupId]/apply/ClientPage.tsx create mode 100644 frontend/src/app/groups/[groupId]/apply/page.tsx diff --git a/frontend/src/app/groups/[groupId]/apply/ClientPage.tsx b/frontend/src/app/groups/[groupId]/apply/ClientPage.tsx new file mode 100644 index 00000000..e0b948b5 --- /dev/null +++ b/frontend/src/app/groups/[groupId]/apply/ClientPage.tsx @@ -0,0 +1,110 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { useRouter } from "next/navigation"; + +interface ClientPageProps { + groupId: string; +} + +const ClientPage = ({ groupId }: ClientPageProps) => { + const router = useRouter(); + const [formData, setFormData] = useState({ reason: "" }); + const [token, setToken] = useState(undefined); + const [loading, setLoading] = useState(true); + + // 클라이언트에서 localStorage 접근하도록 useEffect 사용 + useEffect(() => { + if (typeof window !== "undefined") { + const storedToken = localStorage.getItem("token"); + setToken(storedToken || null); + } + setLoading(false); + }, []); + + // 입력값 변경 핸들러 + const handleChange = (e: React.ChangeEvent) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + + // 신청 폼 제출 핸들러 + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + // useEffect 실행이 끝나기 전에 submit되었을 경우, 다시 localStorage에서 확인 + const currentToken = token ?? localStorage.getItem("token"); + + if (!currentToken) { + alert("로그인이 필요합니다."); + router.push("/login"); + return; + } + + try { + const response = await fetch(`/api/v1/groups/${groupId}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${currentToken}`, + }, + credentials: "include", // 인증 정보 포함 (CORS 문제 방지) + body: JSON.stringify(formData), + }); + + const contentType = response.headers.get("content-type"); + + console.log("Response Status:", response.status); + console.log("Response Content-Type:", contentType); + + if (!response.ok) { + const errorMessage = contentType?.includes("application/json") + ? (await response.json()).message + : await response.text(); // HTML 에러 페이지일 경우 + + throw new Error(errorMessage || "신청에 실패했습니다."); + } + + const data = await response.json(); + alert(data.message); + router.push(`/groups/${groupId}`); + } catch (error) { + console.error("Error submitting application:", error); + alert(`오류 발생: ${error.message || "알 수 없는 오류"}`); + } + }; + + if (loading) { + return

로딩 중...

; + } + + return ( +
+

모임 신청

+
+
+ +