Skip to content

Commit

Permalink
[feat] 작물 시장 기능 및 UI 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
using2 committed Dec 3, 2024
1 parent dec6ad4 commit 503eb19
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 158 deletions.
101 changes: 66 additions & 35 deletions apps/frontend/src/components/CropMarket/AskingPrice.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useEffect, useRef } from 'react';

interface AskingPriceProps {
validCropName: string;
marketData: {
Expand All @@ -8,52 +10,81 @@ interface AskingPriceProps {
}

const AskingPrice: React.FC<AskingPriceProps> = ({ validCropName, marketData }) => {
const containerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
if (containerRef.current) {
containerRef.current.scrollTop =
containerRef.current.scrollHeight / 2 - containerRef.current.clientHeight / 2;
}
}, [marketData.sellOrders, marketData.buyOrders]);

if (!validCropName) {
return <div>작물 정보가 없습니다.</div>;
}

const maxItems = 4;
const emptyOrder = { price: 0, quantity: 0 };

const sellOrdersToDisplay = [
...new Array(Math.max(0, maxItems - marketData.sellOrders.length)).fill(emptyOrder),
...marketData.sellOrders.sort((a, b) => b.price - a.price).slice(0, maxItems)
];

const buyOrdersToDisplay = [
...marketData.buyOrders.sort((a, b) => b.price - a.price).slice(0, maxItems),
...new Array(Math.max(0, maxItems - marketData.buyOrders.length)).fill(emptyOrder)
];

return (
<div className="w-full h-full md:text-xs lg:text-xs xl:text-sm">
<div className="grid grid-cols-[1fr_1fr_1fr] gap-1 font-semibold bg-gray-800 px-1">
<div className="w-full h-full md:text-xs lg:text-xs xl:text-sm flex flex-col">
<div className="grid grid-cols-[1fr_1fr_1fr] gap-1 font-semibold px-1">
<div className="text-center">구분</div>
<div className="text-center">가격</div>
<div className="text-center">수량</div>
</div>
<div className="md:h-24 lg:h-26 xl:h-28 overflow-y-auto scrollbar-hidden">
{marketData.sellOrders
.sort((a, b) => b.price - a.price)
.map((order, idx) => (
<div
key={idx}
className={`relative grid grid-cols-[1fr_1fr_1fr] gap-1 py-1 px-1 items-center ${
order.price === marketData.nowPrice ? 'border border-black' : ''
}`}
>
{order.price === marketData.nowPrice && (
<div className="absolute top-1/2 transform -translate-y-1/2 scale-x-[-1] w-0 h-0 border-t-[6px] border-t-transparent border-b-[6px] border-b-transparent border-r-[6px] border-r-black"></div>
)}
<div className="text-center">팔아요</div>
<div className="text-center">{order.price}</div>
<div className="font-bold text-center text-blue-600">{order.quantity}</div>
<div ref={containerRef} className="md:h-24 lg:h-26 xl:h-28 overflow-y-auto scrollbar-hidden">
{sellOrdersToDisplay.map((order, idx) => (
<div
key={idx}
className={`relative grid grid-cols-[1fr_1fr_1fr] gap-1 py-1 px-1 items-center ${
order.price === marketData.nowPrice && order.price !== 0 ? 'border border-black' : ''
}`}
>
{order.price === marketData.nowPrice && order.price !== 0 && (
<div className="absolute top-1/2 transform -translate-y-1/2 scale-x-[-1] w-0 h-0 border-t-[6px] border-t-transparent border-b-[6px] border-b-transparent border-r-[6px] border-r-black"></div>
)}
<div className="text-center">{order.price > 0 ? '팔아요' : '\u00A0'}</div>
<div className="text-center">
{order.price > 0 ? `₩ ${order.price.toLocaleString()}` : '\u00A0'}
</div>
<div className="font-bold text-center text-blue-600">
{order.quantity > 0 ? order.quantity.toLocaleString() : '\u00A0'}
</div>
</div>
))}
{(marketData.sellOrders.length > 0 || marketData.buyOrders.length > 0) && (
<hr className="bg-black h-[1px] border-none" />
)}
{buyOrdersToDisplay.map((order, idx) => (
<div
key={idx}
className={`relative grid grid-cols-[1fr_1fr_1fr] gap-1 py-1 px-1 items-center ${
order.price === marketData.nowPrice && order.price !== 0 ? 'border border-black' : ''
}`}
>
{order.price === marketData.nowPrice && order.price !== 0 && (
<div className="absolute top-1/2 transform -translate-y-1/2 scale-x-[-1] w-0 h-0 border-t-[6px] border-t-transparent border-b-[6px] border-b-transparent border-r-[6px] border-r-black"></div>
)}
<div className="text-center">{order.price > 0 ? '살게요' : '\u00A0'}</div>
<div className="text-center">
{order.price > 0 ? `₩ ${order.price.toLocaleString()}` : '\u00A0'}
</div>
))}
{marketData.buyOrders
.sort((a, b) => b.price - a.price)
.map((order, idx) => (
<div
key={idx}
className={`relative grid grid-cols-[1fr_1fr_1fr] gap-1 py-1 px-1 items-center ${
order.price === marketData.nowPrice ? 'border border-black' : ''
}`}
>
{order.price === marketData.nowPrice && (
<div className="absolute top-1/2 transform -translate-y-1/2 scale-x-[-1] w-0 h-0 border-t-[6px] border-t-transparent border-b-[6px] border-b-transparent border-r-[6px] border-r-black"></div>
)}
<div className="text-center">살게요</div>
<div className="text-center">{order.price}</div>
<div className="font-bold text-center text-red-500">{order.quantity}</div>
<div className="font-bold text-center text-red-500">
{order.quantity > 0 ? order.quantity.toLocaleString() : '\u00A0'}
</div>
))}
</div>
))}
</div>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/components/CropMarket/OwnCrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const OwnCrop: React.FC<OwnCropProps> = ({ ownCrop, cropNameList, nowPrice }) =>
return (
<tr key={cropId}>
<td>{cropDisplayName}</td>
<td>{totalQuantity}</td>
<td>{price * totalQuantity}</td>
<td>{totalQuantity.toLocaleString()}</td>
<td>{(price * totalQuantity).toLocaleString()}</td>
</tr>
);
})}
Expand Down
14 changes: 9 additions & 5 deletions apps/frontend/src/components/CropMarket/Pending.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ const Pending: React.FC<PendingProps> = ({ cropNameList }) => {
fetchPending();
}, []);

