diff --git a/src/components/GuestInfoForm.jsx b/src/components/GuestInfoForm.jsx index 0b117ba..1c4f542 100644 --- a/src/components/GuestInfoForm.jsx +++ b/src/components/GuestInfoForm.jsx @@ -1,6 +1,8 @@ import styled from "styled-components"; import { useState } from "react"; import useSignupStore from "../stores/useSignupStore"; +import useAuthStore from "../stores/useAuthStore"; +import axios from "axios"; // 아이콘 import backIcon from "../assets/icons/backIcon.svg"; @@ -196,6 +198,7 @@ const NextButton = styled.button` const GuestInfoForm = () => { const { setNextStep, setBackStep, name, setName } = useSignupStore(); + const { token } = useAuthStore(); // Bearer Token 가져오기 // 상태 정의 const [profile, setProfile] = useState(profileIcon); @@ -222,10 +225,45 @@ const GuestInfoForm = () => { setFile(file); }; - const handleNext = (e) => { + const handleNext = async (e) => { e.preventDefault(); if (!isValid) return; - setNextStep(3); // SignupSuccess 화면으로 이동 + + const formData = new FormData(); + formData.append("name", name); + formData.append("introduction", introduce); + + if (profile && profile !== profileIcon) { + const profileBlob = dataURLtoFile(profile, "profile.png"); + formData.append("profileImagUrl", profileBlob); + } + + if (idFile) formData.append("idFile", idFile); + + try { + await axios.patch("/api/v1/user/my/update-profile", formData, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + setNextStep(3); // SignupSuccess 화면으로 이동 + } catch (err) { + console.error(err); + alert("프로필 업데이트 중 오류가 발생했습니다."); + } + }; + + // Base64 -> File 변환 + const dataURLtoFile = (dataurl, filename) => { + const arr = dataurl.split(","); + const mime = arr[0].match(/:(.*?);/)[1]; + const bstr = atob(arr[1]); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new File([u8arr], filename, { type: mime }); }; return ( diff --git a/src/components/HostInfoForm.jsx b/src/components/HostInfoForm.jsx index 71e2eb2..d18ed5e 100644 --- a/src/components/HostInfoForm.jsx +++ b/src/components/HostInfoForm.jsx @@ -1,6 +1,8 @@ import styled from "styled-components"; import { useState } from "react"; import useSignupStore from "../stores/useSignupStore"; +import useAuthStore from "../stores/useAuthStore"; +import axios from "axios"; // 아이콘 import backIcon from "../assets/icons/backIcon.svg"; @@ -199,6 +201,7 @@ const NextButton = styled.button` const HostInfoForm = () => { const { setNextStep, setBackStep, name, setName } = useSignupStore(); + const { token } = useAuthStore(); // Bearer Token 가져오기 // 상태 정의 const [profile, setProfile] = useState(profileIcon); @@ -231,10 +234,48 @@ const HostInfoForm = () => { setFile(file); }; - const handleNext = (e) => { + const handleNext = async (e) => { e.preventDefault(); if (!isValid) return; - setNextStep(3); // SignupSuccess 화면으로 이동 + + const formData = new FormData(); + formData.append("name", name); + formData.append("introduction", introduce); + + if (profile && profile !== profileIcon) { + const profileBlob = dataURLtoFile(profile, "profile.png"); + formData.append("profileImagUrl", profileBlob); + } + + if (idFile) formData.append("idFile", idFile); + if (buildingFile) formData.append("buildingFile", buildingFile); + if (leaseFile) formData.append("leaseFile", leaseFile); + if (bankFile) formData.append("bankFile", bankFile); + + try { + await axios.patch("/api/v1/user/my/update-profile", formData, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + setNextStep(3); // SignupSuccess 화면으로 이동 + } catch (err) { + console.error(err); + alert("프로필 업데이트 중 오류가 발생했습니다."); + } + }; + + // Base64 -> File 변환 + const dataURLtoFile = (dataurl, filename) => { + const arr = dataurl.split(","); + const mime = arr[0].match(/:(.*?);/)[1]; + const bstr = atob(arr[1]); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new File([u8arr], filename, { type: mime }); }; return ( diff --git a/src/hooks/useAuthRedirect.js b/src/hooks/useAuthRedirect.js index ea26526..2b7d42c 100644 --- a/src/hooks/useAuthRedirect.js +++ b/src/hooks/useAuthRedirect.js @@ -1,8 +1,10 @@ import { useEffect } from "react"; import { useSearchParams } from "react-router-dom"; +import useAuthStore from "../stores/useAuthStore"; const useAuthRedirect = () => { const [searchParams] = useSearchParams(); + const { setTokens } = useAuthStore(); useEffect(() => { const accessToken = searchParams.get("access_token"); @@ -11,8 +13,11 @@ const useAuthRedirect = () => { if (accessToken && refreshToken) { localStorage.setItem("access_token", accessToken); localStorage.setItem("refresh_token", refreshToken); + + // zustand 상태에도 저장 + setTokens(accessToken, refreshToken); } - }, [searchParams]); + }, [searchParams, setTokens]); }; export default useAuthRedirect; diff --git a/src/stores/useAuthStore.js b/src/stores/useAuthStore.js index 993cd8e..15d3b6f 100644 --- a/src/stores/useAuthStore.js +++ b/src/stores/useAuthStore.js @@ -1,8 +1,11 @@ import { create } from "zustand"; const useAuthStore = create((set) => ({ - token: localStorage.getItem("access_token") || null, - setToken: (token) => set({ token }), + token: null, + refreshToken: null, + + setTokens: (accessToken, refreshToken) => + set({ token: accessToken, refreshToken }), })); export default useAuthStore;