refactor(market): pass currency config through market UI
Market listings, offer dialogs, negotiation panels, and history now render prices from the full CurrencyConfig (symbol + singular/plural) instead of a nullable currency label string. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
52ecc4f3b6
commit
80ec3a0386
7 changed files with 42 additions and 47 deletions
|
|
@ -6,7 +6,7 @@ import { StoreIcon } from "lucide-react";
|
||||||
import { MarketView } from "@/components/frontend/market/MarketView";
|
import { MarketView } from "@/components/frontend/market/MarketView";
|
||||||
import { hasPermission } from "@/utils/access-control/hasPermission";
|
import { hasPermission } from "@/utils/access-control/hasPermission";
|
||||||
import { ensureLockerStorage } from "@/lib/locker";
|
import { ensureLockerStorage } from "@/lib/locker";
|
||||||
import { getMainCurrencyName } from "@/lib/banking";
|
import { getCurrencyConfig } from "@/lib/banking";
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: "Market — Polaris Task Force",
|
title: "Market — Polaris Task Force",
|
||||||
|
|
@ -76,8 +76,8 @@ export default async function MarketPage() {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
const isManager = user ? (await hasPermission(payload, user, "logistics:manage")) : false;
|
const isManager = user ? await hasPermission(payload, user, "logistics:manage") : false;
|
||||||
const currencyLabel = await getMainCurrencyName(payload);
|
const currencyConfig = await getCurrencyConfig(payload);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-5 flex flex-col gap-6">
|
<div className="p-5 flex flex-col gap-6">
|
||||||
|
|
@ -97,7 +97,7 @@ export default async function MarketPage() {
|
||||||
negotiations={negotiations}
|
negotiations={negotiations}
|
||||||
locker={lockerFull}
|
locker={lockerFull}
|
||||||
currentUserId={userId}
|
currentUserId={userId}
|
||||||
currencyLabel={currencyLabel}
|
currencyConfig={currencyConfig}
|
||||||
isManager={isManager}
|
isManager={isManager}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import { createMarketListing } from "@/app/(frontend)/logistics/market/actions";
|
||||||
|
|
||||||
interface CreateListingDialogProps {
|
interface CreateListingDialogProps {
|
||||||
locker: LockerStorage | null;
|
locker: LockerStorage | null;
|
||||||
currencyLabel: string | null;
|
currencyLabel: string;
|
||||||
open?: boolean;
|
open?: boolean;
|
||||||
onOpenChange?: (open: boolean) => void;
|
onOpenChange?: (open: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +225,7 @@ export function CreateListingDialog({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 flex-col gap-1.5">
|
<div className="flex flex-1 flex-col gap-1.5">
|
||||||
<Label>Price per unit ({currencyLabel ?? "units"})</Label>
|
<Label>Price per unit ({currencyLabel})</Label>
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
min={0.01}
|
min={0.01}
|
||||||
|
|
@ -254,7 +254,7 @@ export function CreateListingDialog({
|
||||||
</label>
|
</label>
|
||||||
{negotiable && (
|
{negotiable && (
|
||||||
<div className="flex flex-col gap-1.5">
|
<div className="flex flex-col gap-1.5">
|
||||||
<Label>Minimum price per unit ({currencyLabel ?? "units"})</Label>
|
<Label>Minimum price per unit ({currencyLabel})</Label>
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
min={0.01}
|
min={0.01}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import {
|
||||||
} from "@/components/ui/item";
|
} from "@/components/ui/item";
|
||||||
import { getAssetTypeLabel } from "@/lib/locker";
|
import { getAssetTypeLabel } from "@/lib/locker";
|
||||||
import { getRarityLabel, isNegotiable } from "@/lib/market";
|
import { getRarityLabel, isNegotiable } from "@/lib/market";
|
||||||
import { formatAmount } from "@/lib/banking/format";
|
import { formatAmount, type CurrencyConfig } from "@/lib/banking/format";
|
||||||
import { PackageIcon, ShoppingCartIcon, XIcon } from "lucide-react";
|
import { PackageIcon, ShoppingCartIcon, XIcon } from "lucide-react";
|
||||||
import { buyMarketListing, cancelMarketListing } from "@/app/(frontend)/logistics/market/actions";
|
import { buyMarketListing, cancelMarketListing } from "@/app/(frontend)/logistics/market/actions";
|
||||||
import { Countdown } from "@/components/frontend/market/Countdown";
|
import { Countdown } from "@/components/frontend/market/Countdown";
|
||||||
|
|
@ -28,7 +28,7 @@ import { useNow } from "@/hooks/useNow";
|
||||||
interface ListingCardProps {
|
interface ListingCardProps {
|
||||||
listing: MarketListing;
|
listing: MarketListing;
|
||||||
currentUserId: number;
|
currentUserId: number;
|
||||||
currencyLabel: string | null;
|
currencyConfig: CurrencyConfig;
|
||||||
canManage: boolean;
|
canManage: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ function sellerName(listing: MarketListing): string {
|
||||||
export function ListingCard({
|
export function ListingCard({
|
||||||
listing,
|
listing,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
currencyLabel,
|
currencyConfig,
|
||||||
canManage,
|
canManage,
|
||||||
}: ListingCardProps) {
|
}: ListingCardProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
@ -141,7 +141,7 @@ export function ListingCard({
|
||||||
</ItemDescription>
|
</ItemDescription>
|
||||||
<div className="flex items-center justify-between gap-2 w-full">
|
<div className="flex items-center justify-between gap-2 w-full">
|
||||||
<span className="text-sm font-semibold font-mono">
|
<span className="text-sm font-semibold font-mono">
|
||||||
{formatAmount(listing.price ?? 0, { name: currencyLabel ?? undefined })} / unit
|
{formatAmount(listing.price ?? 0, currencyConfig)} / unit
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-muted-foreground">
|
<span className="text-xs text-muted-foreground">
|
||||||
{stock > 1 && (
|
{stock > 1 && (
|
||||||
|
|
@ -149,7 +149,7 @@ export function ListingCard({
|
||||||
{selectedQty}/{stock} ·{" "}
|
{selectedQty}/{stock} ·{" "}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
total {formatAmount(selectedTotal, { name: currencyLabel ?? undefined })}
|
total {formatAmount(selectedTotal, currencyConfig)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{error && <p className="text-sm text-red-400">{error}</p>}
|
{error && <p className="text-sm text-red-400">{error}</p>}
|
||||||
|
|
@ -188,7 +188,7 @@ export function ListingCard({
|
||||||
<MakeOfferDialog
|
<MakeOfferDialog
|
||||||
listing={listing}
|
listing={listing}
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
currencyLabel={currencyLabel}
|
currencyConfig={currencyConfig}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import {
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { formatAmount } from "@/lib/banking/format";
|
import { currencyLabel, formatAmount, type CurrencyConfig } from "@/lib/banking/format";
|
||||||
import {
|
import {
|
||||||
acceptMarketOffer,
|
acceptMarketOffer,
|
||||||
cancelMarketOffer,
|
cancelMarketOffer,
|
||||||
|
|
@ -55,10 +55,10 @@ function outcomeOf(negotiation: MarketNegotiation | null): OfferOutcome | null {
|
||||||
interface MakeOfferDialogProps {
|
interface MakeOfferDialogProps {
|
||||||
listing: MarketListing;
|
listing: MarketListing;
|
||||||
currentUserId: number;
|
currentUserId: number;
|
||||||
currencyLabel: string | null;
|
currencyConfig: CurrencyConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MakeOfferDialog({ listing, currentUserId, currencyLabel }: MakeOfferDialogProps) {
|
export function MakeOfferDialog({ listing, currentUserId, currencyConfig }: MakeOfferDialogProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [amount, setAmount] = useState("");
|
const [amount, setAmount] = useState("");
|
||||||
|
|
@ -76,7 +76,8 @@ export function MakeOfferDialog({ listing, currentUserId, currencyLabel }: MakeO
|
||||||
const isVendor = listing.isAutoGenerated;
|
const isVendor = listing.isAutoGenerated;
|
||||||
const stock = listing.quantity ?? 1;
|
const stock = listing.quantity ?? 1;
|
||||||
const outcome = outcomeOf(negotiation);
|
const outcome = outcomeOf(negotiation);
|
||||||
const fmt = (n: number) => formatAmount(n, { name: currencyLabel ?? undefined });
|
const displayCurrency = currencyLabel(currencyConfig);
|
||||||
|
const fmt = (n: number) => formatAmount(n, currencyConfig);
|
||||||
const clampedQty = Math.max(1, Math.min(stock, qty));
|
const clampedQty = Math.max(1, Math.min(stock, qty));
|
||||||
|
|
||||||
const sinceAccept = acceptedAt != null ? nowTick - acceptedAt : 0;
|
const sinceAccept = acceptedAt != null ? nowTick - acceptedAt : 0;
|
||||||
|
|
@ -244,7 +245,7 @@ export function MakeOfferDialog({ listing, currentUserId, currencyLabel }: MakeO
|
||||||
|
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
{isVendor && (
|
{isVendor && (
|
||||||
<NpcChat listing={listing} negotiation={negotiation} currencyLabel={currencyLabel} />
|
<NpcChat listing={listing} negotiation={negotiation} currencyLabel={displayCurrency} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{loadingThread && !outcome && (
|
{loadingThread && !outcome && (
|
||||||
|
|
@ -254,7 +255,7 @@ export function MakeOfferDialog({ listing, currentUserId, currencyLabel }: MakeO
|
||||||
{!outcome && !loadingThread && (
|
{!outcome && !loadingThread && (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-col gap-1.5">
|
<div className="flex flex-col gap-1.5">
|
||||||
<Label>Your offer ({currencyLabel ?? "units"} per unit)</Label>
|
<Label>Your offer ({displayCurrency} per unit)</Label>
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
min={0.01}
|
min={0.01}
|
||||||
|
|
@ -310,7 +311,7 @@ export function MakeOfferDialog({ listing, currentUserId, currencyLabel }: MakeO
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col gap-1.5">
|
<div className="flex flex-col gap-1.5">
|
||||||
<Label>Your counter ({currencyLabel ?? "units"} per unit)</Label>
|
<Label>Your counter ({displayCurrency} per unit)</Label>
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
min={0.01}
|
min={0.01}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { CreateListingDialog } from "@/components/frontend/market/CreateListingD
|
||||||
import { NegotiationPanel } from "@/components/frontend/market/NegotiationPanel";
|
import { NegotiationPanel } from "@/components/frontend/market/NegotiationPanel";
|
||||||
import { PlusIcon, SearchIcon } from "lucide-react";
|
import { PlusIcon, SearchIcon } from "lucide-react";
|
||||||
import { usePageCommands } from "@/components/command-palette/CommandPaletteContext";
|
import { usePageCommands } from "@/components/command-palette/CommandPaletteContext";
|
||||||
|
import { currencyLabel, type CurrencyConfig } from "@/lib/banking/format";
|
||||||
|
|
||||||
const ASSET_TYPE_OPTIONS: { value: string; label: string }[] = [
|
const ASSET_TYPE_OPTIONS: { value: string; label: string }[] = [
|
||||||
{ value: "weapon", label: "Weapon" },
|
{ value: "weapon", label: "Weapon" },
|
||||||
|
|
@ -61,7 +62,7 @@ interface MarketViewProps {
|
||||||
negotiations: MarketNegotiation[];
|
negotiations: MarketNegotiation[];
|
||||||
locker: LockerStorage | null;
|
locker: LockerStorage | null;
|
||||||
currentUserId: number;
|
currentUserId: number;
|
||||||
currencyLabel: string | null;
|
currencyConfig: CurrencyConfig;
|
||||||
isManager: boolean;
|
isManager: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,13 +72,14 @@ export function MarketView({
|
||||||
negotiations,
|
negotiations,
|
||||||
locker,
|
locker,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
currencyLabel,
|
currencyConfig,
|
||||||
isManager,
|
isManager,
|
||||||
}: MarketViewProps) {
|
}: MarketViewProps) {
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const [rarity, setRarity] = useState("all");
|
const [rarity, setRarity] = useState("all");
|
||||||
const [assetType, setAssetType] = useState("all");
|
const [assetType, setAssetType] = useState("all");
|
||||||
const [createListingOpen, setCreateListingOpen] = useState(false);
|
const [createListingOpen, setCreateListingOpen] = useState(false);
|
||||||
|
const currencyName = currencyLabel(currencyConfig);
|
||||||
|
|
||||||
usePageCommands([
|
usePageCommands([
|
||||||
{
|
{
|
||||||
|
|
@ -153,7 +155,7 @@ export function MarketView({
|
||||||
</div>
|
</div>
|
||||||
<CreateListingDialog
|
<CreateListingDialog
|
||||||
locker={locker}
|
locker={locker}
|
||||||
currencyLabel={currencyLabel}
|
currencyLabel={currencyName}
|
||||||
open={createListingOpen}
|
open={createListingOpen}
|
||||||
onOpenChange={setCreateListingOpen}
|
onOpenChange={setCreateListingOpen}
|
||||||
/>
|
/>
|
||||||
|
|
@ -179,7 +181,7 @@ export function MarketView({
|
||||||
key={listing.id}
|
key={listing.id}
|
||||||
listing={listing}
|
listing={listing}
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
currencyLabel={currencyLabel}
|
currencyConfig={currencyConfig}
|
||||||
canManage={isManager}
|
canManage={isManager}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
@ -190,7 +192,7 @@ export function MarketView({
|
||||||
<NegotiationPanel
|
<NegotiationPanel
|
||||||
negotiations={negotiations}
|
negotiations={negotiations}
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
currencyLabel={currencyLabel}
|
currencyConfig={currencyConfig}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{myListings.length > 0 && (
|
{myListings.length > 0 && (
|
||||||
|
|
@ -207,7 +209,7 @@ export function MarketView({
|
||||||
key={listing.id}
|
key={listing.id}
|
||||||
listing={listing}
|
listing={listing}
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
currencyLabel={currencyLabel}
|
currencyConfig={currencyConfig}
|
||||||
canManage={isManager}
|
canManage={isManager}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import {
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||||
import { formatAmount } from "@/lib/banking/format";
|
import { currencyLabel, formatAmount, type CurrencyConfig } from "@/lib/banking/format";
|
||||||
import { buildChatBubbles } from "@/lib/market/chatBubbles";
|
import { buildChatBubbles } from "@/lib/market/chatBubbles";
|
||||||
import { ChatBubbleList } from "@/components/frontend/market/ChatBubbleList";
|
import { ChatBubbleList } from "@/components/frontend/market/ChatBubbleList";
|
||||||
import { ChevronDownIcon, HistoryIcon } from "lucide-react";
|
import { ChevronDownIcon, HistoryIcon } from "lucide-react";
|
||||||
|
|
@ -71,15 +71,15 @@ function counterpartyLabel(negotiation: MarketNegotiation, role: "buyer" | "sell
|
||||||
function HistoryRow({
|
function HistoryRow({
|
||||||
negotiation,
|
negotiation,
|
||||||
role,
|
role,
|
||||||
currencyLabel,
|
currencyConfig,
|
||||||
}: {
|
}: {
|
||||||
negotiation: MarketNegotiation;
|
negotiation: MarketNegotiation;
|
||||||
role: "buyer" | "seller";
|
role: "buyer" | "seller";
|
||||||
currencyLabel: string | null;
|
currencyConfig: CurrencyConfig;
|
||||||
}) {
|
}) {
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const listing = listingOf(negotiation);
|
const listing = listingOf(negotiation);
|
||||||
const fmt = (n: number) => formatAmount(n, { name: currencyLabel ?? undefined });
|
const fmt = (n: number) => formatAmount(n, currencyConfig);
|
||||||
|
|
||||||
const buyerLabel = role === "buyer" ? "You" : counterpartyLabel(negotiation, "buyer");
|
const buyerLabel = role === "buyer" ? "You" : counterpartyLabel(negotiation, "buyer");
|
||||||
const sellerLabel = role === "seller" ? "You" : counterpartyLabel(negotiation, "seller");
|
const sellerLabel = role === "seller" ? "You" : counterpartyLabel(negotiation, "seller");
|
||||||
|
|
@ -112,7 +112,7 @@ function HistoryRow({
|
||||||
{listing && (
|
{listing && (
|
||||||
<CollapsibleContent className="border-t">
|
<CollapsibleContent className="border-t">
|
||||||
<ChatBubbleList
|
<ChatBubbleList
|
||||||
bubbles={buildChatBubbles(negotiation, listing, currencyLabel)}
|
bubbles={buildChatBubbles(negotiation, listing, currencyLabel(currencyConfig))}
|
||||||
buyerLabel={buyerLabel}
|
buyerLabel={buyerLabel}
|
||||||
sellerLabel={sellerLabel}
|
sellerLabel={sellerLabel}
|
||||||
maxHeight="max-h-64"
|
maxHeight="max-h-64"
|
||||||
|
|
@ -126,13 +126,13 @@ function HistoryRow({
|
||||||
interface NegotiationHistoryDialogProps {
|
interface NegotiationHistoryDialogProps {
|
||||||
negotiations: MarketNegotiation[];
|
negotiations: MarketNegotiation[];
|
||||||
currentUserId: number;
|
currentUserId: number;
|
||||||
currencyLabel: string | null;
|
currencyConfig: CurrencyConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NegotiationHistoryDialog({
|
export function NegotiationHistoryDialog({
|
||||||
negotiations,
|
negotiations,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
currencyLabel,
|
currencyConfig,
|
||||||
}: NegotiationHistoryDialogProps) {
|
}: NegotiationHistoryDialogProps) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
|
@ -170,7 +170,7 @@ export function NegotiationHistoryDialog({
|
||||||
key={negotiation.id}
|
key={negotiation.id}
|
||||||
negotiation={negotiation}
|
negotiation={negotiation}
|
||||||
role={role}
|
role={role}
|
||||||
currencyLabel={currencyLabel}
|
currencyConfig={currencyConfig}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,5 @@
|
||||||
export type NpcDialogueKind =
|
export type NpcDialogueKind =
|
||||||
| "firm"
|
"firm" | "lowball" | "backward" | "stall" | "concede" | "good" | "overpay" | "closed" | "accept";
|
||||||
| "lowball"
|
|
||||||
| "backward"
|
|
||||||
| "stall"
|
|
||||||
| "concede"
|
|
||||||
| "good"
|
|
||||||
| "overpay"
|
|
||||||
| "closed"
|
|
||||||
| "accept";
|
|
||||||
|
|
||||||
type DialogueLine = (amount: string, asking: string) => string;
|
type DialogueLine = (amount: string, asking: string) => string;
|
||||||
|
|
||||||
|
|
@ -18,8 +10,8 @@ const LINES: Record<NpcDialogueKind, DialogueLine[]> = {
|
||||||
(amount) => `I'm holding at ${amount}. My prices are already fair.`,
|
(amount) => `I'm holding at ${amount}. My prices are already fair.`,
|
||||||
],
|
],
|
||||||
lowball: [
|
lowball: [
|
||||||
(amount) => `That's an insult! I'll come down to ${amount} — not a unit less.`,
|
(amount) => `That's an insult! I'll come down to ${amount} — not a fraction less.`,
|
||||||
(amount) => `You're joking, right? ${amount} and not a unit less.`,
|
(amount) => `You're joking, right? ${amount} and not a fraction less.`,
|
||||||
(amount) => `I paid more than that for lunch! ${amount} — final offer.`,
|
(amount) => `I paid more than that for lunch! ${amount} — final offer.`,
|
||||||
],
|
],
|
||||||
backward: [
|
backward: [
|
||||||
|
|
@ -28,8 +20,8 @@ const LINES: Record<NpcDialogueKind, DialogueLine[]> = {
|
||||||
],
|
],
|
||||||
stall: [
|
stall: [
|
||||||
() => "Really? That's hardly different. Negotiate like you mean it.",
|
() => "Really? That's hardly different. Negotiate like you mean it.",
|
||||||
() => "A whole dollar more? That's not negotiating, that's teasing. Come back with a real number.",
|
() => "That tiny increase isn't negotiating. Come back with a real number.",
|
||||||
() => "You're just wearing me down with pennies now. Bring something meaningful.",
|
() => "You're just inching up now. Bring something meaningful.",
|
||||||
],
|
],
|
||||||
concede: [
|
concede: [
|
||||||
(amount) => `Hmm, not sure about that... how about ${amount}?`,
|
(amount) => `Hmm, not sure about that... how about ${amount}?`,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue