diff --git a/project/package.json b/project/package.json index fe2c59ba..25e46c0b 100644 --- a/project/package.json +++ b/project/package.json @@ -65,5 +65,5 @@ "@types/styled-components": "^5.1.26", "styled-components": "^5.3.6" }, - "proxy": "http://pikcha36.o-r.kr:8080" + "proxy" : "http://pikcha36.o-r.kr:8080" } diff --git a/project/src/App.tsx b/project/src/App.tsx index 8c01d229..bc717d3c 100644 --- a/project/src/App.tsx +++ b/project/src/App.tsx @@ -12,6 +12,7 @@ import { RecoilRoot } from "recoil"; import DetailPost from "./pages/DetailPost"; import MyPage from "./pages/MyPage"; import EditPost from "./pages/EditPost "; +import Oauth from "./pages/Oauth" function App() { if (localStorage.getItem("loginStatus") === null) { @@ -33,6 +34,7 @@ function App() { } /> } /> } /> + } /> diff --git a/project/src/components/GoogleLogin.js b/project/src/components/GoogleLogin.js deleted file mode 100644 index 5f30e2fa..00000000 --- a/project/src/components/GoogleLogin.js +++ /dev/null @@ -1,59 +0,0 @@ -import { GoogleLogin } from "@react-oauth/google"; -import { GoogleOAuthProvider } from "@react-oauth/google"; - -const GoogleLogIn = () => { - return ( - - { - console.log(credentialResponse); - }} - onError={() => { - console.log("Login Failed"); - }} - /> - - ); -}; - -export default GoogleLogIn; - -// import React, { useEffect } from 'react' -// import { GoogleLogin, GoogleLogout } from 'react-google-login' - -// const GoogleLogIn = () => { - -// // 로그인 성공했을 때 처리 함수 -// const successGoogle = (response) => { -// console.log(response); -// } - -// //로그인 실패했을 때 처리 함수 -// const failGoogle = (response) => { -// console.log(response); -// } - -// // 로그아웃 성공했을 때 처리 함수 -// const onLogoutSuccess = () => { -// console.log('SUCESS LOG OUT'); -// }; - -// return ( -// -// -// -// -// ) -// } - -// export default GoogleLogIn diff --git a/project/src/components/Header/index.tsx b/project/src/components/Header/index.tsx index 196532ca..e4be2987 100644 --- a/project/src/components/Header/index.tsx +++ b/project/src/components/Header/index.tsx @@ -25,7 +25,6 @@ const SearchBar = lazy(() => import("./SearchBar")); const IMG_SRC = "https://drive.google.com/uc?id=1OmsgU1GLU9iUBYe9ruw_Uy1AcrN57n4g"; -const isLoggedIn = true; const HeaderTopBar = () => { const navigate = useNavigate(); diff --git a/project/src/components/KakaoMap.tsx b/project/src/components/KakaoMap.tsx index 6d0ac269..4c4323f0 100644 --- a/project/src/components/KakaoMap.tsx +++ b/project/src/components/KakaoMap.tsx @@ -8,15 +8,6 @@ declare global { } } -// 안내창 커스텀입니다. -let info = -`
-

광화문

-

주소 : 종로구 사직로 161

