diff --git a/apps/web/package.json b/apps/web/package.json index 878c3f21..0b11426a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -51,8 +51,8 @@ "@next/bundle-analyzer": "^16.1.6", "@svgr/webpack": "^8.1.0", "@types/node": "^20.11.19", - "@types/react": "18.3.27", - "@types/react-dom": "18.3.7", + "@types/react": "19.2.10", + "@types/react-dom": "19.2.3", "autoprefixer": "^10.4.20", "critters": "^0.0.23", "postcss": "^8.4.45", diff --git a/apps/web/src/apis/Auth/postAppleAuth.ts b/apps/web/src/apis/Auth/postAppleAuth.ts index 900d27d5..93249feb 100644 --- a/apps/web/src/apis/Auth/postAppleAuth.ts +++ b/apps/web/src/apis/Auth/postAppleAuth.ts @@ -11,36 +11,36 @@ import { type AppleAuthRequest, type AppleAuthResponse, authApi } from "./api"; * @description 애플 로그인을 위한 useMutation 커스텀 훅 */ const usePostAppleAuth = () => { - const router = useRouter(); - const searchParams = useSearchParams(); + const router = useRouter(); + const searchParams = useSearchParams(); - return useMutation({ - mutationFn: (data) => authApi.postAppleAuth(data), - onSuccess: (data) => { - if (data.isRegistered) { - // 기존 회원일 시 - Zustand persist가 자동으로 localStorage에 저장 - // refreshToken은 서버에서 HTTP-only 쿠키로 자동 설정됨 - useAuthStore.getState().setAccessToken(data.accessToken); + return useMutation({ + mutationFn: (data) => authApi.postAppleAuth(data), + onSuccess: (data) => { + if (data.isRegistered) { + // 기존 회원일 시 - Zustand persist가 자동으로 localStorage에 저장 + // refreshToken은 서버에서 HTTP-only 쿠키로 자동 설정됨 + useAuthStore.getState().setAccessToken(data.accessToken); - // 안전한 리다이렉트 처리 - 오픈 리다이렉트 방지 - const redirectParam = searchParams.get("redirect"); - const safeRedirect = validateSafeRedirect(redirectParam); + // 안전한 리다이렉트 처리 - 오픈 리다이렉트 방지 + const redirectParam = searchParams.get("redirect"); + const safeRedirect = validateSafeRedirect(redirectParam); - toast.success("로그인에 성공했습니다."); + toast.success("로그인에 성공했습니다."); - setTimeout(() => { - router.push(safeRedirect); - }, 100); - } else { - // 새로운 회원일 시 - 회원가입 페이지로 이동 - router.push(`/sign-up?token=${data.signUpToken}`); - } - }, - onError: () => { - toast.error("애플 로그인 중 오류가 발생했습니다. 다시 시도해주세요."); - router.push("/login"); - }, - }); + setTimeout(() => { + router.push(safeRedirect); + }, 100); + } else { + // 새로운 회원일 시 - 회원가입 페이지로 이동 + router.push(`/sign-up?token=${data.signUpToken}`); + } + }, + onError: () => { + toast.error("애플 로그인 중 오류가 발생했습니다. 다시 시도해주세요."); + router.push("/login"); + }, + }); }; export default usePostAppleAuth; diff --git a/apps/web/src/apis/Auth/postKakaoAuth.ts b/apps/web/src/apis/Auth/postKakaoAuth.ts index 40894959..8f641666 100644 --- a/apps/web/src/apis/Auth/postKakaoAuth.ts +++ b/apps/web/src/apis/Auth/postKakaoAuth.ts @@ -11,37 +11,37 @@ import { authApi, type KakaoAuthRequest, type KakaoAuthResponse } from "./api"; * @description 카카오 로그인을 위한 useMutation 커스텀 훅 */ const usePostKakaoAuth = () => { - const { setAccessToken } = useAuthStore(); - const router = useRouter(); - const searchParams = useSearchParams(); + const { setAccessToken } = useAuthStore(); + const router = useRouter(); + const searchParams = useSearchParams(); - return useMutation({ - mutationFn: (data) => authApi.postKakaoAuth(data), - onSuccess: (data) => { - if (data.isRegistered) { - // 기존 회원일 시 - Zustand persist가 자동으로 localStorage에 저장 - // refreshToken은 서버에서 HTTP-only 쿠키로 자동 설정됨 - setAccessToken(data.accessToken); + return useMutation({ + mutationFn: (data) => authApi.postKakaoAuth(data), + onSuccess: (data) => { + if (data.isRegistered) { + // 기존 회원일 시 - Zustand persist가 자동으로 localStorage에 저장 + // refreshToken은 서버에서 HTTP-only 쿠키로 자동 설정됨 + setAccessToken(data.accessToken); - // 안전한 리다이렉트 처리 - 오픈 리다이렉트 방지 - const redirectParam = searchParams.get("redirect"); - const safeRedirect = validateSafeRedirect(redirectParam); + // 안전한 리다이렉트 처리 - 오픈 리다이렉트 방지 + const redirectParam = searchParams.get("redirect"); + const safeRedirect = validateSafeRedirect(redirectParam); - toast.success("로그인에 성공했습니다."); + toast.success("로그인에 성공했습니다."); - setTimeout(() => { - router.push(safeRedirect); - }, 100); - } else { - // 새로운 회원일 시 - 회원가입 페이지로 이동 - router.push(`/sign-up?token=${data.signUpToken}`); - } - }, - onError: () => { - toast.error("카카오 로그인 중 오류가 발생했습니다. 다시 시도해주세요."); - router.push("/login"); - }, - }); + setTimeout(() => { + router.push(safeRedirect); + }, 100); + } else { + // 새로운 회원일 시 - 회원가입 페이지로 이동 + router.push(`/sign-up?token=${data.signUpToken}`); + } + }, + onError: () => { + toast.error("카카오 로그인 중 오류가 발생했습니다. 다시 시도해주세요."); + router.push("/login"); + }, + }); }; export default usePostKakaoAuth; diff --git a/apps/web/src/apis/universities/server/getRecommendedUniversity.ts b/apps/web/src/apis/universities/server/getRecommendedUniversity.ts index 3950cfe5..b3f7ae70 100644 --- a/apps/web/src/apis/universities/server/getRecommendedUniversity.ts +++ b/apps/web/src/apis/universities/server/getRecommendedUniversity.ts @@ -4,15 +4,15 @@ import serverFetch from "@/utils/serverFetchUtil"; type GetRecommendedUniversityResponse = { recommendedUniversities: ListUniversity[] }; const getRecommendedUniversity = async () => { - const endpoint = "/univ-apply-infos/recommend"; + const endpoint = "/univ-apply-infos/recommend"; - const res = await serverFetch(endpoint); + const res = await serverFetch(endpoint); - if (!res.ok) { - console.error(`Failed to fetch recommended universities:`, res.error); - } + if (!res.ok) { + console.error(`Failed to fetch recommended universities:`, res.error); + } - return res; + return res; }; export default getRecommendedUniversity; diff --git a/apps/web/src/apis/universities/server/getSearchUniversitiesByFilter.ts b/apps/web/src/apis/universities/server/getSearchUniversitiesByFilter.ts index 2b6ba386..3fdd37c4 100644 --- a/apps/web/src/apis/universities/server/getSearchUniversitiesByFilter.ts +++ b/apps/web/src/apis/universities/server/getSearchUniversitiesByFilter.ts @@ -3,60 +3,58 @@ import type { CountryCode, LanguageTestType, ListUniversity } from "@/types/univ import serverFetch from "@/utils/serverFetchUtil"; interface UniversitySearchResponse { - univApplyInfoPreviews: ListUniversity[]; + univApplyInfoPreviews: ListUniversity[]; } /** * 필터 검색에 사용될 파라미터 타입 */ export interface UniversitySearchFilterParams { - languageTestType?: LanguageTestType; - testScore?: number; - countryCode?: CountryCode[]; + languageTestType?: LanguageTestType; + testScore?: number; + countryCode?: CountryCode[]; } export const getSearchUniversitiesByFilter = async ( - filters: UniversitySearchFilterParams, + filters: UniversitySearchFilterParams, ): Promise => { - const params = new URLSearchParams(); - - if (filters.languageTestType) { - params.append("languageTestType", filters.languageTestType); - } - if (filters.testScore !== undefined) { - params.append("testScore", String(filters.testScore)); - } - // countryCode는 여러 개일 수 있으므로 각각 append 해줍니다. - if (filters.countryCode) { - filters.countryCode.forEach((code) => params.append("countryCode", code)); - } - - // 필터 값이 하나도 없으면 빈 배열을 반환합니다. - if (params.size === 0) { - return []; - } - - const endpoint = `/univ-apply-infos/search/filter?${params.toString()}`; - const response = await serverFetch(endpoint); - - if (!response.ok) { - console.error(`Failed to search universities by filter:`, response.error); - return []; - } - - return response.data.univApplyInfoPreviews; + const params = new URLSearchParams(); + + if (filters.languageTestType) { + params.append("languageTestType", filters.languageTestType); + } + if (filters.testScore !== undefined) { + params.append("testScore", String(filters.testScore)); + } + // countryCode는 여러 개일 수 있으므로 각각 append 해줍니다. + if (filters.countryCode) { + filters.countryCode.forEach((code) => params.append("countryCode", code)); + } + + // 필터 값이 하나도 없으면 빈 배열을 반환합니다. + if (params.size === 0) { + return []; + } + + const endpoint = `/univ-apply-infos/search/filter?${params.toString()}`; + const response = await serverFetch(endpoint); + + if (!response.ok) { + console.error(`Failed to search universities by filter:`, response.error); + return []; + } + + return response.data.univApplyInfoPreviews; }; -export const getSearchUniversitiesAllRegions = async (): Promise< - ListUniversity[] -> => { - const endpoint = `/univ-apply-infos/search/filter`; - const response = await serverFetch(endpoint); +export const getSearchUniversitiesAllRegions = async (): Promise => { + const endpoint = `/univ-apply-infos/search/filter`; + const response = await serverFetch(endpoint); - if (!response.ok) { - console.error(`Failed to fetch all regions universities:`, response.error); - return []; - } + if (!response.ok) { + console.error(`Failed to fetch all regions universities:`, response.error); + return []; + } - return response.data.univApplyInfoPreviews; + return response.data.univApplyInfoPreviews; }; diff --git a/apps/web/src/apis/universities/server/getSearchUniversitiesByText.ts b/apps/web/src/apis/universities/server/getSearchUniversitiesByText.ts index 92f4b362..dd20d096 100644 --- a/apps/web/src/apis/universities/server/getSearchUniversitiesByText.ts +++ b/apps/web/src/apis/universities/server/getSearchUniversitiesByText.ts @@ -3,54 +3,48 @@ import serverFetch from "@/utils/serverFetchUtil"; // --- 타입 정의 --- interface UniversitySearchResponse { - univApplyInfoPreviews: ListUniversity[]; + univApplyInfoPreviews: ListUniversity[]; } -export const getUniversitiesByText = async ( - value: string, -): Promise => { - if (value === null || value === undefined) { - return []; - } - const endpoint = `/univ-apply-infos/search/text?value=${encodeURIComponent(value)}`; - const response = await serverFetch(endpoint); - - if (!response.ok) { - console.error( - `Failed to search universities by text (value: "${value}"):`, - response.error, - ); - return []; - } - - return response.data.univApplyInfoPreviews; +export const getUniversitiesByText = async (value: string): Promise => { + if (value === null || value === undefined) { + return []; + } + const endpoint = `/univ-apply-infos/search/text?value=${encodeURIComponent(value)}`; + const response = await serverFetch(endpoint); + + if (!response.ok) { + console.error(`Failed to search universities by text (value: "${value}"):`, response.error); + return []; + } + + return response.data.univApplyInfoPreviews; }; export const getAllUniversities = async (): Promise => { - return getUniversitiesByText(""); + return getUniversitiesByText(""); }; -export const getCategorizedUniversities = - async (): Promise => { - // 1. 단 한 번의 API 호출로 모든 대학 데이터를 가져옵니다. - const allUniversities = await getAllUniversities(); - - const categorizedList: AllRegionsUniversityList = { - [RegionEnumExtend.ALL]: allUniversities, - [RegionEnumExtend.AMERICAS]: [], - [RegionEnumExtend.EUROPE]: [], - [RegionEnumExtend.ASIA]: [], - [RegionEnumExtend.CHINA]: [], - }; - if (!allUniversities) return categorizedList; - - for (const university of allUniversities) { - const region = university.region as RegionEnumExtend; // API 응답의 region 타입을 enum으로 간주 - - if (region && Object.hasOwn(categorizedList, region)) { - categorizedList[region].push(university); - } - } - - return categorizedList; - }; +export const getCategorizedUniversities = async (): Promise => { + // 1. 단 한 번의 API 호출로 모든 대학 데이터를 가져옵니다. + const allUniversities = await getAllUniversities(); + + const categorizedList: AllRegionsUniversityList = { + [RegionEnumExtend.ALL]: allUniversities, + [RegionEnumExtend.AMERICAS]: [], + [RegionEnumExtend.EUROPE]: [], + [RegionEnumExtend.ASIA]: [], + [RegionEnumExtend.CHINA]: [], + }; + if (!allUniversities) return categorizedList; + + for (const university of allUniversities) { + const region = university.region as RegionEnumExtend; // API 응답의 region 타입을 enum으로 간주 + + if (region && Object.hasOwn(categorizedList, region)) { + categorizedList[region].push(university); + } + } + + return categorizedList; +}; diff --git a/apps/web/src/app/(home)/_ui/NewsSection/_hooks/useSectionHadnler.ts b/apps/web/src/app/(home)/_ui/NewsSection/_hooks/useSectionHadnler.ts index 947cbc65..57d935d2 100644 --- a/apps/web/src/app/(home)/_ui/NewsSection/_hooks/useSectionHadnler.ts +++ b/apps/web/src/app/(home)/_ui/NewsSection/_hooks/useSectionHadnler.ts @@ -1,7 +1,7 @@ import { type RefObject, useEffect, useRef, useState } from "react"; interface UseSectionHandlerReturn { - sectionRef: RefObject; + sectionRef: RefObject; visible: boolean; } diff --git a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/_hooks/useSelectedTab.ts b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/_hooks/useSelectedTab.ts index 8f1295d8..4c65cd6f 100644 --- a/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/_hooks/useSelectedTab.ts +++ b/apps/web/src/app/mentor/_ui/MentorClient/_ui/MentorFindSection/_hooks/useSelectedTab.ts @@ -3,7 +3,7 @@ import { type RefObject, useRef, useState } from "react"; import { FilterTab } from "@/types/mentor"; interface UseSelectedTabReturn { - listRef: RefObject; + listRef: RefObject; selectedTab: FilterTab; handleSelectTab: (tab: FilterTab) => void; } diff --git a/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatNavBar/index.tsx b/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatNavBar/index.tsx index 31a08b58..36e8d107 100644 --- a/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatNavBar/index.tsx +++ b/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatNavBar/index.tsx @@ -20,7 +20,8 @@ interface ChatNavBarProps { const ChatNavBar = ({ chatId }: ChatNavBarProps) => { const [isExpanded, setIsExpanded] = useState(false); const [isAnimating, setIsAnimating] = useState(false); - const result = tokenParse(useAuthStore.getState().accessToken); + const accessToken = useAuthStore((state) => state.accessToken); + const result = tokenParse(accessToken); const isMentor = result?.role === UserRole.MENTOR || result?.role === UserRole.ADMIN; // 파트너 정보 가져오기 diff --git a/apps/web/src/app/my/modify/_ui/ModifyContent/_ui/ImageInputFiled/_hooks/useImageInputHandler.ts b/apps/web/src/app/my/modify/_ui/ModifyContent/_ui/ImageInputFiled/_hooks/useImageInputHandler.ts index f01c2cfd..25fd7b21 100644 --- a/apps/web/src/app/my/modify/_ui/ModifyContent/_ui/ImageInputFiled/_hooks/useImageInputHandler.ts +++ b/apps/web/src/app/my/modify/_ui/ModifyContent/_ui/ImageInputFiled/_hooks/useImageInputHandler.ts @@ -6,7 +6,7 @@ import { convertUploadedImageUrl } from "@/utils/fileUtils"; interface ImageInputHandlerReturn { selectedImage: File | undefined; imagePreviewUrl: string | null; - fileInputRef: RefObject; + fileInputRef: RefObject; handleImageSelect: () => void; handleFileChange: (event: ChangeEvent) => void; } diff --git a/apps/web/src/app/my/modify/_ui/ModifyContent/index.tsx b/apps/web/src/app/my/modify/_ui/ModifyContent/index.tsx index 197ca9d7..a6811124 100644 --- a/apps/web/src/app/my/modify/_ui/ModifyContent/index.tsx +++ b/apps/web/src/app/my/modify/_ui/ModifyContent/index.tsx @@ -11,85 +11,64 @@ import InputField from "./_ui/InputFiled"; import ReadOnlyField from "./_ui/ReadOnlyField"; const ModifyContent = () => { - const { methods, myInfo, onSubmit } = useModifyUserHookform(); + const { methods, myInfo, onSubmit } = useModifyUserHookform(); - const defaultUniversity: string = - (myInfo?.role === UserRole.MENTOR || myInfo?.role === UserRole.ADMIN) && - myInfo.attendedUniversity - ? myInfo.attendedUniversity - : "인하대학교"; + const defaultUniversity: string = + (myInfo?.role === UserRole.MENTOR || myInfo?.role === UserRole.ADMIN) && myInfo.attendedUniversity + ? myInfo.attendedUniversity + : "인하대학교"; - const { - handleSubmit, - formState: { isValid, isDirty }, - } = methods; + const { + handleSubmit, + formState: { isValid, isDirty }, + } = methods; - if (!myInfo) { - return ; - } - return ( - -
-
- {/* Profile Image Section */} - + if (!myInfo) { + return ; + } + return ( + +
+ + {/* Profile Image Section */} + - {/* Form Fields */} -
- {/* 닉네임 - 수정 가능 */} - + {/* Form Fields */} +
+ {/* 닉네임 - 수정 가능 */} + - {/* 출신학교 - 읽기 전용 */} - + {/* 출신학교 - 읽기 전용 */} + - {/* 수학 학교 - 읽기 전용 */} - + {/* 수학 학교 - 읽기 전용 */} + - {/* 사용자 유형 - 읽기 전용 */} - -
+ {/* 사용자 유형 - 읽기 전용 */} + +
- {/* Submit Button */} -
- -
- -
-
- ); + {/* Submit Button */} +
+ +
+ +
+
+ ); }; export default ModifyContent; diff --git a/apps/web/src/app/university/(home)/_ui/HomeUniversityCard.tsx b/apps/web/src/app/university/(home)/_ui/HomeUniversityCard.tsx index 5c37567d..e646b073 100644 --- a/apps/web/src/app/university/(home)/_ui/HomeUniversityCard.tsx +++ b/apps/web/src/app/university/(home)/_ui/HomeUniversityCard.tsx @@ -47,13 +47,7 @@ const HomeUniversityCard = ({ university }: HomeUniversityCardProps) => { xmlns="http://www.w3.org/2000/svg" className="text-k-400 group-hover:text-primary" > - + diff --git a/apps/web/src/app/university/[homeUniversity]/_ui/UniversityListContent.tsx b/apps/web/src/app/university/[homeUniversity]/_ui/UniversityListContent.tsx index bf5d8b6e..97df47b1 100644 --- a/apps/web/src/app/university/[homeUniversity]/_ui/UniversityListContent.tsx +++ b/apps/web/src/app/university/[homeUniversity]/_ui/UniversityListContent.tsx @@ -28,8 +28,7 @@ const UniversityListContent = ({ universities, homeUniversity, homeUniversitySlu if (searchText.trim()) { const searchLower = searchText.toLowerCase().trim(); result = result.filter( - (uni) => - uni.koreanName.toLowerCase().includes(searchLower) || uni.country.toLowerCase().includes(searchLower), + (uni) => uni.koreanName.toLowerCase().includes(searchLower) || uni.country.toLowerCase().includes(searchLower), ); } diff --git a/apps/web/src/app/university/[homeUniversity]/search/_ui/SearchPageContent.tsx b/apps/web/src/app/university/[homeUniversity]/search/_ui/SearchPageContent.tsx index afb4e40a..80050f0a 100644 --- a/apps/web/src/app/university/[homeUniversity]/search/_ui/SearchPageContent.tsx +++ b/apps/web/src/app/university/[homeUniversity]/search/_ui/SearchPageContent.tsx @@ -6,18 +6,16 @@ import { useRouter } from "next/navigation"; import { useMemo, useState } from "react"; import { Controller, type SubmitHandler, useForm } from "react-hook-form"; import { z } from "zod"; - -import { IconSearch } from "@/public/svgs/search"; +import CustomDropdown from "@/app/university/CustomDropdown"; import { COUNTRY_CODE_MAP, LANGUAGE_TEST_TYPE_MAP, REGION_TO_COUNTRIES_MAP, REGIONS_SEARCH, } from "@/constants/university"; +import { IconSearch } from "@/public/svgs/search"; import { CountryCode, LanguageTestType } from "@/types/university"; -import CustomDropdown from "@/app/university/CustomDropdown"; - // Zod 스키마 const searchSchema = z.object({ searchText: z.string().optional(), diff --git a/apps/web/src/app/university/[homeUniversity]/search/page.tsx b/apps/web/src/app/university/[homeUniversity]/search/page.tsx index f35476c1..960bc518 100644 --- a/apps/web/src/app/university/[homeUniversity]/search/page.tsx +++ b/apps/web/src/app/university/[homeUniversity]/search/page.tsx @@ -49,7 +49,10 @@ const SearchPage = async ({ params }: PageProps) => { return ( <> - +

오직 나를 위한

diff --git a/apps/web/src/app/university/application/ScoreSearchBar.tsx b/apps/web/src/app/university/application/ScoreSearchBar.tsx index 2f402fe0..f202fc71 100644 --- a/apps/web/src/app/university/application/ScoreSearchBar.tsx +++ b/apps/web/src/app/university/application/ScoreSearchBar.tsx @@ -3,7 +3,7 @@ import { IconSearchFilled } from "@/public/svgs"; type ScoreSearchBarProps = { onClick: () => void; - textRef: RefObject; + textRef: RefObject; searchHandler: (_e: React.FormEvent) => void; }; diff --git a/apps/web/src/app/university/list/[homeUniversityName]/page.tsx b/apps/web/src/app/university/list/[homeUniversityName]/page.tsx index b427c9f3..8126e5ea 100644 --- a/apps/web/src/app/university/list/[homeUniversityName]/page.tsx +++ b/apps/web/src/app/university/list/[homeUniversityName]/page.tsx @@ -41,7 +41,9 @@ export async function generateMetadata({ params }: PageProps): Promise const UniversityListPage = async ({ params }: PageProps) => { const { homeUniversityName } = await params; - const universityName = HOME_UNIVERSITY_SLUG_MAP[homeUniversityName as HomeUniversitySlug] as HomeUniversityName | undefined; + const universityName = HOME_UNIVERSITY_SLUG_MAP[homeUniversityName as HomeUniversitySlug] as + | HomeUniversityName + | undefined; if (!universityName) { notFound(); diff --git a/apps/web/src/components/login/signup/SignupSurvey.tsx b/apps/web/src/components/login/signup/SignupSurvey.tsx index fb59fab5..de393136 100644 --- a/apps/web/src/components/login/signup/SignupSurvey.tsx +++ b/apps/web/src/components/login/signup/SignupSurvey.tsx @@ -16,167 +16,157 @@ import SignupProfileScreen from "./SignupProfileScreen"; import SignupRegionScreen from "./SignupRegionScreen"; type SignupSurveyProps = { - baseNickname: string; - baseEmail: string; - baseProfileImageUrl: string; + baseNickname: string; + baseEmail: string; + baseProfileImageUrl: string; }; -const SignupSurvey = ({ - baseNickname, - baseEmail, - baseProfileImageUrl, -}: SignupSurveyProps) => { - const router = useRouter(); - const searchParams = useSearchParams(); - - const signUpToken = searchParams?.get("token"); - if (!signUpToken) { - router.push("/login"); - } - const { setAccessToken } = useAuthStore(); - const [curStage, setCurStage] = useState(1); - const [curProgress, setCurProgress] = useState(0); - - const [curPreparation, setCurPreparation] = - useState(null); - - const [region, setRegion] = useState( - null, - ); - const [countries, setCountries] = useState([]); - - const [nickname, setNickname] = useState(baseNickname); - const [profileImageFile, setProfileImageFile] = useState(null); - - const signUpMutation = usePostSignUp(); - const uploadImageMutation = useUploadProfileImagePublic(); - - useEffect(() => { - setCurProgress(((curStage - 1) / 3) * 100); - }, [curStage]); - - const createRegisterRequest = async (): Promise => { - const submitRegion: RegionKo[] = - region === "아직 잘 모르겠어요" ? [] : [region as RegionKo]; - - if (!curPreparation) { - throw new Error("준비 단계를 선택해주세요"); - } - - let imageUrl: string | null = baseProfileImageUrl; - - if (profileImageFile) { - try { - const result = await uploadImageMutation.mutateAsync(profileImageFile); - imageUrl = result.fileUrl; - } catch (err: unknown) { - const error = err as { message?: string }; - console.error("Error", error.message); - // toast.error는 hook의 onError에서 이미 처리되므로 중복 호출 제거 - } - } - - return { - signUpToken: signUpToken as string, - interestedRegions: submitRegion, - interestedCountries: countries, - preparationStatus: curPreparation, - nickname, - profileImageUrl: imageUrl, - }; - }; - - const submitRegisterRequest = async () => { - try { - const registerRequest = await createRegisterRequest(); - signUpMutation.mutate(registerRequest, { - onSuccess: (data) => { - setAccessToken(data.accessToken); - toast.success("회원가입이 완료되었습니다."); - - setTimeout(() => { - router.push("/"); - }, 100); - }, - onError: (error: unknown) => { - const axiosError = error as { - response?: { data?: { message?: string } }; - message?: string; - }; - if (axiosError.response) { - console.error("Axios response error", axiosError.response); - toast.error( - axiosError.response.data?.message || "회원가입에 실패했습니다.", - ); - } else { - console.error("Error", axiosError.message); - toast.error(axiosError.message || "회원가입에 실패했습니다."); - } - }, - }); - } catch (err: unknown) { - const error = err as { message?: string }; - console.error("Error", error.message); - toast.error(error.message || "회원가입에 실패했습니다."); - } - }; - - const renderCurrentSurvey = () => { - switch (curStage) { - case 1: - return ( - { - setCurStage(2); - }} - /> - ); - case 2: - return ( - { - setCurStage(3); - }} - /> - ); - case 3: - return ( - { - setCurStage(4); - }} - /> - ); - case 4: - return ( - - ); - default: - return
회원 가입이 완료되었습니다
; - } - }; - - return ( -
-
- -
- {renderCurrentSurvey()} -
- ); +const SignupSurvey = ({ baseNickname, baseEmail, baseProfileImageUrl }: SignupSurveyProps) => { + const router = useRouter(); + const searchParams = useSearchParams(); + + const signUpToken = searchParams?.get("token"); + if (!signUpToken) { + router.push("/login"); + } + const { setAccessToken } = useAuthStore(); + const [curStage, setCurStage] = useState(1); + const [curProgress, setCurProgress] = useState(0); + + const [curPreparation, setCurPreparation] = useState(null); + + const [region, setRegion] = useState(null); + const [countries, setCountries] = useState([]); + + const [nickname, setNickname] = useState(baseNickname); + const [profileImageFile, setProfileImageFile] = useState(null); + + const signUpMutation = usePostSignUp(); + const uploadImageMutation = useUploadProfileImagePublic(); + + useEffect(() => { + setCurProgress(((curStage - 1) / 3) * 100); + }, [curStage]); + + const createRegisterRequest = async (): Promise => { + const submitRegion: RegionKo[] = region === "아직 잘 모르겠어요" ? [] : [region as RegionKo]; + + if (!curPreparation) { + throw new Error("준비 단계를 선택해주세요"); + } + + let imageUrl: string | null = baseProfileImageUrl; + + if (profileImageFile) { + try { + const result = await uploadImageMutation.mutateAsync(profileImageFile); + imageUrl = result.fileUrl; + } catch (err: unknown) { + const error = err as { message?: string }; + console.error("Error", error.message); + // toast.error는 hook의 onError에서 이미 처리되므로 중복 호출 제거 + } + } + + return { + signUpToken: signUpToken as string, + interestedRegions: submitRegion, + interestedCountries: countries, + preparationStatus: curPreparation, + nickname, + profileImageUrl: imageUrl, + }; + }; + + const submitRegisterRequest = async () => { + try { + const registerRequest = await createRegisterRequest(); + signUpMutation.mutate(registerRequest, { + onSuccess: (data) => { + setAccessToken(data.accessToken); + toast.success("회원가입이 완료되었습니다."); + + setTimeout(() => { + router.push("/"); + }, 100); + }, + onError: (error: unknown) => { + const axiosError = error as { + response?: { data?: { message?: string } }; + message?: string; + }; + if (axiosError.response) { + console.error("Axios response error", axiosError.response); + toast.error(axiosError.response.data?.message || "회원가입에 실패했습니다."); + } else { + console.error("Error", axiosError.message); + toast.error(axiosError.message || "회원가입에 실패했습니다."); + } + }, + }); + } catch (err: unknown) { + const error = err as { message?: string }; + console.error("Error", error.message); + toast.error(error.message || "회원가입에 실패했습니다."); + } + }; + + const renderCurrentSurvey = () => { + switch (curStage) { + case 1: + return ( + { + setCurStage(2); + }} + /> + ); + case 2: + return ( + { + setCurStage(3); + }} + /> + ); + case 3: + return ( + { + setCurStage(4); + }} + /> + ); + case 4: + return ( + + ); + default: + return
회원 가입이 완료되었습니다
; + } + }; + + return ( +
+
+ +
+ {renderCurrentSurvey()} +
+ ); }; export default SignupSurvey; diff --git a/apps/web/src/components/mentor/ChannelSelct/_hooks/useSelectHandler.ts b/apps/web/src/components/mentor/ChannelSelct/_hooks/useSelectHandler.ts index 8f03f1d1..2b03daf9 100644 --- a/apps/web/src/components/mentor/ChannelSelct/_hooks/useSelectHandler.ts +++ b/apps/web/src/components/mentor/ChannelSelct/_hooks/useSelectHandler.ts @@ -5,7 +5,7 @@ import type { ChannelType } from "@/types/mentor"; interface useSelectHandlerReturn { isOpen: boolean; - dropdownRef: RefObject; + dropdownRef: RefObject; handleChannelChange: (val: ChannelType | null) => void; toggleDropdown: () => void; } diff --git a/apps/web/src/components/mentor/MentorApplyCountContent/index.tsx b/apps/web/src/components/mentor/MentorApplyCountContent/index.tsx index 00e16474..0d996957 100644 --- a/apps/web/src/components/mentor/MentorApplyCountContent/index.tsx +++ b/apps/web/src/components/mentor/MentorApplyCountContent/index.tsx @@ -8,58 +8,54 @@ import { UserRole } from "@/types/mentor"; import { tokenParse } from "@/utils/jwtUtils"; const MentorApplyCountContent = () => { - // 로그인 된경우에만 신규 신청 카운트 모달 표시 - const { accessToken, isInitialized } = useAuthStore(); - const isMentor = - tokenParse(accessToken)?.role === UserRole.MENTOR || - tokenParse(accessToken)?.role === UserRole.ADMIN; - - const { data: count, isSuccess } = useGetUnconfirmedMentoringCount( - isInitialized && !!accessToken && isMentor, - ); - - const [isModalOpen, setIsModalOpen] = useState(true); - - // 신규 신청 없으면 표시 - if (!isInitialized || !isMentor || !isSuccess || !isModalOpen || count === 0) - return null; - - return ( -
- {/* close button */} - - setIsModalOpen(false)}> -
- {/* left: message */} -
-

알림

-

새로운 요청이 들어왔어요!

-

어서 요청을 수락해주세요.

-
- - {/* divider */} -
- - {/* right: count */} -
- 신규 신청 -
{count}명
-
-
- -
- ); + // 로그인 된경우에만 신규 신청 카운트 모달 표시 + const { accessToken, isInitialized } = useAuthStore(); + const isMentor = + tokenParse(accessToken)?.role === UserRole.MENTOR || tokenParse(accessToken)?.role === UserRole.ADMIN; + + const { data: count, isSuccess } = useGetUnconfirmedMentoringCount(isInitialized && !!accessToken && isMentor); + + const [isModalOpen, setIsModalOpen] = useState(true); + + // 신규 신청 없으면 표시 + if (!isInitialized || !isMentor || !isSuccess || !isModalOpen || count === 0) return null; + + return ( +
+ {/* close button */} + + setIsModalOpen(false)}> +
+ {/* left: message */} +
+

알림

+

새로운 요청이 들어왔어요!

+

어서 요청을 수락해주세요.

+
+ + {/* divider */} +
+ + {/* right: count */} +
+ 신규 신청 +
{count}명
+
+
+ +
+ ); }; export default MentorApplyCountContent; diff --git a/apps/web/src/components/ui/BottomSheet/hooks/useHandleModal.ts b/apps/web/src/components/ui/BottomSheet/hooks/useHandleModal.ts index 3b0e5f6f..9ebb4154 100644 --- a/apps/web/src/components/ui/BottomSheet/hooks/useHandleModal.ts +++ b/apps/web/src/components/ui/BottomSheet/hooks/useHandleModal.ts @@ -6,7 +6,7 @@ const isInteractiveElement = (el: EventTarget | null): boolean => { }; interface UseHandleModalReturn { - elementRef: RefObject; + elementRef: RefObject; isVisible: boolean; translateY: number; isDraggingRef: MutableRefObject; diff --git a/apps/web/src/lib/web-socket/useConnectWebSocket.ts b/apps/web/src/lib/web-socket/useConnectWebSocket.ts index 3f82ec2c..274f3e08 100644 --- a/apps/web/src/lib/web-socket/useConnectWebSocket.ts +++ b/apps/web/src/lib/web-socket/useConnectWebSocket.ts @@ -23,6 +23,8 @@ const useConnectWebSocket = ({ roomId, clientRef }: UseConnectWebSocketProps): U // Hook 내부에서 연결 상태를 직접 관리 const [connectionStatus, setConnectionStatus] = useState(ConnectionStatus.Disconnected); const [submittedMessages, setSubmittedMessages] = useState([]); + const accessToken = useAuthStore((state) => state.accessToken); + const isInitialized = useAuthStore((state) => state.isInitialized); useEffect(() => { if (!roomId) { @@ -30,14 +32,14 @@ const useConnectWebSocket = ({ roomId, clientRef }: UseConnectWebSocketProps): U return; } + if (!isInitialized || !accessToken || accessToken.trim() === "") { + setConnectionStatus(ConnectionStatus.Pending); + return; + } + const connect = async () => { setConnectionStatus(ConnectionStatus.Pending); // 연결 시도 중 상태로 설정 - const token = useAuthStore.getState().accessToken; - if (!token || typeof token !== "string" || token.trim() === "") { - console.error("WebSocket connection aborted: Access token is missing or invalid."); - setConnectionStatus(ConnectionStatus.Error); - return; - } + const token = accessToken; try { const client = new Client({ @@ -92,7 +94,7 @@ const useConnectWebSocket = ({ roomId, clientRef }: UseConnectWebSocketProps): U } clientRef.current = null; }; - }, [roomId, clientRef]); + }, [roomId, clientRef, accessToken, isInitialized]); // 관리하는 connectionStatus를 반환 return { connectionStatus, submittedMessages, setSubmittedMessages }; diff --git a/apps/web/src/utils/axiosInstance.ts b/apps/web/src/utils/axiosInstance.ts index 2564c499..be02b52a 100644 --- a/apps/web/src/utils/axiosInstance.ts +++ b/apps/web/src/utils/axiosInstance.ts @@ -52,7 +52,8 @@ export const axiosInstance: AxiosInstance = axios.create({ // 1. 요청 인터셉터 (Request Interceptor) axiosInstance.interceptors.request.use( async (config) => { - const { accessToken, isInitialized, setLoading, clearAccessToken, setInitialized } = useAuthStore.getState(); + const { accessToken, setLoading, clearAccessToken, setInitialized, refreshStatus, setRefreshStatus } = + useAuthStore.getState(); // 토큰이 있으면 헤더에 추가하고 진행 if (accessToken) { @@ -60,8 +61,7 @@ axiosInstance.interceptors.request.use( return config; } - // 토큰이 없고 아직 초기화되지 않은 경우 reissue 시도 - if (!isInitialized) { + if (refreshStatus !== "failed") { try { // 이미 reissue가 진행 중인지 확인 if (reissuePromise) { @@ -69,11 +69,14 @@ axiosInstance.interceptors.request.use( } else { // 새로운 reissue 프로세스 시작 (HTTP-only 쿠키의 refreshToken 사용) reissuePromise = (async () => { + setRefreshStatus("refreshing"); setLoading(true); try { await postReissueToken(); + setRefreshStatus("success"); } catch { clearAccessToken(); + setRefreshStatus("failed"); } finally { setLoading(false); setInitialized(true); @@ -101,8 +104,10 @@ axiosInstance.interceptors.request.use( } } + const { isInitialized: currentInitialized, accessToken: currentAccessToken } = useAuthStore.getState(); + // 초기화는 되었지만 토큰이 없는 경우 로그인 필요 - if (isInitialized && !accessToken) { + if (currentInitialized && !currentAccessToken) { redirectToLogin("로그인이 필요합니다. 다시 로그인해주세요."); return Promise.reject(new AuthenticationRequiredError()); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f59ccaa..16ceef35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -143,16 +143,16 @@ importers: version: 14.2.35(next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@radix-ui/react-checkbox': specifier: ^1.1.4 - version: 1.3.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-label': specifier: ^2.1.2 - version: 2.1.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-progress': specifier: ^1.1.2 - version: 1.1.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-select': specifier: ^2.1.6 - version: 2.2.6(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-google-maps/api': specifier: ^2.19.2 version: 2.20.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -224,7 +224,7 @@ importers: version: 4.3.5 zustand: specifier: ^5.0.7 - version: 5.0.10(@types/react@18.3.27)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) + version: 5.0.10(@types/react@19.2.10)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) devDependencies: '@next/bundle-analyzer': specifier: ^16.1.6 @@ -236,11 +236,11 @@ importers: specifier: ^20.11.19 version: 20.19.30 '@types/react': - specifier: 18.3.27 - version: 18.3.27 + specifier: 19.2.10 + version: 19.2.10 '@types/react-dom': - specifier: 18.3.7 - version: 18.3.7(@types/react@18.3.27) + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.10) autoprefixer: specifier: ^10.4.20 version: 10.4.23(postcss@8.5.6) @@ -3147,22 +3147,11 @@ packages: '@types/pg@8.15.6': resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} - '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - - '@types/react-dom@18.3.7': - resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} - peerDependencies: - '@types/react': ^18.0.0 - '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: '@types/react': ^19.2.0 - '@types/react@18.3.27': - resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} - '@types/react@19.2.10': resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==} @@ -7699,42 +7688,42 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: @@ -7748,11 +7737,11 @@ snapshots: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -7760,11 +7749,11 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-context@1.1.2(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-context@1.1.2(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-context@1.1.2(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -7772,17 +7761,17 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-context@1.1.3(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-context@1.1.3(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - '@radix-ui/react-direction@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-direction@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-direction@1.1.1(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -7790,42 +7779,42 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-focus-guards@1.1.3(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-id@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-id@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-id@1.1.1(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -7834,14 +7823,14 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-label@2.1.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: @@ -7852,43 +7841,43 @@ snapshots: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.10)(react@18.3.1) '@radix-ui/rect': 1.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: @@ -7900,14 +7889,14 @@ snapshots: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: @@ -7918,14 +7907,14 @@ snapshots: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-primitive@2.1.4(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.2.4(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: @@ -7936,15 +7925,15 @@ snapshots: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-progress@1.1.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-progress@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-context': 1.1.3(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-context': 1.1.3(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: @@ -7963,41 +7952,41 @@ snapshots: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-select@2.2.6(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.2(@types/react@18.3.27)(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@19.2.10)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-slot@1.2.3(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-slot@1.2.3(@types/react@19.2.10)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-slot@1.2.3(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -8006,12 +7995,12 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-slot@1.2.4(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-slot@1.2.4(@types/react@19.2.10)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-slot@1.2.4(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -8036,11 +8025,11 @@ snapshots: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -8048,13 +8037,13 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.27)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.10)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -8064,12 +8053,12 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -8078,18 +8067,18 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.10)(react@19.2.4)': dependencies: @@ -8097,34 +8086,34 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 - '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.1 react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - '@radix-ui/react-use-size@1.1.1(@types/react@18.3.27)(react@18.3.1)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.10)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@18.3.1) react: 18.3.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 - '@types/react-dom': 18.3.7(@types/react@18.3.27) + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) '@radix-ui/rect@1.1.1': {} @@ -9088,21 +9077,10 @@ snapshots: pg-protocol: 1.11.0 pg-types: 2.2.0 - '@types/prop-types@15.7.15': {} - - '@types/react-dom@18.3.7(@types/react@18.3.27)': - dependencies: - '@types/react': 18.3.27 - '@types/react-dom@19.2.3(@types/react@19.2.10)': dependencies: '@types/react': 19.2.10 - '@types/react@18.3.27': - dependencies: - '@types/prop-types': 15.7.15 - csstype: 3.2.3 - '@types/react@19.2.10': dependencies: csstype: 3.2.3 @@ -10957,32 +10935,32 @@ snapshots: react-refresh@0.18.0: {} - react-remove-scroll-bar@2.3.8(@types/react@18.3.27)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@19.2.10)(react@18.3.1): dependencies: react: 18.3.1 - react-style-singleton: 2.2.3(@types/react@18.3.27)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@19.2.10)(react@18.3.1) tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - react-remove-scroll@2.7.2(@types/react@18.3.27)(react@18.3.1): + react-remove-scroll@2.7.2(@types/react@19.2.10)(react@18.3.1): dependencies: react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@18.3.27)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@18.3.27)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@19.2.10)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@19.2.10)(react@18.3.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@18.3.27)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@18.3.27)(react@18.3.1) + use-callback-ref: 1.3.3(@types/react@19.2.10)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@19.2.10)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - react-style-singleton@2.2.3(@types/react@18.3.27)(react@18.3.1): + react-style-singleton@2.2.3(@types/react@19.2.10)(react@18.3.1): dependencies: get-nonce: 1.0.1 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 react@18.3.1: dependencies: @@ -11527,20 +11505,20 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - use-callback-ref@1.3.3(@types/react@18.3.27)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@19.2.10)(react@18.3.1): dependencies: react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 - use-sidecar@1.1.3(@types/react@18.3.27)(react@18.3.1): + use-sidecar@1.1.3(@types/react@19.2.10)(react@18.3.1): dependencies: detect-node-es: 1.1.0 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 use-sync-external-store@1.6.0(react@18.3.1): dependencies: @@ -11821,8 +11799,8 @@ snapshots: zod@4.3.5: {} - zustand@5.0.10(@types/react@18.3.27)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)): + zustand@5.0.10(@types/react@19.2.10)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)): optionalDependencies: - '@types/react': 18.3.27 + '@types/react': 19.2.10 react: 18.3.1 use-sync-external-store: 1.6.0(react@18.3.1)