728x90
disabled
-비활성화하는거다.
-특별하게 티가 안날거다.
-그냥 아무리 클릭해도 먹히지가 않을거다.
-안에 boolean값이 들어가야한다.
콘솔찍을때 메세지 달면서 찍으면 다른것들하고 구분하기 좋다.
console.log("select >> ", select);
오늘의 마무리 코드
likelistpage
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import { MdOutlineKeyboardArrowRight } from "react-icons/md";
import axios from "axios";
import { ButtonDark } from "@components/Common/Button";
import Pagination from "@components/AlcoholPage/Pagination";
import PriceDisplay from "@components/Common/PriceDisplay";
//components
interface Likeitem {
titleKor: string;
price: number;
quantity: number;
capacity: number;
reviewRating: number;
itemId: number;
checked: boolean;
profile: string;
}
const TotalStyled = styled.div`
display: flex;
justify-content: center;
align-items: center;
background-color: #f7f7f7;
`;
const PageTitle = styled.div`
/* border: 1px solid black; */
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 30px;
height: 100px;
`;
const LikepageContainer = styled.div`
/* border: 5px solid blue; */
width: 100vw;
height: 100vh;
max-width: 1250px;
margin-top: 150px; //호버됬을때가 150이래서 일단 150으로 설정함.
display: flex;
flex-direction: column;
`;
//누구누구님 등급써있는부분
const LikepageHeadStyled = styled.div`
border: 3px solid #dedede;
font-size: 18px;
color: #181818;
display: flex;
flex-direction: column;
justify-content: center;
height: 100px;
padding-left: 10px;
font-weight: 600;
`;
//찜리스트 나오는 부분
const LikepageMainStyled = styled.div`
/* border: 3px solid red; */
> * {
font-size: 18px;
}
`;
const HeadTable = styled.div`
/* border: 3px solid blue; */
height: 100px;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding-bottom: 10px;
padding-left: 10px;
font-weight: 600;
line-height: 25px;
`;
const TotalTableStyled = styled.div`
border: 3px solid #dedede;
flex-grow: 1;
`;
const StyledTable = styled.table`
/* border: 1px solid black; */
font-size: 18px;
width: 1240px;
height: 300px;
`;
const StyledTh = styled.th`
/* border: 1px solid black; */
padding: 8px;
`;
const StyledTd = styled.td`
/* border: 1px solid black; */
padding: 8px;
text-align: center;
vertical-align: middle;
.button-container {
display: flex;
justify-content: center;
width: 100%;
}
> img {
width: 50%;
height: 80px;
}
`;
//맨밑 페이지네이션부분
const PigStyled = styled.div`
/* border: 1px solid red; */
display: flex;
flex-direction: row;
justify-content: center;
padding-bottom: 10px;
`;
const LikePage = () => {
const [likelist, setLikelist] = useState<Likeitem[]>([]);
const [totalLength, setTotalLength] = useState<number>(0);
const [currentPage, setCurrentPage] = useState<number>(1);
const navigate = useNavigate();
const [userName, setUserName] = useState<string>("");
const totalPages = Math.ceil(totalLength / 5); //나오는 총 페이지수
const paginationData = likelist.slice(5 * (currentPage - 1), 5 * currentPage); //각페이지에서 보이는내용
// console.log(currentPage);
// console.log(likelist);
// console.log(totalpages);
// console.log(itemsPerPage);
// console.log(paginationData);
const LikeGetHandle = () => {
const access_token = `Bearer ${localStorage.getItem("authToken")}`;
axios
.get(`${process.env.REACT_APP_API_URL}/members/favorite`, {
headers: {
"Content-Type": "application/json",
Authorization: access_token,
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
})
.then((res) => {
// console.log(res);
// console.log(res.data.data[0]);
// console.log(res.data.data);
setLikelist(res.data.data);
// console.log(res.data.data.length);
setTotalLength(res.data.data.length);
})
.catch((err) => console.log(err));
};
useEffect(() => {
LikeGetHandle();
}, []);
const handleDeleteBtn = (itemId: number) => {
const access_token = `Bearer ${localStorage.getItem("authToken")}`;
axios
.delete(`${process.env.REACT_APP_API_URL}/items/${itemId}/favorite`, {
headers: {
"Content-Type": "application/json",
Authorization: access_token,
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
})
.then((res) => {
LikeGetHandle();
})
.catch((error) => console.log(error));
};
const handleCartBtn = (itemId: number) => {
const access_token = `Bearer ${localStorage.getItem("authToken")}`;
axios
.post(
`${process.env.REACT_APP_API_URL}/cart`,
{
itemId: itemId,
quantity: 1,
},
{
headers: {
"Content-Type": "application/json",
Authorization: access_token,
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
},
)
.then((res) => navigate("/cart"))
.catch((err) => console.log(err));
};
//닉네임 불러오는부분 0520추가함 데이터들어오는지 확인해봐야하는부분임
useEffect(() => {
const access_token = `Bearer ${localStorage.getItem("authToken")}`;
axios
.get(`${process.env.REACT_APP_API_URL}/members`, {
headers: {
"Content-Type": "application/json",
Authorization: access_token,
"ngrok-skip-browser-warning": "69420",
},
})
.then((res) => setUserName(res.data.data.displayName))
.catch((err) => console.error(err));
}, []);
return (
<>
<TotalStyled>
<LikepageContainer>
<PageTitle>
<div>My Page</div>
<MdOutlineKeyboardArrowRight size="20px" />
<div>찜리스트</div>
</PageTitle>
<LikepageHeadStyled>
<p>{userName}님의 등급은 Green입니다.</p>
</LikepageHeadStyled>
<LikepageMainStyled>
<HeadTable>
<p>찜리스트</p>
<p>총 {likelist.length}건</p>
</HeadTable>
<TotalTableStyled>
<StyledTable>
<thead>
<tr>
<StyledTh></StyledTh>
<StyledTh>상품 목록</StyledTh>
<StyledTh>가 격(원)</StyledTh>
<StyledTh></StyledTh>
<StyledTh></StyledTh>
</tr>
</thead>
<tbody>
{paginationData.map((el: Likeitem, idx: number) => {
return (
<tr key={idx}>
<StyledTd>
<img src={el.profile} />
</StyledTd>
<StyledTd>{el.titleKor}</StyledTd>
<StyledTd>
<PriceDisplay price={el.price} />
</StyledTd>
<StyledTd>
<div className="button-container">
<ButtonDark
width="100px"
height="50%"
onClick={() => {
handleCartBtn(el.itemId);
}}
>
장바구니
</ButtonDark>
</div>
</StyledTd>
<StyledTd>
<div className="button-container">
<ButtonDark
width="100px"
height="50%"
onClick={() => {
handleDeleteBtn(el.itemId);
}}
>
삭제
</ButtonDark>
</div>
</StyledTd>
</tr>
);
})}
</tbody>
</StyledTable>
</TotalTableStyled>
</LikepageMainStyled>
<PigStyled>
<Pagination
currentPage={currentPage}
setCurrentPage={setCurrentPage}
itemsPerPage={5}
totalData={likelist.length}
/>
</PigStyled>
</LikepageContainer>
</TotalStyled>
</>
);
};
export default LikePage;
orderlistpage
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import styled from "styled-components";
import { MdOutlineKeyboardArrowRight } from "react-icons/md";
import { ButtonDark } from "@components/Common/Button";
import Pagination from "@components/AlcoholPage/Pagination";
interface Orderitem {
orderId: number;
orderStatus: string;
orderedAt: string;
pickupDate: string;
titleKor: string;
quantity: number;
itemId: number;
}
interface OrderTableProps {
orderlist: Orderitem[];
}
interface ReveiwUpdateProps {
itemId: number;
}
const TotalStyled = styled.div`
display: flex;
justify-content: center;
align-items: center;
background-color: #f7f7f7;
`;
const OrderContainer = styled.div`
/* border: 5px solid blue; */
width: 100vw;
height: 100vh;
max-width: 1250px;
margin-top: 150px; //호버됬을때가 150이래서 일단 150으로 설정함.
display: flex;
flex-direction: column;
`;
const PageTitle = styled.div`
/* border: 3px solid red; */
height: 100px;
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 30px;
`;
//누구누구님 등급써있는부분
const OrderpageHeadStyled = styled.div`
border: 2px solid #dedede;
font-size: 18px;
display: flex;
flex-direction: row;
align-items: center;
padding-left: 10px;
height: 100px;
color: #181818;
font-weight: 600;
`;
//주문내역써있는부분
const OrderpageMainStyled = styled.div`
/* border: 3px solid blue; */
height: 100px;
display: flex;
flex-direction: column;
justify-content: flex-end;
font-size: 18px;
font-weight: 600;
padding-bottom: 10px;
padding-left: 10px;
line-height: 25px;
`;
//기간설정하는 부분
const PeriodStyled = styled.div`
border: 2px solid #dedede;
height: 120px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding-left: 170px;
padding-right: 170px;
> * {
margin-left: 20px;
}
> input {
height: 30px;
width: 250px;
}
> p {
font-weight: 600;
}
`;
//목록부분
const OrderlistStyled = styled.div`
border: 2px solid #dedede;
margin-top: 10px;
margin-bottom: 10px;
flex-grow: 1;
> p {
font-weight: 600;
padding-left: 10px;
padding-top: 10px;
padding-bottom: 10px;
}
`;
const StyledTable = styled.table`
/* border: 1px solid black; */
width: 1240px;
height: 500px;
font-size: 18px;
`;
const StyledTh = styled.th`
/* border: 1px solid black; */
padding: 8px;
font-weight: 600;
`;
const StyledTd = styled.td`
/* border: 1px solid black; */
padding: 8px;
text-align: center;
vertical-align: middle;
.button-container {
display: flex;
justify-content: center;
width: 100%;
}
`;
//맨밑 페이지네이션부분
const PigStyled = styled.div`
/* border: 2px solid red; */
display: flex;
flex-direction: row;
justify-content: center;
padding-bottom: 10px;
`;
const OrderTable = ({ orderlist }: OrderTableProps) => {
const navigate = useNavigate();
//후기연결
const ReviewWindow = (itemId: number) => {
const reviewCreate: ReveiwUpdateProps = {
itemId,
};
navigate(`/review/edit/${itemId}`, {
state: { reviewCreate },
});
};
const realOrderList = orderlist; //진짜데이터에서는 어차피 하나만 들어오니까 필요없는 로직이 될것이다.
// console.log(orderlist);
// console.log(realOrderList); //원래 들어오는 오더
const OrderPatchHandle = (orderId: number) => {
const access_token = `Bearer ${localStorage.getItem("authToken")}`;
axios
.patch(
`${process.env.REACT_APP_API_URL}/order/${orderId}/cancel`,
{},
{
headers: {
"Content-Type": "application/json",
Authorization: access_token,
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
},
)
.then((res) => {
// console.log(res.data);
window.location.reload();
})
.catch((err) => console.log(err));
};
return (
<>
{/* {console.log(orderlist[0].itemOrders)} */}
{/* {console.log(orderlist)} */}
{/* {console.log(filterData)} */}
{/* {console.log(realOrderList)} */}
<StyledTable>
<thead>
<tr>
<StyledTh>주문날짜</StyledTh>
<StyledTh>픽업날짜</StyledTh>
<StyledTh>구매목록</StyledTh>
<StyledTh>수량(개)</StyledTh>
<StyledTh>상태</StyledTh>
<StyledTh>주문취소</StyledTh>
<StyledTh>후기보기</StyledTh>
</tr>
</thead>
<tbody>
{orderlist.map((el: Orderitem, idx: number) => {
return (
<tr key={idx}>
<StyledTd>{el.orderedAt}</StyledTd>
<StyledTd>{el.pickupDate}</StyledTd>
<StyledTd>{el.titleKor}</StyledTd>
<StyledTd>{el.quantity}</StyledTd>
<StyledTd>{el.orderStatus}</StyledTd>
<StyledTd>
{el.orderStatus === "픽업 완료" ? null : (
<div className="button-container">
<ButtonDark
width="100px"
height="50%"
onClick={() => {
OrderPatchHandle(el.orderId);
}}
disabled={el.orderStatus === "픽업 완료"}
>
취소
</ButtonDark>
</div>
)}
</StyledTd>
<StyledTd>
<div className="button-container">
<ButtonDark width="100px" height="50%" onClick={() => ReviewWindow(el.itemId)}>
후기
</ButtonDark>
</div>
</StyledTd>
</tr>
);
})}
</tbody>
</StyledTable>
</>
);
};
const OrderPage = () => {
const [orderlist, setOrderlist] = useState<Orderitem[]>([]);
const [totalLength, setTotalLength] = useState<number>(0); //페이지네이션관련
const [currentPage, setCurrentPage] = useState<number>(1); //페이지네이션관련
const [choiceFronDay, setChoiceFronDay] = useState<string>(""); //조회할때 선택하는 날짜앞부분
const [choiceBackDay, setChoiceBackDay] = useState<string>(""); //조회할때 선택하는 날짜뒷부분
const [filterlist, setFilterlist] = useState<Orderitem[]>([]); //정신없는 데이터를 새로 정제한것.
const [userName, setUserName] = useState<string>("");
//페이지네이션관련
const totalPg = Math.ceil(totalLength / 5);
const pageData = filterlist.slice(5 * (currentPage - 1), 5 * currentPage);
//조회버튼 함수
const Search = () => {
console.log("a");
const newData = orderlist.slice();
const first = new Date(choiceFronDay);
const second = new Date(choiceBackDay);
setFilterlist(newData.filter((el) => new Date(el.orderedAt) >= first && new Date(el.orderedAt) <= second));
};
useEffect(() => {
const access_token = `Bearer ${localStorage.getItem("authToken")}`;
axios
.get(`${process.env.REACT_APP_API_URL}/members/orders`, {
headers: {
"Content-Type": "application/json",
Authorization: access_token,
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
})
.then((res) => {
// console.log(res.data.data);
const data = res.data.data;
const newData = [];
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].itemOrders.length; j++) {
const singleData = data[i].itemOrders[j];
singleData["orderedAt"] = data[i].orderedAt;
singleData["orderStatus"] = data[i].orderStatus;
singleData["pickupDate"] = data[i].pickupDate;
singleData["orderId"] = data[i].orderId;
newData.push(singleData);
// console.log(newData);
}
}
setOrderlist(newData);
setFilterlist(newData);
})
.catch((err) => console.log(err));
axios
.get(`${process.env.REACT_APP_API_URL}/members`, {
headers: {
"Content-Type": "application/json",
Authorization: access_token,
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
})
.then((res) => setUserName(res.data.data.displayName))
.catch((err) => console.error(err));
}, []);
return (
<>
<TotalStyled>
<OrderContainer>
<PageTitle>
<div>My Page</div>
<MdOutlineKeyboardArrowRight size="20px" />
<div>주문내역</div>
</PageTitle>
<OrderpageHeadStyled>
<p>{userName}님의 등급은 Green입니다.</p>
</OrderpageHeadStyled>
<OrderpageMainStyled>
<p>주문내역</p>
<p>총 {filterlist.length}건</p>
</OrderpageMainStyled>
<PeriodStyled>
<p>주문기간조회</p>
<input type="date" className="FrontInput" onChange={(e) => setChoiceFronDay(e.target.value)}></input>
<p>~</p>
<input type="date" className="BackInput" onChange={(e) => setChoiceBackDay(e.target.value)}></input>
<ButtonDark width="120px" height="70%" onClick={Search}>
조 회
</ButtonDark>
</PeriodStyled>
<OrderlistStyled>
{filterlist.length !== 0 ? <OrderTable orderlist={pageData}></OrderTable> : <div>주문내역이 없습니다.</div>}
</OrderlistStyled>
<PigStyled>
<Pagination
currentPage={currentPage}
setCurrentPage={setCurrentPage}
itemsPerPage={5}
totalData={filterlist.length}
></Pagination>
</PigStyled>
</OrderContainer>
</TotalStyled>
</>
);
};
export default OrderPage;
map
import React, { useEffect } from "react";
declare global {
interface Window {
kakao: any;
closeOverlay: () => void;
}
}
interface Shopitem {
address: string;
choice: boolean;
comment: string;
lat: number;
lng: number;
marketId: number;
name: string;
phone: string;
workTime: string;
}
interface ShopProps {
shoplist: Shopitem[];
setSelect: React.Dispatch<React.SetStateAction<Shopitem | null>>;
}
const MapComponent = ({ shoplist, setSelect }: ShopProps) => {
useEffect(() => {
const container = document.getElementById("map");
const options = {
center: new window.kakao.maps.LatLng(37.32569664033685, 127.10734442799804), //죽전역
level: 8,
};
const map = new window.kakao.maps.Map(container, options);
//사용자 현재위치 정보
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
const lat = position.coords.latitude,
lon = position.coords.longitude;
const locPosition = new window.kakao.maps.LatLng(lat, lon),
message = "<div>현재위치</div>";
// console.log(locPosition, message); // 이게 현재위치 잡히는거다 !!!!!!!!
displayMarker(locPosition, message);
});
} else {
const locPosition = new window.kakao.maps.LatLng(37.57022168346011, 126.98314742271637), //종각역
message = "<div>아니야</div>";
displayMarker(locPosition, message);
}
function displayMarker(locPosition: any, message: any) {
const marker = new window.kakao.maps.Marker({
map: map,
position: locPosition,
});
const iwContent = message,
iwRemoveable = true;
const infowindow = new window.kakao.maps.InfoWindow({
content: iwContent,
removable: iwRemoveable,
});
infowindow.open(map, marker);
map.setCenter(locPosition);
}
shoplist.forEach((el: any) => {
const marker = new window.kakao.maps.Marker({
map: map,
position: new window.kakao.maps.LatLng(el.lat, el.lng),
data: el.data,
});
const content =
'<div onClick={handleChoice} className="overlayContainer" style="background-color: red;">' +
`<div style="color: black;" >${el.name}</div>` +
`<div className="shopPhone">${el.phone}</div>` +
"</div>";
const customOverlay = new window.kakao.maps.CustomOverlay({
content: content,
position: new window.kakao.maps.LatLng(el.lat, el.lng),
});
//마우스오버하면 커스텀어레이가 생성된다.
window.kakao.maps.event.addListener(marker, "mouseover", () => {
customOverlay.setMap(map);
});
//마우스아웃하면 커스텀어레이가 없어진다.
window.kakao.maps.event.addListener(marker, "mouseout", () => {
customOverlay.setMap(null);
});
window.kakao.maps.event.addListener(marker, "click", () => {
setSelect(el);
});
});
}, [shoplist]);
return <div id="map" style={{ width: "800px", height: "500px" }}></div>;
};
export default MapComponent;
place
import React, { useState, useEffect, lazy, Suspense } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import axios from "axios";
import styled from "styled-components";
import { ButtonDark } from "../components/Common/Button";
import { useDispatch } from "react-redux";
import { setMarker } from "../redux/slice/store";
const MapComponent = lazy(() => import("./Map"));
const TotalStyled = styled.section`
display: flex;
justify-content: center;
align-items: center;
background-color: #f7f7f7;
`;
const PlaceContainer = styled.div`
/* border: 5px solid black; */
width: 100vw;
height: 100vh;
max-width: 1250px;
margin-top: 150px; //호버됬을때가 150이래서 일단 150으로 설정함.
display: flex;
flex-direction: column;
`;
//지도부분
const MapBodyStyled = styled.div`
display: flex;
flex-direction: column;
flex-grow: 6.5;
justify-content: center;
align-items: center;
`;
//지도제목
const MapArticleStyled = styled.div`
border: 3px solid #dedede;
margin-bottom: 80px;
font-size: 18px;
width: 300px;
height: 50px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
line-height: 25px;
font-weight: 600;
`;
const MapBottomStyled = styled.div`
flex-grow: 1;
display: flex;
flex-grow: 3.5;
justify-content: center;
align-items: center;
margin-bottom: 50px;
`;
interface Shopitem {
address: string;
choice: boolean;
comment: string;
lat: number;
lng: number;
marketId: number;
name: string;
phone: string;
workTime: string;
}
const Place = () => {
const dispatch = useDispatch();
const [shoplist, setShoplist] = useState<Shopitem[]>([]);
const navigate = useNavigate();
const [select, setSelect] = useState<Shopitem | null>(null);
const location = useLocation();
const items = location.state ? location.state.items : [];
const selectedDate = location.state ? location.state.selectedDate : [];
const King = async () => {
await axios
.get(`${process.env.REACT_APP_API_URL}/marts`, {
headers: {
"Content-Type": "application/json",
Authorization: localStorage.getItem("authToken"),
"ngrok-skip-browser-warning": "69420", // ngrok cors 에러
},
})
.then((res) => {
setShoplist(res.data.content);
})
.catch((err) => console.log(err));
};
useEffect(() => {
King();
}, []);
const handleSelect = () => {
dispatch(setMarker(select));
navigate("/payment", { state: { items: items, selectedDate: selectedDate } });
};
return (
<>
<TotalStyled>
<PlaceContainer>
<MapBodyStyled>
<MapArticleStyled>
픽업 매장을 선택하세요.
{select?.name === null ? null : <p>{select?.name}</p>}
</MapArticleStyled>
<Suspense fallback={<div>loading</div>}>
<MapComponent shoplist={shoplist} setSelect={setSelect} />
</Suspense>
</MapBodyStyled>
<MapBottomStyled>
<ButtonDark width="350px" height="50%" onClick={handleSelect}>
선택
</ButtonDark>
</MapBottomStyled>
</PlaceContainer>
</TotalStyled>
</>
);
};
export default Place;
728x90
'개인공부 > 메인프로젝트' 카테고리의 다른 글
0524 리팩토링전 코드 (0) | 2023.05.24 |
---|---|
0524 기록 (0) | 2023.05.24 |
지도페이지 완료 (0) | 2023.05.17 |
suspense, lazy 적용 (0) | 2023.05.16 |
카카오맵-사용자위치조회,마커, 커스텀어레이 (0) | 2023.05.16 |