- 더보기 -
` - - // 주소 더미 데이터 var listData = [ '종로구 사직로 161', @@ -33,14 +24,17 @@ interface Map { left:string, regionFilter:string, component:string, - dataset:any + dataset:any, + modalData:any, + filterOrPosition:any, + setFilterOrPosition:any } export interface DataList { attractionAddress: string, attractionId:number, attractionName:string, - fixedImage:string + fixedImage:string, } const MyPosition = styled.div` @@ -64,11 +58,12 @@ const MyPosition = styled.div` ` -const KakaoMap = ({width, height, dataList, position, left, regionFilter, component, dataset }:Map) =>{ - const [filterOrPosition, setFilterOrPosition] = useState(false); +const KakaoMap = ({width, height, dataList, position, left, regionFilter, component, dataset, modalData ,filterOrPosition, setFilterOrPosition}:Map) =>{ + //const [filterOrPosition, setFilterOrPosition] = useState(false); // false 일때는 필터링, // true일때는 내위치 + // 여기 useEffect(()=>{ const container = document.getElementById('map');// 지도를 담을 dom영역 @@ -83,49 +78,84 @@ const KakaoMap = ({width, height, dataList, position, left, regionFilter, compon // 기본 주소 객체 생성 const map = new window.kakao.maps.Map(container,options); var geocoder = new window.kakao.maps.services.Geocoder(); + + // map 페이지에서 사용 + if (component === 'map'){ - console.log('이거 왜 안들어감?',dataset) + if(filterOrPosition === true){ + // 내위치 받아오기 예제 + if (navigator.geolocation) { + console.log('내 위치를 받아오기') + + // 주변 데이터 보여주기 위해서 값 불러오기 + console.log('리스트 데이터',dataset) + dataset.forEach(function(addr:any,index:number){ + geocoder.addressSearch(addr.attractionAddress, function(result:any, status:any) { + // 정상적으로 검색이 완료됐으면 + if (status === window.kakao.maps.services.Status.OK) { + var coords = new window.kakao.maps.LatLng(result[0].y, result[0].x); + // 결과값으로 받은 위치를 마커로 표시합니다 + var marker = new window.kakao.maps.Marker({ + map: map, + position: coords + }); + + // 인포 윈도우 설정 + var infowindow = new window.kakao.maps.InfoWindow({ + content: + `
+

+ ${addr.attractionName} +

+

+ ${addr.attractionAddress} +

+ + 더보기 + +
`, + disableAutoPan: false + }); + infowindow.open(map, marker); + // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다 + map.setCenter(coords); + } + }); + }) - if (Array.isArray(dataList)){ - // Map 컴포넌트에서 사용 --무조건 전체 목록 마커 넣어야함 - console.log('데이터 리스트 배열입니다. '); - console.log('받아온 데이터',dataList) - // 받아온 전체 데이터인지 확인 - console.log('마커용 데이터',dataset) - // 배열인 경우에는 무조건 마커를 다 찍음 - 이거 - // 그리고 누른 곳 장소 가져와서 그곳의 위치로 이동시킴. - listData.forEach(function(addr,index){ - geocoder.addressSearch(addr, function(result:any, status:any) { - // 정상적으로 검색이 완료됐으면 - if (status === window.kakao.maps.services.Status.OK) { - var coords = new window.kakao.maps.LatLng(result[0].y, result[0].x); - // 결과값으로 받은 위치를 마커로 표시합니다 - var marker = new window.kakao.maps.Marker({ - map: map, - position: coords - }); - - // 인포 윈도우 설정 - var infowindow = new window.kakao.maps.InfoWindow({ - content: info, - disableAutoPan: false - }); - infowindow.open(map, marker); - // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다 - map.setCenter(coords); - } - }); - }) - if(filterOrPosition === true){ - // 내위치 받아오기 예제 - if (navigator.geolocation) { - console.log('내 위치를 받아오기') // GeoLocation을 이용해서 접속 위치를 얻어옵니다 navigator.geolocation.getCurrentPosition(function(position) { @@ -137,16 +167,81 @@ const KakaoMap = ({width, height, dataList, position, left, regionFilter, compon map.setCenter(locPosition); }); } + + + + }else { console.log('주변 필터링 데이터 보여주기') - //console.log(d) - } + console.log('아이디',modalData.attractionId) + // 모달데이터를 클릭한 곳으로 위치를 이동시킵니다. + geocoder.addressSearch(modalData.attractionAddress, function(result:any, status:any){ + if (status === window.kakao.maps.services.Status.OK){ + console.log('좌표 검색 완료',result[0].y, result[0].x) + var placePosition = new window.kakao.maps.LatLng(result[0].y, result[0].x); + // 결과값으로 받은 위치를 마커로 표시합니다 + var marker = new window.kakao.maps.Marker({ + map: map, + position: placePosition, + }); + // 인포 윈도우 설정 + var infowindow = new window.kakao.maps.InfoWindow({ + content: + `
+

+ ${modalData.attractionName} +

+

+ ${modalData.attractionAddress} +

+ + 더보기 + +
`, + disableAutoPan: false + }); + + // 인포윈도우 표시 + infowindow.open(map, marker); - }else{ - // placedetail 컴포넌트에서 사용 -- 수정 금지 - console.log('단일 데이터 값 입니다. '); - console.log(dataList) + //map.setCenter(coords); + map.panTo(placePosition); + map.relayout(); + } + }) + } + } + + // placedetail 컴포넌트에서 사용 -- 수정 금지 + if(component === 'place'){ geocoder.addressSearch(dataList, function(result:any, status:any) { if (status === window.kakao.maps.services.Status.OK) { var coords = new window.kakao.maps.LatLng(result[0].y, result[0].x); @@ -165,7 +260,7 @@ const KakaoMap = ({width, height, dataList, position, left, regionFilter, compon // 지도에 컨트롤을 추가해야 지도위에 표시됩니다 // kakao.maps.ControlPosition은 컨트롤이 표시될 위치를 정의하는데 TOPRIGHT는 오른쪽 위를 의미합니다 map.addControl(mapTypeControl, window.kakao.maps.ControlPosition.TOPLEFT); - },[filterOrPosition]) + },[filterOrPosition,dataset=== undefined, modalData]) //document.getElementsByClassName(class) @@ -187,7 +282,7 @@ const KakaoMap = ({width, height, dataList, position, left, regionFilter, compon onClick={()=>{ setFilterOrPosition(!filterOrPosition) }}> - {filterOrPosition ? "위치 검색 OFF": "내 주변 검색"} + {filterOrPosition ? "실시간 위치 OFF": "실시간 위치"} : null} diff --git a/project/src/components/Login.tsx b/project/src/components/Login.tsx index 0c61c416..b1968c11 100644 --- a/project/src/components/Login.tsx +++ b/project/src/components/Login.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import styled from "styled-components"; import ButtonForm from "./Button"; import Axios from "axios"; @@ -8,6 +8,7 @@ import { useNavigate } from "react-router-dom"; import { useRecoilState } from "recoil"; import { LoginState, AuthToken, LoggedUser } from "../recoil/state"; + interface TextProps { fontSize: string; color: string; @@ -308,38 +309,12 @@ const Login = () => { } }; - const GoogleHandler = () => { - axios - // .post("/login/oauth2/code/google", { - // username: loginemail, - // password: loginpassword, - // }) - .get("oauth2/authorization/google", { - // headers: { - // "Content-Type" : "application/x-www-form-urlencoded" - // } - }) - .then((res) => console.log(res)) - .catch((err) => console.error(err)); - }; - - const googlelogin = () => { - window.location.href = - "http://localhost:8090/oauth2/authorization/google"; - const query = window.location.search; - console.log("이게무야2", query); - const param = new URLSearchParams(query); - console.log(param); - }; - - const kakaologin = () => { - window.location.href = - "http://localhost:8090/oauth2/authorization/kakao" - const query = window.location.search; - console.log("이게무야2", query); - const param = new URLSearchParams(query); - console.log(param); - }; + const googleLogin = () => { + window.location.href = "http://pikcha36.o-r.kr:8080/oauth2/authorization/google"; + }; + const kakaologin = () => { + window.location.href = "http://pikcha36.o-r.kr:8080/oauth2/authorization/kakao"; + }; return ( @@ -367,15 +342,9 @@ const Login = () => { 로그인 - - - - - - G - - - + + + G SNS 계정으로 로그인 diff --git a/project/src/components/PostBox.tsx b/project/src/components/PostBox.tsx index c0c5ed1b..4aa70fc9 100644 --- a/project/src/components/PostBox.tsx +++ b/project/src/components/PostBox.tsx @@ -106,10 +106,10 @@ const PostBox = ({postData}:any) => { postData.map((el:any)=>{ return( -
+
- +
{el.username}
{(el.createdAt).slice(0,10)} diff --git a/project/src/components/PostCardComponent.tsx b/project/src/components/PostCardComponent.tsx index f61cd84b..1afae16a 100644 --- a/project/src/components/PostCardComponent.tsx +++ b/project/src/components/PostCardComponent.tsx @@ -124,7 +124,7 @@ const PostCardComponent = ({
- +
{post.username}
{post.createdAt.slice(0, 10)} diff --git a/project/src/pages/Map.tsx b/project/src/pages/Map.tsx index 1c04e3bb..fe3d342a 100644 --- a/project/src/pages/Map.tsx +++ b/project/src/pages/Map.tsx @@ -10,6 +10,7 @@ import HiddenHeader from "../components/Header/HiddenHeader"; import '../index.css'; import axios from "axios"; import { DataList } from "../components/KakaoMap"; +import {GiTalk} from 'react-icons/gi'; @@ -97,11 +98,6 @@ const PlaceComponent = styled.div` overflow-y:scroll; overflow-x: hidden; -ms-overflow-style: none; - - //뺄지말지 나중에 결정 - /* ::-webkit-scrollbar { - display: none; -} */ ` const Place = styled.div<{imgUrl:string}>` background-color: skyblue; @@ -176,7 +172,7 @@ const PlaceDetailModalHeader = styled.div` } & p{ font-size: 10px; - margin-left: 3px; + margin-left: 5px; color:#373737; } } @@ -189,6 +185,7 @@ const PlaceDetailModalHeader = styled.div` background-color: #fbf8ba; margin-left: 15px; font-weight: 700; + margin-bottom: 5px; } >a{ font-size: 13px; @@ -201,7 +198,7 @@ const PlaceDetailModalHeader = styled.div` } >p:nth-child(4){ color:#555555; - font-size: 15px; + font-size: 14px; margin: 4px 0 0 15px; font-weight: 600; } @@ -216,6 +213,7 @@ const PlaceDetailModalHeader = styled.div` } >p{ font-size: 12px; + font-weight: 500; } } @@ -224,7 +222,7 @@ const PlaceDetailModalHeader = styled.div` font-size: 15px; font-weight: bold; margin: 20px 0 0 17px; - color:#555555; + color:#2e3776; } >span{ color:#555555; @@ -242,6 +240,7 @@ const PlaceDetailModalMain = styled.div` font-size: 15px; font-weight: 700; margin: 25px 0 10px 20px; + color: #393939; } ` @@ -257,25 +256,20 @@ const PostImgContainer = styled.div` } ` -const Map = () => { +const PostNone = styled.div` + padding: 10px; + width: 300px; + height: 100px; + font-size: 13px; + color:grey; + display: flex; + >div{ + margin-right: 5px; + } + //background-color:red; +` - // // 주소 더미 데이터 - // var listData = [ - // '종로구 사직로 161', - // '종로구 세종대로 198', - // '종로구 세종대로 209', - // '종로구 세종대로 175' - // ]; - - // // 이미지 더미데이터 - // var imgUrl = [ - // "https://a.cdn-hotels.com/gdcs/production123/d477/f88c6cdb-3e47-45f5-bfd7-d3775d1f3bcc.jpg?impolicy=fcrop&w=1600&h=1066&q=medium", - // "https://a.cdn-hotels.com/gdcs/production43/d333/469e9780-6653-4879-a396-cea7714fc209.jpg?impolicy=fcrop&w=1600&h=1066&q=medium", - // "https://a.cdn-hotels.com/gdcs/production90/d1936/e6925d65-cc4b-4605-8bd4-debb712fe764.jpg?impolicy=fcrop&w=1600&h=1066&q=medium", - // "https://a.cdn-hotels.com/gdcs/production167/d282/bf00d54a-0bb2-487e-8fbb-2ce495d3113b.jpg?impolicy=fcrop&w=1600&h=1066&q=medium", - // "https://a.cdn-hotels.com/gdcs/production41/d1748/0b5fab45-59f0-4574-8ac3-d19fb1778e2e.jpg?impolicy=fcrop&w=1600&h=1066&q=medium", - - // ] +const Map = () => { // 드롭다운 메뉴를 보여줄지 말지 설정하는 변수 const [dropdownView, setDropdownView] = useState(false) @@ -297,8 +291,28 @@ const Map = () => { // 카카오맵에 전체 마커로 찍을 데이터 저장용 const [wholeData, setWholeData] = useState(); - const url = 'http://pikcha36.o-r.kr:8080/attractions/maps?page=1&size=100&sort=newest'; + + const tags = [ + '#가족 여행지', + '#야경이 아름다운 곳', + '#여름 여행지', + '#체험 학습', + '#겨울 여행 추천', + '#야경이 아름다운 곳', + '#가을 여행지', + '#친구와 방문하기 좋은 곳', + '#연인과 함께', + '#가을에 방문하기 좋은 곳', + '#테마 거리', + + ] + + + + const url = 'http://pikcha36.o-r.kr:8080/attractions/maps?page=1&size=100&sort=posts'; //const url2 = 'http://pikcha36.o-r.kr:8080/attractions/mapdetails/1'; + const [filterOrPosition, setFilterOrPosition] = useState(false); + useEffect(()=>{ // 처음에 무조건 데이터를 받아옴 @@ -327,7 +341,7 @@ const Map = () => { console.log('전체 데이터----', wholeData) console.log('전체 데이터----', regionList) - },[]) + },[regionFilter,setDropdownView]) const handleModalData = (dataUrl:string) => { @@ -353,7 +367,7 @@ const Map = () => { { regionDummy.map((el:any, index:number)=>{ return( - + ) }) } @@ -364,7 +378,14 @@ const Map = () => { {regionList!== undefined && regionList.map((el:any, index:any)=>{ return( - {setDetailModal(true); handleModalData(el.attractionId); console.log('모달 데이터 아이디',modalDataId)}} imgUrl={el.fixedImage} key={el.attractionId}> + { + setDetailModal(true); + handleModalData(el.attractionId); + setModalDataId(el.attractionId); + console.log('모달 데이터 아이디',modalDataId) + setFilterOrPosition(false) + }} + imgUrl={el.fixedImage} key={el.attractionId}>
{el.attractionName}

{el.attractionAddress}

@@ -386,14 +407,14 @@ const Map = () => {

{modalData.attractionName}

- 더보기 + 더보기

{modalData.attractionAddress}

{modalData && modalData.numOfPosts}개의 리뷰

-
#야경 #야경이 아름다운 곳
+
{tags[(modalData.attractionId % tags.length)]} {tags[((modalData.attractionId -1) % tags.length)]}
setDetailModal(false)}>{'<<<'} @@ -407,7 +428,9 @@ const Map = () => { ) }) - :
등록된 포토리뷰가 없습니다
} + : +
+ 등록된 포토리뷰가 없습니다.
}
@@ -422,6 +445,9 @@ const Map = () => { regionFilter = {regionFilter} component = "map" dataset = {wholeData} + modalData = {modalData} + filterOrPosition = {filterOrPosition} + setFilterOrPosition={setFilterOrPosition} > : @@ -434,6 +460,9 @@ const Map = () => { regionFilter = {regionFilter} component = "map" dataset = {wholeData} + modalData = {modalData} + filterOrPosition = {filterOrPosition} + setFilterOrPosition={setFilterOrPosition} > } diff --git a/project/src/pages/MyPage.tsx b/project/src/pages/MyPage.tsx index 5f6a3f24..6948a35b 100644 --- a/project/src/pages/MyPage.tsx +++ b/project/src/pages/MyPage.tsx @@ -292,7 +292,7 @@ const MyPage = () => {
- +
개구리 뒷다리
diff --git a/project/src/pages/Oauth.tsx b/project/src/pages/Oauth.tsx new file mode 100644 index 00000000..3057deb6 --- /dev/null +++ b/project/src/pages/Oauth.tsx @@ -0,0 +1,37 @@ +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { + useRecoilState, +} from "recoil"; +import { LoginState, AuthToken, LoggedUser } from "../recoil/state"; + +const Oauth = () => { + const navigate = useNavigate(); + const [isLogin, setIsLogin] = useRecoilState(LoginState); + const [isToken, setToken] = useRecoilState(AuthToken); + + useEffect(() => { + const query = window.location.search; + const param = new URLSearchParams(query); + + const getaccessToken = param.get("accessToken"); + const getId = param.get("id"); + + // console.log("팔람팔람팔람:",param) + // console.log("퀄퀄:",query) + // console.log("토토토토토토 :", getaccessToken) + + localStorage.setItem("Authorization",`Bearer ${getaccessToken}`) + localStorage.setItem("memberId", `${getId}`) + localStorage.setItem("loginStatus",`true`) + setIsLogin(true); + setToken(`Bearer ${getaccessToken}`); + + window.location.replace("/") + ; + } ,[] + ) + return <> +}; + +export default Oauth; \ No newline at end of file diff --git a/project/src/pages/PlaceDetail.tsx b/project/src/pages/PlaceDetail.tsx index 64db6697..cb918023 100644 --- a/project/src/pages/PlaceDetail.tsx +++ b/project/src/pages/PlaceDetail.tsx @@ -201,7 +201,7 @@ const dummyBookmarks = [10, 13, 20, 50, 60, 81, 90]; const PlaceDetail = (): JSX.Element => { let [view, setView] = useState("info"); const scrollRefContent = useRef(null); - const [shareOpen, setShareOpen] = useState(false); + //const [shareOpen, setShareOpen] = useState(false); const [fixBar, setFixBar] = useState(0); const [attractionData, setAttractionData] = useState(); // 명소 정보 저장 const [postData, setPostData] = useState(); @@ -398,7 +398,10 @@ const PlaceDetail = (): JSX.Element => { left="20%" regionFilter="null" component="place" - dataset="" + dataset = '' + modalData ='ex' + setFilterOrPosition='11' + filterOrPosition='11' > diff --git a/project/src/utils/axiosinstance.tsx b/project/src/utils/axiosinstance.tsx new file mode 100644 index 00000000..4cc39898 --- /dev/null +++ b/project/src/utils/axiosinstance.tsx @@ -0,0 +1,61 @@ +import Axios, { AxiosHeaders } from "axios"; + +const axios = Axios.create({ +}); + +axios.interceptors.request.use( + (config) => { + // const accessToken = localStorage.getItem("Authorization"); + // axios.defaults.headers.common["Authorization"] = accessToken; + return config; + }, + (error) => { + console.log("request error", error); + return Promise.reject(error); + } +); + +axios.interceptors.response.use( + function (res) { + console.log("리스폰 인터셉트"); + return res; + }, + async (error) => { + const { + config, + response: { status }, + } = error; + if (status === 400 && error.response.data.message === "Token Expired") { + const originalRequest = config; + axios.defaults.headers.common["Authorization"] = null; + const memberId = localStorage.getItem("memberId"); + const { data } = await axios.get(`/token/refresh/${memberId}`); + console.log("리프데이터 : ", data) + const accessToken = data.data.accessToken; + console.log("어쏘 : ", accessToken) + localStorage.setItem("Authorization", `${accessToken}`); + originalRequest.headers.Authorization = accessToken; + axios.defaults.headers.common["Authorization"] = accessToken; + localStorage.setItem("loginStatus", "true") + return axios(originalRequest); + } + if (status === 400 && error.response.data.message === "RefreshToken Expired"){ + localStorage.setItem("loginStatus", "false") + localStorage.removeItem("memberId") + localStorage.removeItem("Authorization") + alert("로그인 시간 만료.") + window.location.replace("/login") + } + if (status === 500){ + localStorage.setItem("loginStatus", "false") + localStorage.removeItem("memberId") + localStorage.removeItem("Authorization") + alert("로그인 시간 만료.") + window.location.replace("/login") + } + console.log("response error", error); + return Promise.reject(error); + } +); + +export default axios;