Tarkov-style flea market where users list locker items at a fixed price and buyers pay through the banking system; items transfer directly into the buyer's locker. - market-listings + market-negotiations collections and the market page with search/rarity filters and a Countdown timer on each card - service lib (buyListing with partial-quantity + negotiated-price support, clean-stock rule, creditLockerQuantity, auto pricing) - negotiation flow: make/accept/reject/counter/withdraw, strictly- increasing buyer offers, NPC vendor auto-resolution - NPC vendors: game-npcs attribution, patience meter, dialogue, chat bubbles, historical threads dialog - 30d user / 7d auto listing durations, market-tick bin for expiry + vendor restock, SSE notify on tick - market event types + game-npcs/market target collections in the event log; sidebar Market entry under Logistics - partial-quantity purchases (buyListing/buyMarketListing/makeMarketOffer) with full int test coverage (25 tests)
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import type { Asset, MarketListing, MarketNegotiation } from "@/payload-types";
|
|
import { StoreIcon } from "lucide-react";
|
|
import { buildChatBubbles } from "@/lib/market/chatBubbles";
|
|
import { ChatBubbleList } from "@/components/frontend/market/ChatBubbleList";
|
|
|
|
interface NpcChatProps {
|
|
listing: MarketListing;
|
|
negotiation: MarketNegotiation | null;
|
|
currencyLabel: string | null;
|
|
}
|
|
|
|
export function NpcChat({ listing, negotiation, currencyLabel }: NpcChatProps) {
|
|
const asset = listing.asset as Asset;
|
|
const assetName = typeof asset === "object" && asset ? asset.name : `Asset #${listing.asset}`;
|
|
const bubbles = buildChatBubbles(negotiation, listing, currencyLabel);
|
|
|
|
return (
|
|
<div className="flex flex-col gap-2 rounded-md border bg-card">
|
|
<div className="flex items-center gap-2 border-b px-3 py-2">
|
|
<StoreIcon className="size-4 text-muted-foreground" />
|
|
<span className="text-xs font-medium text-muted-foreground">Vendor</span>
|
|
<span className="text-xs text-muted-foreground">— {assetName}</span>
|
|
</div>
|
|
<ChatBubbleList bubbles={bubbles} buyerLabel="You" sellerLabel="Vendor" />
|
|
</div>
|
|
);
|
|
}
|