Skip to content

Commit

Permalink
Merge pull request #59 from LikeLion-Hackathon-T1/develop
Browse files Browse the repository at this point in the history
손님 뷰 UI 완성
  • Loading branch information
seokkkkkk authored Jul 31, 2024
2 parents a20f8b2 + 3a8b473 commit f004cc1
Show file tree
Hide file tree
Showing 32 changed files with 1,122 additions and 136 deletions.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
content="시장과 사랑에 빠지게 될 달콤한 나들이, Syluv"
/>
<script
type="text/javascript"
Expand Down
12 changes: 12 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import OrderListPage from "pages/OrderListPage";
import OrderDetailPage from "pages/OrderDetailPage";
import OrderPage from "pages/OrderPage";
import ReviewPage from "pages/ReviewPage";
import VisitListPage from "pages/VisitListPage";
import OrderSuccess from "pages/OrderSuccess";
import MyPage from "pages/MyPage";
const App = () => {
useEffect(() => {
if (window.location.host === "syluv.store") {
Expand All @@ -40,6 +43,10 @@ const App = () => {
/>
<Route path="/cart" element={<CartPage />} />
<Route path="/order" element={<OrderPage />} />
<Route
path="/ordersuccess"
element={<OrderSuccess />}
/>
<Route
path="/menuTest"
element={<MenuTestPage />}
Expand All @@ -64,6 +71,11 @@ const App = () => {
path="/review/:orderId"
element={<ReviewPage />}
/>
<Route
path="/visit"
element={<VisitListPage />}
/>
<Route path="/mypage" element={<MyPage />} />
<Route path="/qr" element={<QrPage />} />
<Route path="/qrgen" element={<QrGenPage />} />
<Route
Expand Down
5 changes: 5 additions & 0 deletions src/assets/images/alert.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions src/assets/images/kakao-small.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/no-cart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/no-visit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/assets/images/order-success.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions src/assets/images/toss.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
100 changes: 78 additions & 22 deletions src/components/Cart/StoreList.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import styled from "styled-components";
import Store from "./Store";
import { useCallback } from "react";
import { useCallback, useState } from "react";
import useSyluvAxios from "hooks/useSyluvAxios";
import { useNavigate } from "react-router-dom";
import { ReactComponent as NoItem } from "assets/images/no-item.svg";
import Button from "components/Common/Button";
import noItem from "assets/images/no-cart.png";
import Splash from "components/Common/Splash";
import Toast from "components/Common/Toast";

const StoreList = ({ cartList, setCartList, isLoading }) => {
const syluvAxios = useSyluvAxios();
const navigate = useNavigate();
const [selectedStore, setSelectedStore] = useState(null);
const [toastMessage, setToastMessage] = useState("");

const toggleStoreCheck = useCallback(
(storeName, isChecked) => {
Expand Down Expand Up @@ -40,6 +42,9 @@ const StoreList = ({ cartList, setCartList, isLoading }) => {
return item;
});
});

// 체크된 스토어 업데이트
setSelectedStore(isChecked ? storeName : null);
},
[setCartList]
);
Expand Down Expand Up @@ -78,11 +83,27 @@ const StoreList = ({ cartList, setCartList, isLoading }) => {
return acc;
}, {});

const totalAmount = cartList.reduce(
const selectedItems = cartList.filter((item) => item.isChecked);
const totalAmount = selectedItems.reduce(
(acc, item) => acc + item.price * item.quantity,
0
);

const handleOrder = () => {
const selectedStores = [
...new Set(selectedItems.map((item) => item.storeName)),
];
if (selectedStores.length > 1) {
setToastMessage("한 번에 한 가게만 주문할 수 있어요");
} else {
navigate("/order");
}
};

const closeToast = () => {
setToastMessage("");
};

return (
<CartList>
{Object.keys(stores).length > 0 ? (
Expand All @@ -97,35 +118,45 @@ const StoreList = ({ cartList, setCartList, isLoading }) => {
))
) : (
<NoItemContainer>
<NoItem />
<Button
onClick={() => navigate("/")}
type="2"
text="유도문구 뭐하지"
/>
<span className="title-text">장바구니가 비어있어요</span>
<img src={noItem} alt="no-item" width={158} height={158} />
<span className="sub-text">
시장을 구경하고
<br />
장바구니를 채워주세요
</span>
</NoItemContainer>
)}
{Object.keys(stores).length > 0 && (
<OrderButton onClick={() => navigate("/order")}>
{new Intl.NumberFormat("ko-KR").format(totalAmount)}
<ButtonContainer>
<OrderButton onClick={handleOrder} disabled={totalAmount === 0}>
{totalAmount > 0
? `${new Intl.NumberFormat("ko-KR").format(
totalAmount
)}원 `
: null}
주문하기
</OrderButton>
</ButtonContainer>
{toastMessage && (
<Toast
message={toastMessage}
message2="먼저 주문할 가게만 선택해주세요"
onClose={closeToast}
/>
)}
</CartList>
);
};

const CartList = styled.div`
margin-top: 7px;
display: flex;
flex-direction: column;
position: relative;
margin-bottom: 72px;
const ButtonContainer = styled.div`
position: fixed;
bottom: 0px;
padding: 20px 0px;
background-color: white;
border-top: 1px solid ${({ theme }) => theme.color.gray100};
`;

const OrderButton = styled.button`
position: fixed;
bottom: 12px;
width: 440px;
height: 48px;
margin: 0px 20px;
Expand All @@ -138,8 +169,21 @@ const OrderButton = styled.button`
cursor: pointer;
@media (max-width: 480px) {
width: calc(100% - 40px);
width: calc(100dvw - 40px);
}
&:disabled {
background-color: ${({ theme }) => theme.color.gray300};
cursor: default;
}
`;

const CartList = styled.div`
margin-top: 7px;
display: flex;
flex-direction: column;
position: relative;
margin-bottom: 88px;
`;

const NoItemContainer = styled.div`
Expand All @@ -152,6 +196,18 @@ const NoItemContainer = styled.div`
gap: 43px;
height: calc(100dvh - 140px);
.title-text {
font-size: 20px;
font-weight: ${({ theme }) => theme.fontWeight.semiBold};
}
.sub-text {
font-size: 18px;
font-weight: ${({ theme }) => theme.fontWeight.medium};
text-align: center;
color: ${({ theme }) => theme.color.gray600};
}
`;

export default StoreList;
50 changes: 37 additions & 13 deletions src/components/Common/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ const Search = ({ marketList }) => {
const navigate = useNavigate();
const [searchInput, setSearchInput] = useState("");

const getHighlightedText = (text, highlight) => {
const highlightIndex = Hangul.search(text, highlight);
if (highlightIndex === -1) return text;

const startIndex = highlightIndex;
const endIndex = highlightIndex + highlight.length;

return (
<>
{text.substring(0, startIndex)}
<Highlight>{text.substring(startIndex, endIndex)}</Highlight>
{text.substring(endIndex)}
</>
);
};

const filteredMarkets = marketList.filter(
(market) => Hangul.search(market.marketName, searchInput) >= 0
);
Expand All @@ -24,7 +40,7 @@ const Search = ({ marketList }) => {
}
}
},
[filteredMarkets]
[filteredMarkets, navigate]
);

return (
Expand All @@ -41,14 +57,17 @@ const Search = ({ marketList }) => {
<div>
{filteredMarkets.length > 0 ? (
filteredMarkets.map((market, index) => (
<span
<SearchResult
key={index}
onClick={() => {
navigate(`/market/${market.marketId}`);
}}
>
{market.marketName}
</span>
{getHighlightedText(
market.marketName,
searchInput
)}
</SearchResult>
))
) : (
<NoResults>검색 결과가 없습니다.</NoResults>
Expand Down Expand Up @@ -111,15 +130,6 @@ const Container = styled.div`
flex-direction: column;
gap: 10px;
margin-bottom: 10px;
span {
padding: 0 14px;
padding-top: 10px;
font-size: 16px;
color: ${({ theme }) => theme.color.gray500};
font-weight: ${({ theme }) => theme.fontWeight.regular};
border-top: 1px solid ${({ theme }) => theme.color.gray100};
}
}
}
`;
Expand All @@ -140,6 +150,16 @@ const SearchInput = styled.input`
}
`;

const SearchResult = styled.span`
padding: 0 14px;
padding-top: 10px;
font-size: 16px;
color: ${({ theme }) => theme.color.gray500};
font-weight: ${({ theme }) => theme.fontWeight.regular};
border-top: 1px solid ${({ theme }) => theme.color.gray100};
cursor: pointer;
`;

const NoResults = styled.span`
padding: 0 14px;
padding-top: 10px;
Expand All @@ -148,3 +168,7 @@ const NoResults = styled.span`
font-weight: ${({ theme }) => theme.fontWeight.regular};
border-top: 1px solid ${({ theme }) => theme.color.gray100};
`;

const Highlight = styled.span`
color: ${({ theme }) => theme.color.primary};
`;
9 changes: 8 additions & 1 deletion src/components/Common/Splash.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ const Splash = () => {
export default Splash;

const Wrapper = styled.div`
width: 100%;
position: fixed;
top: 0;
z-index: 5000;
width: 480px;
height: 100dvh;
background-color: ${({ theme }) => theme.color.primary};
Expand All @@ -31,4 +34,8 @@ const Wrapper = styled.div`
font-weight: ${({ theme }) => theme.fontWeight.bold};
color: white;
}
@media (max-width: 480px) {
width: 100%;
}
`;
5 changes: 3 additions & 2 deletions src/components/Common/TabBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useNavigate } from "react-router-dom";
const TabBar = ({ activeTab }) => {
const navigate = useNavigate();
const handleTabClick = (tab) => {
navigate(`/${tab}`);
navigate(`/${tab}`, { replace: true });
};
return (
<>
Expand Down Expand Up @@ -99,7 +99,7 @@ const TabBar = ({ activeTab }) => {
export default TabBar;

const Spacer = styled.div`
height: 72px;
height: 80px;
width: 1px;
`;

Expand All @@ -111,6 +111,7 @@ const Container = styled.div`
height: 72px;
background-color: white;
box-shadow: 0px -2px 4px rgba(0, 0, 0, 0.05);
margin-bottom: 8px;
.wrapper {
position: relative;
padding: 0 40px;
Expand Down
Loading

0 comments on commit f004cc1

Please sign in to comment.