diff --git a/.gitlab/issue_templates/merge_request_templates.md b/.gitlab/merge_request_templates/merge_request_templates.md similarity index 100% rename from .gitlab/issue_templates/merge_request_templates.md rename to .gitlab/merge_request_templates/merge_request_templates.md diff --git a/src/components/layout/HeaderLogoBar.jsx b/src/components/layout/HeaderLogoBar.jsx index 4e08f2d392214ed7a1b08fd7d378b233d9c0a1a2..98ea8709bd4dcb157054ceb41d7674502a868aee 100644 --- a/src/components/layout/HeaderLogoBar.jsx +++ b/src/components/layout/HeaderLogoBar.jsx @@ -1,16 +1,42 @@ -import React from "react"; +import React, { useState } from "react"; import LogoIcon from "../icons/LogoIcon"; import useAuthStore from "../../store/authStore"; +import Button from "../Button"; const HeaderLogoBar = () => { - const { user } = useAuthStore(); // Zustand에서 user 상태 가져오기 + const { user, logoutUser } = useAuthStore(); // Zustand에서 상태 및 메서드 가져오기 + const [loading, setLoading] = useState(false); // 로딩 상태 관리 + + // 로그아웃 처리 + const handleLogout = async () => { + try { + setLoading(true); // 로딩 상태 활성화 + await logoutUser(); // 로그아웃 실행 + } catch (error) { + console.error("Failed to logout:", error); + } finally { + setLoading(false); // 로딩 상태 비활성화 + } + }; return ( - <div className="flex items-center justify-between w-full h-16 px-4 bg-white"> + <div className="flex items-center justify-between w-full h-16 px-4 bg-white shadow-md"> {/* 왼쪽: 로고와 앱 이름 */} <div className="flex items-center"> <LogoIcon width={32} height={32} /> - <span className="title-1">YANAWA</span> + <span className="ml-2 text-lg font-bold text-gray-900">YANAWA</span> + </div> + + {/* 오른쪽: 사용자 정보 및 로그아웃 */} + <div className="flex items-center"> + <span className="mr-3 text-gray-600 label-1"> + {user ? `${user.name}` : "guest"} 님 + </span> + {user && ( + <Button size="sm" onClick={handleLogout} disabled={loading}> + {loading ? "로그아웃 중..." : "로그아웃"} + </Button> + )} </div> {/* 오른쪽: 사용자 이름 */} diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 68fc93321daa4ffbea8c56aeac89e489fa23497d..01e46fe3c60d6ec20f83c7467c67abc1d0397cf8 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,9 +1,32 @@ -import React from "react"; +import React, { useEffect } from "react"; +import useAuthStore from "../store/authStore"; const HomePage = () => { + const { user, fetchSession } = useAuthStore(); // Zustand 상태 및 메서드 가져오기 + + useEffect(() => { + const fetchUserSession = async () => { + try { + await fetchSession(); // 세션 정보 가져오기 + } catch (error) { + console.error("Failed to fetch session:", error); + } + }; + + fetchUserSession(); + }, [fetchSession]); // 페이지 마운트 시 실행 + return ( - <div className="w-full h-screen flex items-center justify-center"> + <div className="flex flex-col items-center justify-center w-full h-screen space-y-4"> <h1 className="heading-1">야나와 홈페이지</h1> + {user ? ( + <p className="text-lg text-gray-700"> + 안녕하세요,{" "} + <span className="font-bold text-primary-500">{user.name}</span> 님! + </p> + ) : ( + <p className="text-lg text-gray-700">로그인이 필요합니다.</p> + )} </div> ); }; diff --git a/src/pages/LoginPage.jsx b/src/pages/LoginPage.jsx index 00aa8837962405d7eda15644f267a4327879f71c..f2ad8ffe56b723184274bb9b2ae090a6703b99c3 100644 --- a/src/pages/LoginPage.jsx +++ b/src/pages/LoginPage.jsx @@ -1,27 +1,15 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect } from "react"; import GoogleLogo from "../components/icons/GoogleLogoIcon"; import Button from "../components/Button"; import { getLoginUrl } from "../api/auth"; import useAuthStore from "../store/authStore"; const LoginPage = () => { - const { user, fetchSession, logoutUser } = useAuthStore(); - const [loading, setLoading] = useState(true); + const { user, fetchSession, logoutUser, loading } = useAuthStore(); // Zustand 상태 가져오기 // 페이지 로드 시 세션 확인 useEffect(() => { - const fetchSessionInfo = async () => { - setLoading(true); - try { - await fetchSession(); // 세션 정보 가져오기 - } catch (error) { - console.error("Failed to fetch session info:", error); - } finally { - setLoading(false); - } - }; - - fetchSessionInfo(); + fetchSession(); // 세션 정보 가져오기 }, [fetchSession]); // Google 로그인 처리 @@ -32,37 +20,34 @@ const LoginPage = () => { // 로그아웃 처리 const handleLogout = async () => { - try { - setLoading(true); - await logoutUser(); - } catch (error) { - console.error("Failed to logout:", error); - } finally { - setLoading(false); - } + await logoutUser(); // 로그아웃 실행 }; + // 로딩 상태 처리 if (loading) { return ( - <div className="flex items-center justify-center min-h-screen"> - <p>Loading...</p> + <div className="flex items-center justify-center min-h-screen bg-gray-100"> + <p className="text-lg text-gray-600">로딩 중...</p> </div> ); } + // 로그인된 상태 if (user) { return ( <div className="flex items-center justify-center min-h-screen p-4 bg-gray-100"> - <div className="flex flex-col items-center justify-center min-w-[260px] w-1/2 max-w-md p-8 space-y-4 bg-white rounded-lg shadow-lg"> + <div className="flex flex-col items-center min-w-[260px] w-1/2 max-w-md p-8 space-y-4 bg-white rounded-lg shadow-lg"> <div> - <h2 className="text-center heading-2">환영합니다!</h2> - <h2 className="text-center heading-1"> - <span className="text-primary-500">{user.name}</span>님 + <h2 className="text-2xl font-semibold text-center text-gray-900"> + 환영합니다! + </h2> + <h2 className="text-xl font-bold text-center text-primary-500"> + {user.name}님 </h2> </div> - <p className="text-center text-gray-700"> - <span className="text-primary-500 title-1">번개모임</span>을 생성해 - 보세요! + <p className="text-center text-gray-600"> + <span className="font-bold text-primary-500">번개모임</span>을 + 생성하거나 참여해 보세요! </p> <Button size="md" theme="black" onClick={handleLogout}> 로그아웃 @@ -72,6 +57,7 @@ const LoginPage = () => { ); } + // 비로그인 상태 return ( <div className="flex items-center justify-center min-h-screen p-4 bg-gray-100"> <div className="flex flex-col items-center min-w-[260px] justify-center w-1/2 max-w-md p-8 space-y-6 bg-white rounded-lg shadow-lg"> diff --git a/src/pages/SchedulePage.jsx b/src/pages/SchedulePage.jsx index 5fa5f28ce29ab4f1a38ee3e07ac4dda555eb0563..6dcb5c7577b178ff5dfdb5f350e200321970d312 100644 --- a/src/pages/SchedulePage.jsx +++ b/src/pages/SchedulePage.jsx @@ -3,7 +3,7 @@ import Label from "../components/Label"; import { createSchedule, deleteSchedule, - fetchScheduleByTimeIndex, + // fetchScheduleByTimeIndex, fetchAllSchedules, updateSchedule, } from "../api/schedule"; @@ -74,34 +74,34 @@ const SchedulePage = () => { if (!isEditMode) return; // API - try { - const response = await fetchScheduleByTimeIndex(timeIdx); - if (response && response.data && response.data.schedule) { - setSelectedSchedule(response.data.schedule); // API로 가져온 스케줄 설정 - } else { - console.error("No schedule found for time index:", timeIdx); - } - } catch (error) { - console.error("Failed to fetch schedule for time index:", timeIdx, error); - } + // try { + // const response = await fetchScheduleByTimeIndex(timeIdx); + // if (response && response.data && response.data.schedule) { + // setSelectedSchedule(response.data.schedule); // API로 가져온 스케줄 설정 + // } else { + // console.error("No schedule found for time index:", timeIdx); + // } + // } catch (error) { + // console.error("Failed to fetch schedule for time index:", timeIdx, error); + // } // 임시 코드 - // const slotInSchedule = schedules.find((s) => - // s.time_indices.includes(timeIdx) - // ); + const slotInSchedule = schedules.find((s) => + s.time_indices.includes(timeIdx) + ); - // if (slotInSchedule) { - // if (selectedSlots.length === 0) { - // setSelectedSchedule(slotInSchedule); - // } - // return; - // } + if (slotInSchedule) { + if (selectedSlots.length === 0) { + setSelectedSchedule(slotInSchedule); + } + return; + } - // if (selectedSlots.includes(timeIdx)) { - // setSelectedSlots((prev) => prev.filter((idx) => idx !== timeIdx)); - // } else { - // setSelectedSlots((prev) => [...prev, timeIdx]); - // } + if (selectedSlots.includes(timeIdx)) { + setSelectedSlots((prev) => prev.filter((idx) => idx !== timeIdx)); + } else { + setSelectedSlots((prev) => [...prev, timeIdx]); + } }; const handleCancelSchedule = () => { diff --git a/src/store/authStore.js b/src/store/authStore.js index 1d1223be9a0c5fda04df8865f53e3e606e5a1cbd..05da3b6d76f0c33cc904ff09ce58023eeacdb35f 100644 --- a/src/store/authStore.js +++ b/src/store/authStore.js @@ -3,16 +3,19 @@ import { getSessionInfo, logout } from "../api/auth"; const useAuthStore = create((set) => ({ user: null, // 사용자 정보 - // user: { name: "윤석찬", email: "ysc0731@ajou.ac.kr" }, // 사용자 정보 + loading: true, // 로딩 상태 // 세션 정보 가져오기 fetchSession: async () => { + set({ loading: true }); try { const userInfo = await getSessionInfo(); set({ user: userInfo }); } catch (error) { console.error("Failed to fetch session info:", error); set({ user: null }); + } finally { + set({ loading: false }); } },