const handleCancel = async (order: MergedPendingData) => {
const handleCancel = async (e: React.MouseEvent<HTMLButtonElement>, order: MergedPendingData) => {
e.currentTarget.blur();

try {
const data = {
cropId: order.cropId,
Expand Down Expand Up @@ -89,7 +91,7 @@ const Pending: React.FC<PendingProps> = ({ cropNameList }) => {
<div>{error}</div>
) : (
<>
<div className="grid grid-cols-[1.2fr_2fr_1fr_1fr_auto] gap-1 font-semibold bg-gray-800 py-1 px-1">
<div className="grid grid-cols-[1.2fr_2fr_1fr_1fr_auto] gap-1 font-semibold py-1 px-1">
<div className="text-center">작물명</div>
<div className="text-center">주문시간</div>
<div className="text-center">수량</div>
Expand All @@ -105,12 +107,14 @@ const Pending: React.FC<PendingProps> = ({ cropNameList }) => {
>
<div className="text-center">{cropList[pending.cropName]}</div>
<div className="text-center">{formatDate(pending.time)}</div>
<div className="text-center">{pending.quantity}</div>
<div className="text-center">{pending.unfilledQuantity.toLocaleString()}</div>
<div className="text-center">{pending.price.toLocaleString()}</div>
<div className="text-center">
<button
className="px-1 bg-green-500 text-white rounded text-[9px]"
onClick={() => handleCancel(pending)}
className={`px-1 rounded text-[9px] ${
pending.orderType === 'buy' ? 'bg-red-500' : 'bg-blue-500'
} text-white`}
onClick={e => handleCancel(e, pending)}
>
취소
</button>
Expand Down
Loading

0 comments on commit 503eb19

Please sign in to comment.