Update the prediction market UI and translate related text to English

Translate prediction market UI elements and success/error messages to English. Refactor prediction market display, including market questions, resolution dates, and bet options, to align with updated UI/UX design principles.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0fb68265-c270-4198-9584-3d9be9bddb41
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/0fb68265-c270-4198-9584-3d9be9bddb41/rOJiPGe
This commit is contained in:
kimjaehyeon0101
2025-09-30 04:36:22 +00:00
parent 3940d23c1a
commit c478d37b58
4 changed files with 68 additions and 118 deletions

View File

@ -33,16 +33,16 @@ export default function Article() {
}, },
onSuccess: () => { onSuccess: () => {
toast({ toast({
title: "베팅 성공", title: "Bet Placed Successfully",
description: "예측시장 베팅이 성공적으로 완료되었습니다." description: "Your prediction market bet has been placed."
}); });
queryClient.invalidateQueries({ queryKey: ["/api/articles", params?.slug, "markets"] }); queryClient.invalidateQueries({ queryKey: ["/api/articles", params?.slug, "markets"] });
setBetAmounts({}); setBetAmounts({});
}, },
onError: (error: any) => { onError: (error: any) => {
toast({ toast({
title: "베팅 실패", title: "Bet Failed",
description: error.message || "베팅 처리 중 오류가 발생했습니다.", description: error.message || "An error occurred while placing your bet.",
variant: "destructive" variant: "destructive"
}); });
} }
@ -80,16 +80,8 @@ export default function Article() {
}; };
const handlePlaceBet = (marketId: string, side: "yes" | "no") => { const handlePlaceBet = (marketId: string, side: "yes" | "no") => {
const amount = parseFloat(betAmounts[marketId] || "0"); // Default bet amount (can be customized later)
if (amount <= 0) { const amount = 10000;
toast({
title: "잘못된 금액",
description: "베팅 금액을 올바르게 입력해주세요.",
variant: "destructive"
});
return;
}
placeBetMutation.mutate({ marketId, side, amount }); placeBetMutation.mutate({ marketId, side, amount });
}; };
@ -217,10 +209,7 @@ export default function Article() {
{/* Prediction Markets Section */} {/* Prediction Markets Section */}
<section className="max-w-4xl mx-auto"> <section className="max-w-4xl mx-auto">
<div className="flex items-center space-x-3 mb-6"> <h2 className="text-xl font-bold mb-6">Related Prediction Markets</h2>
<TrendingUp className="h-6 w-6 text-primary" />
<h2 className="text-2xl font-bold"> </h2>
</div>
{marketsLoading ? ( {marketsLoading ? (
<div className="space-y-4"> <div className="space-y-4">
@ -237,115 +226,76 @@ export default function Article() {
))} ))}
</div> </div>
) : markets.length > 0 ? ( ) : markets.length > 0 ? (
<div className="space-y-6"> <div className="space-y-4">
{markets.map((market) => ( {markets.map((market) => (
<Card key={market.id} className="border-primary/20"> <Card key={market.id} className="border border-gray-200">
<CardHeader>
<CardTitle className="flex items-center justify-between">
<span data-testid={`text-market-question-${market.id}`}>{market.question}</span>
<Badge variant="outline" className="flex items-center space-x-1">
<Clock className="h-3 w-3" />
<span>{formatDate(market.resolutionDate)}</span>
</Badge>
</CardTitle>
</CardHeader>
<CardContent className="p-6"> <CardContent className="p-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> {/* Question and Live Badge */}
{/* Yes Option */} <div className="flex items-start justify-between mb-6">
<div className="border rounded-lg p-4 bg-green-50 border-green-200"> <h3 className="text-base font-medium flex-1 pr-4" data-testid={`text-market-question-${market.id}`}>
<div className="flex items-center justify-between mb-3"> {market.question}
<div className="flex items-center space-x-2"> </h3>
<TrendingUp className="h-5 w-5 text-green-600" /> {market.isActive && (
<span className="font-semibold text-green-900">YES</span> <Badge className="bg-red-500 text-white text-xs px-2 py-0.5 shrink-0">
LIVE
</Badge>
)}
</div> </div>
<div className="text-right">
<div className="text-sm text-green-700"> </div> {/* Percentages */}
<div className="font-bold text-green-900" data-testid={`text-yes-price-${market.id}`}> <div className="flex items-center justify-between mb-6">
<div className="text-left">
<div className="text-4xl font-bold" data-testid={`text-yes-price-${market.id}`}>
{formatPercentage(market.yesPrice)} {formatPercentage(market.yesPrice)}
</div> </div>
</div> <div className="text-sm text-gray-500 mt-1">YES</div>
</div>
<div className="space-y-3">
<Input
type="number"
placeholder="베팅 금액 (원)"
value={betAmounts[market.id] || ""}
onChange={(e) => handleBetAmountChange(market.id, e.target.value)}
className="border-green-300 focus:border-green-500"
data-testid={`input-bet-amount-${market.id}`}
/>
<Button
onClick={() => handlePlaceBet(market.id, "yes")}
disabled={placeBetMutation.isPending}
className="w-full bg-green-600 hover:bg-green-700"
data-testid={`button-bet-yes-${market.id}`}
>
<DollarSign className="h-4 w-4 mr-2" />
YES
</Button>
</div>
</div>
{/* No Option */}
<div className="border rounded-lg p-4 bg-red-50 border-red-200">
<div className="flex items-center justify-between mb-3">
<div className="flex items-center space-x-2">
<TrendingDown className="h-5 w-5 text-red-600" />
<span className="font-semibold text-red-900">NO</span>
</div> </div>
<div className="text-right"> <div className="text-right">
<div className="text-sm text-red-700"> </div> <div className="text-4xl font-bold" data-testid={`text-no-price-${market.id}`}>
<div className="font-bold text-red-900" data-testid={`text-no-price-${market.id}`}>
{formatPercentage(market.noPrice)} {formatPercentage(market.noPrice)}
</div> </div>
<div className="text-sm text-gray-500 mt-1">NO</div>
</div> </div>
</div> </div>
<div className="space-y-3"> {/* Yes/No Buttons */}
<Input <div className="grid grid-cols-2 gap-3 mb-6">
type="number"
placeholder="베팅 금액 (원)"
value={betAmounts[market.id] || ""}
onChange={(e) => handleBetAmountChange(market.id, e.target.value)}
className="border-red-300 focus:border-red-500"
data-testid={`input-bet-amount-no-${market.id}`}
/>
<Button <Button
variant="outline"
className="w-full border-gray-300 hover:bg-gray-50"
onClick={() => handlePlaceBet(market.id, "yes")}
disabled={placeBetMutation.isPending}
data-testid={`button-bet-yes-${market.id}`}
>
Yes
</Button>
<Button
variant="outline"
className="w-full border-gray-300 hover:bg-gray-50"
onClick={() => handlePlaceBet(market.id, "no")} onClick={() => handlePlaceBet(market.id, "no")}
disabled={placeBetMutation.isPending} disabled={placeBetMutation.isPending}
className="w-full bg-red-600 hover:bg-red-700"
data-testid={`button-bet-no-${market.id}`} data-testid={`button-bet-no-${market.id}`}
> >
<DollarSign className="h-4 w-4 mr-2" /> No
NO
</Button> </Button>
</div> </div>
</div>
</div>
{/* Market Stats */} {/* Market Info */}
<div className="mt-4 pt-4 border-t border-gray-200"> <div className="flex items-center justify-between text-sm text-gray-500 pt-4 border-t border-gray-200">
<div className="grid grid-cols-3 gap-4 text-center text-sm text-muted-foreground"> <div className="flex items-center space-x-4">
<div> <div className="flex items-center space-x-1">
<div className="font-semibold" data-testid={`text-total-volume-${market.id}`}> <DollarSign className="h-4 w-4" />
{formatCurrency(market.totalVolume)} <span data-testid={`text-total-volume-${market.id}`}>
</div> {formatCurrency(market.totalVolume)} Vol.
<div> </div> </span>
</div> </div>
<div> <div>
<div className="font-semibold" data-testid={`text-total-bets-${market.id}`}> <span>Politics</span>
{market.totalBets}
</div> </div>
<div> </div>
</div>
<div>
<div className="font-semibold">
{formatDate(market.resolutionDate)}
</div>
<div> </div>
</div> </div>
<div className="flex items-center space-x-1">
<Clock className="h-4 w-4" />
<span>in 3 months</span>
</div> </div>
</div> </div>
</CardContent> </CardContent>
@ -356,8 +306,8 @@ export default function Article() {
<Card> <Card>
<CardContent className="p-8 text-center text-muted-foreground"> <CardContent className="p-8 text-center text-muted-foreground">
<TrendingUp className="h-12 w-12 mx-auto mb-4 opacity-50" /> <TrendingUp className="h-12 w-12 mx-auto mb-4 opacity-50" />
<h3 className="text-lg font-semibold mb-2"> </h3> <h3 className="text-lg font-semibold mb-2">No Related Prediction Markets</h3>
<p> .</p> <p>There are no prediction markets related to this article yet.</p>
</CardContent> </CardContent>
</Card> </Card>
)} )}