From 077a81a13cb7e2a7c7d4087bf2e78dde9dd16788 Mon Sep 17 00:00:00 2001 From: wonil Date: Fri, 6 Dec 2024 01:32:10 +0900 Subject: [PATCH 01/19] =?UTF-8?q?=F0=9F=90=9B=20=20Fix:=20Geolocation=20?= =?UTF-8?q?=EC=A3=BC=EC=86=8C=20=EB=B6=88=EB=9F=AC=EC=98=A4=EA=B8=B0=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useGeolocation.ts | 70 ++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/src/hooks/useGeolocation.ts b/src/hooks/useGeolocation.ts index 66aed861..a5d348dc 100644 --- a/src/hooks/useGeolocation.ts +++ b/src/hooks/useGeolocation.ts @@ -5,12 +5,42 @@ interface Location { address: string | null error: string | null } + interface AddressComponent { long_name: string short_name: string types: string[] } +interface GeocodeResult { + address_components: AddressComponent[] + formatted_address: string + geometry: { + location: { + lat: number + lng: number + } + location_type: string + viewport: { + northeast: { + lat: number + lng: number + } + southwest: { + lat: number + lng: number + } + } + } + place_id: string + types: string[] +} + +interface GeocodeResponse { + results: GeocodeResult[] + status: string +} + export const useGeolocation = () => { const [location, setLocation] = useState({ address: null, @@ -18,10 +48,7 @@ export const useGeolocation = () => { }) const getCurrentLocation = () => { - console.log('getCurrentLocation 호출됨') - if (!navigator.geolocation) { - console.log('geolocation 지원되지 않음') setLocation({ address: null, error: '위치 서비스가 지원되지 않습니다.' }) return } @@ -30,29 +57,32 @@ export const useGeolocation = () => { async position => { try { const { latitude, longitude } = position.coords - console.log('위치 확인:', latitude, longitude) - const apiKey = import.meta.env.VITE_GOOGLE_MAP_API_KEY - - const response = await axios.get( + const response = await axios.get( `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&language=ko&key=${apiKey}` ) console.log('Google API 응답:', response.data) + let si: string | undefined + let district: string | undefined + let neighborhood: string | undefined if (response.data.results.length > 0) { - const addressComponents = response.data.results[0].address_components - const district = addressComponents.find((component: AddressComponent) => - component.types.includes('sublocality_level_1') - )?.long_name - const neighborhood = addressComponents.find((component: AddressComponent) => - component.types.includes('sublocality_level_2') - )?.long_name - - console.log('찾은 주소:', district, neighborhood) + response.data.results.forEach(result => { + const addressComponents = result.address_components + if (!si) si = addressComponents.find(component => component.long_name.endsWith('시'))?.long_name + if (!district) + district = addressComponents.find(component => component.long_name.endsWith('구'))?.long_name + if (!neighborhood) + neighborhood = addressComponents.find(component => component.long_name.endsWith('동'))?.long_name + console.log(si, district, neighborhood) + }) + } + const address = [si, district, neighborhood].join(' ').trim() + if (address) { setLocation({ - address: `${district} ${neighborhood}`, + address: `${address}`, error: null, }) } @@ -66,9 +96,9 @@ export const useGeolocation = () => { setLocation({ address: null, error: '위치 권한이 거부되었습니다.' }) }, { - enableHighAccuracy: false, // 위치 정보 정확도 설정. false설정 시 배터리 소모가 적고 더 빠르게 위치 파악 - timeout: 10000, // 위치 정보 가져오는데 허용되는 최대 시간 10000 == 10초 - maximumAge: 1000, // 캐시된 위치 정보를 사용할 수 있는 최대 시간 1000 == 1초 + enableHighAccuracy: false, + timeout: 10000, + maximumAge: 1000, } ) } From 97dbdf7369e5f649365b2547f3cf91d12506d48a Mon Sep 17 00:00:00 2001 From: wonil Date: Fri, 6 Dec 2024 10:40:52 +0900 Subject: [PATCH 02/19] =?UTF-8?q?=F0=9F=90=9B=20=20Fix:=20=EB=82=B4=20?= =?UTF-8?q?=EC=A3=BC=EC=86=8C=20=EB=B6=88=EB=9F=AC=EC=98=A4=EA=B8=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GenderSelectButton/index.tsx | 4 +- src/hooks/useGeolocation.ts | 43 ++++++++++++++------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/components/GenderSelectButton/index.tsx b/src/components/GenderSelectButton/index.tsx index 69587a6a..d1b14868 100644 --- a/src/components/GenderSelectButton/index.tsx +++ b/src/components/GenderSelectButton/index.tsx @@ -1,6 +1,6 @@ import * as S from './styles' -import MALE from '~assets/MALE.svg' -import FEMALE from '~assets/FEMALE.svg' +import MALE from '~assets/male.svg' +import FEMALE from '~assets/female.svg' import { Typo17 } from '~components/Typo/index' interface GenderSelectButtonProps { diff --git a/src/hooks/useGeolocation.ts b/src/hooks/useGeolocation.ts index a5d348dc..fa2174c4 100644 --- a/src/hooks/useGeolocation.ts +++ b/src/hooks/useGeolocation.ts @@ -41,11 +41,37 @@ interface GeocodeResponse { status: string } +const locality = ['시', '군', '구', '동', '읍', '면', '리'] + export const useGeolocation = () => { const [location, setLocation] = useState({ address: null, error: null, }) + const matches = new Set() + + const extractMatchingComponents = (components: AddressComponent[], locality: string[]) => { + components.forEach(component => { + if (locality.some(loc => component.long_name.endsWith(loc))) { + matches.add(component.long_name) + } + }) + } + + const sortByLocality = (matches: string[]) => { + const sorted = matches.sort((a, b) => { + const aIndex = locality.findIndex(loc => a.endsWith(loc)) + const bIndex = locality.findIndex(loc => b.endsWith(loc)) + return aIndex - bIndex + }) + + const result = sorted.filter((loc, index) => { + const currentLastChar = loc.slice(-1) + return !sorted.slice(0, index).some(prev => prev.slice(-1) === currentLastChar) + }) + + return result + } const getCurrentLocation = () => { if (!navigator.geolocation) { @@ -64,25 +90,16 @@ export const useGeolocation = () => { console.log('Google API 응답:', response.data) - let si: string | undefined - let district: string | undefined - let neighborhood: string | undefined if (response.data.results.length > 0) { response.data.results.forEach(result => { const addressComponents = result.address_components - if (!si) si = addressComponents.find(component => component.long_name.endsWith('시'))?.long_name - if (!district) - district = addressComponents.find(component => component.long_name.endsWith('구'))?.long_name - if (!neighborhood) - neighborhood = addressComponents.find(component => component.long_name.endsWith('동'))?.long_name - - console.log(si, district, neighborhood) + extractMatchingComponents(addressComponents, locality) }) } - const address = [si, district, neighborhood].join(' ').trim() - if (address) { + if (matches.size) { + const sortedMatches = sortByLocality(Array.from(matches) as string[]) setLocation({ - address: `${address}`, + address: sortedMatches.slice(-2).join(' '), error: null, }) } From a27cb0b3de5874afc5d432fda4ed678790bc8042 Mon Sep 17 00:00:00 2001 From: wonil Date: Fri, 6 Dec 2024 10:51:21 +0900 Subject: [PATCH 03/19] =?UTF-8?q?=F0=9F=93=9D=20Docs:=20positionLabelMap?= =?UTF-8?q?=20=EA=B3=B5=ED=86=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/RegisterPage/Register/index.tsx | 12 +----------- src/utils/positionLabelMap.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 src/utils/positionLabelMap.ts diff --git a/src/pages/RegisterPage/Register/index.tsx b/src/pages/RegisterPage/Register/index.tsx index fadc6496..1b738b39 100644 --- a/src/pages/RegisterPage/Register/index.tsx +++ b/src/pages/RegisterPage/Register/index.tsx @@ -15,19 +15,9 @@ import Toast from '~components/Toast' import { useToastStore } from '~stores/toastStore' import { useSearchParams } from 'react-router-dom' import { createRegister } from '~apis/register/createRegister' +import { positionLabelMap } from '~utils/positionLabelMap' import { FamilyRole } from '~types/common' -const positionLabelMap: Record = { - MOTHER: '엄마', - FATHER: '아빠', - OLDER_BROTHER: '형', - ELDER_BROTHER: '오빠', - ELDER_SISTER: '언니', - OLDER_SISTER: '누나', - GRANDFATHER: '할아버지', - GRANDMOTHER: '할머니', -} - export default function Register() { const { ownerProfile, setOwnerProfile } = useOwnerProfileStore() const { location, getCurrentLocation } = useGeolocation() diff --git a/src/utils/positionLabelMap.ts b/src/utils/positionLabelMap.ts new file mode 100644 index 00000000..0347fe31 --- /dev/null +++ b/src/utils/positionLabelMap.ts @@ -0,0 +1,12 @@ +import { FamilyRole } from '~types/common' + +export const positionLabelMap: Record = { + MOTHER: '엄마', + FATHER: '아빠', + OLDER_BROTHER: '형', + ELDER_BROTHER: '오빠', + ELDER_SISTER: '언니', + OLDER_SISTER: '누나', + GRANDFATHER: '할아버지', + GRANDMOTHER: '할머니', +} From 5ff14b1442f7e6d41c6484328e1b756e504dafaf Mon Sep 17 00:00:00 2001 From: wonil Date: Fri, 6 Dec 2024 19:18:08 +0900 Subject: [PATCH 04/19] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=20Refactor:=20?= =?UTF-8?q?=EB=B0=98=EB=A0=A4=EA=B2=AC=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/dog/createDogProfile.ts | 50 +++++++------ src/apis/dog/deleteDogProfile.ts | 37 +++++++--- src/apis/dog/fetchDogProfile.ts | 51 +++++++------ src/apis/dog/useCreateDogProfile.ts | 23 ++++++ .../DogProfileDetailSection/index.tsx | 71 ++++++------------- src/pages/FamilyDDangPage/index.tsx | 13 +--- src/stores/dogProfileStore.ts | 6 +- src/types/api.ts | 2 +- src/types/dogProfile.ts | 14 ++-- src/utils/validateDogProfile.ts | 32 ++++----- 10 files changed, 157 insertions(+), 142 deletions(-) create mode 100644 src/apis/dog/useCreateDogProfile.ts diff --git a/src/apis/dog/createDogProfile.ts b/src/apis/dog/createDogProfile.ts index e7fd87d9..5520af27 100644 --- a/src/apis/dog/createDogProfile.ts +++ b/src/apis/dog/createDogProfile.ts @@ -1,23 +1,22 @@ import { AxiosError } from 'axios' -import { APIResponse, ErrorResponse } from '~types/api' +import { APIResponse, ErrorResponse, CommonAPIResponse } from '~types/api' import { axiosInstance } from '~apis/axiosInstance' -interface CreateDogProfileResponse { - dogId: number - name: string - breed: string - birthDate: string - weight: number - gender: 'MALE' | 'FEMALE' - profileImg: File - isNeutered: 'TRUE' | 'FALSE' - familyId: number - comment: string -} +export type CreateDogProfileRequest = FormData + +export type CreateDogProfileResponse = Pick< + CommonAPIResponse, + 'dogId' | 'name' | 'breed' | 'birthDate' | 'weight' | 'gender' | 'profileImg' +> -export const createDogProfile = async (formData: FormData): Promise> => { +/** + * 새로운 반려견 프로필을 생성합니다. + */ +export const createDogProfile = async ( + req: CreateDogProfileRequest +): Promise> => { try { - const { data } = await axiosInstance.post>('/dogs/create', formData, { + const { data } = await axiosInstance.post>('/dogs/create', req, { headers: { 'Content-Type': 'multipart/form-data', }, @@ -25,17 +24,24 @@ export const createDogProfile = async (formData: FormData): Promise + const { response } = error as AxiosError if (response) { - console.error('반려견 등록 오류:', response.data) - throw new Error(response.data.message ?? '요청 실패') + const { code, message } = response.data + switch (code) { + case 400: + throw new Error(message || '잘못된 요청입니다.') + case 401: + throw new Error(message || '인증에 실패했습니다.') + case 500: + throw new Error(message || '서버 오류가 발생했습니다.') + default: + throw new Error(message || '알 수 없는 오류가 발생했습니다.') + } } - if (request) { - console.error('요청 에러:', request) - throw new Error('네트워크 연결을 확인해주세요') - } + // 요청 자체가 실패한 경우 + throw new Error('네트워크 연결을 확인해주세요') } console.error('예상치 못한 에러:', error) diff --git a/src/apis/dog/deleteDogProfile.ts b/src/apis/dog/deleteDogProfile.ts index ed40751b..26ebac1d 100644 --- a/src/apis/dog/deleteDogProfile.ts +++ b/src/apis/dog/deleteDogProfile.ts @@ -2,27 +2,42 @@ import { AxiosError } from 'axios' import { APIResponse, ErrorResponse } from '~types/api' import { axiosInstance } from '~apis/axiosInstance' -interface DeleteDogProfileResponse { +export type DeleteDogProfileRequest = { + id: number +} + +export type DeleteDogProfileResponse = { data: Record } -export const deleteDogProfile = async (id: number): Promise> => { +/** + * 반려견 프로필을 삭제합니다. + */ +export const deleteDogProfile = async ( + req: DeleteDogProfileRequest +): Promise> => { try { - const { data } = await axiosInstance.delete>(`/dogs/${id}`) + const { data } = await axiosInstance.delete>(`/dogs/${req.id}`) return data } catch (error) { if (error instanceof AxiosError) { - const { response, request } = error as AxiosError + const { response } = error as AxiosError if (response) { - console.error('반려견 삭제 오류:', response.data) - throw new Error(response.data.message ?? '요청 실패') - } - - if (request) { - console.error('요청 에러:', request) - throw new Error('네트워크 연결을 확인해주세요') + const { code, message } = response.data + switch (code) { + case 400: + throw new Error(message || '잘못된 요청입니다.') + case 401: + throw new Error(message || '인증에 실패했습니다.') + case 500: + throw new Error(message || '서버 오류가 발생했습니다.') + default: + throw new Error(message || '알 수 없는 오류가 발생했습니다.') + } } + // 요청 자체가 실패한 경우 + throw new Error('네트워크 연결을 확인해주세요') } console.error('예상치 못한 에러:', error) diff --git a/src/apis/dog/fetchDogProfile.ts b/src/apis/dog/fetchDogProfile.ts index 1cab553a..f122c229 100644 --- a/src/apis/dog/fetchDogProfile.ts +++ b/src/apis/dog/fetchDogProfile.ts @@ -1,41 +1,46 @@ import { AxiosError } from 'axios' -import { APIResponse, ErrorResponse } from '~types/api' +import { APIResponse, CommonAPIResponse, ErrorResponse } from '~types/api' import { axiosInstance } from '~apis/axiosInstance' -interface DogProfileDetail { - dogId: number - name: string - breed: string - birthDate: string - weight: number - gender: 'MALE' | 'FEMALE' - profileImg: string - isNeutered: 'TRUE' | 'FALSE' - familyId: number - comment: string +type DogProfileDetail = Pick< + CommonAPIResponse, + 'dogId' | 'name' | 'breed' | 'birthDate' | 'weight' | 'gender' | 'profileImg' | 'isNeutered' | 'familyId' | 'comment' +> + +export type FetchDogProfileRequest = { + id: number } -export interface FetchDogProfileResponse { +export type FetchDogProfileResponse = { data: DogProfileDetail } -export const fetchDogProfile = async (id: number): Promise> => { +/** + * 반려견의 상세 프로필 정보를 조회합니다. + */ +export const fetchDogProfile = async (req: FetchDogProfileRequest): Promise> => { try { - const { data } = await axiosInstance.get>(`/dogs/${id}`) + const { data } = await axiosInstance.get>(`/dogs/${req.id}`) return data } catch (error) { if (error instanceof AxiosError) { - const { response, request } = error as AxiosError + const { response } = error as AxiosError if (response) { - console.error('반려견 조회 오류:', response.data) - throw new Error(response.data.message ?? '요청 실패') - } - - if (request) { - console.error('요청 에러:', request) - throw new Error('네트워크 연결을 확인해주세요') + const { code, message } = response.data + switch (code) { + case 400: + throw new Error(message || '잘못된 요청입니다.') + case 401: + throw new Error(message || '인증에 실패했습니다.') + case 500: + throw new Error(message || '서버 오류가 발생했습니다.') + default: + throw new Error(message || '알 수 없는 오류가 발생했습니다.') + } } + // 요청 자체가 실패한 경우 + throw new Error('네트워크 연결을 확인해주세요') } console.error('예상치 못한 에러:', error) diff --git a/src/apis/dog/useCreateDogProfile.ts b/src/apis/dog/useCreateDogProfile.ts new file mode 100644 index 00000000..0f2778b5 --- /dev/null +++ b/src/apis/dog/useCreateDogProfile.ts @@ -0,0 +1,23 @@ +import { useMutation } from '@tanstack/react-query' +import { createDogProfile } from '~apis/dog/createDogProfile' +import { useNavigate } from 'react-router-dom' +import { useModalStore } from '~stores/modalStore' +import { useToastStore } from '~stores/toastStore' + +export function useCreateDogProfile() { + const navigate = useNavigate() + const { clearModal } = useModalStore() + const { showToast } = useToastStore() + + return useMutation({ + mutationFn: (formData: FormData) => createDogProfile(formData), + onSuccess: () => { + alert('반려견 등록 완료') + clearModal() + navigate('/') + }, + onError: (error: Error) => { + showToast(error.message) + }, + }) +} diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index dda4412e..3cada66c 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -1,24 +1,23 @@ -import * as S from './styles' import { useState } from 'react' +import { useDogProfileStore } from '~/stores/dogProfileStore' +import Check from '~assets/is-neutered-check.svg' import { ActionButton } from '~components/Button/ActionButton' import GenderSelectButton from '~components/GenderSelectButton' -import { Typo24 } from '~components/Typo/index' -import Check from '~assets/is-neutered-check.svg' import Header from '~components/Header/index' +import Toast from '~components/Toast' +import { Typo24 } from '~components/Typo/index' import SearchModal from '~modals/SearchModal' +import { useCreateDogProfile } from '~apis/dog/useCreateDogProfile' import { useModalStore } from '~stores/modalStore' -import { useDogProfileStore } from '~/stores/dogProfileStore' -import { validateDogDetailProfile } from '~utils/validateDogProfile' import { useToastStore } from '~stores/toastStore' -import Toast from '~components/Toast' -import { createDogProfile } from '~apis/dog/createDogProfile' -import { useNavigate } from 'react-router-dom' +import { validateDogDetailProfile } from '~utils/validateDogProfile' +import * as S from './styles' export default function DogProfileDetailSection() { const { dogProfile, setDogProfile } = useDogProfileStore() - const { pushModal, popModal, clearModal } = useModalStore() + const { pushModal, popModal } = useModalStore() const { showToast } = useToastStore() - const navigate = useNavigate() + const createDogProfile = useCreateDogProfile() const [displayValue, setDisplayValue] = useState(dogProfile.weight && dogProfile.weight + 'kg') const [inputType, setInputType] = useState('text') @@ -45,7 +44,7 @@ export default function DogProfileDetailSection() { const handleFocus = () => { setInputType('number') - setDisplayValue(dogProfile.weight.toString()) + setDisplayValue(dogProfile.weight?.toString()) } const handleBlur = () => { @@ -62,43 +61,19 @@ export default function DogProfileDetailSection() { return } - try { - const formData = new FormData() - const requestData = { - name: dogProfile.name, - breed: dogProfile.breed, - birthDate: dogProfile.birthDate, - weight: dogProfile.weight, - gender: dogProfile.gender, - isNeutered: dogProfile.isNeutered, - familyId: null, - comment: dogProfile.comment!.trim(), - } - formData.append( - 'request', - new Blob([JSON.stringify(requestData)], { - type: 'application/json', - }) - ) - if (dogProfile.profileImgFile) { - console.log(dogProfile.profileImgFile) - formData.append('profileImgFile', dogProfile.profileImgFile) - } - - const response = await createDogProfile(formData) - - if (response.code === 201) { - // 홈으로 이동 - alert('반려견 등록 완료') - clearModal() - navigate('/') - // 성공 후 추가 처리 (예: 홈으로 이동) - } - } catch (error) { - if (error instanceof Error) { - showToast(error.message) - } + const formData = new FormData() + const requestData = { + ...dogProfile, + famliyId: null, } + formData.append( + 'request', + new Blob([JSON.stringify(requestData)], { + type: 'application/json', + }) + ) + if (dogProfile.profileImgFile) formData.append('profileImgFile', dogProfile.profileImgFile) + createDogProfile.mutate(formData) } return ( <> @@ -139,7 +114,7 @@ export default function DogProfileDetailSection() { - {dogInfo && ( - - )} + {dogInfo && } diff --git a/src/stores/dogProfileStore.ts b/src/stores/dogProfileStore.ts index 3677c215..2f715118 100644 --- a/src/stores/dogProfileStore.ts +++ b/src/stores/dogProfileStore.ts @@ -9,14 +9,14 @@ interface DogProfileStore { export const useDogProfileStore = create(set => ({ dogProfile: { name: '', - profileImg: undefined, + profileImg: '', profileImgFile: undefined, - birthDate: undefined, + birthDate: '', comment: '', gender: null, isNeutered: 'FALSE', breed: '', - weight: 0, + weight: undefined, familyId: null, }, setDogProfile: update => diff --git a/src/types/api.ts b/src/types/api.ts index 3912c63d..afc67c33 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -13,7 +13,7 @@ export type BasicInfo = { /** 이름 @example "홍길동" */ name: string /** 생년월일 @example "1990-01-01" */ - birthDate?: string + birthDate: string /** 성별 @example "MALE" */ gender: Gender } diff --git a/src/types/dogProfile.ts b/src/types/dogProfile.ts index fae00d71..3a4c4c8d 100644 --- a/src/types/dogProfile.ts +++ b/src/types/dogProfile.ts @@ -1,11 +1,13 @@ +import { BooleanString, Gender } from './common' + export interface DogProfileType { name: string - profileImg?: string + profileImg: string profileImgFile?: File - birthDate?: string - gender: 'MALE' | 'FEMALE' | null - isNeutered: 'TRUE' | 'FALSE' + birthDate: string + gender: Gender | null + isNeutered: BooleanString breed: string - weight: number - comment?: string + weight?: number + comment: string } diff --git a/src/utils/validateDogProfile.ts b/src/utils/validateDogProfile.ts index edec62d3..262f2432 100644 --- a/src/utils/validateDogProfile.ts +++ b/src/utils/validateDogProfile.ts @@ -10,27 +10,27 @@ const isFutureDate = (date: Date) => { } export const validateDogProfile = (dogProfile: DogProfileType): string | null => { - if (!dogProfile.name) return '반려견의 이름을 입력해주세요' - if (!HangeulRegex.test(dogProfile.name) || dogProfile.name.length > 10) return '최대 10자의 한글이름만 사용해 주세요' - if (!dogProfile.profileImg) return '반려견의 사진을 등록해주세요' - if (dogProfile.profileImgFile && !dogProfile.profileImgFile.type.startsWith('image/')) - return '올바른 이미지 파일이 아닙니다' - if (dogProfile.profileImgFile && dogProfile.profileImgFile.size > 5 * 1024 * 1024) - return '이미지 크기는 5MB 이하여야 합니다' - if (!dogProfile.birthDate) return '반려견의 생일을 입력해주세요' - if (isFutureDate(stringToDate(dogProfile.birthDate))) return '생일은 미래 날짜를 선택할 수 없습니다' - if (!dogProfile.comment) return '한줄 소개를 적어주세요' - if (dogProfile.comment.length < 2) return '한줄 소개는 최소 2자 이상 입력해주세요' - if (dogProfile.comment.length > 30) return '한줄 소개는 최대 30자까지만 적어주세요' + const { name, profileImg, profileImgFile, birthDate, comment } = dogProfile + + if (!name) return '반려견의 이름을 입력해주세요' + if (!HangeulRegex.test(name) || name.length > 10) return '최대 10자의 한글이름만 사용해 주세요' + if (!profileImg) return '반려견의 사진을 등록해주세요' + if (profileImgFile && !profileImgFile.type.startsWith('image/')) return '올바른 이미지 파일이 아닙니다' + if (profileImgFile && profileImgFile.size > 5 * 1024 * 1024) return '이미지 크기는 5MB 이하여야 합니다' + if (!birthDate) return '반려견의 생일을 입력해주세요' + if (isFutureDate(stringToDate(birthDate))) return '생일은 미래 날짜를 선택할 수 없습니다' + if (!comment) return '한줄 소개를 적어주세요' + if (comment.length < 2) return '한줄 소개는 최소 2자 이상 입력해주세요' + if (comment.length > 30) return '한줄 소개는 최대 30자까지만 적어주세요' return null } export const validateDogDetailProfile = (dogProfile: DogProfileType): string | null => { - const weight = dogProfile.weight + const { gender, breed, weight } = dogProfile - if (!dogProfile.gender) return '성별을 선택해주세요' - if (!dogProfile.breed) return '견종을 선택해주세요' - if (!dogProfile.weight) return '몸무게를 입력해주세요' + if (!gender) return '성별을 선택해주세요' + if (!breed) return '견종을 선택해주세요' + if (weight === undefined) return '몸무게를 입력해주세요' if (weight < 0.1) return '올바른 몸무게를 입력해주세요' if (weight > 100) return '100kg 이하의 몸무게만 입력 가능합니다' return null From 7ac4b1449d4f856410b8bcab809d46274d800614 Mon Sep 17 00:00:00 2001 From: wonil Date: Sat, 7 Dec 2024 06:37:40 +0900 Subject: [PATCH 05/19] =?UTF-8?q?=F0=9F=8E=A8=20=20Design:=20=EB=B0=98?= =?UTF-8?q?=EB=A0=A4=EA=B2=AC=20=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 6 +- src/apis/dog/useCreateDogProfile.ts | 6 +- .../EditDogProfileModal/DogImageUploader.tsx | 36 +++ src/modals/EditDogProfileModal/index.tsx | 168 ++++++++++++++ src/modals/EditDogProfileModal/styles.ts | 205 ++++++++++++++++++ .../DogProfileSection/styles.ts | 2 + src/pages/HomePage/index.tsx | 5 + src/pages/RegisterPage/Dog/index.tsx | 3 +- src/stores/dogProfileStore.ts | 1 + 9 files changed, 427 insertions(+), 5 deletions(-) create mode 100644 src/modals/EditDogProfileModal/DogImageUploader.tsx create mode 100644 src/modals/EditDogProfileModal/index.tsx create mode 100644 src/modals/EditDogProfileModal/styles.ts diff --git a/src/App.tsx b/src/App.tsx index afcd894f..29242433 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,5 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { Suspense, useState } from 'react' import { Helmet, HelmetProvider } from 'react-helmet-async' import { RouterProvider } from 'react-router-dom' @@ -6,10 +8,8 @@ import PWABadge from '~/PWABadge' import { router } from '~/router' import GlobalStyle from '~/styles/globalStyle' import { darkTheme, lightTheme } from '~/styles/theme' -import Loader from '~components/Loader' import { WebSocketProvider } from '~/WebSocketContext' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import Loader from '~components/Loader' const queryClient = new QueryClient() function App() { diff --git a/src/apis/dog/useCreateDogProfile.ts b/src/apis/dog/useCreateDogProfile.ts index 0f2778b5..ce909404 100644 --- a/src/apis/dog/useCreateDogProfile.ts +++ b/src/apis/dog/useCreateDogProfile.ts @@ -3,15 +3,19 @@ import { createDogProfile } from '~apis/dog/createDogProfile' import { useNavigate } from 'react-router-dom' import { useModalStore } from '~stores/modalStore' import { useToastStore } from '~stores/toastStore' +import { useDogProfileStore } from '~stores/dogProfileStore' export function useCreateDogProfile() { const navigate = useNavigate() const { clearModal } = useModalStore() const { showToast } = useToastStore() + const { setDogProfile } = useDogProfileStore() return useMutation({ mutationFn: (formData: FormData) => createDogProfile(formData), - onSuccess: () => { + onSuccess: response => { + console.log(response.data) + setDogProfile({ ...response.data }) alert('반려견 등록 완료') clearModal() navigate('/') diff --git a/src/modals/EditDogProfileModal/DogImageUploader.tsx b/src/modals/EditDogProfileModal/DogImageUploader.tsx new file mode 100644 index 00000000..1fb607a1 --- /dev/null +++ b/src/modals/EditDogProfileModal/DogImageUploader.tsx @@ -0,0 +1,36 @@ +import { AddDogPictureBtnWrapper, AddDogPictureBtn, HiddenFileInput, DogImage } from './styles' +import { AddPicture } from './styles' +import { useRef } from 'react' + +interface DogImageUploaderProps { + image: string | undefined + setImage: (update: { profileImg: string; profileImgFile: File }) => void +} + +export default function DogImageUploader({ image, setImage }: DogImageUploaderProps) { + const fileInputRef = useRef(null) + + const handleImageChange = (e: React.ChangeEvent) => { + const file = e.target.files?.[0] + if (file) { + const reader = new FileReader() + reader.onloadend = () => { + setImage({ + profileImg: reader.result as string, + profileImgFile: file, + }) + } + reader.readAsDataURL(file) + } + } + + return ( + + + + {image && } + + fileInputRef.current?.click()}>사진 추가 + + ) +} diff --git a/src/modals/EditDogProfileModal/index.tsx b/src/modals/EditDogProfileModal/index.tsx new file mode 100644 index 00000000..908a4e85 --- /dev/null +++ b/src/modals/EditDogProfileModal/index.tsx @@ -0,0 +1,168 @@ +import { useState } from 'react' +import { Typo24 } from '~components/Typo/index.ts' +import * as S from './styles.ts' +import { useDogProfileStore } from '~stores/dogProfileStore.ts' +import { useModalStore } from '~stores/modalStore.ts' +import SearchModal from '~modals/SearchModal/index.tsx' +import { useToastStore } from '~stores/toastStore.ts' +import Header from '~components/Header/index.tsx' +import { validateDogProfile, validateDogDetailProfile } from '~utils/validateDogProfile.ts' +import GenderSelectButton from '~components/GenderSelectButton/index.tsx' +import TwoLineInput from '~components/Input/TwoLineInput/index.tsx' +import Toast from '~components/Toast/index.tsx' +import { ActionButton } from '~components/Button/ActionButton.ts' +import Check from '~assets/is-neutered-check.svg' +import DogImageUploader from './DogImageUploader.tsx' +import DatePickerModal from '~modals/DatePickerModal/index.tsx' +import { dateToString, stringToDate } from '~utils/dateFormat.ts' + +export default function EditDogProfile() { + const { popModal, pushModal } = useModalStore() + const { showToast } = useToastStore() + const { dogProfile, setDogProfile } = useDogProfileStore() + + const [displayValue, setDisplayValue] = useState(dogProfile.weight && dogProfile.weight + 'kg') + const [inputType, setInputType] = useState('text') + + const handleGenderSelect = (gender: 'MALE' | 'FEMALE') => { + setDogProfile({ gender }) + } + + const onChangeWeightInput = (e: React.ChangeEvent) => { + const value = e.target.value + if (value === '') { + setDogProfile({ weight: 0 }) + setDisplayValue('') + return + } + + if (/^\d*\.?\d*$/.test(value)) { + const formatted = value.includes('.') ? value.match(/^\d*\.?\d{0,2}/)![0] : value + + setDogProfile({ weight: Number(formatted) }) + setDisplayValue(inputType === 'number' ? formatted : `${formatted}kg`) + } + } + + const handleFocus = () => { + setInputType('number') + setDisplayValue(dogProfile.weight?.toString()) + } + + const handleBlur = () => { + setInputType('text') + if (dogProfile.weight) { + setDisplayValue(`${dogProfile.weight}kg`) + } + } + + const handleDatePickerOpen = () => { + pushModal( + setDogProfile({ birthDate: dateToString(date) })} + /> + ) + } + + const handleComfirmClick = async () => { + let alertMessage = validateDogProfile(dogProfile) + if (alertMessage) { + showToast(alertMessage) + return + } + alertMessage = validateDogDetailProfile(dogProfile) + if (alertMessage) { + showToast(alertMessage) + return + } + + // const formData = new FormData() + // const requestData = { + // ...dogProfile, + // famliyId: null, + // } + // formData.append( + // 'request', + // new Blob([JSON.stringify(requestData)], { + // type: 'application/json', + // }) + // ) + // if (dogProfile.profileImgFile) formData.append('profileImgFile', dogProfile.profileImgFile) + // createDogProfile.mutate(formData) + } + + return ( + +
popModal()} prevBtn /> + + + 반려견 정보 수정 + + + setDogProfile(update)} /> + + setDogProfile({ name: e.target.value })} + /> + pushModal()} $hasBreed={!!dogProfile.breed}> + {dogProfile.breed || '견종 입력'} + + + {dogProfile.birthDate?.split('-').join('. ') || '생년월일 선택'} + + + + + + handleGenderSelect('MALE')} + /> + handleGenderSelect('FEMALE')} + /> + + setDogProfile({ isNeutered: dogProfile.isNeutered == 'TRUE' ? 'FALSE' : 'TRUE' })} + > + + {dogProfile.isNeutered == 'TRUE' && check} + + 중성화 했어요 + + + + setDogProfile({ comment: e.target.value })} + > + 한줄 소개 입력 + + + + + 확인 + + + + + ) +} diff --git a/src/modals/EditDogProfileModal/styles.ts b/src/modals/EditDogProfileModal/styles.ts new file mode 100644 index 00000000..eef5a614 --- /dev/null +++ b/src/modals/EditDogProfileModal/styles.ts @@ -0,0 +1,205 @@ +import styled from 'styled-components' + +export const EditDogProfileModal = styled.div` + overflow-y: auto; + padding: 90px 20px 24px 20px; + background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + + display: flex; + flex-direction: column; + gap: 20px; + + &::-webkit-scrollbar { + display: none; + } + @media (max-height: 700px) { + padding: 100px 20px 24px 20px; + } +` + +export const PrevBtnWrapper = styled.div` + height: 56px; + + @media (max-height: 700px) { + margin-bottom: 10px; + } +` + +export const TypoWrapper = styled.div` + text-align: center; + margin-bottom: 30px; +` + +export const AddDogPictureBtnWrapper = styled.div` + display: flex; + justify-content: center; + align-content: center; + flex-direction: column; + gap: 16px; +` +export const AddPicture = styled.button` + background-color: black; + color: ${props => props.theme.colors.grayscale.gc_4}; + width: 75px; + height: 32px; + border-radius: 30px; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + align-self: center; +` + +export const AddDogPictureBtn = styled.div` + align-self: center; + position: relative; + overflow: hidden; + width: 180px; + height: 180px; + background-color: ${({ theme }) => theme.colors.brand.lighten_2}; + border-radius: 50%; + + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 0.5rem; + + font-weight: 700; + color: ${({ theme }) => theme.colors.brand.darken}; +` + +export const HiddenFileInput = styled.input` + display: none; +` + +export const DogImage = styled.img<{ $hasImage: boolean }>` + background-color: ${props => props.theme.colors.grayscale.gc_4}; + border: solid 2px ${props => props.theme.colors.grayscale.gc_2}; + position: absolute; + z-index: ${({ $hasImage }) => ($hasImage ? '100' : '-100')}; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; +` + +export const InputArea = styled.div` + margin-top: 15px; + display: flex; + flex-direction: column; + gap: 10px; +` + +export const NameInput = styled.input` + width: 100%; + border: none; + text-align: center; + padding: 17px 32px; + border-radius: 12px; + font-size: ${({ theme }) => theme.typography._20}; + font-weight: 700; + &:focus { + box-shadow: ${({ theme }) => `inset 0 0 0 1px ${theme.colors.grayscale.font_1}`}; + } + &::placeholder { + font-weight: 400; + } +` + +export const PickerBtn = styled.div<{ $hasBreed: boolean }>` + width: 100%; + border: none; + text-align: center; + padding: 17px 32px; + font-size: ${({ theme }) => theme.typography._20}; + color: ${({ theme, $hasBreed }) => ($hasBreed ? 'black' : theme.colors.grayscale.font_3)}; + font-weight: ${({ $hasBreed }) => ($hasBreed ? 'bold' : 'default')}; + cursor: pointer; +` + +export const DatePickerBtn = styled.div<{ $hasBirth: boolean }>` + width: 100%; + border: none; + text-align: center; + padding: 17px 32px; + font-size: ${({ theme }) => theme.typography._20}; + color: ${({ theme, $hasBirth }) => ($hasBirth ? 'black' : theme.colors.grayscale.font_3)}; + font-weight: ${({ $hasBirth }) => ($hasBirth ? '700' : '400')}; + cursor: pointer; +` + +export const WeightInput = styled.input<{ $hasWeight: boolean }>` + width: 100%; + border: none; + text-align: center; + padding: 17px 32px; + border-radius: 12px; + font-size: ${({ theme }) => theme.typography._20}; + font-weight: ${({ $hasWeight }) => ($hasWeight ? 'bold' : 'default')}; + &:focus { + box-shadow: ${({ theme }) => `inset 0 0 0 1px ${theme.colors.grayscale.font_1}`}; + } + + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + &[type='number'] { + -moz-appearance: textfield; + } +` + +export const GenderBtnArea = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +` + +export const GenderSelectBtnWrapper = styled.div` + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.5rem; +` + +export const CheckboxWrapper = styled.div` + display: flex; + justify-content: center; + gap: 0.5rem; + margin-bottom: 20px; +` + +export const CheckboxCircle = styled.div<{ $isChecked: boolean }>` + border: solid 1px red; + width: 24px; + height: 24px; + border: 2px solid ${({ $isChecked }) => ($isChecked ? '#000' : '#ccc')}; + border-radius: 50%; + + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; +` + +export const CheckboxLabel = styled.span<{ $isChecked: boolean }>` + color: ${({ $isChecked }) => ($isChecked ? '#000' : '#ccc')}; +` + +export const TwoLineinputWrapper = styled.div` + height: 100px; + margin-bottom: 10px; +` + +export const ToastWrapper = styled.div` + position: relative; +` diff --git a/src/modals/RegisterDogModal/DogProfileSection/styles.ts b/src/modals/RegisterDogModal/DogProfileSection/styles.ts index 92983e3f..8b40b540 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/styles.ts +++ b/src/modals/RegisterDogModal/DogProfileSection/styles.ts @@ -60,6 +60,8 @@ export const HiddenFileInput = styled.input` ` export const DogImage = styled.img<{ $hasImage: boolean }>` + background-color: ${props => props.theme.colors.grayscale.gc_4}; + border: solid 2px ${props => props.theme.colors.grayscale.gc_2}; position: absolute; z-index: ${({ $hasImage }) => ($hasImage ? '100' : '-100')}; top: 0; diff --git a/src/pages/HomePage/index.tsx b/src/pages/HomePage/index.tsx index bb5fc1f1..ec2d4126 100644 --- a/src/pages/HomePage/index.tsx +++ b/src/pages/HomePage/index.tsx @@ -19,10 +19,15 @@ import { useModalStore } from '~stores/modalStore' import * as S from './styles' import { useSearchParams, useNavigate } from 'react-router-dom' import { useEffect } from 'react' +import { useDogProfileStore } from '~stores/dogProfileStore' function HomeContent() { const { data } = useHomePageData() const { pushModal } = useModalStore() + const { dogProfile } = useDogProfileStore() + useEffect(() => { + console.log(dogProfile) + }, []) return ( <> diff --git a/src/pages/RegisterPage/Dog/index.tsx b/src/pages/RegisterPage/Dog/index.tsx index dd7a8685..5e3a80aa 100644 --- a/src/pages/RegisterPage/Dog/index.tsx +++ b/src/pages/RegisterPage/Dog/index.tsx @@ -6,6 +6,7 @@ import addDogProfile from '~assets/add-dog-profile.svg' import addFamilycode from '~assets/add-family-code.svg' import DogProfileSection from '~modals/RegisterDogModal/DogProfileSection' import FamilyCodeSection from '~modals/RegisterDogModal/FamilyCodeSection' +import EditDogProfile from '~modals/EditDogProfileModal' export default function RegisterDogPage() { return ( @@ -25,7 +26,7 @@ export default function RegisterDogPage() { title='반려견 프로필 추가하기' description='반려견 프로필을 추가해보세요' src={addDogProfile} - modal={} + modal={} /> (set => ({ dogProfile: { + dogId: 0, name: '', profileImg: '', profileImgFile: undefined, From d957b556e086121ea4f1aae3f9e68eb6e33f3ada Mon Sep 17 00:00:00 2001 From: wonil Date: Sat, 7 Dec 2024 21:39:42 +0900 Subject: [PATCH 06/19] =?UTF-8?q?=E2=9C=A8=20=20=EA=B0=95=EC=95=84?= =?UTF-8?q?=EC=A7=80=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/dog/createDogProfile.ts | 6 +- src/apis/dog/patchDogProfile.ts | 44 ++++++++ src/apis/dog/useCreateDogProfile.ts | 27 ----- src/apis/dog/useDogProfile.ts | 56 ++++++++++ src/constants/queryKey.ts | 3 + src/modals/EditDogProfileModal/index.tsx | 100 +++++++++++------- .../DogProfileDetailSection/index.tsx | 2 +- src/types/dogProfile.ts | 1 + 8 files changed, 166 insertions(+), 73 deletions(-) create mode 100644 src/apis/dog/patchDogProfile.ts delete mode 100644 src/apis/dog/useCreateDogProfile.ts create mode 100644 src/apis/dog/useDogProfile.ts diff --git a/src/apis/dog/createDogProfile.ts b/src/apis/dog/createDogProfile.ts index 5520af27..5996e0aa 100644 --- a/src/apis/dog/createDogProfile.ts +++ b/src/apis/dog/createDogProfile.ts @@ -1,13 +1,11 @@ import { AxiosError } from 'axios' import { APIResponse, ErrorResponse, CommonAPIResponse } from '~types/api' import { axiosInstance } from '~apis/axiosInstance' +import { DogProfileType } from '~types/dogProfile' export type CreateDogProfileRequest = FormData -export type CreateDogProfileResponse = Pick< - CommonAPIResponse, - 'dogId' | 'name' | 'breed' | 'birthDate' | 'weight' | 'gender' | 'profileImg' -> +export type CreateDogProfileResponse = DogProfileType /** * 새로운 반려견 프로필을 생성합니다. diff --git a/src/apis/dog/patchDogProfile.ts b/src/apis/dog/patchDogProfile.ts new file mode 100644 index 00000000..a9ea174f --- /dev/null +++ b/src/apis/dog/patchDogProfile.ts @@ -0,0 +1,44 @@ +import { AxiosError } from 'axios' +import { APIResponse, ErrorResponse } from '~types/api' +import { axiosInstance } from '~apis/axiosInstance' +import { DogProfileType } from '~types/dogProfile' + +export type PatchDogProfileRequest = FormData + +export type PatchDogProfileResponse = DogProfileType + +/** + * 반려견 프로필 정보를 수정합니다. + */ +export const patchDogProfile = async ( + id: number, + req: PatchDogProfileRequest +): Promise> => { + try { + const { data } = await axiosInstance.patch>(`/dogs/${id}`, req) + return data + } catch (error) { + if (error instanceof AxiosError) { + const { response } = error as AxiosError + + if (response) { + const { code, message } = response.data + switch (code) { + case 400: + throw new Error(message || '잘못된 요청입니다.') + case 401: + throw new Error(message || '인증에 실패했습니다.') + case 500: + throw new Error(message || '서버 오류가 발생했습니다.') + default: + throw new Error(message || '알 수 없는 오류가 발생했습니다.') + } + } + + throw new Error('네트워크 연결을 확인해주세요') + } + + console.error('예상치 못한 에러:', error) + throw new Error('다시 시도해주세요') + } +} diff --git a/src/apis/dog/useCreateDogProfile.ts b/src/apis/dog/useCreateDogProfile.ts deleted file mode 100644 index ce909404..00000000 --- a/src/apis/dog/useCreateDogProfile.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { useMutation } from '@tanstack/react-query' -import { createDogProfile } from '~apis/dog/createDogProfile' -import { useNavigate } from 'react-router-dom' -import { useModalStore } from '~stores/modalStore' -import { useToastStore } from '~stores/toastStore' -import { useDogProfileStore } from '~stores/dogProfileStore' - -export function useCreateDogProfile() { - const navigate = useNavigate() - const { clearModal } = useModalStore() - const { showToast } = useToastStore() - const { setDogProfile } = useDogProfileStore() - - return useMutation({ - mutationFn: (formData: FormData) => createDogProfile(formData), - onSuccess: response => { - console.log(response.data) - setDogProfile({ ...response.data }) - alert('반려견 등록 완료') - clearModal() - navigate('/') - }, - onError: (error: Error) => { - showToast(error.message) - }, - }) -} diff --git a/src/apis/dog/useDogProfile.ts b/src/apis/dog/useDogProfile.ts new file mode 100644 index 00000000..b7f15440 --- /dev/null +++ b/src/apis/dog/useDogProfile.ts @@ -0,0 +1,56 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { createDogProfile } from '~apis/dog/createDogProfile' +import { useNavigate } from 'react-router-dom' +import { useModalStore } from '~stores/modalStore' +import { useToastStore } from '~stores/toastStore' +import { useDogProfileStore } from '~stores/dogProfileStore' +import { useSuspenseQuery } from '@tanstack/react-query' +import { fetchDogProfile } from '~apis/dog/fetchDogProfile' +import { queryKey } from '~constants/queryKey' +import { patchDogProfile, PatchDogProfileRequest } from '~apis/dog/patchDogProfile' + +export function useCreateDogProfile() { + const navigate = useNavigate() + const { clearModal } = useModalStore() + const { showToast } = useToastStore() + const { setDogProfile } = useDogProfileStore() + + return useMutation({ + mutationFn: (formData: FormData) => createDogProfile(formData), + onSuccess: response => { + console.log(response.data) + setDogProfile({ ...response.data }) + alert('반려견 등록 완료') + clearModal() + navigate('/') + }, + onError: (error: Error) => { + showToast(error.message) + }, + }) +} + +export function useFetchDogProfile(id: number) { + return useSuspenseQuery({ + queryKey: queryKey.dog.profile(id), + queryFn: () => fetchDogProfile({ id }).then(res => res.data), + }) +} + +export function usePatchDogProfile(id: number) { + const { popModal } = useModalStore() + const { showToast } = useToastStore() + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: (data: PatchDogProfileRequest) => patchDogProfile(id, data), + onSuccess: () => { + alert('반려견 정보가 수정되었습니다') + queryClient.invalidateQueries({ queryKey: queryKey.dog.profile(id) }) + popModal() + }, + onError: (error: Error) => { + showToast(error.message) + }, + }) +} diff --git a/src/constants/queryKey.ts b/src/constants/queryKey.ts index deba03bc..04c793f5 100644 --- a/src/constants/queryKey.ts +++ b/src/constants/queryKey.ts @@ -6,4 +6,7 @@ export const queryKey = { profile: (memberId: number) => ['profile', memberId], home: () => ['homePageData'], notification: () => ['notification'], + dog: { + profile: (id: number) => ['dog', 'profile', id], + }, } diff --git a/src/modals/EditDogProfileModal/index.tsx b/src/modals/EditDogProfileModal/index.tsx index 908a4e85..de69c8cb 100644 --- a/src/modals/EditDogProfileModal/index.tsx +++ b/src/modals/EditDogProfileModal/index.tsx @@ -1,37 +1,44 @@ -import { useState } from 'react' -import { Typo24 } from '~components/Typo/index.ts' -import * as S from './styles.ts' -import { useDogProfileStore } from '~stores/dogProfileStore.ts' -import { useModalStore } from '~stores/modalStore.ts' -import SearchModal from '~modals/SearchModal/index.tsx' -import { useToastStore } from '~stores/toastStore.ts' -import Header from '~components/Header/index.tsx' -import { validateDogProfile, validateDogDetailProfile } from '~utils/validateDogProfile.ts' -import GenderSelectButton from '~components/GenderSelectButton/index.tsx' -import TwoLineInput from '~components/Input/TwoLineInput/index.tsx' -import Toast from '~components/Toast/index.tsx' -import { ActionButton } from '~components/Button/ActionButton.ts' +import { useState, useEffect } from 'react' +import { Typo24 } from '~components/Typo/index' +import * as S from './styles' +import { useModalStore } from '~stores/modalStore' +import SearchModal from '~modals/SearchModal/index' +import { useToastStore } from '~stores/toastStore' +import Header from '~components/Header/index' +import { validateDogProfile, validateDogDetailProfile } from '~utils/validateDogProfile' +import GenderSelectButton from '~components/GenderSelectButton/index' +import TwoLineInput from '~components/Input/TwoLineInput/index' +import Toast from '~components/Toast/index' +import { ActionButton } from '~components/Button/ActionButton' import Check from '~assets/is-neutered-check.svg' -import DogImageUploader from './DogImageUploader.tsx' -import DatePickerModal from '~modals/DatePickerModal/index.tsx' -import { dateToString, stringToDate } from '~utils/dateFormat.ts' +import DogImageUploader from './DogImageUploader' +import DatePickerModal from '~modals/DatePickerModal/index' +import { dateToString, stringToDate } from '~utils/dateFormat' +import { DogProfileType } from '~types/dogProfile' +// import { patchDogProfile } from '~apis/dog/patchDogProfile' +import { usePatchDogProfile } from '~apis/dog/useDogProfile' -export default function EditDogProfile() { +interface EditDogProfileProps { + initialDogProfile: DogProfileType +} + +export default function EditDogProfileModal({ initialDogProfile }: EditDogProfileProps) { const { popModal, pushModal } = useModalStore() const { showToast } = useToastStore() - const { dogProfile, setDogProfile } = useDogProfileStore() - const [displayValue, setDisplayValue] = useState(dogProfile.weight && dogProfile.weight + 'kg') + const [dogProfile, setDogProfile] = useState(initialDogProfile) + const [displayValue, setDisplayValue] = useState(initialDogProfile.weight + 'kg') const [inputType, setInputType] = useState('text') + const patchDogProfileMutation = usePatchDogProfile(dogProfile.dogId) const handleGenderSelect = (gender: 'MALE' | 'FEMALE') => { - setDogProfile({ gender }) + setDogProfile(prev => ({ ...prev, gender })) } const onChangeWeightInput = (e: React.ChangeEvent) => { const value = e.target.value if (value === '') { - setDogProfile({ weight: 0 }) + setDogProfile(prev => ({ ...prev, weight: 0 })) setDisplayValue('') return } @@ -39,14 +46,14 @@ export default function EditDogProfile() { if (/^\d*\.?\d*$/.test(value)) { const formatted = value.includes('.') ? value.match(/^\d*\.?\d{0,2}/)![0] : value - setDogProfile({ weight: Number(formatted) }) + setDogProfile(prev => ({ ...prev, weight: Number(formatted) })) setDisplayValue(inputType === 'number' ? formatted : `${formatted}kg`) } } const handleFocus = () => { setInputType('number') - setDisplayValue(dogProfile.weight?.toString()) + setDisplayValue(dogProfile.weight?.toString() || '') } const handleBlur = () => { @@ -60,7 +67,7 @@ export default function EditDogProfile() { pushModal( setDogProfile({ birthDate: dateToString(date) })} + setDate={date => setDogProfile(prev => ({ ...prev, birthDate: dateToString(date) }))} /> ) } @@ -77,19 +84,19 @@ export default function EditDogProfile() { return } - // const formData = new FormData() - // const requestData = { - // ...dogProfile, - // famliyId: null, - // } - // formData.append( - // 'request', - // new Blob([JSON.stringify(requestData)], { - // type: 'application/json', - // }) - // ) - // if (dogProfile.profileImgFile) formData.append('profileImgFile', dogProfile.profileImgFile) - // createDogProfile.mutate(formData) + const formData = new FormData() + const requestData = { + ...dogProfile, + famliyId: null, + } + formData.append( + 'request', + new Blob([JSON.stringify(requestData)], { + type: 'application/json', + }) + ) + if (dogProfile.profileImgFile) formData.append('profileImgFile', dogProfile.profileImgFile) + patchDogProfileMutation.mutate(formData) } return ( @@ -100,12 +107,21 @@ export default function EditDogProfile() { 반려견 정보 수정 - setDogProfile(update)} /> + + setDogProfile(prev => ({ + ...prev, + profileImg, + profileImgFile, + })) + } + /> setDogProfile({ name: e.target.value })} + onChange={e => setDogProfile(prev => ({ ...prev, name: e.target.value }))} /> pushModal()} $hasBreed={!!dogProfile.breed}> {dogProfile.breed || '견종 입력'} @@ -137,7 +153,9 @@ export default function EditDogProfile() { /> setDogProfile({ isNeutered: dogProfile.isNeutered == 'TRUE' ? 'FALSE' : 'TRUE' })} + onClick={() => + setDogProfile(prev => ({ ...prev, isNeutered: dogProfile.isNeutered == 'TRUE' ? 'FALSE' : 'TRUE' })) + } > {dogProfile.isNeutered == 'TRUE' && check} @@ -149,7 +167,7 @@ export default function EditDogProfile() { setDogProfile({ comment: e.target.value })} + onChange={e => setDogProfile(prev => ({ ...prev, comment: e.target.value }))} > 한줄 소개 입력 diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index 3cada66c..5bfc35d0 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -7,7 +7,7 @@ import Header from '~components/Header/index' import Toast from '~components/Toast' import { Typo24 } from '~components/Typo/index' import SearchModal from '~modals/SearchModal' -import { useCreateDogProfile } from '~apis/dog/useCreateDogProfile' +import { useCreateDogProfile } from '~apis/dog/useDogProfile' import { useModalStore } from '~stores/modalStore' import { useToastStore } from '~stores/toastStore' import { validateDogDetailProfile } from '~utils/validateDogProfile' diff --git a/src/types/dogProfile.ts b/src/types/dogProfile.ts index 3a4c4c8d..0e8a26dc 100644 --- a/src/types/dogProfile.ts +++ b/src/types/dogProfile.ts @@ -1,6 +1,7 @@ import { BooleanString, Gender } from './common' export interface DogProfileType { + dogId: number name: string profileImg: string profileImgFile?: File From 0a4e3fc18fcb65f282ff68b0515f058ad1dcd45f Mon Sep 17 00:00:00 2001 From: wonil Date: Sun, 8 Dec 2024 07:58:27 +0900 Subject: [PATCH 07/19] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EB=B0=98=EB=A0=A4?= =?UTF-8?q?=EA=B2=AC=20=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/dog/patchDogProfile.ts | 6 +- src/apis/dog/useDogProfile.ts | 2 +- src/apis/myPage/useMyPage.ts | 10 ++ src/components/DogProfile/index.tsx | 28 +++--- src/components/DogProfile/styles.ts | 28 ++++++ src/constants/queryKey.ts | 1 + src/modals/EditDogProfileModal/index.tsx | 91 ++++++++++++------- .../DogProfileDetailSection/index.tsx | 5 +- src/modals/SearchModal/index.tsx | 9 +- src/pages/FamilyDDangPage/index.tsx | 18 ++-- src/pages/RegisterPage/Dog/index.tsx | 3 +- 11 files changed, 132 insertions(+), 69 deletions(-) create mode 100644 src/apis/myPage/useMyPage.ts diff --git a/src/apis/dog/patchDogProfile.ts b/src/apis/dog/patchDogProfile.ts index a9ea174f..24683a28 100644 --- a/src/apis/dog/patchDogProfile.ts +++ b/src/apis/dog/patchDogProfile.ts @@ -15,7 +15,11 @@ export const patchDogProfile = async ( req: PatchDogProfileRequest ): Promise> => { try { - const { data } = await axiosInstance.patch>(`/dogs/${id}`, req) + const { data } = await axiosInstance.patch>(`/dogs/${id}`, req, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }) return data } catch (error) { if (error instanceof AxiosError) { diff --git a/src/apis/dog/useDogProfile.ts b/src/apis/dog/useDogProfile.ts index b7f15440..0727dd5d 100644 --- a/src/apis/dog/useDogProfile.ts +++ b/src/apis/dog/useDogProfile.ts @@ -1,4 +1,4 @@ -import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { useMutation, useQueryClient } from '@tanstack/react-query' import { createDogProfile } from '~apis/dog/createDogProfile' import { useNavigate } from 'react-router-dom' import { useModalStore } from '~stores/modalStore' diff --git a/src/apis/myPage/useMyPage.ts b/src/apis/myPage/useMyPage.ts new file mode 100644 index 00000000..d4f5c81f --- /dev/null +++ b/src/apis/myPage/useMyPage.ts @@ -0,0 +1,10 @@ +import { useSuspenseQuery } from '@tanstack/react-query' +import { fetchMypage } from '~apis/myPage/fetchMypage' +import { queryKey } from '~constants/queryKey' + +export function useMyPage() { + return useSuspenseQuery({ + queryKey: queryKey.myPage(), + queryFn: () => fetchMypage().then(res => res.data), + }) +} diff --git a/src/components/DogProfile/index.tsx b/src/components/DogProfile/index.tsx index 7a1bc100..0cb3c187 100644 --- a/src/components/DogProfile/index.tsx +++ b/src/components/DogProfile/index.tsx @@ -3,26 +3,21 @@ import { Typo13, Typo15, Typo20 } from '~components/Typo' import { Separator } from '~components/Separator' import Profile from '~components/Profile' import { DogProfileType } from '~types/dogProfile' -import { stringToDate } from '~utils/dateFormat' +import { MdOutlineModeEdit } from 'react-icons/md' +import { useModalStore } from '~stores/modalStore' +import EditDogProfileModal from '~modals/EditDogProfileModal' +import { calculateAge } from '~utils/calculateAge' -//날짜 계산 로직 -const calculateAge = (birthDate?: Date): number => { - if (!birthDate) return 0 - const today = new Date() - const birth = new Date(birthDate) - let age = today.getFullYear() - birth.getFullYear() - const monthDiff = today.getMonth() - birth.getMonth() - - if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) { - age-- - } - return age -} -export default function DogProfile({ name, gender, profileImg, birthDate, breed, comment }: DogProfileType) { - const age = calculateAge(stringToDate(birthDate!)) +export default function DogProfile({ ...dogInfo }: DogProfileType) { + const { dogId, name, gender, profileImg, birthDate, breed, comment } = dogInfo + const age = calculateAge(birthDate!) + const { pushModal } = useModalStore() return ( + pushModal()}> + + @@ -35,7 +30,6 @@ export default function DogProfile({ name, gender, profileImg, birthDate, breed, - 우리 댕댕이를 소개해요! diff --git a/src/components/DogProfile/styles.ts b/src/components/DogProfile/styles.ts index c46dbce4..6d30d79c 100644 --- a/src/components/DogProfile/styles.ts +++ b/src/components/DogProfile/styles.ts @@ -7,6 +7,20 @@ export const TypoWrapper = styled.div<{ $gap?: number }>` gap: ${({ $gap = 4 }) => $gap}px; ` +export const EditIconWrapper = styled.div` + position: absolute; + right: 48px; + width: 2rem; + height: 2rem; + background-color: ${({ theme }) => theme.colors.brand.lighten_2}; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + margin-left: auto; +` + export const DogInfoArea = styled(Box)` padding: 16px 20px; ` @@ -20,6 +34,7 @@ export const DogDetailWrapper = styled.div` display: flex; flex-direction: column; ` + export const OneLineIntro = styled(Box)` margin-top: 12px; display: flex; @@ -33,3 +48,16 @@ export const OneLineIntro = styled(Box)` display: none; } ` + +export const InviteBtn = styled.button` + width: 57px; + height: 36px; + display: flex; + padding: 0.5rem; + border-radius: 0.75rem; + background: #ecf9da; + color: ${({ theme }) => theme.colors.brand.sub}; + line-height: 150%; + justify-content: center; + cursor: pointer; +` diff --git a/src/constants/queryKey.ts b/src/constants/queryKey.ts index 18aa7b41..f9ae9d25 100644 --- a/src/constants/queryKey.ts +++ b/src/constants/queryKey.ts @@ -17,4 +17,5 @@ export const queryKey = { totalWalks: () => ['totalWalks'], currentMonthWalks: () => ['currentMonthWalks'], }, + myPage: () => ['myPage'], } diff --git a/src/modals/EditDogProfileModal/index.tsx b/src/modals/EditDogProfileModal/index.tsx index de69c8cb..6c2cfe0d 100644 --- a/src/modals/EditDogProfileModal/index.tsx +++ b/src/modals/EditDogProfileModal/index.tsx @@ -1,44 +1,65 @@ import { useState, useEffect } from 'react' -import { Typo24 } from '~components/Typo/index' -import * as S from './styles' -import { useModalStore } from '~stores/modalStore' -import SearchModal from '~modals/SearchModal/index' -import { useToastStore } from '~stores/toastStore' -import Header from '~components/Header/index' -import { validateDogProfile, validateDogDetailProfile } from '~utils/validateDogProfile' +import { usePatchDogProfile } from '~apis/dog/useDogProfile' +import Check from '~assets/is-neutered-check.svg' +import { ActionButton } from '~components/Button/ActionButton' import GenderSelectButton from '~components/GenderSelectButton/index' +import Header from '~components/Header/index' import TwoLineInput from '~components/Input/TwoLineInput/index' import Toast from '~components/Toast/index' -import { ActionButton } from '~components/Button/ActionButton' -import Check from '~assets/is-neutered-check.svg' -import DogImageUploader from './DogImageUploader' +import { Typo24 } from '~components/Typo/index' import DatePickerModal from '~modals/DatePickerModal/index' +import SearchModal from '~modals/SearchModal/index' +import { useModalStore } from '~stores/modalStore' +import { useToastStore } from '~stores/toastStore' import { dateToString, stringToDate } from '~utils/dateFormat' +import { validateDogDetailProfile, validateDogProfile } from '~utils/validateDogProfile' +import DogImageUploader from './DogImageUploader' +import * as S from './styles' +import { useMyPage } from '~apis/myPage/useMyPage' import { DogProfileType } from '~types/dogProfile' -// import { patchDogProfile } from '~apis/dog/patchDogProfile' -import { usePatchDogProfile } from '~apis/dog/useDogProfile' -interface EditDogProfileProps { - initialDogProfile: DogProfileType +interface EditDogProfileModalProps { + dogId: number } -export default function EditDogProfileModal({ initialDogProfile }: EditDogProfileProps) { +export default function EditDogProfileModal({ dogId }: EditDogProfileModalProps) { + const { data, refetch } = useMyPage() + const [dogProfile, setDogProfile] = useState(null) + const patchDogProfileMutation = usePatchDogProfile(dogId) const { popModal, pushModal } = useModalStore() const { showToast } = useToastStore() - - const [dogProfile, setDogProfile] = useState(initialDogProfile) - const [displayValue, setDisplayValue] = useState(initialDogProfile.weight + 'kg') + const [displayValue, setDisplayValue] = useState('') const [inputType, setInputType] = useState('text') - const patchDogProfileMutation = usePatchDogProfile(dogProfile.dogId) + + useEffect(() => { + if (data?.dog) { + setDogProfile(data.dog) + setDisplayValue(data.dog.weight ? `${data.dog.weight}kg` : '') + } else refetch() + }, [data]) + + if (!dogProfile) { + return null + } + + const updateDogProfile = (update: Partial) => { + setDogProfile(prev => { + if (!prev) return null + return { + ...prev, + ...update, + } as DogProfileType + }) + } const handleGenderSelect = (gender: 'MALE' | 'FEMALE') => { - setDogProfile(prev => ({ ...prev, gender })) + updateDogProfile({ gender }) } const onChangeWeightInput = (e: React.ChangeEvent) => { const value = e.target.value if (value === '') { - setDogProfile(prev => ({ ...prev, weight: 0 })) + updateDogProfile({ weight: undefined }) setDisplayValue('') return } @@ -46,7 +67,7 @@ export default function EditDogProfileModal({ initialDogProfile }: EditDogProfil if (/^\d*\.?\d*$/.test(value)) { const formatted = value.includes('.') ? value.match(/^\d*\.?\d{0,2}/)![0] : value - setDogProfile(prev => ({ ...prev, weight: Number(formatted) })) + updateDogProfile({ weight: Number(formatted) }) setDisplayValue(inputType === 'number' ? formatted : `${formatted}kg`) } } @@ -67,18 +88,18 @@ export default function EditDogProfileModal({ initialDogProfile }: EditDogProfil pushModal( setDogProfile(prev => ({ ...prev, birthDate: dateToString(date) }))} + setDate={date => updateDogProfile({ birthDate: dateToString(date) })} /> ) } const handleComfirmClick = async () => { - let alertMessage = validateDogProfile(dogProfile) + let alertMessage = validateDogProfile(dogProfile!) if (alertMessage) { showToast(alertMessage) return } - alertMessage = validateDogDetailProfile(dogProfile) + alertMessage = validateDogDetailProfile(dogProfile!) if (alertMessage) { showToast(alertMessage) return @@ -108,22 +129,24 @@ export default function EditDogProfileModal({ initialDogProfile }: EditDogProfil - setDogProfile(prev => ({ - ...prev, + updateDogProfile({ profileImg, profileImgFile, - })) + }) } /> setDogProfile(prev => ({ ...prev, name: e.target.value }))} + onChange={e => updateDogProfile({ name: e.target.value })} /> - pushModal()} $hasBreed={!!dogProfile.breed}> + pushModal( updateDogProfile(update)} />)} + $hasBreed={!!dogProfile.breed} + > {dogProfile.breed || '견종 입력'} @@ -153,9 +176,7 @@ export default function EditDogProfileModal({ initialDogProfile }: EditDogProfil /> - setDogProfile(prev => ({ ...prev, isNeutered: dogProfile.isNeutered == 'TRUE' ? 'FALSE' : 'TRUE' })) - } + onClick={() => updateDogProfile({ isNeutered: dogProfile.isNeutered == 'TRUE' ? 'FALSE' : 'TRUE' })} > {dogProfile.isNeutered == 'TRUE' && check} @@ -167,7 +188,7 @@ export default function EditDogProfileModal({ initialDogProfile }: EditDogProfil setDogProfile(prev => ({ ...prev, comment: e.target.value }))} + onChange={e => updateDogProfile({ comment: e.target.value })} > 한줄 소개 입력 diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index 5bfc35d0..4158bb2b 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -108,7 +108,10 @@ export default function DogProfileDetailSection() { - pushModal()} $hasBreed={!!dogProfile.breed}> + pushModal()} + $hasBreed={!!dogProfile.breed} + > {dogProfile.breed || '견종 입력'} ) => void +} + +export default function SearchModal({ setDogProfile }: SearchModalProps) { const { popModal } = useModalStore() const [searchTerm, setSearchTerm] = useState('') const [searchResults, setSearchResults] = useState([]) diff --git a/src/pages/FamilyDDangPage/index.tsx b/src/pages/FamilyDDangPage/index.tsx index b9a86a94..21dc4ec5 100644 --- a/src/pages/FamilyDDangPage/index.tsx +++ b/src/pages/FamilyDDangPage/index.tsx @@ -6,20 +6,20 @@ import CountSection from '~components/WalkCountArea' import { Avatar10, Avatar3 } from '~assets/avatars' import Profile from '~components/Profile' import DogProfile from '~components/DogProfile' -import { useQuery } from '@tanstack/react-query' -import { fetchMypage, FetchMypageResponse } from '~apis/myPage/fetchMypage' -import { APIResponse } from '~types/api' import { useModalStore } from '~stores/modalStore' import ShareCodeModal from '~modals/FamilyDDangModal/ShareCodeModal' +import { useMyPage } from '~apis/myPage/useMyPage' +import { useEffect } from 'react' export default function FamilyDDang() { - const { data } = useQuery>({ - queryKey: ['myPage'], - queryFn: fetchMypage, - }) - const dogInfo = data?.data?.dog + const { data, refetch } = useMyPage() + const dogInfo = data?.dog - const { pushModal } = useModalStore() + const { pushModal, modalList } = useModalStore() + + useEffect(() => { + refetch() + }, [modalList]) const onClickCodeShare = () => { pushModal() diff --git a/src/pages/RegisterPage/Dog/index.tsx b/src/pages/RegisterPage/Dog/index.tsx index 5e3a80aa..dd7a8685 100644 --- a/src/pages/RegisterPage/Dog/index.tsx +++ b/src/pages/RegisterPage/Dog/index.tsx @@ -6,7 +6,6 @@ import addDogProfile from '~assets/add-dog-profile.svg' import addFamilycode from '~assets/add-family-code.svg' import DogProfileSection from '~modals/RegisterDogModal/DogProfileSection' import FamilyCodeSection from '~modals/RegisterDogModal/FamilyCodeSection' -import EditDogProfile from '~modals/EditDogProfileModal' export default function RegisterDogPage() { return ( @@ -26,7 +25,7 @@ export default function RegisterDogPage() { title='반려견 프로필 추가하기' description='반려견 프로필을 추가해보세요' src={addDogProfile} - modal={} + modal={} /> Date: Sun, 8 Dec 2024 19:57:39 +0900 Subject: [PATCH 08/19] =?UTF-8?q?=F0=9F=8E=A8=20Design:=20=EA=B0=80?= =?UTF-8?q?=EC=A1=B1=20=EC=B4=88=EB=8C=80=EC=BD=94=EB=93=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=8E=98=EC=9D=B4=EC=A7=80=20UI=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/family-invitaion.svg | 16 +++++ src/assets/familyddang-join.svg | 24 +++++++ .../FamilyDDangModal/ShareCodeModal/index.tsx | 18 ++++- .../FamilyDDangModal/ShareCodeModal/styles.ts | 71 +++++++++++++++---- 4 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 src/assets/family-invitaion.svg create mode 100644 src/assets/familyddang-join.svg diff --git a/src/assets/family-invitaion.svg b/src/assets/family-invitaion.svg new file mode 100644 index 00000000..301d3dba --- /dev/null +++ b/src/assets/family-invitaion.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/assets/familyddang-join.svg b/src/assets/familyddang-join.svg new file mode 100644 index 00000000..cbaec6f6 --- /dev/null +++ b/src/assets/familyddang-join.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx index 81571966..b630782b 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx +++ b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx @@ -3,9 +3,11 @@ import { useModalStore } from '~stores/modalStore.ts' import { Typo17, Typo24, Typo15 } from '~components/Typo/index.ts' import Header from '~components/Header/index.tsx' import DogImage from '~assets/dog_standup.svg?react' +import { useState } from 'react' export default function ShareCodeModal() { const { popModal } = useModalStore() + const [familyCode, setFamilyCode] = useState('GaMJATaNG01') return ( @@ -14,7 +16,12 @@ export default function ShareCodeModal() { 가족과 함께 해요 - 가족으로 등록된 회원의 앱에서도 동일한 반려견 프로필을 공유하여 산책을 효율적으로 관리할 수 있어요. + 가족으로 등록된 회원의 앱에서도 동일한 +
+ 반려견 프로필을 공유하여 +
+ 산책을 효율적으로 +
관리할 수 있어요.
@@ -25,9 +32,18 @@ export default function ShareCodeModal() { 초대 코드 복사 + + +

유효 시간

+ 3:00 +
+ + + +
) } diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts b/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts index b929b169..bde63951 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts +++ b/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts @@ -1,14 +1,22 @@ import { styled } from 'styled-components' import { HEADER_HEIGHT } from '~constants/layout' +import FamilyInvitationImg from '~assets/family-invitaion.svg?react' +import FamilyDDangJoinImg from '~assets/familyddang-join.svg?react' export const ShareCodeModal = styled.div` display: flex; height: 100%; flex-direction: column; position: relative; + isolation: isolate; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; overflow: hidden; - padding: ${HEADER_HEIGHT + 52}px 90px 0 20px; + padding: ${HEADER_HEIGHT + 52}px 20px 27px 20px; + overflow-y: auto; + + &::-webkit-scrollbar { + display: none; + } @media (max-height: 700px) { padding: ${HEADER_HEIGHT + 52}px 1.25rem 1rem; @@ -20,33 +28,42 @@ export const MainContainer = styled.div` margin: 1rem; ` -export const CommentSection = styled.div`` +export const CommentSection = styled.div` + display: flex; + flex-direction: column; + gap: 8px; + height: 300px; +` export const DogImageWrapper = styled.div` - white-space: pre-line; - padding-bottom: 1rem; - padding-left: 10rem; - justify-content: left; + position: absolute; + z-index: -1; + top: 200px; + right: 40px; width: 137.651px; height: 176px; ` export const CodeShareSection = styled.div` - position: absolute; - bottom: 17rem; - left: 20px; - right: 20px; border-bottom: 2px solid ${({ theme }) => theme.colors.grayscale.gc_2}; - padding-bottom: 40px; + padding-bottom: 30px; + margin-bottom: 40px; +` + +export const FamilyCode = styled.p` + color: black; + font-weight: 700; ` -export const CodeShareButtonWrapper = styled.div`` +export const CodeShareButtonWrapper = styled.div` + position: relative; +` export const CodeShareButton = styled.div` border-radius: 12px; background: #ecf9da; display: flex; - width: 335px; + width: 100%; padding: 16.5px 24px; justify-content: center; align-items: center; @@ -54,3 +71,31 @@ export const CodeShareButton = styled.div` cursor: pointer; color: ${({ theme }) => theme.colors.brand.sub}; ` + +export const TimerWrapper = styled.div` + margin-top: 8px; + display: flex; + gap: 10px; + justify-content: center; +` + +export const Timer = styled.p` + font-weight: 700; + color: red; +` + +export const Manual = styled.div` + display: flex; + flex-direction: column; + gap: 27px; +` + +export const FamilyInvitaion = styled(FamilyInvitationImg)` + width: 100%; + height: auto; +` + +export const FamlyDDangJoin = styled(FamilyDDangJoinImg)` + width: 100%; + height: auto; +` From 5ed8c6b82282812d286bbcce58477c63538a17d6 Mon Sep 17 00:00:00 2001 From: wonil Date: Sun, 8 Dec 2024 20:22:37 +0900 Subject: [PATCH 09/19] =?UTF-8?q?=E2=9C=A8=20=20Feat:=20=20=ED=83=80?= =?UTF-8?q?=EC=9D=B4=EB=A8=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FamilyDDangModal/ShareCodeModal/Timer.tsx | 33 +++++++++++++++++++ .../FamilyDDangModal/ShareCodeModal/index.tsx | 27 +++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/modals/FamilyDDangModal/ShareCodeModal/Timer.tsx diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/Timer.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/Timer.tsx new file mode 100644 index 00000000..c10dab57 --- /dev/null +++ b/src/modals/FamilyDDangModal/ShareCodeModal/Timer.tsx @@ -0,0 +1,33 @@ +import { useEffect, useState } from 'react' +import * as S from './styles' + +interface TimerProps { + time: number + onTimeEnd: () => void +} + +export function Timer({ time, onTimeEnd }: TimerProps) { + const [timeLeft, setTimeLeft] = useState(time * 1000) + + const minutes = String(Math.floor((timeLeft / (1000 * 60)) % 60)).padStart(2, '0') + const seconds = String(Math.floor((timeLeft / 1000) % 60)).padStart(2, '0') + + useEffect(() => { + const timer = setInterval(() => { + setTimeLeft(prevTime => prevTime - 1000) + }, 1000) + + if (timeLeft <= 0) { + clearInterval(timer) + onTimeEnd() + } + + return () => clearInterval(timer) + }, [timeLeft, onTimeEnd]) + + return ( + + {minutes}:{seconds} + + ) +} diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx index b630782b..a99570ed 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx +++ b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx @@ -4,11 +4,32 @@ import { Typo17, Typo24, Typo15 } from '~components/Typo/index.ts' import Header from '~components/Header/index.tsx' import DogImage from '~assets/dog_standup.svg?react' import { useState } from 'react' +import { Timer } from './Timer.tsx' export default function ShareCodeModal() { const { popModal } = useModalStore() const [familyCode, setFamilyCode] = useState('GaMJATaNG01') + const handleShare = async () => { + if (navigator.share) { + try { + await navigator.share({ + title: '패밀리코드', + text: '텍스트', + url: familyCode, + }) + } catch (err) { + console.error('Error sharing:', err) + } + } else { + navigator.clipboard.writeText(window.location.href) + alert('Link copied to clipboard!') + } + } + + const onTimeEnd = () => { + console.log('타이머 끝') + } return (
@@ -30,13 +51,13 @@ export default function ShareCodeModal() { - + 초대 코드 복사 - + {familyCode}

유효 시간

- 3:00 +
From 9b6b3fc9796f1c237cd543ca2eb55da9889d1be1 Mon Sep 17 00:00:00 2001 From: wonil Date: Sun, 8 Dec 2024 21:43:37 +0900 Subject: [PATCH 10/19] =?UTF-8?q?=20=E2=9C=A8=20Feat:=20=EC=B4=88=EB=8C=80?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=AC=B4=ED=95=9C=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/family/fetchInviteCode.ts | 31 +++++++++++++++++++ src/apis/family/useFamily.ts | 10 ++++++ src/constants/queryKey.ts | 3 ++ .../{Timer.tsx => Timer/index.tsx} | 6 +++- .../ShareCodeModal/Timer/styles.ts | 5 +++ .../FamilyDDangModal/ShareCodeModal/index.tsx | 13 ++++---- .../FamilyDDangModal/ShareCodeModal/styles.ts | 4 --- 7 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 src/apis/family/fetchInviteCode.ts create mode 100644 src/apis/family/useFamily.ts rename src/modals/FamilyDDangModal/ShareCodeModal/{Timer.tsx => Timer/index.tsx} (91%) create mode 100644 src/modals/FamilyDDangModal/ShareCodeModal/Timer/styles.ts diff --git a/src/apis/family/fetchInviteCode.ts b/src/apis/family/fetchInviteCode.ts new file mode 100644 index 00000000..01446cb1 --- /dev/null +++ b/src/apis/family/fetchInviteCode.ts @@ -0,0 +1,31 @@ +import { AxiosError } from 'axios' +import { APIResponse, CommonAPIResponse, ErrorResponse } from '~types/api' +import { axiosInstance } from '~apis/axiosInstance' + +export type InviteCodeResponse = Pick + +export const fetchInviteCode = async (): Promise> => { + try { + const { data } = await axiosInstance.get>('/family/invite-code') + return data + } catch (error) { + if (error instanceof AxiosError) { + const { response } = error as AxiosError> + if (response) { + const { code, message } = response.data + switch (code) { + case 400: + throw new Error(message || '잘못된 요청입니다') + case 401: + throw new Error(message || '인증에 실패했습니다') + case 500: + throw new Error(message || '서버 오류가 발생했습니다') + default: + throw new Error(message || '알 수 없는 오류가 발생했습니다') + } + } + throw new Error('네트워크 연결을 확인해주세요') + } + throw new Error('알 수 없는 오류가 발생했습니다') + } +} diff --git a/src/apis/family/useFamily.ts b/src/apis/family/useFamily.ts new file mode 100644 index 00000000..a7557024 --- /dev/null +++ b/src/apis/family/useFamily.ts @@ -0,0 +1,10 @@ +import { useSuspenseQuery } from '@tanstack/react-query' +import { fetchInviteCode } from './fetchInviteCode' +import { queryKey } from '~constants/queryKey' + +export function useInviteCode() { + return useSuspenseQuery({ + queryKey: queryKey.family.inviteCode(), + queryFn: () => fetchInviteCode().then(res => res.data), + }) +} diff --git a/src/constants/queryKey.ts b/src/constants/queryKey.ts index f9ae9d25..3b50fd1f 100644 --- a/src/constants/queryKey.ts +++ b/src/constants/queryKey.ts @@ -18,4 +18,7 @@ export const queryKey = { currentMonthWalks: () => ['currentMonthWalks'], }, myPage: () => ['myPage'], + family: { + inviteCode: () => ['family', 'inviteCode'], + }, } diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/Timer.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/Timer/index.tsx similarity index 91% rename from src/modals/FamilyDDangModal/ShareCodeModal/Timer.tsx rename to src/modals/FamilyDDangModal/ShareCodeModal/Timer/index.tsx index c10dab57..b0703b16 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/Timer.tsx +++ b/src/modals/FamilyDDangModal/ShareCodeModal/Timer/index.tsx @@ -9,7 +9,11 @@ interface TimerProps { export function Timer({ time, onTimeEnd }: TimerProps) { const [timeLeft, setTimeLeft] = useState(time * 1000) - const minutes = String(Math.floor((timeLeft / (1000 * 60)) % 60)).padStart(2, '0') + useEffect(() => { + setTimeLeft(time * 1000) + }, [time]) + + const minutes = String(Math.floor((timeLeft / (1000 * 60)) % 60)) const seconds = String(Math.floor((timeLeft / 1000) % 60)).padStart(2, '0') useEffect(() => { diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/Timer/styles.ts b/src/modals/FamilyDDangModal/ShareCodeModal/Timer/styles.ts new file mode 100644 index 00000000..e2ea8bcc --- /dev/null +++ b/src/modals/FamilyDDangModal/ShareCodeModal/Timer/styles.ts @@ -0,0 +1,5 @@ +import styled from 'styled-components' + +export const Timer = styled.p` + color: red; +` diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx index a99570ed..86b267b7 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx +++ b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx @@ -3,12 +3,12 @@ import { useModalStore } from '~stores/modalStore.ts' import { Typo17, Typo24, Typo15 } from '~components/Typo/index.ts' import Header from '~components/Header/index.tsx' import DogImage from '~assets/dog_standup.svg?react' -import { useState } from 'react' -import { Timer } from './Timer.tsx' +import { Timer } from './Timer' +import { useInviteCode } from '~apis/family/useFamily.ts' export default function ShareCodeModal() { const { popModal } = useModalStore() - const [familyCode, setFamilyCode] = useState('GaMJATaNG01') + const { data, refetch } = useInviteCode() const handleShare = async () => { if (navigator.share) { @@ -16,7 +16,7 @@ export default function ShareCodeModal() { await navigator.share({ title: '패밀리코드', text: '텍스트', - url: familyCode, + url: data.inviteCode, }) } catch (err) { console.error('Error sharing:', err) @@ -29,6 +29,7 @@ export default function ShareCodeModal() { const onTimeEnd = () => { console.log('타이머 끝') + refetch() } return ( @@ -53,11 +54,11 @@ export default function ShareCodeModal() { 초대 코드 복사 - {familyCode} + {data.inviteCode}

유효 시간

- +
diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts b/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts index bde63951..f9fd8760 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts +++ b/src/modals/FamilyDDangModal/ShareCodeModal/styles.ts @@ -77,11 +77,7 @@ export const TimerWrapper = styled.div` display: flex; gap: 10px; justify-content: center; -` - -export const Timer = styled.p` font-weight: 700; - color: red; ` export const Manual = styled.div` From 296be97a21b0fc18f4d0b3f2bc78b4b78eed7d0d Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 05:51:29 +0900 Subject: [PATCH 11/19] =?UTF-8?q?=20=E2=9C=A8=20Feat:=20=EA=B0=80=EC=A1=B1?= =?UTF-8?q?=20=EC=B4=88=EB=8C=80=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/dog/fetchDogProfile.ts | 1 - src/apis/family/fetchfamilyDogs.ts | 37 ++++++++++++++++++ src/apis/family/joinFamily.ts | 38 +++++++++---------- src/apis/family/useFamily.ts | 36 ++++++++++++++++++ src/constants/queryKey.ts | 1 + .../FamilyDDangModal/ShareCodeModal/index.tsx | 6 +-- .../CheckDogProfileSection/index.tsx | 24 +++++++++--- .../FamilyCodeSection/index.tsx | 11 ++---- 8 files changed, 117 insertions(+), 37 deletions(-) create mode 100644 src/apis/family/fetchfamilyDogs.ts diff --git a/src/apis/dog/fetchDogProfile.ts b/src/apis/dog/fetchDogProfile.ts index f122c229..a138b6ed 100644 --- a/src/apis/dog/fetchDogProfile.ts +++ b/src/apis/dog/fetchDogProfile.ts @@ -14,7 +14,6 @@ export type FetchDogProfileRequest = { export type FetchDogProfileResponse = { data: DogProfileDetail } - /** * 반려견의 상세 프로필 정보를 조회합니다. */ diff --git a/src/apis/family/fetchfamilyDogs.ts b/src/apis/family/fetchfamilyDogs.ts new file mode 100644 index 00000000..f9f026e4 --- /dev/null +++ b/src/apis/family/fetchfamilyDogs.ts @@ -0,0 +1,37 @@ +// apis/family/fetchFamilyDogs.ts +import { AxiosError } from 'axios' +import { APIResponse, CommonAPIResponse, ErrorResponse } from '~types/api' +import { axiosInstance } from '~apis/axiosInstance' +import { DogProfileType } from '~types/dogProfile' + +type FetchFamilyDogsRequest = Pick + +export const fetchFamilyDogs = async (request: FetchFamilyDogsRequest): Promise> => { + try { + const { data } = await axiosInstance.post>('/family/dogs', request) + return data + } catch (error) { + if (error instanceof AxiosError) { + const { response } = error as AxiosError + + if (response) { + const { code, message } = response.data + switch (code) { + case 400: + throw new Error(message || '잘못된 요청입니다.') + case 401: + throw new Error(message || '유효하지 않은 코드입니다.') + case 500: + throw new Error(message || '서버 오류가 발생했습니다.') + default: + throw new Error(message || '알 수 없는 오류가 발생했습니다.') + } + } + + throw new Error('네트워크 연결을 확인해주세요') + } + + console.error('예상치 못한 에러:', error) + throw new Error('다시 시도해주세요') + } +} diff --git a/src/apis/family/joinFamily.ts b/src/apis/family/joinFamily.ts index 2309780d..cbd82cc8 100644 --- a/src/apis/family/joinFamily.ts +++ b/src/apis/family/joinFamily.ts @@ -1,33 +1,33 @@ import { AxiosError } from 'axios' -import { APIResponse, ErrorResponse } from '~types/api' +import { APIResponse, ErrorResponse, CommonAPIResponse } from '~types/api' import { axiosInstance } from '~apis/axiosInstance' -interface JoinFamilyResponse { - familyId: number - memberId: number - familyName: string -} +type JoinFamilyRequest = Pick + +type JoinFamilyResponse = Pick -export const joinFamily = async (inviteCode: string): Promise> => { +export const joinFamily = async (request: JoinFamilyRequest): Promise> => { try { - const { data } = await axiosInstance.post>('/family/join', { inviteCode }) + const { data } = await axiosInstance.post>('/family/join', request) return data } catch (error) { if (error instanceof AxiosError) { - const { response, request } = error as AxiosError - + const { response } = error as AxiosError if (response) { - console.error('가족 참여 오류:', response.data) - throw new Error(response.data.message ?? '요청 실패') - } - - if (request) { - console.error('요청 에러:', request) - throw new Error('네트워크 연결을 확인해주세요') + const { code, message } = response.data + switch (code) { + case 400: + throw new Error(message || '잘못된 요청입니다.') + case 401: + throw new Error(message || '인증에 실패했습니다.') + case 500: + throw new Error(message || '서버 오류가 발생했습니다.') + default: + throw new Error(message || '알 수 없는 오류가 발생했습니다.') + } } + throw new Error('네트워크 연결을 확인해주세요') } - - console.error('예상치 못한 에러:', error) throw new Error('다시 시도해주세요') } } diff --git a/src/apis/family/useFamily.ts b/src/apis/family/useFamily.ts index a7557024..f7a77354 100644 --- a/src/apis/family/useFamily.ts +++ b/src/apis/family/useFamily.ts @@ -1,6 +1,12 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { fetchInviteCode } from './fetchInviteCode' import { queryKey } from '~constants/queryKey' +import { useMutation, useQueryClient } from '@tanstack/react-query' +import { fetchFamilyDogs } from './fetchfamilyDogs' +import { joinFamily } from './joinFamily' +import { useToastStore } from '~stores/toastStore' +import { useNavigate } from 'react-router-dom' +import { useModalStore } from '~stores/modalStore' export function useInviteCode() { return useSuspenseQuery({ @@ -8,3 +14,33 @@ export function useInviteCode() { queryFn: () => fetchInviteCode().then(res => res.data), }) } + +export function useFetchFamilyDogs() { + const { showToast } = useToastStore() + return useMutation({ + mutationFn: (inviteCode: string) => fetchFamilyDogs({ inviteCode }).then(res => res.data), + onError: (error: Error) => { + showToast(error.message) + }, + }) +} + +export function useJoinFamily() { + const queryClient = useQueryClient() + const { showToast } = useToastStore() + const { clearModal } = useModalStore() + const navigate = useNavigate() + + return useMutation({ + mutationFn: (inviteCode: string) => joinFamily({ inviteCode }).then(res => res.data), + onSuccess: () => { + alert('가족 참여가 완료되었습니다') + queryClient.invalidateQueries({ queryKey: queryKey.family.profile() }) + navigate('/') + clearModal() + }, + onError: (error: Error) => { + showToast(error.message) + }, + }) +} diff --git a/src/constants/queryKey.ts b/src/constants/queryKey.ts index 3b50fd1f..4cd92665 100644 --- a/src/constants/queryKey.ts +++ b/src/constants/queryKey.ts @@ -20,5 +20,6 @@ export const queryKey = { myPage: () => ['myPage'], family: { inviteCode: () => ['family', 'inviteCode'], + profile: () => ['family', 'dogProfile'], }, } diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx index 86b267b7..6f241e73 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx +++ b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx @@ -27,10 +27,6 @@ export default function ShareCodeModal() { } } - const onTimeEnd = () => { - console.log('타이머 끝') - refetch() - } return (
@@ -58,7 +54,7 @@ export default function ShareCodeModal() {

유효 시간

- + refetch()} />
diff --git a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx index e2e823d1..65dfa952 100644 --- a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx @@ -5,9 +5,23 @@ import { Typo24 } from '~components/Typo/index' import Profile from '~components/Profile' import Tag from '~components/Tag' import { useModalStore } from '~stores/modalStore' +import { DogProfileType } from '~types/dogProfile' +import { useJoinFamily } from '~apis/family/useFamily' -export default function CheckDogProfileSection() { +interface CheckDogProfileSectionProp { + familyCode: string + dogProfiles: DogProfileType[] +} + +export default function CheckDogProfileSection({ familyCode, dogProfiles }: CheckDogProfileSectionProp) { + const joinFamilyMutation = useJoinFamily() const { popModal } = useModalStore() + const dogProfile = dogProfiles[0] + + const handleOnClick = () => { + console.log(familyCode) + joinFamilyMutation.mutate(familyCode) + } return ( <> @@ -35,13 +49,13 @@ export default function CheckDogProfileSection() { userId={0} /> - - - + + + - 다음 + 다음 ) diff --git a/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx b/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx index 002c1a62..52ac66bf 100644 --- a/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx +++ b/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx @@ -9,9 +9,10 @@ import CheckDogProfileSection from '../CheckDogProfileSection' import { useToastStore } from '~stores/toastStore' import { validateFamilyCode } from '~utils/validateDogProfile' import Toast from '~components/Toast' -import { joinFamily } from '~apis/family/joinFamily' +import { useFetchFamilyDogs } from '~apis/family/useFamily' export default function FamilyCodeSection() { + const fetchFamilyDogsMutation = useFetchFamilyDogs() const { pushModal, popModal } = useModalStore() const [familyCode, setFamilyCode] = useState('') const { showToast } = useToastStore() @@ -22,12 +23,8 @@ export default function FamilyCodeSection() { showToast(alertMessage) return } - try { - const response = await joinFamily('ABC12345') - if (response.code === 200) pushModal() - } catch (error) { - if (error instanceof Error) showToast(error.message) - } + const dogProfiles = await fetchFamilyDogsMutation.mutateAsync(familyCode) + if (dogProfiles) pushModal() } return ( <> From b7ead617b99b5ebd03e9b5308475f09e65f9b5c2 Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 07:05:41 +0900 Subject: [PATCH 12/19] =?UTF-8?q?=20=E2=9C=A8=20Feat:=20=ED=99=95=EC=9D=B8?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/dog/createDogProfile.ts | 2 +- .../{useDogProfile.ts => useDogProfile.tsx} | 29 ++++++++++------- .../family/{useFamily.ts => useFamily.tsx} | 14 ++++++--- src/modals/ConfirmModal/index.tsx | 18 +++++++++++ src/modals/ConfirmModal/styles.ts | 31 +++++++++++++++++++ src/utils/positionLabelMap.ts | 12 ------- 6 files changed, 76 insertions(+), 30 deletions(-) rename src/apis/dog/{useDogProfile.ts => useDogProfile.tsx} (69%) rename src/apis/family/{useFamily.ts => useFamily.tsx} (77%) create mode 100644 src/modals/ConfirmModal/index.tsx create mode 100644 src/modals/ConfirmModal/styles.ts delete mode 100644 src/utils/positionLabelMap.ts diff --git a/src/apis/dog/createDogProfile.ts b/src/apis/dog/createDogProfile.ts index 5996e0aa..d71b8fce 100644 --- a/src/apis/dog/createDogProfile.ts +++ b/src/apis/dog/createDogProfile.ts @@ -1,5 +1,5 @@ import { AxiosError } from 'axios' -import { APIResponse, ErrorResponse, CommonAPIResponse } from '~types/api' +import { APIResponse, ErrorResponse } from '~types/api' import { axiosInstance } from '~apis/axiosInstance' import { DogProfileType } from '~types/dogProfile' diff --git a/src/apis/dog/useDogProfile.ts b/src/apis/dog/useDogProfile.tsx similarity index 69% rename from src/apis/dog/useDogProfile.ts rename to src/apis/dog/useDogProfile.tsx index 0727dd5d..17d7ddb4 100644 --- a/src/apis/dog/useDogProfile.ts +++ b/src/apis/dog/useDogProfile.tsx @@ -8,21 +8,25 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { fetchDogProfile } from '~apis/dog/fetchDogProfile' import { queryKey } from '~constants/queryKey' import { patchDogProfile, PatchDogProfileRequest } from '~apis/dog/patchDogProfile' +import ConfirmModal from '~modals/ConfirmModal' + +const { pushModal, popModal, clearModal } = useModalStore() +const { showToast } = useToastStore() +const navigate = useNavigate() export function useCreateDogProfile() { - const navigate = useNavigate() - const { clearModal } = useModalStore() - const { showToast } = useToastStore() const { setDogProfile } = useDogProfileStore() + const completeRegistration = () => { + navigate('/') + clearModal() + } + return useMutation({ mutationFn: (formData: FormData) => createDogProfile(formData), onSuccess: response => { - console.log(response.data) setDogProfile({ ...response.data }) - alert('반려견 등록 완료') - clearModal() - navigate('/') + pushModal() }, onError: (error: Error) => { showToast(error.message) @@ -38,16 +42,17 @@ export function useFetchDogProfile(id: number) { } export function usePatchDogProfile(id: number) { - const { popModal } = useModalStore() - const { showToast } = useToastStore() const queryClient = useQueryClient() + const completeRegistration = () => { + queryClient.invalidateQueries({ queryKey: queryKey.dog.profile(id) }) + popModal() + } + return useMutation({ mutationFn: (data: PatchDogProfileRequest) => patchDogProfile(id, data), onSuccess: () => { - alert('반려견 정보가 수정되었습니다') - queryClient.invalidateQueries({ queryKey: queryKey.dog.profile(id) }) - popModal() + pushModal() }, onError: (error: Error) => { showToast(error.message) diff --git a/src/apis/family/useFamily.ts b/src/apis/family/useFamily.tsx similarity index 77% rename from src/apis/family/useFamily.ts rename to src/apis/family/useFamily.tsx index f7a77354..7ff35e09 100644 --- a/src/apis/family/useFamily.ts +++ b/src/apis/family/useFamily.tsx @@ -7,6 +7,7 @@ import { joinFamily } from './joinFamily' import { useToastStore } from '~stores/toastStore' import { useNavigate } from 'react-router-dom' import { useModalStore } from '~stores/modalStore' +import ConfirmModal from '~modals/ConfirmModal' export function useInviteCode() { return useSuspenseQuery({ @@ -28,16 +29,19 @@ export function useFetchFamilyDogs() { export function useJoinFamily() { const queryClient = useQueryClient() const { showToast } = useToastStore() - const { clearModal } = useModalStore() + const { pushModal, clearModal } = useModalStore() const navigate = useNavigate() + const completeRegistration = () => { + queryClient.invalidateQueries({ queryKey: queryKey.family.profile() }) + navigate('/') + clearModal() + } + return useMutation({ mutationFn: (inviteCode: string) => joinFamily({ inviteCode }).then(res => res.data), onSuccess: () => { - alert('가족 참여가 완료되었습니다') - queryClient.invalidateQueries({ queryKey: queryKey.family.profile() }) - navigate('/') - clearModal() + pushModal() }, onError: (error: Error) => { showToast(error.message) diff --git a/src/modals/ConfirmModal/index.tsx b/src/modals/ConfirmModal/index.tsx new file mode 100644 index 00000000..1f1f29ef --- /dev/null +++ b/src/modals/ConfirmModal/index.tsx @@ -0,0 +1,18 @@ +import * as S from './styles' +import { Typo20 } from '~components/Typo' + +interface ConfirmModalProps { + content: string + onClick: () => void +} + +export default function ConfirmModal({ content, onClick }: ConfirmModalProps) { + return ( + + + {content} + 확인 + + + ) +} diff --git a/src/modals/ConfirmModal/styles.ts b/src/modals/ConfirmModal/styles.ts new file mode 100644 index 00000000..282d0904 --- /dev/null +++ b/src/modals/ConfirmModal/styles.ts @@ -0,0 +1,31 @@ +import styled from 'styled-components' + +export const ConfirmModalOverlay = styled.div` + width: 100%; + height: 100%; + background-color: (0, 0, 0, 0.4); + display: flex; + justify-content: center; + align-content: center; +` + +export const ConfirmModal = styled.div` + width: 300px; + height: 200px; + background-color: ${props => props.theme.colors.grayscale.gc_4}; + + display: flex; + flex-direction: column; + gap: 30px; + + font-size: 20px; + font-weight: 700; +` + +export const ConfirmButton = styled.button` + border-radius: 30px; + width: 80px; + height: 50px; + background-color: ${props => props.theme.colors.brand.darken}; + color: ${props => props.theme.colors.grayscale.gc_4}; +` diff --git a/src/utils/positionLabelMap.ts b/src/utils/positionLabelMap.ts deleted file mode 100644 index 0347fe31..00000000 --- a/src/utils/positionLabelMap.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { FamilyRole } from '~types/common' - -export const positionLabelMap: Record = { - MOTHER: '엄마', - FATHER: '아빠', - OLDER_BROTHER: '형', - ELDER_BROTHER: '오빠', - ELDER_SISTER: '언니', - OLDER_SISTER: '누나', - GRANDFATHER: '할아버지', - GRANDMOTHER: '할머니', -} From da11c05c4f25905c4eba54d609b375a1f0035faa Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 07:21:52 +0900 Subject: [PATCH 13/19] =?UTF-8?q?=F0=9F=8E=A8=20Design:=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=ED=8F=B0=20=EC=83=88=EB=A1=9C=EA=B3=A0=EC=B9=A8=20?= =?UTF-8?q?=EB=A7=89=EA=B8=B0,=20=EB=B0=98=EB=A0=A4=EA=B2=AC=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B8=80=EC=9E=90=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RegisterDogModal/CheckDogProfileSection/index.tsx | 10 ++-------- src/pages/LogPage/styles.ts | 1 + .../RegisterPage/Dog/SelectSectionButton/index.tsx | 4 +++- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx index 65dfa952..ccf99d4d 100644 --- a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx @@ -26,7 +26,7 @@ export default function CheckDogProfileSection({ familyCode, dogProfiles }: Chec return ( <> -
+
@@ -41,13 +41,7 @@ export default function CheckDogProfileSection({ familyCode, dogProfiles }: Chec index.html 파일에서 과 같이 url을 추가해주세요. */} - + diff --git a/src/pages/LogPage/styles.ts b/src/pages/LogPage/styles.ts index 7541b6a7..c5ff2a59 100644 --- a/src/pages/LogPage/styles.ts +++ b/src/pages/LogPage/styles.ts @@ -1,6 +1,7 @@ import styled from 'styled-components' export const LogPage = styled.div` + overscroll-behavior: none; display: flex; flex-direction: column; overflow: hidden; diff --git a/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx b/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx index cbc9b7e5..88fffb27 100644 --- a/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx +++ b/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx @@ -16,7 +16,9 @@ export default function SelectSectionButton({ title, description, src, modal }: return ( pushModal(modal)}> - {title} + + {title} + {description} From a6db3a49ba3b09d3a77613bfbe768c3010db1cdd Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 07:24:48 +0900 Subject: [PATCH 14/19] =?UTF-8?q?=F0=9F=8E=A8=20Design:=20=EB=B0=98?= =?UTF-8?q?=EB=A0=A4=EA=B2=AC=20=EC=A3=BC=EC=9D=B8=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B0=95?= =?UTF-8?q?=EC=95=84=EC=A7=80=20=EB=82=98=EC=9D=B4=20=ED=91=9C=EC=8B=9C?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx index ccf99d4d..1045d7a0 100644 --- a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx @@ -7,6 +7,7 @@ import Tag from '~components/Tag' import { useModalStore } from '~stores/modalStore' import { DogProfileType } from '~types/dogProfile' import { useJoinFamily } from '~apis/family/useFamily' +import { calculateAge } from '~utils/calculateAge' interface CheckDogProfileSectionProp { familyCode: string @@ -45,7 +46,7 @@ export default function CheckDogProfileSection({ familyCode, dogProfiles }: Chec - + From dab92bc410c1a3312f540e3048ffd8daea7c7bbd Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 10:56:00 +0900 Subject: [PATCH 15/19] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=B4=88=EB=8C=80?= =?UTF-8?q?=EB=B0=9B=EC=9D=80=20=EC=9C=A0=EC=A0=80=20=EA=B0=80=EC=A1=B1?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 1474 ++++++++--------- src/apis/dog/useDogProfile.tsx | 13 +- src/apis/family/fetchfamilyDogs.ts | 1 - src/modals/ConfirmModal/index.tsx | 4 +- src/modals/ConfirmModal/styles.ts | 27 +- src/modals/EditDogProfileModal/index.tsx | 1 + src/modals/EditDogProfileModal/styles.ts | 1 + .../FamilyDDangModal/ShareCodeModal/index.tsx | 2 +- .../CheckDogProfileSection/index.tsx | 6 +- .../CheckDogProfileSection/styles.ts | 4 + 10 files changed, 775 insertions(+), 758 deletions(-) diff --git a/package-lock.json b/package-lock.json index 325e69cc..7a8ae0bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -105,9 +105,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", - "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "dev": true, "engines": { "node": ">=6.9.0" @@ -143,6 +143,12 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -153,12 +159,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", - "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "dependencies": { - "@babel/parser": "^7.26.2", - "@babel/types": "^7.26.0", + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -179,19 +185,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", - "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", @@ -248,13 +241,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", - "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", - "regexpu-core": "^6.1.1", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -386,19 +379,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", - "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", @@ -465,11 +445,11 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.26.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -849,12 +829,11 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", - "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { @@ -989,14 +968,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", - "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-simple-access": "^7.25.9" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1574,15 +1552,15 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", + "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1599,9 +1577,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" @@ -1634,29 +1612,6 @@ "stylis": "4.2.0" } }, - "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" - }, - "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" - }, "node_modules/@emotion/cache": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.5.tgz", @@ -1669,33 +1624,23 @@ "stylis": "4.2.0" } }, - "node_modules/@emotion/cache/node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" - }, - "node_modules/@emotion/cache/node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" - }, "node_modules/@emotion/hash": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", "dependencies": { - "@emotion/memoize": "^0.8.1" + "@emotion/memoize": "^0.9.0" } }, "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "node_modules/@emotion/react": { "version": "11.13.5", @@ -1732,16 +1677,6 @@ "csstype": "^3.0.2" } }, - "node_modules/@emotion/serialize/node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" - }, - "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" - }, "node_modules/@emotion/sheet": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", @@ -1769,23 +1704,10 @@ } } }, - "node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", - "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", - "dependencies": { - "@emotion/memoize": "^0.9.0" - } - }, - "node_modules/@emotion/styled/node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" - }, "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.1.0", @@ -2273,52 +2195,52 @@ } }, "node_modules/@eslint/js": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", - "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", - "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.5.tgz", + "integrity": "sha512-ep/5vGkyZvMSi6s8nQG8k7vTcKjuXs402fgGIWixj0AWRgKbeaZeLuYc32NIPXexgBjWepMeZGgHLuZXkuD2Gg==", "dev": true, "dependencies": { - "@formatjs/fast-memoize": "2.2.3", + "@formatjs/fast-memoize": "2.2.4", "@formatjs/intl-localematcher": "0.5.8", "tslib": "2" } }, "node_modules/@formatjs/fast-memoize": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz", - "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.4.tgz", + "integrity": "sha512-8SzI0cBADgbLOYsoQW/IqVHljCH964CrOdESFQ07wMkRLP90+MfV7k6gZPiGD88ubqET9igJV5c292rT28B7xQ==", "dev": true, "dependencies": { "tslib": "2" } }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz", - "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==", + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.5.tgz", + "integrity": "sha512-mHauC9wuVXtnshAIoAYjlNrh6+OFOT6cC4fpK+AG+DHkVWwIPFVQE28hLQ/KptuvQ8VMfG/zYx6rRjtaeFPkSQ==", "dev": true, "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/icu-skeleton-parser": "1.8.8", + "@formatjs/ecma402-abstract": "2.2.5", + "@formatjs/icu-skeleton-parser": "1.8.9", "tslib": "2" } }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz", - "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==", + "version": "1.8.9", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.9.tgz", + "integrity": "sha512-1KSSlU7ywsU5E5v7xr6VTlBzLGszMi3GOu7EVINjkfA501GN5OkeNSbd5q6ie1wIknZJGBlqkvXPYYdp3YXjpw==", "dev": true, "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", + "@formatjs/ecma402-abstract": "2.2.5", "tslib": "2" } }, @@ -2525,6 +2447,15 @@ "node": ">=10" } }, + "node_modules/@microsoft/api-extractor/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", @@ -2585,24 +2516,24 @@ "dev": true }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.9.tgz", - "integrity": "sha512-TWqj7b1w5cmSz4H/uf+y2AHxAH4ldPR7D2bz0XVyn60GCAo/zRbRPx7cF8gTs/i7CiYeHzV6dtat0VpMwOtolw==", + "version": "6.1.10", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.10.tgz", + "integrity": "sha512-LY5wdiLCBDY7u+Od8UmFINZFGN/5ZU90fhAslf/ZtfP+5RhuY45f679pqYIxe0y54l6Gkv9PFOc8Cs10LDTBYg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/material": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.9.tgz", - "integrity": "sha512-NwqIN0bdsgzSbZd5JFcC+2ez0XW/XNs8uiV2PDHrqQ4qf/FEasFJG1z6g8JbCN0YlTrHZekVb17X0Fv0qcYJfQ==", + "version": "6.1.10", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.10.tgz", + "integrity": "sha512-txnwYObY4N9ugv5T2n5h1KcbISegZ6l65w1/7tpSU5OB6MQCU94YkP8n/3slDw2KcEfRk4+4D8EUGfhSPMODEQ==", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.1.9", - "@mui/system": "^6.1.9", + "@mui/core-downloads-tracker": "^6.1.10", + "@mui/system": "^6.1.10", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.9", + "@mui/utils": "^6.1.10", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", @@ -2621,7 +2552,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.1.9", + "@mui/material-pigment-css": "^6.1.10", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -2641,18 +2572,13 @@ } } }, - "node_modules/@mui/material/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, "node_modules/@mui/private-theming": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.9.tgz", - "integrity": "sha512-7aum/O1RquBYhfwL/7egDyl9GqJgPM6hoJDFFBbhF6Sgv9yI9v4w3ArKUkuVvR0CtVj4NXRVMKEioh1bjUzvuA==", + "version": "6.1.10", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.10.tgz", + "integrity": "sha512-DqgsH0XFEweeG3rQfVkqTkeXcj/E76PGYWag8flbPdV8IYdMo+DfVdFlZK8JEjsaIVD2Eu1kJg972XnH5pfnBQ==", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.1.9", + "@mui/utils": "^6.1.10", "prop-types": "^15.8.1" }, "engines": { @@ -2673,9 +2599,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.9.tgz", - "integrity": "sha512-xynSLlJRxHLzSfQaiDjkaTx8LiFb9ByVa7aOdwFnTxGWFMY1F+mkXwAUY4jDDE+MAxkWxlzzQE0wOohnsxhdQg==", + "version": "6.1.10", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.10.tgz", + "integrity": "sha512-+NV9adKZYhslJ270iPjf2yzdVJwav7CIaXcMlPSi1Xy1S/zRe5xFgZ6BEoMdmGRpr34lIahE8H1acXP2myrvRw==", "dependencies": { "@babel/runtime": "^7.26.0", "@emotion/cache": "^11.13.5", @@ -2706,9 +2632,9 @@ } }, "node_modules/@mui/styled-engine-sc": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-6.1.9.tgz", - "integrity": "sha512-M6ue0dQNEqeWxv+pi4qX1RxWfH7U2yc0N21log1XglYu9shu0OFOsfWK9pKOeLzsPJtMdbJB+98gtlZzQ0gAfQ==", + "version": "6.1.10", + "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-6.1.10.tgz", + "integrity": "sha512-MZcdfSxu9WnDQr+sd3Y+sxd/G6dTxfvRitqPrwVeUiR8mohWfCOgRCEwCjZTx//rL2+wVDyU40z1VtR1eqQ+QQ==", "dependencies": { "@babel/runtime": "^7.26.0", "@types/hoist-non-react-statics": "^3.3.5", @@ -2728,15 +2654,15 @@ } }, "node_modules/@mui/system": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.9.tgz", - "integrity": "sha512-8x+RucnNp21gfFYsklCaZf0COXbv3+v0lrVuXONxvPEkESi2rwLlOi8UPJfcz6LxZOAX3v3oQ7qw18vnpgueRg==", + "version": "6.1.10", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.10.tgz", + "integrity": "sha512-5YNIqxETR23SIkyP7MY2fFnXmplX/M4wNi2R+10AVRd3Ub+NLctWY/Vs5vq1oAMF0eSDLhRTGUjaUe+IGSfWqg==", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.1.9", - "@mui/styled-engine": "^6.1.9", + "@mui/private-theming": "^6.1.10", + "@mui/styled-engine": "^6.1.10", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.9", + "@mui/utils": "^6.1.10", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -2780,9 +2706,9 @@ } }, "node_modules/@mui/utils": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.9.tgz", - "integrity": "sha512-N7uzBp7p2or+xanXn3aH2OTINC6F/Ru/U8h6amhRZEev8bJhKN86rIDIoxZZ902tj+09LXtH83iLxFMjMHyqNA==", + "version": "6.1.10", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.10.tgz", + "integrity": "sha512-1ETuwswGjUiAf2dP9TkBy8p49qrw2wXa+RuAjNTRE5+91vtXJ1HKrs7H9s8CZd1zDlQVzUcUAPm9lpQwF5ogTw==", "dependencies": { "@babel/runtime": "^7.26.0", "@mui/types": "^7.2.19", @@ -2808,11 +2734,6 @@ } } }, - "node_modules/@mui/utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2995,9 +2916,9 @@ } }, "node_modules/@octokit/types": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", - "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "version": "13.6.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.2.tgz", + "integrity": "sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==", "dev": true, "dependencies": { "@octokit/openapi-types": "^22.2.0" @@ -3024,9 +2945,9 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.1.tgz", - "integrity": "sha512-0kdAbmic3J09I6dT8e9vE2JOCSt13wHCW5x/ly8TSt2bDtuIWe2TgLZZDHdcziw9AVCzflMAXCrVyRIhIs44Ng==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.5.0.tgz", + "integrity": "sha512-6TQAc/5uRILE6deixJ1CR8rXyTbzXIXNgO1D0Woi9Bqicz2FV5iKP3BHYEg6o4UATCMcbQQ0jbmeaOkn/HQk2w==", "dev": true, "dependencies": { "debug": "^4.3.7", @@ -3134,9 +3055,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz", - "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", + "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", "cpu": [ "arm" ], @@ -3147,9 +3068,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz", - "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", + "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", "cpu": [ "arm64" ], @@ -3160,9 +3081,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz", - "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", + "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", "cpu": [ "arm64" ], @@ -3173,9 +3094,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz", - "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", + "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", "cpu": [ "x64" ], @@ -3186,9 +3107,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz", - "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", + "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", "cpu": [ "arm64" ], @@ -3199,9 +3120,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz", - "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", + "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", "cpu": [ "x64" ], @@ -3212,9 +3133,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz", - "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", + "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", "cpu": [ "arm" ], @@ -3225,9 +3146,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz", - "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", + "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", "cpu": [ "arm" ], @@ -3238,9 +3159,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz", - "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", + "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", "cpu": [ "arm64" ], @@ -3251,9 +3172,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz", - "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", + "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", "cpu": [ "arm64" ], @@ -3263,10 +3184,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", + "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz", - "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", + "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", "cpu": [ "ppc64" ], @@ -3277,9 +3211,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz", - "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", + "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", "cpu": [ "riscv64" ], @@ -3290,9 +3224,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz", - "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", + "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", "cpu": [ "s390x" ], @@ -3303,9 +3237,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz", - "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", + "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", "cpu": [ "x64" ], @@ -3316,9 +3250,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz", - "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", + "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", "cpu": [ "x64" ], @@ -3329,9 +3263,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz", - "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", + "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", "cpu": [ "arm64" ], @@ -3342,9 +3276,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz", - "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", + "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", "cpu": [ "ia32" ], @@ -3355,9 +3289,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz", - "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", + "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", "cpu": [ "x64" ], @@ -3563,41 +3497,41 @@ "dev": true }, "node_modules/@sentry-internal/tracing": { - "version": "7.120.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.0.tgz", - "integrity": "sha512-VymJoIGMV0PcTJyshka9uJ1sKpR7bHooqW5jTEr6g0dYAwB723fPXHjVW+7SETF7i5+yr2KMprYKreqRidKyKA==", + "version": "7.120.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.1.tgz", + "integrity": "sha512-MwZlhQY27oM4V05m2Q46WB2F7jqFu8fewg14yRcjCuK3tdxvQoLsXOEPMZxLxpoXPTqPCm3Ig7mA4GwdlCL41w==", "dev": true, "dependencies": { - "@sentry/core": "7.120.0", - "@sentry/types": "7.120.0", - "@sentry/utils": "7.120.0" + "@sentry/core": "7.120.1", + "@sentry/types": "7.120.1", + "@sentry/utils": "7.120.1" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/core": { - "version": "7.120.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.120.0.tgz", - "integrity": "sha512-uTc2sUQ0heZrMI31oFOHGxjKgw16MbV3C2mcT7qcrb6UmSGR9WqPOXZhnVVuzPWCnQ8B5IPPVdynK//J+9/m6g==", + "version": "7.120.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.120.1.tgz", + "integrity": "sha512-tXpJlf/8ngsSCpcRD+4DDvh4TqUbY0MlvE9Mpc/jO5GgYl/goAH2H1COw6W/UNfkr/l80P2jejS0HLPk0moi0A==", "dev": true, "dependencies": { - "@sentry/types": "7.120.0", - "@sentry/utils": "7.120.0" + "@sentry/types": "7.120.1", + "@sentry/utils": "7.120.1" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/integrations": { - "version": "7.120.0", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.120.0.tgz", - "integrity": "sha512-/Hs9MgSmG4JFNyeQkJ+MWh/fxO/U38Pz0VSH3hDrfyCjI8vH9Vz9inGEQXgB9Ke4eH8XnhsQ7xPnM27lWJts6g==", + "version": "7.120.1", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.120.1.tgz", + "integrity": "sha512-dshhLZUN+pYpyZiS5QRYKaYSqvWYtmsbwmBlH4SCGOnN9sbY4nZn0h8njr+xKT8UFnPxoTlbZmkcrVY3qPVMfg==", "dev": true, "dependencies": { - "@sentry/core": "7.120.0", - "@sentry/types": "7.120.0", - "@sentry/utils": "7.120.0", + "@sentry/core": "7.120.1", + "@sentry/types": "7.120.1", + "@sentry/utils": "7.120.1", "localforage": "^1.8.1" }, "engines": { @@ -3605,37 +3539,37 @@ } }, "node_modules/@sentry/node": { - "version": "7.120.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.120.0.tgz", - "integrity": "sha512-GAyuNd8WUznsiOyDq2QUwR/aVnMmItUc4tgZQxhH1R+n4Adx3cAhnpq3zEuzsIAC5+/7ut+4Q4B3akh6SDZd4w==", + "version": "7.120.1", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.120.1.tgz", + "integrity": "sha512-YF/TDUCtUOQeUMwL4vcUWGNv/8Qz9624xBnaL8nXW888xNBoSRr2vH/zMrmTup5zfmWAh9lVbp98BZFF6F0WJg==", "dev": true, "dependencies": { - "@sentry-internal/tracing": "7.120.0", - "@sentry/core": "7.120.0", - "@sentry/integrations": "7.120.0", - "@sentry/types": "7.120.0", - "@sentry/utils": "7.120.0" + "@sentry-internal/tracing": "7.120.1", + "@sentry/core": "7.120.1", + "@sentry/integrations": "7.120.1", + "@sentry/types": "7.120.1", + "@sentry/utils": "7.120.1" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/types": { - "version": "7.120.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.120.0.tgz", - "integrity": "sha512-3mvELhBQBo6EljcRrJzfpGJYHKIZuBXmqh0y8prh03SWE62pwRL614GIYtd4YOC6OP1gfPn8S8h9w3dD5bF5HA==", + "version": "7.120.1", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.120.1.tgz", + "integrity": "sha512-f/WT7YUH8SA2Jhez/hYz/dA351AJqr1Eht/URUdYsqMFecXr/blAcNKRVFccSsvQeTqWVV9HVQ9BXUSjPJOvFA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@sentry/utils": { - "version": "7.120.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.120.0.tgz", - "integrity": "sha512-XZsPcBHoYu4+HYn14IOnhabUZgCF99Xn4IdWn8Hjs/c+VPtuAVDhRTsfPyPrpY3OcN8DgO5fZX4qcv/6kNbX1A==", + "version": "7.120.1", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.120.1.tgz", + "integrity": "sha512-4boeo5Y3zw3gFrWZmPHsYOIlTh//eBaGBgWL25FqLbLObO23gFE86G6O6knP1Gamm1DGX2IWH7w4MChYuBm6tA==", "dev": true, "dependencies": { - "@sentry/types": "7.120.0" + "@sentry/types": "7.120.1" }, "engines": { "node": ">=8" @@ -3644,8 +3578,7 @@ "node_modules/@stomp/stompjs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@stomp/stompjs/-/stompjs-7.0.0.tgz", - "integrity": "sha512-fGdq4wPDnSV/KyOsjq4P+zLc8MFWC3lMmP5FBgLWKPJTYcuCbAIrnRGjB7q2jHZdYCOD5vxLuFoKIYLy5/u8Pw==", - "license": "Apache-2.0" + "integrity": "sha512-fGdq4wPDnSV/KyOsjq4P+zLc8MFWC3lMmP5FBgLWKPJTYcuCbAIrnRGjB7q2jHZdYCOD5vxLuFoKIYLy5/u8Pw==" }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", @@ -3842,6 +3775,32 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@svgr/core/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", @@ -3882,9 +3841,9 @@ } }, "node_modules/@swc/core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.9.3.tgz", - "integrity": "sha512-oRj0AFePUhtatX+BscVhnzaAmWjpfAeySpM1TCbxA1rtBDeH/JDhi5yYzAKneDYtVtBvA7ApfeuzhMC9ye4xSg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.0.tgz", + "integrity": "sha512-+CuuTCmQFfzaNGg1JmcZvdUVITQXJk9sMnl1C2TiDLzOSVOJRwVD4dNo5dljX/qxpMAN+2BIYlwjlSkoGi6grg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3899,16 +3858,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.9.3", - "@swc/core-darwin-x64": "1.9.3", - "@swc/core-linux-arm-gnueabihf": "1.9.3", - "@swc/core-linux-arm64-gnu": "1.9.3", - "@swc/core-linux-arm64-musl": "1.9.3", - "@swc/core-linux-x64-gnu": "1.9.3", - "@swc/core-linux-x64-musl": "1.9.3", - "@swc/core-win32-arm64-msvc": "1.9.3", - "@swc/core-win32-ia32-msvc": "1.9.3", - "@swc/core-win32-x64-msvc": "1.9.3" + "@swc/core-darwin-arm64": "1.10.0", + "@swc/core-darwin-x64": "1.10.0", + "@swc/core-linux-arm-gnueabihf": "1.10.0", + "@swc/core-linux-arm64-gnu": "1.10.0", + "@swc/core-linux-arm64-musl": "1.10.0", + "@swc/core-linux-x64-gnu": "1.10.0", + "@swc/core-linux-x64-musl": "1.10.0", + "@swc/core-win32-arm64-msvc": "1.10.0", + "@swc/core-win32-ia32-msvc": "1.10.0", + "@swc/core-win32-x64-msvc": "1.10.0" }, "peerDependencies": { "@swc/helpers": "*" @@ -3920,9 +3879,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.9.3.tgz", - "integrity": "sha512-hGfl/KTic/QY4tB9DkTbNuxy5cV4IeejpPD4zo+Lzt4iLlDWIeANL4Fkg67FiVceNJboqg48CUX+APhDHO5G1w==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.0.tgz", + "integrity": "sha512-wCeUpanqZyzvgqWRtXIyhcFK3CqukAlYyP+fJpY2gWc/+ekdrenNIfZMwY7tyTFDkXDYEKzvn3BN/zDYNJFowQ==", "cpu": [ "arm64" ], @@ -3936,9 +3895,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.9.3.tgz", - "integrity": "sha512-IaRq05ZLdtgF5h9CzlcgaNHyg4VXuiStnOFpfNEMuI5fm5afP2S0FHq8WdakUz5WppsbddTdplL+vpeApt/WCQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.0.tgz", + "integrity": "sha512-0CZPzqTynUBO+SHEl/qKsFSahp2Jv/P2ZRjFG0gwZY5qIcr1+B/v+o74/GyNMBGz9rft+F2WpU31gz2sJwyF4A==", "cpu": [ "x64" ], @@ -3952,9 +3911,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.9.3.tgz", - "integrity": "sha512-Pbwe7xYprj/nEnZrNBvZfjnTxlBIcfApAGdz2EROhjpPj+FBqBa3wOogqbsuGGBdCphf8S+KPprL1z+oDWkmSQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.0.tgz", + "integrity": "sha512-oq+DdMu5uJOFPtRkeiITc4kxmd+QSmK+v+OBzlhdGkSgoH3yRWZP+H2ao0cBXo93ZgCr2LfjiER0CqSKhjGuNA==", "cpu": [ "arm" ], @@ -3968,9 +3927,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.9.3.tgz", - "integrity": "sha512-AQ5JZiwNGVV/2K2TVulg0mw/3LYfqpjZO6jDPtR2evNbk9Yt57YsVzS+3vHSlUBQDRV9/jqMuZYVU3P13xrk+g==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.0.tgz", + "integrity": "sha512-Y6+PC8knchEViRxiCUj3j8wsGXaIhuvU+WqrFqV834eiItEMEI9+Vh3FovqJMBE3L7d4E4ZQtgImHCXjrHfxbw==", "cpu": [ "arm64" ], @@ -3984,9 +3943,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.9.3.tgz", - "integrity": "sha512-tzVH480RY6RbMl/QRgh5HK3zn1ZTFsThuxDGo6Iuk1MdwIbdFYUY034heWUTI4u3Db97ArKh0hNL0xhO3+PZdg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.0.tgz", + "integrity": "sha512-EbrX9A5U4cECCQQfky7945AW9GYnTXtCUXElWTkTYmmyQK87yCyFfY8hmZ9qMFIwxPOH6I3I2JwMhzdi8Qoz7g==", "cpu": [ "arm64" ], @@ -4000,9 +3959,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.9.3.tgz", - "integrity": "sha512-ivXXBRDXDc9k4cdv10R21ccBmGebVOwKXT/UdH1PhxUn9m/h8erAWjz5pcELwjiMf27WokqPgaWVfaclDbgE+w==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.0.tgz", + "integrity": "sha512-TaxpO6snTjjfLXFYh5EjZ78se69j2gDcqEM8yB9gguPYwkCHi2Ylfmh7iVaNADnDJFtjoAQp0L41bTV/Pfq9Cg==", "cpu": [ "x64" ], @@ -4016,9 +3975,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.9.3.tgz", - "integrity": "sha512-ILsGMgfnOz1HwdDz+ZgEuomIwkP1PHT6maigZxaCIuC6OPEhKE8uYna22uU63XvYcLQvZYDzpR3ms47WQPuNEg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.0.tgz", + "integrity": "sha512-IEGvDd6aEEKEyZFZ8oCKuik05G5BS7qwG5hO5PEMzdGeh8JyFZXxsfFXbfeAqjue4UaUUrhnoX+Ze3M2jBVMHw==", "cpu": [ "x64" ], @@ -4032,9 +3991,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.9.3.tgz", - "integrity": "sha512-e+XmltDVIHieUnNJHtspn6B+PCcFOMYXNJB1GqoCcyinkEIQNwC8KtWgMqUucUbEWJkPc35NHy9k8aCXRmw9Kg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.0.tgz", + "integrity": "sha512-UkQ952GSpY+Z6XONj9GSW8xGSkF53jrCsuLj0nrcuw7Dvr1a816U/9WYZmmcYS8tnG2vHylhpm6csQkyS8lpCw==", "cpu": [ "arm64" ], @@ -4048,9 +4007,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.9.3.tgz", - "integrity": "sha512-rqpzNfpAooSL4UfQnHhkW8aL+oyjqJniDP0qwZfGnjDoJSbtPysHg2LpcOBEdSnEH+uIZq6J96qf0ZFD8AGfXA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.0.tgz", + "integrity": "sha512-a2QpIZmTiT885u/mUInpeN2W9ClCnqrV2LnMqJR1/Fgx1Afw/hAtiDZPtQ0SqS8yDJ2VR5gfNZo3gpxWMrqdVA==", "cpu": [ "ia32" ], @@ -4064,9 +4023,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.9.3.tgz", - "integrity": "sha512-3YJJLQ5suIEHEKc1GHtqVq475guiyqisKSoUnoaRtxkDaW5g1yvPt9IoSLOe2mRs7+FFhGGU693RsBUSwOXSdQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.0.tgz", + "integrity": "sha512-tZcCmMwf483nwsEBfUk5w9e046kMa1iSik4bP9Kwi2FGtOfHuDfIcwW4jek3hdcgF5SaBW1ktnK/lgQLDi5AtA==", "cpu": [ "x64" ], @@ -4095,9 +4054,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.62.2", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.2.tgz", - "integrity": "sha512-LcwVcC5qpsDpHcqlXUUL5o9SaOBwhNkGeV+B06s0GBoyBr8FqXPuXT29XzYXR36lchhnerp6XO+CWc84/vh7Zg==", + "version": "5.62.3", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.3.tgz", + "integrity": "sha512-Jp/nYoz8cnO7kqhOlSv8ke/0MJRJVGuZ0P/JO9KQ+f45mpN90hrerzavyTKeSoT/pOzeoOUkv1Xd0wPsxAWXfg==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -4113,11 +4072,11 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.62.2", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.2.tgz", - "integrity": "sha512-fkTpKKfwTJtVPKVR+ag7YqFgG/7TRVVPzduPAUF9zRCiiA8Wu305u+KJl8rCrh98Qce77vzIakvtUyzWLtaPGA==", + "version": "5.62.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.3.tgz", + "integrity": "sha512-y2zDNKuhgiuMgsKkqd4AcsLIBiCfEO8U11AdrtAUihmLbRNztPrlcZqx2lH1GacZsx+y1qRRbCcJLYTtF1vKsw==", "dependencies": { - "@tanstack/query-core": "5.62.2" + "@tanstack/query-core": "5.62.3" }, "funding": { "type": "github", @@ -4128,9 +4087,9 @@ } }, "node_modules/@tanstack/react-query-devtools": { - "version": "5.62.2", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.62.2.tgz", - "integrity": "sha512-s4+88OZ6ygD4ziNfUgh9y1XxsGqpscI77c8EaLP7KwEfa5WqnlB9MT/uslFkFq3vwb8JhMjB7Osv2MYrSMry6w==", + "version": "5.62.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.62.3.tgz", + "integrity": "sha512-4iaQap/iP5ErS094u1WehFntHtjRo6g5HJMvyHovBVbsxnvgPc6AtKAw7qxPPoKy6Wj5Bew0045eYP5phiiBmw==", "dependencies": { "@tanstack/query-devtools": "5.61.4" }, @@ -4139,7 +4098,7 @@ "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.62.2", + "@tanstack/react-query": "^5.62.3", "react": "^18 || ^19" } }, @@ -4456,27 +4415,27 @@ "dev": true }, "node_modules/@types/geojson": { - "version": "7946.0.14", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "version": "7946.0.15", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz", + "integrity": "sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==", "dev": true }, "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", - "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", "dependencies": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" } }, "node_modules/@types/node": { - "version": "22.9.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz", - "integrity": "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, "node_modules/@types/ol": { @@ -4495,31 +4454,31 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" }, "node_modules/@types/rbush": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-3.0.3.tgz", - "integrity": "sha512-lX55lR0iYCgapxD3IrgujpQA1zDxwZI5qMRelKvmKAsSMplFVr7wmMpG7/6+Op2tjrgEex8o3vjg8CRDrRNYxg==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-4.0.0.tgz", + "integrity": "sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==" }, "node_modules/@types/react": { - "version": "18.3.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", - "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "version": "18.3.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.14.tgz", + "integrity": "sha512-NzahNKvjNhVjuPBQ+2G7WlxstQ+47kXZNHlUvFakDViuIEfGY926GqhMueQFZ7woG+sPiQKlF36XfrIUVSUfFg==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "version": "18.3.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.2.tgz", + "integrity": "sha512-Fqp+rcvem9wEnGr3RY8dYNvSQ8PoLqjZ9HLgaPUOjJJD120uDyOxOjc/39M4Kddp9JQCxpGQbnhVQF0C0ncYVg==", "dev": true, "dependencies": { - "@types/react": "*" + "@types/react": "^18" } }, "node_modules/@types/react-textarea-autosize": { @@ -4550,8 +4509,7 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/sockjs-client/-/sockjs-client-1.5.4.tgz", "integrity": "sha512-zk+uFZeWyvJ5ZFkLIwoGA/DfJ+pYzcZ8eH4H/EILCm2OBZyHH6Hkdna1/UWL/CFruh5wj6ES7g75SvUB0VsH5w==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/styled-components": { "version": "5.1.34", @@ -4771,9 +4729,9 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", "dev": true }, "node_modules/@vite-pwa/assets-generator": { @@ -4800,14 +4758,14 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", - "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", "dev": true, "dependencies": { - "@babel/core": "^7.25.2", - "@babel/plugin-transform-react-jsx-self": "^7.24.7", - "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, @@ -4815,19 +4773,19 @@ "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/@vitejs/plugin-react-swc": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.1.tgz", - "integrity": "sha512-vgWOY0i1EROUK0Ctg1hwhtC3SdcDjZcdit4Ups4aPkDcB1jYhmo+RMYWY87cmXMhvtD5uf8lV89j2w16vkdSVg==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.2.tgz", + "integrity": "sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==", "dev": true, "dependencies": { "@swc/core": "^1.7.26" }, "peerDependencies": { - "vite": "^4 || ^5" + "vite": "^4 || ^5 || ^6" } }, "node_modules/@volar/language-core": { @@ -4941,13 +4899,10 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, "engines": { "node": ">= 14" } @@ -5151,9 +5106,9 @@ } }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "dev": true, "dependencies": { "follow-redirects": "^1.15.6", @@ -5181,21 +5136,6 @@ "npm": ">=6" } }, - "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.12", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", @@ -5444,16 +5384,15 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -5462,6 +5401,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.0.tgz", + "integrity": "sha512-CCKAP2tkPau7D3GE8+V8R6sQubA9R5foIzGp+85EXCVSCivuxBNAWqcpn72PKYiIcqoViv/kcUDpaEIMBVi1lQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5491,9 +5443,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001684", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz", - "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==", + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", "dev": true, "funding": [ { @@ -5676,10 +5628,12 @@ } }, "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } }, "node_modules/common-tags": { "version": "1.8.2", @@ -5741,10 +5695,9 @@ } }, "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/core-js-compat": { "version": "3.39.0", @@ -5760,29 +5713,18 @@ } }, "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=10" } }, "node_modules/cross-spawn": { @@ -5996,14 +5938,6 @@ "node": ">=12" } }, - "node_modules/d3-dsv/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -6282,9 +6216,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dependencies": { "ms": "^2.1.3" }, @@ -6519,6 +6453,20 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/earcut": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", @@ -6540,9 +6488,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.64", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.64.tgz", - "integrity": "sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ==", + "version": "1.5.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", + "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==", "dev": true }, "node_modules/emoji-regex": { @@ -6593,11 +6541,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-ex/node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, "node_modules/es-abstract": { "version": "1.23.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", @@ -6659,13 +6602,10 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -6706,14 +6646,14 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -6801,6 +6741,16 @@ "source-map": "~0.6.1" } }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", @@ -6882,12 +6832,12 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.14.tgz", - "integrity": "sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA==", + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz", + "integrity": "sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==", "dev": true, "peerDependencies": { - "eslint": ">=7" + "eslint": ">=8.40" } }, "node_modules/eslint-scope": { @@ -7058,7 +7008,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", - "license": "MIT", "engines": { "node": ">=12.0.0" } @@ -7163,7 +7112,6 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -7316,9 +7264,9 @@ "dev": true }, "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -7326,7 +7274,7 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=14.14" + "node": ">=12" } }, "node_modules/fs.realpath": { @@ -7421,16 +7369,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -7478,15 +7429,14 @@ } }, "node_modules/get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", + "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", "dev": true, "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" + "debug": "^4.3.4" }, "engines": { "node": ">= 14" @@ -7554,9 +7504,9 @@ } }, "node_modules/globals": { - "version": "15.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.12.0.tgz", - "integrity": "sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==", + "version": "15.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz", + "integrity": "sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==", "dev": true, "engines": { "node": ">=18" @@ -7608,12 +7558,12 @@ "dev": true }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7662,10 +7612,13 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -7674,9 +7627,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "engines": { "node": ">= 0.4" @@ -7728,6 +7681,11 @@ "react-is": "^16.7.0" } }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/http-link-header": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.1.3.tgz", @@ -7740,8 +7698,7 @@ "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "license": "MIT" + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "node_modules/http-proxy-agent": { "version": "7.0.2", @@ -7757,12 +7714,12 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -7911,14 +7868,14 @@ } }, "node_modules/intl-messageformat": { - "version": "10.7.7", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.7.tgz", - "integrity": "sha512-F134jIoeYMro/3I0h08D0Yt4N9o9pjddU/4IIxMMURqbAtI2wu70X8hvG1V48W49zXHXv3RKSF/po+0fDfsGjA==", + "version": "10.7.8", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.8.tgz", + "integrity": "sha512-XnFFzJnTfdaDqeiF/ZAUjpkoKEM8UKwHijQXuqpLiM42kuJCawytP/rYAMDYNNaWww/PTaI0rIoG4oUjRrRlnA==", "dev": true, "dependencies": { - "@formatjs/ecma402-abstract": "2.2.4", - "@formatjs/fast-memoize": "2.2.3", - "@formatjs/icu-messageformat-parser": "2.9.4", + "@formatjs/ecma402-abstract": "2.2.5", + "@formatjs/fast-memoize": "2.2.4", + "@formatjs/icu-messageformat-parser": "2.9.5", "tslib": "2" } }, @@ -7969,10 +7926,9 @@ } }, "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-async-function": { "version": "2.0.0", @@ -7990,25 +7946,28 @@ } }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.0.tgz", + "integrity": "sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8188,12 +8147,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.0.tgz", + "integrity": "sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8221,13 +8181,15 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.0.tgz", + "integrity": "sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "gopd": "^1.1.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -8285,12 +8247,13 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz", + "integrity": "sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8300,12 +8263,14 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.0.tgz", + "integrity": "sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "call-bind": "^1.0.7", + "has-symbols": "^1.0.3", + "safe-regex-test": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -8811,9 +8776,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.13", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.13.tgz", - "integrity": "sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==", + "version": "0.30.14", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.14.tgz", + "integrity": "sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" @@ -8970,9 +8935,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -9089,15 +9054,15 @@ } }, "node_modules/ol": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ol/-/ol-10.2.1.tgz", - "integrity": "sha512-2bB/y2vEnmzjqynP0NA7Cp8k86No3Psn63Dueicep3E3i09axWRVIG5IS/bylEAGfWQx0QXD/uljkyFoY60Wig==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/ol/-/ol-10.3.1.tgz", + "integrity": "sha512-D1nRQVLOBCRempVqBFV8pSI5H13BtnhuLDjGl+3NKdMOFyjx/UqRX/tcMspEw3LhFOSPWn1Ev+1KIRV8AlHM7A==", "dependencies": { - "@types/rbush": "3.0.3", + "@types/rbush": "4.0.0", "color-rgba": "^3.0.0", "color-space": "^2.0.1", "earcut": "^3.0.0", - "geotiff": "^2.0.7", + "geotiff": "^2.1.3", "pbf": "4.0.1", "rbush": "^4.0.0" }, @@ -9180,19 +9145,19 @@ } }, "node_modules/pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", + "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", "dev": true, "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.5", + "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -9457,9 +9422,9 @@ } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -9502,25 +9467,30 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, "node_modules/proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "dev": true, "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", + "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", + "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -9561,12 +9531,12 @@ } }, "node_modules/puppeteer-core": { - "version": "23.9.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.9.0.tgz", - "integrity": "sha512-hLVrav2HYMVdK0YILtfJwtnkBAwNOztUdR4aJ5YKDvgsbtagNr6urUJk9HyjRA9e+PaLI3jzJ0wM7A4jSZ7Qxw==", + "version": "23.10.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.10.1.tgz", + "integrity": "sha512-ey6NwixHYEUnhCA/uYi7uQQ4a0CZw4k+MatbHXGl5GEzaiRQziYUxc2HGpdQZ/gnh4KQWAKkocyIg1/dIm5d0g==", "dev": true, "dependencies": { - "@puppeteer/browsers": "2.4.1", + "@puppeteer/browsers": "2.5.0", "chromium-bidi": "0.8.0", "debug": "^4.3.7", "devtools-protocol": "0.0.1367902", @@ -9607,8 +9577,7 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "license": "MIT" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -9746,17 +9715,17 @@ } }, "node_modules/react-icons": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", - "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz", + "integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==", "peerDependencies": { "react": "*" } }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/react-refresh": { "version": "0.14.2", @@ -9843,18 +9812,19 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.7.tgz", - "integrity": "sha512-bMvFGIUKlc/eSfXNX+aZ+EL95/EgZzuwA0OBPTbZZDEJw/0AkentjMuM1oiRfwHrshqk4RzdgiTg5CcDalXN5g==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz", + "integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", + "dunder-proto": "^1.0.0", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "which-builtin-type": "^1.1.4" + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.0" }, "engines": { "node": ">= 0.4" @@ -9969,8 +9939,7 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { "version": "1.22.8", @@ -10045,9 +10014,9 @@ "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" }, "node_modules/rollup": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.4.tgz", - "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", + "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", "dev": true, "dependencies": { "@types/estree": "1.0.6" @@ -10060,24 +10029,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.27.4", - "@rollup/rollup-android-arm64": "4.27.4", - "@rollup/rollup-darwin-arm64": "4.27.4", - "@rollup/rollup-darwin-x64": "4.27.4", - "@rollup/rollup-freebsd-arm64": "4.27.4", - "@rollup/rollup-freebsd-x64": "4.27.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.27.4", - "@rollup/rollup-linux-arm-musleabihf": "4.27.4", - "@rollup/rollup-linux-arm64-gnu": "4.27.4", - "@rollup/rollup-linux-arm64-musl": "4.27.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.27.4", - "@rollup/rollup-linux-riscv64-gnu": "4.27.4", - "@rollup/rollup-linux-s390x-gnu": "4.27.4", - "@rollup/rollup-linux-x64-gnu": "4.27.4", - "@rollup/rollup-linux-x64-musl": "4.27.4", - "@rollup/rollup-win32-arm64-msvc": "4.27.4", - "@rollup/rollup-win32-ia32-msvc": "4.27.4", - "@rollup/rollup-win32-x64-msvc": "4.27.4", + "@rollup/rollup-android-arm-eabi": "4.28.1", + "@rollup/rollup-android-arm64": "4.28.1", + "@rollup/rollup-darwin-arm64": "4.28.1", + "@rollup/rollup-darwin-x64": "4.28.1", + "@rollup/rollup-freebsd-arm64": "4.28.1", + "@rollup/rollup-freebsd-x64": "4.28.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", + "@rollup/rollup-linux-arm-musleabihf": "4.28.1", + "@rollup/rollup-linux-arm64-gnu": "4.28.1", + "@rollup/rollup-linux-arm64-musl": "4.28.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", + "@rollup/rollup-linux-riscv64-gnu": "4.28.1", + "@rollup/rollup-linux-s390x-gnu": "4.28.1", + "@rollup/rollup-linux-x64-gnu": "4.28.1", + "@rollup/rollup-linux-x64-musl": "4.28.1", + "@rollup/rollup-win32-arm64-msvc": "4.28.1", + "@rollup/rollup-win32-ia32-msvc": "4.28.1", + "@rollup/rollup-win32-x64-msvc": "4.28.1", "fsevents": "~2.3.2" } }, @@ -10367,6 +10337,12 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -10406,7 +10382,6 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz", "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==", - "license": "MIT", "dependencies": { "debug": "^3.2.7", "eventsource": "^2.0.2", @@ -10425,7 +10400,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -10445,12 +10419,12 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -10459,10 +10433,9 @@ } }, "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { "node": ">=0.10.0" } @@ -10485,6 +10458,15 @@ "source-map": "^0.6.0" } }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -10513,9 +10495,9 @@ "dev": true }, "node_modules/streamx": { - "version": "2.20.2", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.2.tgz", - "integrity": "sha512-aDGDLU+j9tJcUdPGOaHmVF1u/hhI+CsGkT02V3OKlHDV7IukOI+nTWAGkiZEKCO35rWN1wIr4tS7YFr1f4qSvA==", + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.0.tgz", + "integrity": "sha512-Qz6MsDZXJ6ur9u+b+4xCG18TluU7PGlRfXVAAjNiGsFrBUt/ioyLkxbFaKJygoPs+/kW4VyBj0bSj89Qu0IGyg==", "dev": true, "dependencies": { "fast-fifo": "^1.3.2", @@ -10716,6 +10698,29 @@ "react-dom": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/styled-components/node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/styled-components/node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" + }, "node_modules/styled-components/node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -10733,9 +10738,9 @@ } }, "node_modules/stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { "version": "7.2.0", @@ -10825,9 +10830,9 @@ } }, "node_modules/terser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", - "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -10842,12 +10847,21 @@ "node": ">=10" } }, - "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/text-decoder": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.2.tgz", + "integrity": "sha512-/MDslo7ZyWTA2vnk1j7XoDVfXsGk3tp+zFEJHJGm0UjIlQifonVFwlVbQDFh8KJzTBnT8ie115TYqir6bclddA==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10906,18 +10920,18 @@ } }, "node_modules/tldts-core": { - "version": "6.1.64", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.64.tgz", - "integrity": "sha512-uqnl8vGV16KsyflHOzqrYjjArjfXaU6rMPXYy2/ZWoRKCkXtghgB4VwTDXUG+t0OTGeSewNAG31/x1gCTfLt+Q==", + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.66.tgz", + "integrity": "sha512-s07jJruSwndD2X8bVjwioPfqpIc1pDTzszPe9pL1Skbh4bjytL85KNQ3tolqLbCvpQHawIsGfFi9dgerWjqW4g==", "dev": true }, "node_modules/tldts-icann": { - "version": "6.1.64", - "resolved": "https://registry.npmjs.org/tldts-icann/-/tldts-icann-6.1.64.tgz", - "integrity": "sha512-P9UZA03O8xhgWc1ZltY8gyJyHMjmL2udAi66BzIhkx1cVqOTMQG0zrfIpdmKtuddiYq46a17FsDUbVarIcLfiQ==", + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts-icann/-/tldts-icann-6.1.66.tgz", + "integrity": "sha512-f4AgNXjymBX3/EXYrnvjyBhXVQ+NWyPzXjqRb17vr0b6SprZKVNnsWNFJAPI6JkPHCm7dHhFDgyneHQEq5uJRA==", "dev": true, "dependencies": { - "tldts-core": "^6.1.64" + "tldts-core": "^6.1.66" } }, "node_modules/to-data-view": { @@ -10948,9 +10962,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "engines": { "node": ">=16" @@ -11124,14 +11138,14 @@ } }, "node_modules/typescript-eslint": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.15.0.tgz", - "integrity": "sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.17.0.tgz", + "integrity": "sha512-409VXvFd/f1br1DCbuKNFqQpXICoTB+V51afcwG1pn1a3Cp92MqAUges3YjwEdQ0cMUoCIodjVDAYzyD8h3SYA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.15.0", - "@typescript-eslint/parser": "8.15.0", - "@typescript-eslint/utils": "8.15.0" + "@typescript-eslint/eslint-plugin": "8.17.0", + "@typescript-eslint/parser": "8.17.0", + "@typescript-eslint/utils": "8.17.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11150,16 +11164,16 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", - "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz", + "integrity": "sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/type-utils": "8.15.0", - "@typescript-eslint/utils": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", + "@typescript-eslint/scope-manager": "8.17.0", + "@typescript-eslint/type-utils": "8.17.0", + "@typescript-eslint/utils": "8.17.0", + "@typescript-eslint/visitor-keys": "8.17.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -11183,15 +11197,15 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", - "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.17.0.tgz", + "integrity": "sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/typescript-estree": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", + "@typescript-eslint/scope-manager": "8.17.0", + "@typescript-eslint/types": "8.17.0", + "@typescript-eslint/typescript-estree": "8.17.0", + "@typescript-eslint/visitor-keys": "8.17.0", "debug": "^4.3.4" }, "engines": { @@ -11211,13 +11225,13 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", - "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz", + "integrity": "sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0" + "@typescript-eslint/types": "8.17.0", + "@typescript-eslint/visitor-keys": "8.17.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11228,13 +11242,13 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", - "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.17.0.tgz", + "integrity": "sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.15.0", - "@typescript-eslint/utils": "8.15.0", + "@typescript-eslint/typescript-estree": "8.17.0", + "@typescript-eslint/utils": "8.17.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -11255,9 +11269,9 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.15.0.tgz", - "integrity": "sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.17.0.tgz", + "integrity": "sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11268,13 +11282,13 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz", - "integrity": "sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz", + "integrity": "sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", + "@typescript-eslint/types": "8.17.0", + "@typescript-eslint/visitor-keys": "8.17.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -11296,15 +11310,15 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.15.0.tgz", - "integrity": "sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.17.0.tgz", + "integrity": "sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/typescript-estree": "8.15.0" + "@typescript-eslint/scope-manager": "8.17.0", + "@typescript-eslint/types": "8.17.0", + "@typescript-eslint/typescript-estree": "8.17.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11323,12 +11337,12 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", - "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz", + "integrity": "sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/types": "8.17.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -11397,9 +11411,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -11522,7 +11536,6 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -11543,11 +11556,11 @@ } }, "node_modules/use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -11650,31 +11663,17 @@ "vite": ">=2.0.0" } }, - "node_modules/vite-plugin-compression/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/vite-plugin-compression2": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/vite-plugin-compression2/-/vite-plugin-compression2-1.3.1.tgz", - "integrity": "sha512-UMr66CFu+RVPiD8E3iaX9BdZjCgO+lzzaAPAZvL5YgwH6FU4OR/MulJEyp9wq9EKoO6ErjUtPpaiDi3hvzv79Q==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/vite-plugin-compression2/-/vite-plugin-compression2-1.3.3.tgz", + "integrity": "sha512-Mb+xi/C5b68awtF4fNwRBPtoZiyUHU3I0SaBOAGlerlR31kusq1si6qG31lsjJH8T7QNg/p3IJY2HY9O9SvsfQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.1.0", "tar-mini": "^0.2.0" }, - "optionalDependencies": { - "vite": "^5.3.4" + "peerDependencies": { + "vite": "^2.0.0||^3.0.0||^4.0.0||^5.0.0 ||^6.0.0" } }, "node_modules/vite-plugin-dts": { @@ -11769,9 +11768,9 @@ } }, "node_modules/vite-tsconfig-paths": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.3.tgz", - "integrity": "sha512-0bz+PDlLpGfP2CigeSKL9NFTF1KtXkeHGZSSaGQSuPZH77GhoiQaA8IjYgOaynSuwlDTolSUEU0ErVvju3NURg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", + "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -11836,7 +11835,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -11850,7 +11848,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } @@ -11882,16 +11879,19 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.0.tgz", + "integrity": "sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==", "dev": true, "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.0", + "is-number-object": "^1.1.0", + "is-string": "^1.1.0", + "is-symbol": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11943,9 +11943,9 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz", + "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", @@ -12485,9 +12485,9 @@ "integrity": "sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==" }, "node_modules/zustand": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.1.tgz", - "integrity": "sha512-pRET7Lao2z+n5R/HduXMio35TncTlSW68WsYBq2Lg1ASspsNGjpwLAsij3RpouyV6+kHMwwwzP0bZPD70/Jx/w==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.2.tgz", + "integrity": "sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw==", "engines": { "node": ">=12.20.0" }, diff --git a/src/apis/dog/useDogProfile.tsx b/src/apis/dog/useDogProfile.tsx index 17d7ddb4..53c0acfa 100644 --- a/src/apis/dog/useDogProfile.tsx +++ b/src/apis/dog/useDogProfile.tsx @@ -10,12 +10,11 @@ import { queryKey } from '~constants/queryKey' import { patchDogProfile, PatchDogProfileRequest } from '~apis/dog/patchDogProfile' import ConfirmModal from '~modals/ConfirmModal' -const { pushModal, popModal, clearModal } = useModalStore() -const { showToast } = useToastStore() -const navigate = useNavigate() - export function useCreateDogProfile() { const { setDogProfile } = useDogProfileStore() + const { pushModal, clearModal } = useModalStore() + const { showToast } = useToastStore() + const navigate = useNavigate() const completeRegistration = () => { navigate('/') @@ -43,16 +42,18 @@ export function useFetchDogProfile(id: number) { export function usePatchDogProfile(id: number) { const queryClient = useQueryClient() + const { clearModal, pushModal } = useModalStore() + const { showToast } = useToastStore() const completeRegistration = () => { queryClient.invalidateQueries({ queryKey: queryKey.dog.profile(id) }) - popModal() + clearModal() } return useMutation({ mutationFn: (data: PatchDogProfileRequest) => patchDogProfile(id, data), onSuccess: () => { - pushModal() + pushModal() }, onError: (error: Error) => { showToast(error.message) diff --git a/src/apis/family/fetchfamilyDogs.ts b/src/apis/family/fetchfamilyDogs.ts index f9f026e4..8b696ce3 100644 --- a/src/apis/family/fetchfamilyDogs.ts +++ b/src/apis/family/fetchfamilyDogs.ts @@ -1,4 +1,3 @@ -// apis/family/fetchFamilyDogs.ts import { AxiosError } from 'axios' import { APIResponse, CommonAPIResponse, ErrorResponse } from '~types/api' import { axiosInstance } from '~apis/axiosInstance' diff --git a/src/modals/ConfirmModal/index.tsx b/src/modals/ConfirmModal/index.tsx index 1f1f29ef..772dd3f1 100644 --- a/src/modals/ConfirmModal/index.tsx +++ b/src/modals/ConfirmModal/index.tsx @@ -1,5 +1,5 @@ import * as S from './styles' -import { Typo20 } from '~components/Typo' +import { Typo17 } from '~components/Typo' interface ConfirmModalProps { content: string @@ -10,7 +10,7 @@ export default function ConfirmModal({ content, onClick }: ConfirmModalProps) { return ( - {content} + {content} 확인 diff --git a/src/modals/ConfirmModal/styles.ts b/src/modals/ConfirmModal/styles.ts index 282d0904..2117f241 100644 --- a/src/modals/ConfirmModal/styles.ts +++ b/src/modals/ConfirmModal/styles.ts @@ -1,30 +1,37 @@ import styled from 'styled-components' export const ConfirmModalOverlay = styled.div` - width: 100%; - height: 100%; - background-color: (0, 0, 0, 0.4); + z-index: 999; + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.4); display: flex; justify-content: center; align-content: center; ` export const ConfirmModal = styled.div` - width: 300px; - height: 200px; + position: absolute; + transform: translateY(-50%); + top: 50%; + width: 260px; + height: 180px; background-color: ${props => props.theme.colors.grayscale.gc_4}; + padding: 20px 24px; display: flex; flex-direction: column; + justify-content: center; + align-items: center; gap: 30px; - - font-size: 20px; - font-weight: 700; ` export const ConfirmButton = styled.button` - border-radius: 30px; - width: 80px; + border-radius: 24px; + width: 90px; height: 50px; background-color: ${props => props.theme.colors.brand.darken}; color: ${props => props.theme.colors.grayscale.gc_4}; diff --git a/src/modals/EditDogProfileModal/index.tsx b/src/modals/EditDogProfileModal/index.tsx index 6c2cfe0d..695b3d39 100644 --- a/src/modals/EditDogProfileModal/index.tsx +++ b/src/modals/EditDogProfileModal/index.tsx @@ -116,6 +116,7 @@ export default function EditDogProfileModal({ dogId }: EditDogProfileModalProps) type: 'application/json', }) ) + console.log('hi') if (dogProfile.profileImgFile) formData.append('profileImgFile', dogProfile.profileImgFile) patchDogProfileMutation.mutate(formData) } diff --git a/src/modals/EditDogProfileModal/styles.ts b/src/modals/EditDogProfileModal/styles.ts index eef5a614..81563d68 100644 --- a/src/modals/EditDogProfileModal/styles.ts +++ b/src/modals/EditDogProfileModal/styles.ts @@ -1,6 +1,7 @@ import styled from 'styled-components' export const EditDogProfileModal = styled.div` + z-index: 100; overflow-y: auto; padding: 90px 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx index 6f241e73..9ee23b67 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx +++ b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx @@ -4,7 +4,7 @@ import { Typo17, Typo24, Typo15 } from '~components/Typo/index.ts' import Header from '~components/Header/index.tsx' import DogImage from '~assets/dog_standup.svg?react' import { Timer } from './Timer' -import { useInviteCode } from '~apis/family/useFamily.ts' +import { useInviteCode } from '~apis/family/useFamily.tsx' export default function ShareCodeModal() { const { popModal } = useModalStore() diff --git a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx index 1045d7a0..af67a3c4 100644 --- a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx @@ -8,6 +8,7 @@ import { useModalStore } from '~stores/modalStore' import { DogProfileType } from '~types/dogProfile' import { useJoinFamily } from '~apis/family/useFamily' import { calculateAge } from '~utils/calculateAge' +import Toast from '~components/Toast/index' interface CheckDogProfileSectionProp { familyCode: string @@ -50,7 +51,10 @@ export default function CheckDogProfileSection({ familyCode, dogProfiles }: Chec - 다음 + + 다음 + + ) diff --git a/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts b/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts index 920d7c6d..81435419 100644 --- a/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts +++ b/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts @@ -45,3 +45,7 @@ export const TagWrapper = styled.div` export const TypoWrapper = styled.div` text-align: center; ` + +export const ActionButtonWrapper = styled.div` + position: relative; +` From 1ccacbcf1106bd0e170ef43687b326ae39f7b80c Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 11:56:15 +0900 Subject: [PATCH 16/19] =?UTF-8?q?=20=F0=9F=90=9B=20Fix:=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B0=95=EC=95=84=EC=A7=80=20=EC=88=98=EC=A0=95=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=B3=B4=EC=9D=B4=EB=8A=94=20=ED=98=84=EC=83=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DogProfile/index.tsx | 41 +++++++++++++---------------- src/pages/FamilyDDangPage/index.tsx | 2 +- src/pages/MyPage/index.tsx | 2 +- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/components/DogProfile/index.tsx b/src/components/DogProfile/index.tsx index d077b9d7..4f326b69 100644 --- a/src/components/DogProfile/index.tsx +++ b/src/components/DogProfile/index.tsx @@ -8,41 +8,38 @@ import { useModalStore } from '~stores/modalStore' import EditDogProfileModal from '~modals/EditDogProfileModal' import { calculateAge } from '~utils/calculateAge' -export default function DogProfile({ - dogId, - name, - gender, - profileImg, - birthDate, - breed, - comment, - isNeutered, - weight, -}: DogProfileType) { - const age = calculateAge(birthDate!) +interface DogProfileProps { + dogProfile: DogProfileType + isEditBtnVisible?: boolean +} + +export default function DogProfile({ dogProfile, isEditBtnVisible = false }: DogProfileProps) { + const age = calculateAge(dogProfile.birthDate!) const { pushModal } = useModalStore() return ( - pushModal()}> - - - + {isEditBtnVisible && ( + pushModal()}> + + + )} + - {name} + {dogProfile.name} - {breed} + {dogProfile.breed} {age}살 - {gender === 'MALE' ? '남' : '여'} + {dogProfile.gender === 'MALE' ? '남' : '여'} - 중성화 {isNeutered === 'TRUE' ? 'O' : 'X'} + 중성화 {dogProfile.isNeutered === 'TRUE' ? 'O' : 'X'} - {weight} KG + {dogProfile.weight} KG @@ -51,7 +48,7 @@ export default function DogProfile({ 우리 댕댕이를 소개해요! - {comment} + {dogProfile.comment} diff --git a/src/pages/FamilyDDangPage/index.tsx b/src/pages/FamilyDDangPage/index.tsx index 21dc4ec5..bc7dae7c 100644 --- a/src/pages/FamilyDDangPage/index.tsx +++ b/src/pages/FamilyDDangPage/index.tsx @@ -33,7 +33,7 @@ export default function FamilyDDang() { - {dogInfo && } + {dogInfo && } diff --git a/src/pages/MyPage/index.tsx b/src/pages/MyPage/index.tsx index 785216e7..d214ddea 100644 --- a/src/pages/MyPage/index.tsx +++ b/src/pages/MyPage/index.tsx @@ -79,7 +79,7 @@ export default function MyPage() { - {myPageData?.dog && } + {myPageData?.dog && } {/* {myPageData?.walkCount}회 From a188c29c38c980d2382ad387554f662a8b2befd7 Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 12:15:04 +0900 Subject: [PATCH 17/19] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EC=8A=AC=EB=9D=BC=EC=9D=B4=EB=93=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DogProfile/index.tsx | 2 +- src/modals/RegisterDogModal/FamilyCodeSection/index.tsx | 3 ++- src/pages/FamilyDDangPage/index.tsx | 2 +- src/pages/LogPage/index.tsx | 6 +++++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/DogProfile/index.tsx b/src/components/DogProfile/index.tsx index 4f326b69..309cc7c8 100644 --- a/src/components/DogProfile/index.tsx +++ b/src/components/DogProfile/index.tsx @@ -20,7 +20,7 @@ export default function DogProfile({ dogProfile, isEditBtnVisible = false }: Dog {isEditBtnVisible && ( - pushModal()}> + pushModal(, 'slideLeft')}> )} diff --git a/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx b/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx index 52ac66bf..25f74918 100644 --- a/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx +++ b/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx @@ -24,7 +24,8 @@ export default function FamilyCodeSection() { return } const dogProfiles = await fetchFamilyDogsMutation.mutateAsync(familyCode) - if (dogProfiles) pushModal() + if (dogProfiles) + pushModal(, 'slideLeft') } return ( <> diff --git a/src/pages/FamilyDDangPage/index.tsx b/src/pages/FamilyDDangPage/index.tsx index bc7dae7c..8fd5d8cb 100644 --- a/src/pages/FamilyDDangPage/index.tsx +++ b/src/pages/FamilyDDangPage/index.tsx @@ -22,7 +22,7 @@ export default function FamilyDDang() { }, [modalList]) const onClickCodeShare = () => { - pushModal() + pushModal(, 'slideLeft') } return ( diff --git a/src/pages/LogPage/index.tsx b/src/pages/LogPage/index.tsx index 983017a3..8f1aba13 100644 --- a/src/pages/LogPage/index.tsx +++ b/src/pages/LogPage/index.tsx @@ -32,7 +32,11 @@ export default function LogPage() {
밤톨이 일기 - pushModal()} /> + pushModal(, 'slideLeft')} + />
From e1b4f1f8f3ed48646c4ea99c2a53d602d5fd50fe Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 13:09:59 +0900 Subject: [PATCH 18/19] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=ED=81=B4=EB=A6=BD=EB=B3=B4=EB=93=9C?= =?UTF-8?q?=EC=97=90=20=EB=B3=B5=EC=82=AC=ED=95=98=EA=B3=A0=20=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=ED=95=98=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modals/FamilyDDangModal/ShareCodeModal/index.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx index 9ee23b67..ac823394 100644 --- a/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx +++ b/src/modals/FamilyDDangModal/ShareCodeModal/index.tsx @@ -11,19 +11,15 @@ export default function ShareCodeModal() { const { data, refetch } = useInviteCode() const handleShare = async () => { + navigator.clipboard.writeText(data.inviteCode) if (navigator.share) { try { await navigator.share({ - title: '패밀리코드', - text: '텍스트', - url: data.inviteCode, + text: data.inviteCode, }) } catch (err) { console.error('Error sharing:', err) } - } else { - navigator.clipboard.writeText(window.location.href) - alert('Link copied to clipboard!') } } From bfb19f3a952c2d2fd1bc049b64fb0f2dd08b9fbf Mon Sep 17 00:00:00 2001 From: wonil Date: Mon, 9 Dec 2024 13:28:11 +0900 Subject: [PATCH 19/19] =?UTF-8?q?=F0=9F=90=9B=20Fix:=20=EB=B9=8C=EB=93=9C?= =?UTF-8?q?=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ProfilePage/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ProfilePage/index.tsx b/src/pages/ProfilePage/index.tsx index a845cf0a..b778580e 100644 --- a/src/pages/ProfilePage/index.tsx +++ b/src/pages/ProfilePage/index.tsx @@ -53,7 +53,7 @@ function ProfileContent({ id }: { id: number }) { - {data && } + {data && } ) }