diff --git a/client/src/components/Atoms/Card/index.jsx b/client/src/components/Atoms/Card/index.jsx index 0959d1d6..cc93869b 100644 --- a/client/src/components/Atoms/Card/index.jsx +++ b/client/src/components/Atoms/Card/index.jsx @@ -2,7 +2,7 @@ import React from "react"; import styled, { css } from "styled-components"; import { Link } from "react-router-dom"; -import { convert2UnitPrice } from "../../../utils/converter"; +import { convert2Price, convert2UnitPrice } from "../../../utils/converter"; import ticketIcon from "../../../assets/tickets.svg"; import { getDiffDateTime } from "../../../utils/dateUtil"; @@ -13,7 +13,7 @@ const CardStyle = styled.div` border-radius: 1rem; margin: 1rem; background: white; - width: 13rem; + width: 13.5rem; height: 17rem; padding: 0; cursor: pointer; @@ -44,8 +44,10 @@ const InfoContainer = styled.div` `; const StyledLink = styled(Link)` + height: fit-content; text-decoration: none; color: black; + height: 17rem; `; const BidsStyle = styled.div` @@ -167,6 +169,7 @@ const Card = ({ item }) => { }; const Bids = ({ bids }) => { + if (bids >= 1000) bids = `${Number(bids / 1000)}K`; return ( {"profile @@ -207,7 +210,9 @@ const BuyNowPrice = ({ buyNowPrice }) => { return ( - {convert2UnitPrice(buyNowPrice)} + {Number(buyNowPrice) < 10000 + ? convert2Price(buyNowPrice) + : convert2UnitPrice(buyNowPrice)} ); }; @@ -216,7 +221,9 @@ const TopBid = ({ topBid }) => { return ( - {convert2UnitPrice(topBid)} + {Number(topBid) < 10000 + ? convert2Price(topBid) + : convert2UnitPrice(topBid)} ); }; diff --git a/client/src/components/Atoms/InputWithLimit/index.jsx b/client/src/components/Atoms/InputWithLimit/index.jsx index aa7b64a6..aa1359da 100644 --- a/client/src/components/Atoms/InputWithLimit/index.jsx +++ b/client/src/components/Atoms/InputWithLimit/index.jsx @@ -1,5 +1,5 @@ -import React, { useState } from "react" -import styled from "styled-components" +import React, { useState } from "react"; +import styled from "styled-components"; const Container = styled.div` width: 100%; @@ -16,7 +16,7 @@ const Container = styled.div` border-color: ${props => props.exceed ? "var(--color-danger)" : "var(--color-primary-minus0)"}; } -` +`; const NonBorder = styled.input` font-family: "BMJUA"; @@ -24,29 +24,31 @@ const NonBorder = styled.input` height: fit-content; font-size: var(--font-size-xl); outline: none; -` +`; const Counter = styled.div` width: fit-content; font-size: var(--font-size-xs); color: ${props => (props.exceed ? "var(--color-danger)" : "var(--color-gray)")}; -` +`; const Component = ({ limit, hint, onChange, value, isBlockMode }) => { - const [focus, setFocus] = useState(false) - const [length, setLength] = useState(value.length) + const [focus, setFocus] = useState(false); + const [length, setLength] = useState(value.length); const handleOnChange = e => { - const content = e.target.value + const content = e.target.value; const validContent = - isBlockMode && content.length > limit ? content.substring(0, limit) : content - onChange(validContent) - setLength(validContent.length) - } + isBlockMode && content.length > limit ? content.substring(0, limit) : content; + onChange(validContent); + setLength(validContent.length); + }; const handleBlock = e => { - if (e.target.value.length >= limit) e.preventDefault() - } + const keyCode = e.keyCode; + const value = e.target.value; + if (keyCode !== 8 && keyCode !== 46 && value.length >= limit) e.preventDefault(); + }; return ( limit}> @@ -60,7 +62,7 @@ const Component = ({ limit, hint, onChange, value, isBlockMode }) => { /> limit}>{`${length} / ${limit}`} - ) -} + ); +}; -export default Component +export default Component; diff --git a/client/src/components/Atoms/SmallCard/index.jsx b/client/src/components/Atoms/SmallCard/index.jsx index 2d4d4d7a..5dd9c7b0 100644 --- a/client/src/components/Atoms/SmallCard/index.jsx +++ b/client/src/components/Atoms/SmallCard/index.jsx @@ -1,10 +1,12 @@ import React from "react"; import styled from "styled-components"; +const smallCardSize = "9em"; + const SmallCardStyle = styled.div` display: flex; - height: 9em; - width: 9em; + height: ${smallCardSize}; + width: ${smallCardSize}; margin: 1rem; border-radius: 1rem; overflow: hidden; @@ -22,16 +24,19 @@ const SmallCardStyle = styled.div` transform: scale(1.05); } `; +const Link = styled.a` + height: ${smallCardSize}; +`; const SmallCard = ({ item }) => { const { id, thumbnailUrl } = item; const link = `/products/${id}`; return ( - + {"thumbnail"} - + ); }; diff --git a/client/src/components/Atoms/TextareaWithLength/index.jsx b/client/src/components/Atoms/TextareaWithLength/index.jsx index 5097b4d8..5f9a6700 100644 --- a/client/src/components/Atoms/TextareaWithLength/index.jsx +++ b/client/src/components/Atoms/TextareaWithLength/index.jsx @@ -1,28 +1,28 @@ -import React, { useState } from "react" -import styled from "styled-components" +import React, { useState } from "react"; +import styled from "styled-components"; const Container = styled.div` width: 100%; border: none; outline: none; -` +`; const Header = styled.div` width: 100%; display: flex; justify-content: space-between; margin-bottom: 5px; -` +`; const Title = styled.span` font-weight: bold; -` +`; const Counter = styled.span` color: ${props => (props.isOver ? "var(--color-danger)" : "var(--color-gary)")}; font-weight: ${props => (props.isOver ? "700" : "400")}; font-size: 0.9rem; -` +`; const Content = styled.textarea` font-family: D2Coding, "D2 coding", monosapce; @@ -35,22 +35,24 @@ const Content = styled.textarea` outline: none; font-size: 1.2rem; padding: 1rem; -` +`; const Component = ({ title, limit, content, handler, isBlockMode }) => { - const [len, setLen] = useState(content ? content.length : 0) + const [len, setLen] = useState(content ? content.length : 0); const handleContent = event => { - const content = event.target.value + const content = event.target.value; const validContent = - isBlockMode && content.length > limit ? content.substring(0, limit) : content - handler(validContent) - setLen(validContent.length) - } + isBlockMode && content.length > limit ? content.substring(0, limit) : content; + handler(validContent); + setLen(validContent.length); + }; const handleBlock = e => { - if (e.target.value.length >= limit) e.preventDefault() - } + const keyCode = e.keyCode; + const value = e.target.value; + if (keyCode !== 8 && keyCode !== 46 && value.length >= limit) e.preventDefault(); + }; return ( @@ -65,7 +67,7 @@ const Component = ({ title, limit, content, handler, isBlockMode }) => { value={content} /> - ) -} + ); +}; -export default Component +export default Component; diff --git a/client/src/components/Messenger/Container/ChatContainer/ChatMessage.jsx b/client/src/components/Messenger/Container/ChatContainer/ChatMessage.jsx index 2202cb55..fb9ed3b8 100644 --- a/client/src/components/Messenger/Container/ChatContainer/ChatMessage.jsx +++ b/client/src/components/Messenger/Container/ChatContainer/ChatMessage.jsx @@ -1,6 +1,6 @@ -import styled from "styled-components" -import React from "react" -import { dateDiff2Str, sec2date } from "../../../../utils/converter" +import styled from "styled-components"; +import React from "react"; +import { dateDiff2Str, sec2date } from "../../../../utils/converter"; const Wrap = styled.div` width: 19rem; @@ -9,12 +9,12 @@ const Wrap = styled.div` justify-content: ${props => (props.isSend ? "flex-end" : "flex-end")}; padding: 0.25rem 0.25rem; margin: 0 0.5rem 0 0; -` +`; const MessageText = styled.span` display: inline-block; text-align: left; - word-break: break-all; + word-break: break-word; font-size: var(--font-size-xs); @@ -23,10 +23,10 @@ const MessageText = styled.span` border: solid 0.1rem; border-color: ${props => (props.isSend ? "var(--color-primary-minus0)" : "var(--color-primary)")}; border-radius: 1rem; -` +`; const TimeText = styled.div` font-size: var(--font-size-xxs); -` +`; function ChatMessage(props) { return ( @@ -34,7 +34,7 @@ function ChatMessage(props) { {dateDiff2Str(sec2date(props.Time))} {props.Text} - ) + ); } -export default ChatMessage +export default ChatMessage; diff --git a/client/src/components/Molecules/CardContainer/index.jsx b/client/src/components/Molecules/CardContainer/index.jsx index 45963c21..c98d8e2a 100644 --- a/client/src/components/Molecules/CardContainer/index.jsx +++ b/client/src/components/Molecules/CardContainer/index.jsx @@ -7,7 +7,7 @@ const Container = styled.div` display: flex; flex-direction: column; justify-content: center; - padding-left: 8rem; + padding-left: 7rem; `; const Title = styled.label` diff --git a/client/src/components/Molecules/CustomModal/LoginModal.jsx b/client/src/components/Molecules/CustomModal/LoginModal.jsx index e6b3ca54..10dc08ea 100644 --- a/client/src/components/Molecules/CustomModal/LoginModal.jsx +++ b/client/src/components/Molecules/CustomModal/LoginModal.jsx @@ -141,9 +141,15 @@ const LoginModal = ({ close }) => { } else alert("구글 로그인에 실패하였습니다."); }; const handleKeyUpId = e => { + if (e.keyCode === 13) { + handleSubmit(e); + } setId(e.target.value); }; const handleKeyUpPwd = e => { + if (e.keyCode === 13) { + handleSubmit(e); + } setPwd(e.target.value); }; diff --git a/client/src/components/Molecules/SmallCardContainer/index.jsx b/client/src/components/Molecules/SmallCardContainer/index.jsx index 100efce4..f144b1b5 100644 --- a/client/src/components/Molecules/SmallCardContainer/index.jsx +++ b/client/src/components/Molecules/SmallCardContainer/index.jsx @@ -20,7 +20,7 @@ const Title = styled.label` const SmallCardContainerStyle = styled.div` display: flex; - justify-content: space-between; + justify-content: flex-start; width: 100%; height: ${props => (props.isWrap ? "35rem" : "17rem")}; margin-bottom: 2rem; diff --git a/client/src/components/Organism/CategoryBar/ExpandList/index.jsx b/client/src/components/Organism/CategoryBar/ExpandList/index.jsx index bc99b75f..c6d93cba 100644 --- a/client/src/components/Organism/CategoryBar/ExpandList/index.jsx +++ b/client/src/components/Organism/CategoryBar/ExpandList/index.jsx @@ -7,7 +7,7 @@ import NotifyList from "../../../Molecules/NotifyList"; const Container = styled.div` display: flex; flex-direction: column; - width: ${props => (props.idx === "999" ? 20 : 15)}rem; + width: ${props => (props.idx === 999 ? "21" : "15")}rem; height: 100%; overflow-y: auto; background-color: var(--color-secondary-minus1); @@ -45,11 +45,7 @@ const Components = ({ idx, open, details, onClick }) => { ) : ( details.map((category, index) => ( - + diff --git a/client/src/components/Organism/CategoryBar/index.jsx b/client/src/components/Organism/CategoryBar/index.jsx index 5da9594d..63c7811f 100644 --- a/client/src/components/Organism/CategoryBar/index.jsx +++ b/client/src/components/Organism/CategoryBar/index.jsx @@ -31,7 +31,7 @@ const OriginWrapper = styled.div` const ListWrapper = styled.div` position: absolute; - width: ${props => (props.open ? (props.idx === "999" ? 20 : 15) : 0)}rem; + width: ${props => (props.open ? (props.idx === 999 ? "21" : "15") : 0)}rem; height: 100%; left: 5em; z-index: 999; @@ -186,11 +186,7 @@ const Components = () => { )} diff --git a/client/src/components/Organism/Chat/Chat.jsx b/client/src/components/Organism/Chat/Chat.jsx index b75f956e..92caec33 100644 --- a/client/src/components/Organism/Chat/Chat.jsx +++ b/client/src/components/Organism/Chat/Chat.jsx @@ -23,20 +23,24 @@ const IdText = styled.div` font-size: 0.9rem; color: var(--color-darkgray); `; - +const SellerIdText = styled.div` + font-weight: bold; + font-size: 0.9rem; + color: var(--color-darkgray); +`; const MessageText = styled.div` font-size: 0.8rem; word-break: break-all; `; -const Chat = ({ chat }) => { +const Chat = ({ chat, isSeller }) => { return ( - {chat.id} + {isSeller ? {chat.id}(판매자) : {chat.id}} {chat.text} diff --git a/client/src/components/Organism/Chat/ChatBox.jsx b/client/src/components/Organism/Chat/ChatBox.jsx index 89c4a8da..16eeb950 100644 --- a/client/src/components/Organism/Chat/ChatBox.jsx +++ b/client/src/components/Organism/Chat/ChatBox.jsx @@ -59,7 +59,7 @@ const ChatAlertWithPurchase = styled(ChatAlertWithBid)` background-color: var(--color-primary-minus2); `; -const ChatBox = ({ productId, user }) => { +const ChatBox = ({ productId, sellerId, user }) => { const chatBodyRef = useRef(); const [productPageState] = useContext(ProductPageContext); const { socketClient, chats } = productPageState; @@ -80,7 +80,6 @@ const ChatBox = ({ productId, user }) => { props: { message: "로그인이 필요합니다." } }); } - socketClient.emit("message", { roomId: productId, sender: { ...user, sessionId: socketClient.id }, @@ -91,7 +90,6 @@ const ChatBox = ({ productId, user }) => { e.target.message.value = ""; }; - return ( @@ -100,7 +98,7 @@ const ChatBox = ({ productId, user }) => { {chats.map(chat => { return chat.type === "message" ? ( - + ) : ( {chat.type === "bid" ? ( diff --git a/client/src/components/Organism/TradeListBox/index.jsx b/client/src/components/Organism/TradeListBox/index.jsx index 72ccbb48..93f0def0 100644 --- a/client/src/components/Organism/TradeListBox/index.jsx +++ b/client/src/components/Organism/TradeListBox/index.jsx @@ -34,31 +34,34 @@ const Deviation = styled.span` `; const OptionPriceCheck = styled.div` - display: ${props => (props.isCheck === null ? "none" : "block")}; + display: ${props => (props.isCheck ? "block" : "none")}; `; const Component = props => { const [isHover, setIsHover] = useState(false); const [rateCheck, setRateCheck] = useState(false); - let soldDate = toFormatDateTime(props.solddate); - + let soldDate = props.solddate + ? toFormatDateTime(props.solddate) + : toFormatDateTime(props.registdate); function doCheck() { setRateCheck(true); } let soldseconds = new Date(soldDate).getTime(); return ( -
setIsHover(true)} onMouseOut={() => setIsHover(false)}> +
setIsHover(true)} onMouseLeave={() => setIsHover(false)}> 등록 날짜:{toFormatDateTime(props.registdate)} - + 희망 가격:{convert2Price(props.hopeprice)} 편차:{props.deviation}% @@ -82,7 +85,7 @@ const Component = props => { />
- ) : ( + ) : props.status === "구매" ? (
{rateCheck || props.buyerCheck ? ( "평가완료" @@ -100,8 +103,10 @@ const Component = props => { sellerId={props.targetId} text={"판매자와 대화하기"} /> - +
+ ) : ( + undefined )}
diff --git a/client/src/pages/CategoryItems/index.jsx b/client/src/pages/CategoryItems/index.jsx index 70ed3d31..dee877e3 100644 --- a/client/src/pages/CategoryItems/index.jsx +++ b/client/src/pages/CategoryItems/index.jsx @@ -52,7 +52,7 @@ const CategoryItems = ({ match }) => { return ( <> - {title.length ? ( + {title && title.length ? ( diff --git a/client/src/pages/Product/index.jsx b/client/src/pages/Product/index.jsx index 05311f05..65b7bf3c 100644 --- a/client/src/pages/Product/index.jsx +++ b/client/src/pages/Product/index.jsx @@ -89,8 +89,7 @@ const productPageReducer = (state, action) => { } }; -const DEFAULT_PROFILE_URL = - "https://kr.object.ncloudstorage.com/palda/img/default-profile-img.jpg"; +const DEFAULT_PROFILE_URL = "https://kr.object.ncloudstorage.com/palda/img/default-profile-img.jpg"; const ProductPage = ({ match }) => { const [productPageState, dispatchProductPage] = useReducer( @@ -117,11 +116,7 @@ const ProductPage = ({ match }) => { dispatchProductPage({ type: "FETCH_ERROR", error }); }; - useFetch( - `${pathConfig.productsWithBids}/${productId}`, - handleFetchSuccess, - handleFetchError - ); + useFetch(`${pathConfig.productsWithBids}/${productId}`, handleFetchSuccess, handleFetchError); const getRelatedItemList = async () => { if (!productPageState.loading) { @@ -151,6 +146,7 @@ const ProductPage = ({ match }) => { type, sessionId: sender.sessionId, id: sender.isSnsLogin ? sender.name : sender.loginId, + senderId: sender.id, src: sender.profileUrl || DEFAULT_PROFILE_URL, text, key: `M.${createdAt}.${sender.id}` @@ -164,9 +160,7 @@ const ProductPage = ({ match }) => { sessionId: sender.sessionId, id: sender.loginId, src: sender.profileUrl || DEFAULT_PROFILE_URL, - text: `${sender.name}님께서 ${convert2Price( - bid.bidPrice - )}원에 입찰 하셨습니다.`, + text: `${sender.name}님께서 ${convert2Price(bid.bidPrice)}원에 입찰 하셨습니다.`, key: `B.${createdAt}.${sender.id}` }; @@ -179,9 +173,7 @@ const ProductPage = ({ match }) => { sessionId: sender.sessionId, id: sender.loginId, src: sender.profileUrl || DEFAULT_PROFILE_URL, - text: `${sender.name}님이 ${convert2Price( - sold.soldPrice - )}원에 즉시 구매하셨습니다.`, + text: `${sender.name}님이 ${convert2Price(sold.soldPrice)}원에 즉시 구매하셨습니다.`, key: `P.${createdAt}.${sender.id}` }; @@ -214,13 +206,11 @@ const ProductPage = ({ match }) => { if (productPageState.error) { return ; } - + const sellerId = productPageState.product.seller ? productPageState.product.seller.id : undefined; return productPageState.loading ? ( ) : ( - +
@@ -232,15 +222,11 @@ const ProductPage = ({ match }) => {
) : null}
- +
- +
diff --git a/client/src/pages/TradeList/index.jsx b/client/src/pages/TradeList/index.jsx index fe58c7d7..ebd52694 100644 --- a/client/src/pages/TradeList/index.jsx +++ b/client/src/pages/TradeList/index.jsx @@ -10,6 +10,7 @@ import userContext from "../../context/UserContext"; import apiConfig from "../../config/api"; import pathConfig from "../../config/path"; +import NotFoundImage from "../../assets/notFound.png"; const { apiUrl } = apiConfig; const { logfilter } = pathConfig; @@ -60,6 +61,15 @@ const PageButton = styled.button` color: ${props => (props.currentPage === props.buttonNumber ? "var(--color-primary)" : "black")}; font-size: ${props => (props.currentPage === props.buttonNumber ? "var(--font-size-lg)" : "")}; `; + +const NotFoundDiv = styled.div` + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +`; function TradeList() { const [data, setData] = useState([]); const [isSale, setIsSale] = useState(true); @@ -92,19 +102,27 @@ function TradeList() { }) .then(result => { let resultData = result[0].map(ele => { + let hope_price_check = ele.hopePrice ? ele.hopePrice : undefined; + let sold_price_check = ele.soldPrice ? ele.soldPrice : undefined; + let sold_date_check = ele.soldDate ? ele.soldDate : undefined; + let buyer_id_check = ele.buyerId ? ele.buyerId : undefined; + return { id: ele.id, title: ele.title, thumbnail: ele.thumbnailUrl, - status: ele.seller.id === user.id ? "판매" : "구매", - soldprice: ele.soldPrice, - solddate: ele.soldDate, + status: ele.seller.id === user.id ? (sold_price_check ? "판매" : "판매실패") : "구매", + soldprice: sold_price_check, + solddate: sold_date_check, registdate: ele.registerDate, - hopeprice: ele.hopePrice, - deviation: (((ele.hopePrice - ele.soldPrice) / ele.soldPrice) * 100).toFixed(2), + hopeprice: hope_price_check, + deviation: (((sold_price_check - hope_price_check) / hope_price_check) * 100).toFixed( + 2 + ), + immediatePrice: ele.immediatePrice, userId: user.id, - targetId: ele.seller.id === user.id ? ele.buyerId : ele.seller.id, + targetId: ele.seller.id === user.id ? buyer_id_check : ele.seller.id, sellerCheck: ele.sellerCheck, buyerCheck: ele.buyerCheck @@ -182,19 +200,18 @@ function TradeList() { /> - {data.map(value => ( - - ))} - {/* getData(isSale, isBuy, dayago, page)} - drawer={drawer} - /> */} + {data.length ? ( + data.map(value => ) + ) : ( + + {"Not + 검색 기록이 없습니다. + + )}