diff --git a/sentry.client.config.ts b/sentry.client.config.ts index d455f22e..1abdceed 100644 --- a/sentry.client.config.ts +++ b/sentry.client.config.ts @@ -1,28 +1,15 @@ -// This file configures the initialization of Sentry on the client. -// The config you add here will be used whenever a users loads a page in their browser. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: process.env.SENTRY_DSN || "", environment: process.env.SENTRY_ENVIRONMENT || "development", + tracesSampleRate: 1.0, - // Adjust this value in production, or use tracesSampler for greater control - tracesSampleRate: 1, - - // Setting this option to true will print useful information to the console while you're setting up Sentry. - debug: false, - - replaysOnErrorSampleRate: 1.0, - - // This sets the sample rate to be 10%. You may want this to be 100% while - // in development and sample at a lower rate in production - replaysSessionSampleRate: 0.1, - - // You can remove this option if you're not planning to use the Sentry Session Replay feature: integrations: [ + Sentry.browserTracingIntegration({ + tracePropagationTargets: ["localhost", /^https:\/\/(www\.)?solid\-connection\.com/], + }), Sentry.replayIntegration({ - // Additional Replay configuration goes in here, for example: maskAllText: true, blockAllMedia: true, }), diff --git a/src/api/article/client/useGetArticleList.ts b/src/api/article/client/useGetArticleList.ts new file mode 100644 index 00000000..fd801180 --- /dev/null +++ b/src/api/article/client/useGetArticleList.ts @@ -0,0 +1,40 @@ +import { useEffect, useState } from "react"; + +import useFetch from "@/utils/apiUtils"; + +import { ArticleResponse } from "../type/response"; + +/* ---------- 타입 ---------- */ + +interface ArticleListResponse { + news: ArticleResponse[]; // 최대 5개 +} + +const useGetArticleList = (userId: number | null) => { + const { result, loading, error, fetchData } = useFetch(); + + const [articleList, setArticleList] = useState([]); + + /* 페이지 변경 시 데이터 요청 */ + useEffect(() => { + if (userId === null) return; + + fetchData({ + method: "get", + url: `/news?site-user-id=${userId}`, + body: undefined, + isToken: true, + }); + }, [userId, fetchData]); + + /* 응답 처리 */ + useEffect(() => { + if (result) { + setArticleList(result.data.news); + } + }, [result]); + + return { articleList, loading, error }; +}; + +export default useGetArticleList; diff --git a/src/api/mentor/client/useGetMyMentorProfile.ts b/src/api/mentor/client/useGetMyMentorProfile.ts index f87ad45b..4557913a 100644 --- a/src/api/mentor/client/useGetMyMentorProfile.ts +++ b/src/api/mentor/client/useGetMyMentorProfile.ts @@ -12,7 +12,11 @@ interface UseGetMyMentorDataReturn { const useGetMyMentorProfile = (): UseGetMyMentorDataReturn => { const { result, loading, error, fetchData } = useFetch(); +<<<<<<< HEAD + const [myMentorProfile, setMyMentorProfile] = useState(null); +======= const [myMentorProfile, setMyMentorProfile] = useState({} as MentorCardPreview); +>>>>>>> main useEffect(() => { fetchData({ diff --git a/src/api/mentor/type/response.ts b/src/api/mentor/type/response.ts index ef3b653c..8351458d 100644 --- a/src/api/mentor/type/response.ts +++ b/src/api/mentor/type/response.ts @@ -30,7 +30,7 @@ export interface MentorCardBase { } /** 리스트(미리보기) 용 – passTip / isApplied 없이 사용 */ -export type MentorCardPreview = MentorCardBase & { studyStatus: "24-1" | "24-2" }; // 학업 상태 (예: "24-1") +export type MentorCardPreview = (MentorCardBase & { studyStatus: "24-1" | "24-2" }) | null; // 학업 상태 (예: "24-1") /** 상세 뷰 용 – 추가 정보 포함 */ export interface MentorCardDetail extends MentorCardBase { diff --git a/src/app/application/ScorePageContent.tsx b/src/app/application/ScorePageContent.tsx index 4de7fe5e..a2148054 100644 --- a/src/app/application/ScorePageContent.tsx +++ b/src/app/application/ScorePageContent.tsx @@ -3,9 +3,9 @@ import { useRouter } from "next/navigation"; import { useEffect, useRef, useState } from "react"; -import CloudSpinnerPage from "@/components/loading/CloudSpinnerPage"; import ConfirmCancelModal from "@/components/modal/ConfirmCancelModal"; import ButtonTab from "@/components/ui/ButtonTab"; +import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage"; import Tab from "@/components/ui/Tab"; import ScoreSearchBar from "./ScoreSearchBar"; diff --git a/src/app/community/[boardCode]/CommunityPageContent.tsx b/src/app/community/[boardCode]/CommunityPageContent.tsx index 76568f7a..27e84323 100644 --- a/src/app/community/[boardCode]/CommunityPageContent.tsx +++ b/src/app/community/[boardCode]/CommunityPageContent.tsx @@ -3,8 +3,8 @@ import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; -import CloudSpinnerPage from "@/components/loading/CloudSpinnerPage"; import ButtonTab from "@/components/ui/ButtonTab"; +import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage"; import CommunityRegionSelector from "./CommunityRegionSelector"; import PostCards from "./PostCards"; diff --git a/src/app/community/[boardCode]/[postId]/PostPageContent.tsx b/src/app/community/[boardCode]/[postId]/PostPageContent.tsx index 1f49ecea..41205b2c 100644 --- a/src/app/community/[boardCode]/[postId]/PostPageContent.tsx +++ b/src/app/community/[boardCode]/[postId]/PostPageContent.tsx @@ -4,7 +4,7 @@ import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; -import CloudSpinnerPage from "@/components/loading/CloudSpinnerPage"; +import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage"; import CommentSection from "./CommentSection"; import Content from "./Content"; diff --git a/src/app/community/[boardCode]/[postId]/modify/PostModifyContent.tsx b/src/app/community/[boardCode]/[postId]/modify/PostModifyContent.tsx index 224c6ef6..c6d41c22 100644 --- a/src/app/community/[boardCode]/[postId]/modify/PostModifyContent.tsx +++ b/src/app/community/[boardCode]/[postId]/modify/PostModifyContent.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; -import CloudSpinnerPage from "@/components/loading/CloudSpinnerPage"; +import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage"; import PostModifyForm from "./PostModifyForm"; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 6ab9329e..498e6e0d 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,15 +2,13 @@ import type { Metadata, Viewport } from "next"; import { Inter } from "next/font/google"; import localFont from "next/font/local"; -import AppleScriptLoader from "@/components/layout/AppleScriptLoader"; -import KakaoScriptLoader from "@/components/layout/KakaoScriptLoader"; -import Layout from "@/components/layout/Layout"; -import RootModal from "@/components/layout/RootModal"; +import GlobalLayout from "@/components/layout/GlobalLayout"; import "../styles/globals.css"; import { AlertProvider } from "@/context/AlertContext"; -import { LayoutProvider } from "@/context/LayoutContext"; +import AppleScriptLoader from "@/lib/ScriptLoader/AppleScriptLoader"; +import KakaoScriptLoader from "@/lib/ScriptLoader/KakaoScriptLoader"; import { GoogleAnalytics } from "@next/third-parties/google"; export const metadata: Metadata = { @@ -46,17 +44,14 @@ export const viewport: Viewport = { const RootLayout = ({ children }: { children: React.ReactNode }) => ( - - - - - - - {children} - - - - + + + + + + {children} + + ); diff --git a/src/app/login/LoginContent.tsx b/src/app/login/LoginContent.tsx index 59a7115c..aa6c1974 100644 --- a/src/app/login/LoginContent.tsx +++ b/src/app/login/LoginContent.tsx @@ -15,21 +15,14 @@ import KakaoLoginButton from "./KakaoLoginButton"; import { appleOAuth2CodeResponse } from "@/types/auth"; import { emailAuthApi } from "@/api/auth"; -import { useLayout } from "@/context/LayoutContext"; import { IconSolidConnectionFullBlackLogo } from "@/public/svgs"; const LoginContent = () => { const router = useRouter(); - const { setHideBottomNavigation } = useLayout(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); - useEffect(() => { - setHideBottomNavigation(true); - return () => setHideBottomNavigation(false); - }, [setHideBottomNavigation]); - const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { handleEmailLogin(); diff --git a/src/app/login/apple/callback/AppleLoginCallbackPage.tsx b/src/app/login/apple/callback/AppleLoginCallbackPage.tsx index fdd92b9a..04fd9418 100644 --- a/src/app/login/apple/callback/AppleLoginCallbackPage.tsx +++ b/src/app/login/apple/callback/AppleLoginCallbackPage.tsx @@ -7,11 +7,10 @@ import axios from "axios"; import { saveAccessToken, saveRefreshToken } from "@/utils/localStorage"; -import CloudSpinnerPage from "@/components/loading/CloudSpinnerPage"; import SignupSurvey from "@/components/login/signup/SignupSurvey"; +import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage"; import { appleAuthApi } from "@/api/auth"; -import { useLayout } from "@/context/LayoutContext"; const AppleLoginCallbackPage = () => { const router = useRouter(); @@ -20,13 +19,6 @@ const AppleLoginCallbackPage = () => { // const [signUpToken, setSignUpToken] = useState(""); // const [email, setEmail] = useState(""); - const { setHideBottomNavigation } = useLayout(); - - useEffect(() => { - setHideBottomNavigation(true); - return () => setHideBottomNavigation(false); // 컴포넌트 언마운트 시 다시 보이게 설정 - }, [setHideBottomNavigation]); - useEffect(() => { const code = searchParams?.get("code"); if (code) { diff --git a/src/app/login/kakao/callback/KakaoLoginCallbackPage.tsx b/src/app/login/kakao/callback/KakaoLoginCallbackPage.tsx index 4de4735a..efb7ff5b 100644 --- a/src/app/login/kakao/callback/KakaoLoginCallbackPage.tsx +++ b/src/app/login/kakao/callback/KakaoLoginCallbackPage.tsx @@ -7,11 +7,10 @@ import axios from "axios"; import { saveAccessToken, saveRefreshToken } from "@/utils/localStorage"; -import CloudSpinnerPage from "@/components/loading/CloudSpinnerPage"; import SignupSurvey from "@/components/login/signup/SignupSurvey"; +import CloudSpinnerPage from "@/components/ui/CloudSpinnerPage"; import { kakaoAuthApi } from "@/api/auth"; -import { useLayout } from "@/context/LayoutContext"; const KakaoLoginCallbackPage = () => { const router = useRouter(); @@ -22,13 +21,6 @@ const KakaoLoginCallbackPage = () => { // const [kakaoEmail, setKakaoEmail] = useState(""); // const [kakaoProfileImageUrl, setKakaoProfileImageUrl] = useState(""); - const { setHideBottomNavigation } = useLayout(); - - useEffect(() => { - setHideBottomNavigation(true); - return () => setHideBottomNavigation(false); // 컴포넌트 언마운트 시 다시 보이게 설정 - }, [setHideBottomNavigation]); - useEffect(() => { const code = searchParams?.get("code"); if (code) { diff --git a/src/app/mentor/[id]/_ui/MentorDetialContent/_ui/MentorArticle/index.tsx b/src/app/mentor/[id]/_ui/MentorDetialContent/_ui/MentorArticle/index.tsx index e0dc3a9e..db299faf 100644 --- a/src/app/mentor/[id]/_ui/MentorDetialContent/_ui/MentorArticle/index.tsx +++ b/src/app/mentor/[id]/_ui/MentorDetialContent/_ui/MentorArticle/index.tsx @@ -5,9 +5,22 @@ import { useState } from "react"; import { ArticleResponse } from "@/api/article/type/response"; import { IconLikeFill, IconLikeNotFill } from "@/public/svgs/mentor"; +<<<<<<< HEAD +<<<<<<< HEAD interface MentorArticleProps { article: ArticleResponse; +======= +import { IconLikeFill, IconLkieNotFill } from "@/public/svgs/mentor"; + +interface MentorArticleProps { + article: Article; +>>>>>>> upstream/main +======= + +interface MentorArticleProps { + article: ArticleResponse; +>>>>>>> main } const MentorArticle = ({ article }: MentorArticleProps) => { diff --git a/src/app/mentor/[id]/_ui/MentorDetialContent/index.tsx b/src/app/mentor/[id]/_ui/MentorDetialContent/index.tsx index 4f44711e..3ae98482 100644 --- a/src/app/mentor/[id]/_ui/MentorDetialContent/index.tsx +++ b/src/app/mentor/[id]/_ui/MentorDetialContent/index.tsx @@ -7,7 +7,7 @@ import ProfileWithBadge from "@/components/ui/ProfileWithBadge"; import MentorArticle from "./_ui/MentorArticle"; -import useGetArticleList from "@/api/article/client/useGetAriticleList"; +import useGetArticleList from "@/api/article/client/useGetArticleList"; import useGetMentorDetailPage from "@/api/mentor/client/useGetMentorDetailPage"; import { ChannelType } from "@/api/mentor/type/response"; import { customConfirm } from "@/lib/zustand/useConfirmModalStore"; diff --git a/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx b/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx index f0ef1144..073467db 100644 --- a/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx +++ b/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/index.tsx @@ -13,11 +13,31 @@ import useGetMentorList from "@/api/mentor/client/useGetMentorList"; const MentorFindSection = () => { const [selectedFilter, setSelectedFilter] = useState(FilterTab.ALL); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> main const { page, lastElementRef } = useInfinityScroll(); const { mentorList } = useGetMentorList({ page, region: selectedFilter !== FilterTab.ALL ? selectedFilter : undefined, }); +<<<<<<< HEAD +======= + const mentorListData = getMentorListData(); + + const filteredMentors = useMemo(() => { + return mentorListData.filter((mentor) => { + if (selectedFilter === FilterTab.ALL) return true; + if (selectedFilter === FilterTab.EUROPE) return mentor.country === FilterTab.EUROPE; + if (selectedFilter === FilterTab.AMERICAS) return mentor.country === FilterTab.AMERICAS; + if (selectedFilter === FilterTab.ASIA) return mentor.country === FilterTab.ASIA; + return false; + }); + }, [mentorListData, selectedFilter]); +>>>>>>> upstream/main +======= +>>>>>>> main return (
diff --git a/src/app/mentor/_ui/MentorClient/_ui/MyMentorSection/index.tsx b/src/app/mentor/_ui/MentorClient/_ui/MyMentorSection/index.tsx index 820f7f51..55a092a5 100644 --- a/src/app/mentor/_ui/MentorClient/_ui/MyMentorSection/index.tsx +++ b/src/app/mentor/_ui/MentorClient/_ui/MyMentorSection/index.tsx @@ -11,7 +11,7 @@ const MyMentorSection = () => { <>

나의 멘토 페이지

- +
); diff --git a/src/app/mentor/_ui/MentorClient/index.tsx b/src/app/mentor/_ui/MentorClient/index.tsx index 5e511beb..ef99f4c6 100644 --- a/src/app/mentor/_ui/MentorClient/index.tsx +++ b/src/app/mentor/_ui/MentorClient/index.tsx @@ -7,7 +7,15 @@ const MentorClient = () => { const isMentor = false; return ( <> +<<<<<<< HEAD +<<<<<<< HEAD {isMentor ? ( +======= + {!isMentor ? ( +>>>>>>> upstream/main +======= + {isMentor ? ( +>>>>>>> main // 멘토페이지 <> {/* 나의 멘토 - 멘티 탭 및 채팅카드 */} diff --git a/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx b/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx index 8e24f2fe..13160cfb 100644 --- a/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx +++ b/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx @@ -5,7 +5,7 @@ import { useForm } from "react-hook-form"; import ProfileWithBadge from "@/components/ui/ProfileWithBadge"; -import ChatMessageBox from "./_components/ChatMessageBox"; +import ChatMessageBox from "./_ui/ChatMessageBox"; import { ChatMessage } from "@/types/mentor"; @@ -131,7 +131,7 @@ const ChatContent = () => {
{/* 메시지 입력 영역 - 하단 고정 */} -
+
+
+ + {/* 툴팁을 IconPlus 위치에 맞춰 배치 */} +
+ +
+
+ + setIsArticleModalOpen(false)} + onSubmit={(data) => { + console.log("새 아티클:", data); + // 여기서 아티클 추가 로직 처리 + }} + /> + + ); + } +>>>>>>> upstream/main +======= +const ArticlePanel = ({ article }: ArticlePanelProps) => { + // state + const [isArticleModalOpen, setIsArticleModalOpen] = useState(false); + const { handleDropdownSelect } = useDeleteDropDownHandler({ + articleId: 0, + setIsArticleModalOpen, + }); +>>>>>>> main return ( <>
+<<<<<<< HEAD +<<<<<<< HEAD 멘토 아티클 이미지
{article.updatedAt}
+======= + 멘토 아티클 이미지 +
+
+
{articleData.date}
+>>>>>>> upstream/main +======= + 멘토 아티클 이미지 +
+
+
{article.updatedAt}
+>>>>>>> main
items={dropdownOptions} @@ -44,15 +146,35 @@ const ArticlePanel = ({ article }: ArticlePanelProps) => {
+<<<<<<< HEAD +<<<<<<< HEAD

{article.title}

{article.description}

+======= +

{articleData.title}

+

{articleData.description}

+>>>>>>> upstream/main +======= +

{article.title}

+

{article.description}

+>>>>>>> main setIsArticleModalOpen(false)} initialData={{ +<<<<<<< HEAD +<<<<<<< HEAD + title: article.title, + content: article.description, +======= + title: articleData.title, + content: articleData.description, +>>>>>>> upstream/main +======= title: article.title, content: article.description, +>>>>>>> main }} onSubmit={(data) => { console.log("아티클 수정:", data); diff --git a/src/app/mentor/modify/_ui/ModifyContent/index.tsx b/src/app/mentor/modify/_ui/ModifyContent/index.tsx index d5e77ed6..d79d156e 100644 --- a/src/app/mentor/modify/_ui/ModifyContent/index.tsx +++ b/src/app/mentor/modify/_ui/ModifyContent/index.tsx @@ -11,10 +11,24 @@ import AddArticleCard from "./_ui/AddArticleCard"; import MentoArticlePanel from "./_ui/ArticlePanel"; import ChannelSelect from "./_ui/ChannelSelct"; <<<<<<< HEAD +<<<<<<< HEAD +import ModifyBtnPanel from "./_ui/ModifyBtnPanel"; + +import { ChannelType } from "@/types/mentor"; + +import useGetArticleList from "@/api/article/client/useGetArticleList"; +import useGetMyMentorProfile from "@/api/mentor/client/useGetMyMentorProfile"; +import usePutMyMentorProfile, { PutMyMentorProfileBody } from "@/api/mentor/client/usePutMyMentorProfile"; +======= +======= +>>>>>>> main import ModifyBtnPanel from "./_ui/ModalBtnPanel"; import { ChannelType } from "@/types/mentor"; +<<<<<<< HEAD +>>>>>>> upstream/main +======= ======= import ModifyBtnPanel from "./_ui/ModifyBtnPanel"; @@ -24,14 +38,20 @@ import useGetArticleList from "@/api/article/client/useGetAriticleList"; import useGetMyMentorProfile from "@/api/mentor/client/useGetMyMentorProfile"; import usePutMyMentorProfile, { PutMyMentorProfileBody } from "@/api/mentor/client/usePutMyMentorProfile"; >>>>>>> feature/mentor_api +>>>>>>> main import { IconUserPrimaryColor } from "@/public/svgs/mentor"; import { zodResolver } from "@hookform/resolvers/zod"; const ModifyContent = () => { const { myMentorProfile } = useGetMyMentorProfile(); +<<<<<<< HEAD + const userId = myMentorProfile ? myMentorProfile.id : null; + const { articleList } = useGetArticleList(userId); +======= const { articleList } = useGetArticleList(myMentorProfile.id); const { profileImageUrl, hasBadge, menteeCount, nickname, country, universityName, studyStatus } = myMentorProfile; +>>>>>>> main const { register, @@ -59,6 +79,9 @@ const ModifyContent = () => { putMyMentorProfile(payload); }; + if (!myMentorProfile) return null; + const { profileImageUrl, hasBadge, menteeCount, nickname, country, universityName, studyStatus } = myMentorProfile; + return (
diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 52197003..71f8c8cd 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -1,9 +1,12 @@ -import NotFound from "@/components/loading/NotFound"; +import { IconNotFound } from "@/public/svgs/loading"; const NotFoundPage = () => { return ( -
- +
+ +
+ {"존재하지 않는 페이지입니다"} +
); }; diff --git a/src/app/page.tsx b/src/app/page.tsx index 112483ab..6838f319 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,6 @@ import { Metadata } from "next"; -import TopNavigation from "@/components/layout/TopNavigation"; +import TopLogoBar from "@/components/ui/TopLogoBar"; import Home from "./Home"; @@ -20,7 +20,7 @@ const HomePage = async () => { return (
- +
); diff --git a/src/app/score/submit/gpa/page.tsx b/src/app/score/submit/gpa/page.tsx index e87e8dc2..40c00c21 100644 --- a/src/app/score/submit/gpa/page.tsx +++ b/src/app/score/submit/gpa/page.tsx @@ -2,7 +2,7 @@ import { Metadata } from "next"; import Link from "next/link"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; -import tabStyles from "@/components/ui/tab.module.css"; +import tabStyles from "@/components/ui/Tab/tab.module.css"; import GpaSubmitForm from "./GpaSubmitForm"; diff --git a/src/app/score/submit/language-test/page.tsx b/src/app/score/submit/language-test/page.tsx index d7a81b1b..f3312621 100644 --- a/src/app/score/submit/language-test/page.tsx +++ b/src/app/score/submit/language-test/page.tsx @@ -2,7 +2,7 @@ import { Metadata } from "next"; import Link from "next/link"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; -import tabStyles from "@/components/ui/tab.module.css"; +import tabStyles from "@/components/ui/Tab/tab.module.css"; import LanguageTestSubmitForm from "./LanguageTestSubmitForm"; diff --git a/src/app/sign-up/email/EmailSignUpForm.tsx b/src/app/sign-up/email/EmailSignUpForm.tsx index 0391584a..73ac43bc 100644 --- a/src/app/sign-up/email/EmailSignUpForm.tsx +++ b/src/app/sign-up/email/EmailSignUpForm.tsx @@ -4,7 +4,7 @@ import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import BlockBtn from "@/components/button/BlockBtn"; -import { Input } from "@/components/ui/Input"; +import { Input } from "@/components/ui/Inputa"; import { Label } from "@/components/ui/Label"; import { Progress } from "@/components/ui/Progress"; diff --git a/src/app/university/UniversityPage.tsx b/src/app/university/UniversityPage.tsx index a0cb9e56..f356ebde 100644 --- a/src/app/university/UniversityPage.tsx +++ b/src/app/university/UniversityPage.tsx @@ -4,8 +4,8 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useEffect, useRef, useState } from "react"; import UniversityCards from "@/components/college/UniversityCards"; -import TopNavigation from "@/components/layout/TopNavigation"; import ButtonTab from "@/components/ui/ButtonTab"; +import TopLogoBar from "@/components/ui/TopLogoBar"; import UniversitySearch from "./UniversitySearch"; @@ -85,7 +85,7 @@ const UniversityPage = ({ universities }: { universities: ListUniversity[] }) => return ( <> - + { searchHandler(e); diff --git a/src/app/university/page.tsx b/src/app/university/page.tsx index f72a8276..1250af25 100644 --- a/src/app/university/page.tsx +++ b/src/app/university/page.tsx @@ -1,7 +1,7 @@ import { Metadata } from "next"; import React, { Suspense } from "react"; -import CloudSpinner from "@/components/loading/CloudSpinner"; +import CloudSpinner from "@/components/ui/CloudSpinner"; import UniversityPage from "./UniversityPage"; diff --git a/src/components/layout/AdvancedPathBasedNavigation.tsx b/src/components/layout/AdvancedPathBasedNavigation.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/src/components/layout/BottomNavigation.tsx b/src/components/layout/BottomNavigation.tsx deleted file mode 100644 index 14641444..00000000 --- a/src/components/layout/BottomNavigation.tsx +++ /dev/null @@ -1,75 +0,0 @@ -"use client"; - -import Link from "next/link"; -import { usePathname } from "next/navigation"; - -import DegreeHat from "./icon/DegreeHat"; -import EditTwo from "./icon/EditTwo"; -import Home from "./icon/Home"; -import Human from "./icon/Human"; -import WhatsNew from "./icon/WhatsNew"; - -const BottomNavigation = () => { - const pathname = usePathname(); - - const specificRoutes = ["/university", "/community", "/mento", "/my"]; - const isSpecificRouteActive = specificRoutes.some((specificRoute) => pathname?.startsWith(specificRoute)); - - const navs = [ - { - route: "/university", - text: "학교", - isActive: pathname?.startsWith("/university"), - icon: , - }, - { - route: "/community", - text: "커뮤니티", - isActive: pathname?.startsWith("/community"), - icon: , - }, - { - route: "/", - text: "홈", - isActive: !isSpecificRouteActive, - icon: , - }, - { - route: "/mentor", - text: "멘토", - isActive: pathname?.startsWith("/mentor"), - icon: , - }, - { - route: "/my", - text: "마이", - isActive: pathname?.startsWith("/my"), - icon: , - }, - ]; - - return ( - - ); -}; - -export default BottomNavigation; diff --git a/src/components/layout/GlobalLayout/index.tsx b/src/components/layout/GlobalLayout/index.tsx new file mode 100644 index 00000000..28f6f3af --- /dev/null +++ b/src/components/layout/GlobalLayout/index.tsx @@ -0,0 +1,20 @@ +import React from "react"; + +import BottomNavigation from "./ui/BottomNavigation"; +import RootModal from "./ui/RootModal"; + +type LayoutProps = { + children: React.ReactNode; +}; + +const GlobalLayout = ({ children }: LayoutProps) => { + return ( +
+ {children} + + +
+ ); +}; + +export default GlobalLayout; diff --git a/src/components/layout/GlobalLayout/ui/BottomNavigation/constant/NAV_ITEMS.ts b/src/components/layout/GlobalLayout/ui/BottomNavigation/constant/NAV_ITEMS.ts new file mode 100644 index 00000000..6b77b1e0 --- /dev/null +++ b/src/components/layout/GlobalLayout/ui/BottomNavigation/constant/NAV_ITEMS.ts @@ -0,0 +1,14 @@ +export enum NavIconType { + UNIVERSITY = "university", + COMMUNITY = "community", + HOME = "home", + MENTOR = "mentor", + MY = "my", +} +export const NAV_ITEMS = [ + { route: "/university", text: "학교", iconType: NavIconType.UNIVERSITY }, + { route: "/community", text: "커뮤니티", iconType: NavIconType.COMMUNITY }, + { route: "/", text: "홈", iconType: NavIconType.HOME }, + { route: "/mentor", text: "멘토", iconType: NavIconType.MENTOR }, + { route: "/my", text: "마이", iconType: NavIconType.MY }, +] as const; diff --git a/src/components/layout/GlobalLayout/ui/BottomNavigation/index.tsx b/src/components/layout/GlobalLayout/ui/BottomNavigation/index.tsx new file mode 100644 index 00000000..69aa354e --- /dev/null +++ b/src/components/layout/GlobalLayout/ui/BottomNavigation/index.tsx @@ -0,0 +1,61 @@ +"use client"; + +import Link from "next/link"; +import { usePathname } from "next/navigation"; + +import { NAV_ITEMS } from "./constant/NAV_ITEMS"; +import isRouteActive from "./lib/isRouteActive"; +import DegreeHat from "./ui/DegreeHat"; +import EditTwo from "./ui/EditTwo"; +import Home from "./ui/Home"; +import Human from "./ui/Human"; +import WhatsNew from "./ui/WhatsNew"; + +const ICON_COMPONENTS = { + university: DegreeHat, + community: EditTwo, + home: Home, + mentor: WhatsNew, + my: Human, +} as const; + +const BottomNavigation = () => { + const pathname = usePathname(); + + if (!NAV_ITEMS.some((item) => isRouteActive(pathname, item.route))) { + return null; + } + + return ( + + ); +}; + +export default BottomNavigation; diff --git a/src/components/layout/GlobalLayout/ui/BottomNavigation/lib/isRouteActive.ts b/src/components/layout/GlobalLayout/ui/BottomNavigation/lib/isRouteActive.ts new file mode 100644 index 00000000..9f7c69c9 --- /dev/null +++ b/src/components/layout/GlobalLayout/ui/BottomNavigation/lib/isRouteActive.ts @@ -0,0 +1,5 @@ +const isRouteActive = (pathname: string | null, route: string): boolean => { + const isActive = pathname === route || pathname?.startsWith(route + "/"); + return isActive ? true : false; +}; +export default isRouteActive; diff --git a/src/components/layout/icon/DegreeHat.tsx b/src/components/layout/GlobalLayout/ui/BottomNavigation/ui/DegreeHat.tsx similarity index 100% rename from src/components/layout/icon/DegreeHat.tsx rename to src/components/layout/GlobalLayout/ui/BottomNavigation/ui/DegreeHat.tsx diff --git a/src/components/layout/icon/EditTwo.tsx b/src/components/layout/GlobalLayout/ui/BottomNavigation/ui/EditTwo.tsx similarity index 100% rename from src/components/layout/icon/EditTwo.tsx rename to src/components/layout/GlobalLayout/ui/BottomNavigation/ui/EditTwo.tsx diff --git a/src/components/layout/icon/Home.tsx b/src/components/layout/GlobalLayout/ui/BottomNavigation/ui/Home.tsx similarity index 100% rename from src/components/layout/icon/Home.tsx rename to src/components/layout/GlobalLayout/ui/BottomNavigation/ui/Home.tsx diff --git a/src/components/layout/icon/Human.tsx b/src/components/layout/GlobalLayout/ui/BottomNavigation/ui/Human.tsx similarity index 100% rename from src/components/layout/icon/Human.tsx rename to src/components/layout/GlobalLayout/ui/BottomNavigation/ui/Human.tsx diff --git a/src/components/layout/icon/WhatsNew.tsx b/src/components/layout/GlobalLayout/ui/BottomNavigation/ui/WhatsNew.tsx similarity index 100% rename from src/components/layout/icon/WhatsNew.tsx rename to src/components/layout/GlobalLayout/ui/BottomNavigation/ui/WhatsNew.tsx diff --git a/src/components/layout/icon/World.tsx b/src/components/layout/GlobalLayout/ui/BottomNavigation/ui/World.tsx similarity index 100% rename from src/components/layout/icon/World.tsx rename to src/components/layout/GlobalLayout/ui/BottomNavigation/ui/World.tsx diff --git a/src/components/layout/GlobalLayout/ui/RootModal/index.tsx b/src/components/layout/GlobalLayout/ui/RootModal/index.tsx new file mode 100644 index 00000000..263b12c0 --- /dev/null +++ b/src/components/layout/GlobalLayout/ui/RootModal/index.tsx @@ -0,0 +1,13 @@ +import ClientModal from "./ui/ClientModal"; +import ServerModal from "./ui/ServerModal"; + +const RootModal = () => { + return ( + <> + + + + ); +}; + +export default RootModal; diff --git a/src/components/layout/GlobalLayout/ui/RootModal/ui/ClientModal/index.tsx b/src/components/layout/GlobalLayout/ui/RootModal/ui/ClientModal/index.tsx new file mode 100644 index 00000000..8f9a4594 --- /dev/null +++ b/src/components/layout/GlobalLayout/ui/RootModal/ui/ClientModal/index.tsx @@ -0,0 +1,25 @@ +"use client"; + +import IconConfirmModal from "@/components/modal/IconConfirmModal"; + +import { useConfirmModalStore } from "@/lib/zustand/useConfirmModalStore"; + +const ClientModal = () => { + const { isOpen, payload, confirm, reject } = useConfirmModalStore(); + + return ( + <> + + + ); +}; +export default ClientModal; diff --git a/src/components/layout/GlobalLayout/ui/RootModal/ui/ServerModal/index.tsx b/src/components/layout/GlobalLayout/ui/RootModal/ui/ServerModal/index.tsx new file mode 100644 index 00000000..e240a2bc --- /dev/null +++ b/src/components/layout/GlobalLayout/ui/RootModal/ui/ServerModal/index.tsx @@ -0,0 +1,14 @@ +import { cookies } from "next/headers"; + +import { isTokenExpired } from "@/utils/jwtUtils"; + +import MentorApplyCountModal from "@/components/mentor/MentorApplyCountModal"; + +const ServerModal = () => { + // 서버에서 로그인 상태 확인 + const cookieStore = cookies(); + const refreshToken = cookieStore.get("refreshToken")?.value; + const isNeededLogin = !refreshToken || isTokenExpired(refreshToken); + return <>{isNeededLogin ? null : }; +}; +export default ServerModal; diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx deleted file mode 100644 index 8c1ed990..00000000 --- a/src/components/layout/Layout.tsx +++ /dev/null @@ -1,23 +0,0 @@ -"use client"; - -import React from "react"; - -import BottomNavigation from "./BottomNavigation"; - -import { useLayout } from "@/context/LayoutContext"; - -type LayoutProps = { - children: React.ReactNode; -}; - -const Layout = ({ children }: LayoutProps) => { - const { hideBottomNavigation } = useLayout(); - return ( -
- {children} - {!hideBottomNavigation && } -
- ); -}; - -export default Layout; diff --git a/src/components/layout/TopNavigation.tsx b/src/components/layout/TopNavigation.tsx deleted file mode 100644 index 15246d6d..00000000 --- a/src/components/layout/TopNavigation.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { IconCloud } from "@/public/svgs/home"; - -const TopNavigation = () => ( -
-
- - Solid Connection -
-
-); - -export default TopNavigation; diff --git a/src/components/loading/NotFound.tsx b/src/components/loading/NotFound.tsx deleted file mode 100644 index 072c26cb..00000000 --- a/src/components/loading/NotFound.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { IconNotFound } from "@/public/svgs/loading"; - -type NotFoundProps = { - text?: string; -}; - -const NotFound = ({ text = "" }: NotFoundProps) => { - return ( -
- -
- {text} -
-
- ); -}; - -export default NotFound; diff --git a/src/components/login/signup/SignupProfileScreen.tsx b/src/components/login/signup/SignupProfileScreen.tsx index fee30414..c6dd1fc1 100644 --- a/src/components/login/signup/SignupProfileScreen.tsx +++ b/src/components/login/signup/SignupProfileScreen.tsx @@ -3,7 +3,7 @@ import { Dispatch, SetStateAction, useRef, useState } from "react"; import BlockBtn from "@/components/button/BlockBtn"; -import { Input } from "@/components/ui/Input"; +import { Input } from "@/components/ui/Inputa"; import { IconSignupProfileImage } from "@/public/svgs/auth"; diff --git a/src/components/mentor/MentorApplyCountModal/ui/MentorApplyCountContent/index.tsx b/src/components/mentor/MentorApplyCountModal/ui/MentorApplyCountContent/index.tsx index 17b9f6b5..004fbaf3 100644 --- a/src/components/mentor/MentorApplyCountModal/ui/MentorApplyCountContent/index.tsx +++ b/src/components/mentor/MentorApplyCountModal/ui/MentorApplyCountContent/index.tsx @@ -2,7 +2,11 @@ import { useState } from "react"; -const MentorApplyCountContent = ({ count }) => { +interface MentorApplyCountContentProps { + count: number; // 신규 신청 수 +} + +const MentorApplyCountContent = ({ count }: MentorApplyCountContentProps) => { const [isModalOpen, setIsModalOpen] = useState(true); if (count === 0) return null; // 신규 신청 없으면 표시 X if (!isModalOpen) return null; // 모달이 열려있지 않으면 표시 X diff --git a/src/components/mentor/MentorCard.tsx b/src/components/mentor/MentorCard.tsx new file mode 100644 index 00000000..5d1d7089 --- /dev/null +++ b/src/components/mentor/MentorCard.tsx @@ -0,0 +1,125 @@ +"use client"; + +import React, { useState } from "react"; + +import { Link } from "lucide-react"; + +import IconConfirmCancelModal from "../modal/IconConfirmModal"; +import ChannelBadge from "../ui/ChannelBadge"; +import ProfileWithBadge from "../ui/ProfileWithBadge"; +import StudyDate from "./StudyDate"; + +import { ChannelType, MentorCardDetail, MentorCardPreview } from "@/api/mentor/type/response"; +import { IconCheck, IconDirectionDown, IconDirectionUp, IconTime } from "@/public/svgs/mentor"; + +interface MentorCardProps { + mentor: MentorCardDetail | MentorCardPreview; + observeRef?: React.RefCallback; + isMine?: boolean; // isMine prop 추가 + isDistribute?: boolean; // isDistribute prop 추가 +} + +const MentorCard = ({ mentor, observeRef, isMine = false, isDistribute = false }: MentorCardProps) => { + const [isExpanded, setIsExpanded] = useState(false); + + if (!mentor) return null; // mentor가 없으면 아무것도 렌더링하지 않음 + // 구조분해 할당 + const { profileImageUrl, hasBadge, menteeCount, country, nickname, universityName, introduction, channels } = mentor; + + // 타입 가드: 상세 타입인지 확인 + const isDetail = "studyStatus" in mentor; + + return ( +
+ {/* 멘토 프로필 헤더 */} +
+
+ + 누적 멘티 {menteeCount}명 +
+ +
+
+ {country} + {isDetail && } +
+

{nickname}님

+
+

{universityName}

+
+
+
+ + {/* 확장된 내용 */} + {isExpanded && ( + <> + {/* 멘토 한마디 */} +
+

멘토 한마디

+

{introduction}

+
+ + {/* 멘토 채널 */} +
+

멘토 채널

+
+ {channels.map((channel, idx) => ( +
+ +
+ ))} +
+
+ + {/* 액션 버튼 */} +
+ {isMine ? ( + + 수정하기 + + ) : ( + <> + + + )} +
+ + )} + + {/* 접기/펼치기 버튼 */} +
+ +
+
+ ); +}; + +export default MentorCard; diff --git a/src/components/mentor/MentorCard/index.tsx b/src/components/mentor/MentorCard/index.tsx index e02ee7e4..f1cfcd88 100644 --- a/src/components/mentor/MentorCard/index.tsx +++ b/src/components/mentor/MentorCard/index.tsx @@ -5,7 +5,6 @@ import React, { useState } from "react"; import clsx from "clsx"; -import IconConfirmCancelModalWrapper from "@/components/modal/IconConfirmCancelModalWrapper"; import ChannelBadge from "@/components/ui/ChannelBadge"; import ProfileWithBadge from "@/components/ui/ProfileWithBadge"; @@ -109,7 +108,7 @@ const MentorCard = ({ mentor, isMine = false }: MentorCardProps) => {
{isMine ? ( 수정하기 @@ -122,7 +121,7 @@ const MentorCard = ({ mentor, isMine = false }: MentorCardProps) => { diff --git a/src/components/ui/button-tab.module.css b/src/components/ui/ButtonTab/button-tab.module.css similarity index 100% rename from src/components/ui/button-tab.module.css rename to src/components/ui/ButtonTab/button-tab.module.css diff --git a/src/components/ui/ButtonTab.tsx b/src/components/ui/ButtonTab/index.tsx similarity index 100% rename from src/components/ui/ButtonTab.tsx rename to src/components/ui/ButtonTab/index.tsx diff --git a/src/components/loading/CloudSpinner.tsx b/src/components/ui/CloudSpinner/index.tsx similarity index 100% rename from src/components/loading/CloudSpinner.tsx rename to src/components/ui/CloudSpinner/index.tsx diff --git a/src/components/loading/CloudSpinnerPage.tsx b/src/components/ui/CloudSpinnerPage/index.tsx similarity index 90% rename from src/components/loading/CloudSpinnerPage.tsx rename to src/components/ui/CloudSpinnerPage/index.tsx index cd57b869..f0806350 100644 --- a/src/components/loading/CloudSpinnerPage.tsx +++ b/src/components/ui/CloudSpinnerPage/index.tsx @@ -1,4 +1,4 @@ -import CloudSpinner from "./CloudSpinner"; +import CloudSpinner from "../CloudSpinner"; const CloudSpinnerPage = () => (
diff --git a/src/components/ui/dropdown.module.css b/src/components/ui/Dropdown/dropdown.module.css similarity index 100% rename from src/components/ui/dropdown.module.css rename to src/components/ui/Dropdown/dropdown.module.css diff --git a/src/components/ui/Dropdown.tsx b/src/components/ui/Dropdown/index.tsx similarity index 100% rename from src/components/ui/Dropdown.tsx rename to src/components/ui/Dropdown/index.tsx diff --git a/src/components/ui/Input.tsx b/src/components/ui/Inputa.tsx similarity index 100% rename from src/components/ui/Input.tsx rename to src/components/ui/Inputa.tsx diff --git a/src/components/ui/Tab.tsx b/src/components/ui/Tab/index.tsx similarity index 100% rename from src/components/ui/Tab.tsx rename to src/components/ui/Tab/index.tsx diff --git a/src/components/ui/tab.module.css b/src/components/ui/Tab/tab.module.css similarity index 100% rename from src/components/ui/tab.module.css rename to src/components/ui/Tab/tab.module.css diff --git a/src/components/ui/TopLogoBar/index.tsx b/src/components/ui/TopLogoBar/index.tsx new file mode 100644 index 00000000..ef5e2e89 --- /dev/null +++ b/src/components/ui/TopLogoBar/index.tsx @@ -0,0 +1,19 @@ +import clsx from "clsx"; + +import { IconCloud } from "@/public/svgs/home"; + +const TopLogoBar = () => ( +
+
+ + Solid Connection +
+
+); + +export default TopLogoBar; diff --git a/src/components/ui/dropdown.tsx b/src/components/ui/dropdown.tsx deleted file mode 100644 index 45529732..00000000 --- a/src/components/ui/dropdown.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import styles from "./dropdown.module.css"; - -// DropdownItem 타입 정의 -interface DropdownItem { - label: string; - action: () => void; -} - -// Dropdown 컴포넌트의 props 타입 정의 -interface DropdownProps { - options: DropdownItem[]; -} - -const Dropdown = ({ options }: DropdownProps) => ( -
- {options.map((option) => ( - - ))} -
-); - -export default Dropdown; diff --git a/src/components/ui/tab.tsx b/src/components/ui/tab.tsx deleted file mode 100644 index 1e73acbd..00000000 --- a/src/components/ui/tab.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import styles from "./tab.module.css"; - -type TabProps = { - choices: string[]; - choice: string; - setChoice: React.Dispatch>; - color?: { - activeBtn?: string; - deactiveBtn?: string; - activeBtnFont?: string; - deactiveBtnFont?: string; - }; -}; - -const Tab = ({ choices, choice, setChoice, color }: TabProps) => { - const defaultColor = { - activeBtnFont: "#000", - deactiveBtnFont: "#7D7D7D", - }; - const combinedColor = { ...defaultColor, ...color }; - return ( -
- {choices.map((c) => ( - - ))} -
- ); -}; - -export default Tab; diff --git a/src/constants/commnunity.ts b/src/constants/commnunity.ts deleted file mode 100644 index 7ddc56bd..00000000 --- a/src/constants/commnunity.ts +++ /dev/null @@ -1,19 +0,0 @@ -export enum CommunityBoard { - FREE = "FREE", - EUROPE = "EUROPE", - AMERICAS = "AMERICAS", - ASIA = "ASIA", -} - -export const COMMUNITY_BOARD_NAMES = { - [CommunityBoard.FREE]: "자유", - [CommunityBoard.EUROPE]: "유럽권", - [CommunityBoard.AMERICAS]: "미주권", - [CommunityBoard.ASIA]: "아시아권", -}; - -export enum CommunityCategory { - ALL = "전체", - FREE = "자유", - QUESTION = "질문", -} diff --git a/src/constants/community.ts b/src/constants/community.ts new file mode 100644 index 00000000..60824f66 --- /dev/null +++ b/src/constants/community.ts @@ -0,0 +1,8 @@ +export const COMMUNITY_BOARDS = [ + { code: "FREE", nameKo: "자유" }, + { code: "EUROPE", nameKo: "유럽권" }, + { code: "AMERICAS", nameKo: "미주권" }, + { code: "ASIA", nameKo: "아시아권" }, +]; + +export const COMMUNITY_CATEGORIES = ["전체", "자유", "질문"]; diff --git a/src/constants/university.ts b/src/constants/university.ts index f7f13606..1bae29f4 100644 --- a/src/constants/university.ts +++ b/src/constants/university.ts @@ -1,46 +1,43 @@ -export enum RegionKo { - EUROPE = "유럽권", - AMERICAS = "미주권", - ASIA = "아시아권", - CHINA = "중국권", -} +export const REGIONS_KO = ["유럽권", "미주권", "아시아권", "중국권"]; -export enum CountryKo { +export const COUNTRIES_KO = [ + // 2024-2 기준 // 아시아권 - MALAYSIA = "말레이시아", - BRUNEI = "브루나이", - SINGAPORE = "싱가포르", - AZERBAIJAN = "아제르바이잔", - INDONESIA = "인도네시아", - JAPAN = "일본", - KYRGYZSTAN = "키르기스스탄", - TURKEY = "튀르키예", - HONG_KONG = "홍콩", - KAZAKHSTAN = "카자흐스탄", - ISRAEL = "이스라엘", + "말레이시아", + "브루나이", + "싱가포르", + "아제르바이잔", + "인도네시아", + "일본", + "키르기스스탄", + "튀르키예", + "홍콩", + "카자흐스탄", + "이스라엘", + "말레이시아", // 미주권 - USA = "미국", - CANADA = "캐나다", - AUSTRALIA = "호주", - BRAZIL = "브라질", + "미국", + "캐나다", + "호주", + "브라질", // 유럽권 - NETHERLANDS = "네덜란드", - NORWAY = "노르웨이", - DENMARK = "덴마크", - GERMANY = "독일", - LITHUANIA = "리투아니아", - LIECHTENSTEIN = "리히텐슈타인", - SWEDEN = "스웨덴", - SWITZERLAND = "스위스", - SPAIN = "스페인", - AUSTRIA = "오스트리아", - CZECH = "체코", - PORTUGAL = "포르투갈", - POLAND = "폴란드", - FRANCE = "프랑스", - FINLAND = "핀란드", - RUSSIA = "러시아", + "네덜란드", + "노르웨이", + "덴마크", + "독일", + "리투아니아", + "리히텐슈타인", + "스웨덴", + "스위스", + "스페인", + "오스트리아", + "체코", + "포르투갈", + "폴란드", + "프랑스", + "핀란드", + "러시아", // 중국권 - CHINA = "중국", - TAIWAN = "대만", -} + "중국", + "대만", +]; diff --git a/src/context/LayoutContext.tsx b/src/context/LayoutContext.tsx deleted file mode 100644 index 0ac86746..00000000 --- a/src/context/LayoutContext.tsx +++ /dev/null @@ -1,30 +0,0 @@ -"use client"; - -import { createContext, useContext, useMemo, useState } from "react"; - -type LayoutContextType = { - hideBottomNavigation: boolean; - setHideBottomNavigation: React.Dispatch>; -}; - -const LayoutContext = createContext(undefined); - -export const useLayout = () => { - const context = useContext(LayoutContext); - if (!context) { - throw new Error("useLayout must be used within a LayoutProvider"); - } - return context; -}; - -type LayoutProviderProps = { - children: React.ReactNode; -}; - -export const LayoutProvider = ({ children }: LayoutProviderProps) => { - const [hideBottomNavigation, setHideBottomNavigation] = useState(false); - - const contextValue = useMemo(() => ({ hideBottomNavigation, setHideBottomNavigation }), [hideBottomNavigation]); - - return {children}; -}; diff --git a/src/components/layout/AppleScriptLoader.tsx b/src/lib/ScriptLoader/AppleScriptLoader.tsx similarity index 100% rename from src/components/layout/AppleScriptLoader.tsx rename to src/lib/ScriptLoader/AppleScriptLoader.tsx diff --git a/src/components/layout/KakaoScriptLoader.tsx b/src/lib/ScriptLoader/KakaoScriptLoader.tsx similarity index 100% rename from src/components/layout/KakaoScriptLoader.tsx rename to src/lib/ScriptLoader/KakaoScriptLoader.tsx