diff --git a/src/Router.tsx b/src/Router.tsx index 4572b89..aae8af5 100644 --- a/src/Router.tsx +++ b/src/Router.tsx @@ -20,12 +20,12 @@ const Router = () => { }, { index: true, - path: '/map/:mapName/edit', + path: '/map/:mapId/edit', element: , }, { index: true, - path: '/map/:mapName/view', + path: '/map/:mapId/view', element: , }, { diff --git a/src/apis/Map/fetchMapBasicInfo.ts b/src/apis/Map/fetchMapBasicInfo.ts new file mode 100644 index 0000000..c3ac15d --- /dev/null +++ b/src/apis/Map/fetchMapBasicInfo.ts @@ -0,0 +1,32 @@ +import { useQuery } from 'react-query'; +import instance from '../instance'; +import { BaseResponse } from '../../types/BaseResponse'; +import { MapBasicInfo } from '../../types/map/MapBasicInfo'; +import { MapMode } from '../../types/enum/MapMode'; + +export const fetchMapBasicInfo = async (id: number) => { + const response = await instance.get>( + `/map/${id}/basic-info/edit`, + ); + return response.data; +}; + +export const fetchMapBasicInfoForViewer = async (id: number) => { + const response = await instance.get>( + `/map/${id}/basic-info/view`, + ); + return response.data; +}; + +export const useMapBasicInfoQuery = (id: number, mapMode: MapMode) => { + const { data: mapBasicInfo, isLoading: isMapBasicInfoLoading } = useQuery({ + queryKey: ['fetchMapBasicInfo'], + + queryFn: () => { + if (mapMode === MapMode.EDIT) return fetchMapBasicInfo(id); + if (mapMode === MapMode.VIEW) return fetchMapBasicInfoForViewer(id); + }, + }); + + return { mapBasicInfo, isMapBasicInfoLoading }; +}; diff --git a/src/components/explore/MapList.tsx b/src/components/explore/MapList.tsx index 769c7b4..0b5ded0 100644 --- a/src/components/explore/MapList.tsx +++ b/src/components/explore/MapList.tsx @@ -115,7 +115,7 @@ const MapList: React.FC = ({ map, keywordMap }) => {
User
diff --git a/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.module.scss b/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.module.scss index c372981..82b43e5 100644 --- a/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.module.scss +++ b/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.module.scss @@ -8,3 +8,65 @@ padding: 16px; border-bottom: 1px solid var(--gray_50); } + +.mapInfoInputContainer { + width: 100%; + display: flex; + flex-direction: column; + gap: 12px; + padding-bottom: 16px; + border-bottom: 1px solid var(--gray_50); +} + +.titleContainer { + display: flex; + justify-content: space-between; + align-items: center; +} +#mapTitle { + width: calc(100% - 24px); + border: none; + font-size: 20px; + font-weight: 600; +} +#mapTitle:disabled, +#mapDescription:disabled { + background: none; +} + +#mapDescription { + border: none; + resize: none; + font-size: 14px; + overflow: hidden; + width: 100%; + field-sizing: content; +} +#mapDescription:focus { + outline: none; +} +#mapTitle::-webkit-input-placeholder, +#mapDescription::-webkit-input-placeholder { + color: var(--gray_400); +} + +.bookmarkBtn:hover { + cursor: pointer; +} + +.locationInfoContainer { + display: flex; + flex-direction: column; + gap: 16px; +} + +.locationInfo { + display: flex; + justify-content: space-between; + span { + font-size: 14px; + } +} +.location__title { + color: var(--gray_400); +} diff --git a/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.tsx b/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.tsx index e2b5c23..00e3072 100644 --- a/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.tsx +++ b/src/components/map/MapInfoPanel/MapBasicInfo/MapBasicInfoContainer/MapBasicInfoContainer.tsx @@ -1,17 +1,119 @@ +import { useEffect, useState } from 'react'; import styles from './MapBasicInfoContainer.module.scss'; -import MapTitleAndDescriptionInputContainer from './MapTitleAndDescriptionInputContainer'; -import LocationInfoContainer from './MapLocationInfoContainer'; +import { useMapBasicInfoQuery } from '../../../../../apis/Map/fetchMapBasicInfo'; +import useRegisterStore from '../../../../../stores/registerStore'; import { MapMode } from '../../../../../types/enum/MapMode'; +import { RegisterStatus } from '../../../../../types/enum/RegisterStatus'; +import BookmarkDefault from '../../../../../assets/btn_bookmark_default.svg'; +import BookmarkSelected from '../../../../../assets/btn_bookmark_selected.svg'; interface Props { mode: MapMode; + mapId: number; } -const MapBasicInfoContainer: React.FC = ({ mode }) => { +const MapBasicInfoContainer: React.FC = ({ mode, mapId }) => { + const { registerStatus, setLoginNeededStatus } = useRegisterStore(); + const [editedTitle, setEditedTitle] = useState(''); + const [editedDescription, setEditedDescription] = useState(''); + + const { mapBasicInfo, isMapBasicInfoLoading } = useMapBasicInfoQuery( + mapId, + mode, + ); + + useEffect(() => { + if (!isMapBasicInfoLoading) { + const mapBasicInfoResult = mapBasicInfo!.result; + setEditedTitle(mapBasicInfoResult.title); + setEditedDescription(mapBasicInfoResult.description); + } + }, [isMapBasicInfoLoading]); + + const handleTitleOnChange = (e: React.ChangeEvent) => { + setEditedTitle(e.currentTarget.value); + }; + + const handleDescriptionOnChange = ( + e: React.ChangeEvent, + ) => { + setEditedDescription(e.currentTarget.value); + }; + + const handleFocusOutTitle = () => { + //TODO: 지도 제목 저장 api 호출 + }; + + const handleFocusOutDescription = () => { + //TODO: 지도 설명 저장 api 호출 + }; + + const handleSwitchIsBookmarked = () => { + if (registerStatus !== RegisterStatus.LOG_IN) { + setLoginNeededStatus(true); + } else { + //TODO: 북마크 설정 api 호출 + } + }; return (
- - +
+
+ + {mapBasicInfo !== undefined && + !mapBasicInfo.result.mine && + (mapBasicInfo.result.bookmarked ? ( + 북마크함 + ) : ( + 북마크하지 않음 + ))} +
+