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:
BIN
attached_assets/기사리스트_1759206911936.docx
Normal file
BIN
attached_assets/기사리스트_1759206911936.docx
Normal file
Binary file not shown.
Binary file not shown.
BIN
attached_assets/축구선수와 클럽 7개 추가_1759206911936.docx
Normal file
BIN
attached_assets/축구선수와 클럽 7개 추가_1759206911936.docx
Normal file
Binary file not shown.
@ -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,116 +226,77 @@ 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">
|
||||||
</div>
|
LIVE
|
||||||
<div className="text-right">
|
</Badge>
|
||||||
<div className="text-sm text-green-700">현재 가격</div>
|
)}
|
||||||
<div className="font-bold text-green-900" data-testid={`text-yes-price-${market.id}`}>
|
</div>
|
||||||
{formatPercentage(market.yesPrice)}
|
|
||||||
</div>
|
|
||||||
</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 */}
|
{/* Percentages */}
|
||||||
<div className="border rounded-lg p-4 bg-red-50 border-red-200">
|
<div className="flex items-center justify-between mb-6">
|
||||||
<div className="flex items-center justify-between mb-3">
|
<div className="text-left">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="text-4xl font-bold" data-testid={`text-yes-price-${market.id}`}>
|
||||||
<TrendingDown className="h-5 w-5 text-red-600" />
|
{formatPercentage(market.yesPrice)}
|
||||||
<span className="font-semibold text-red-900">NO</span>
|
|
||||||
</div>
|
|
||||||
<div className="text-right">
|
|
||||||
<div className="text-sm text-red-700">현재 가격</div>
|
|
||||||
<div className="font-bold text-red-900" data-testid={`text-no-price-${market.id}`}>
|
|
||||||
{formatPercentage(market.noPrice)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-sm text-gray-500 mt-1">YES</div>
|
||||||
<div className="space-y-3">
|
</div>
|
||||||
<Input
|
<div className="text-right">
|
||||||
type="number"
|
<div className="text-4xl font-bold" data-testid={`text-no-price-${market.id}`}>
|
||||||
placeholder="베팅 금액 (원)"
|
{formatPercentage(market.noPrice)}
|
||||||
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
|
|
||||||
onClick={() => handlePlaceBet(market.id, "no")}
|
|
||||||
disabled={placeBetMutation.isPending}
|
|
||||||
className="w-full bg-red-600 hover:bg-red-700"
|
|
||||||
data-testid={`button-bet-no-${market.id}`}
|
|
||||||
>
|
|
||||||
<DollarSign className="h-4 w-4 mr-2" />
|
|
||||||
NO 베팅
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-sm text-gray-500 mt-1">NO</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Market Stats */}
|
{/* Yes/No Buttons */}
|
||||||
<div className="mt-4 pt-4 border-t border-gray-200">
|
<div className="grid grid-cols-2 gap-3 mb-6">
|
||||||
<div className="grid grid-cols-3 gap-4 text-center text-sm text-muted-foreground">
|
<Button
|
||||||
<div>
|
variant="outline"
|
||||||
<div className="font-semibold" data-testid={`text-total-volume-${market.id}`}>
|
className="w-full border-gray-300 hover:bg-gray-50"
|
||||||
{formatCurrency(market.totalVolume)}
|
onClick={() => handlePlaceBet(market.id, "yes")}
|
||||||
</div>
|
disabled={placeBetMutation.isPending}
|
||||||
<div>총 거래량</div>
|
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")}
|
||||||
|
disabled={placeBetMutation.isPending}
|
||||||
|
data-testid={`button-bet-no-${market.id}`}
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Market Info */}
|
||||||
|
<div className="flex items-center justify-between text-sm text-gray-500 pt-4 border-t border-gray-200">
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
|
<div className="flex items-center space-x-1">
|
||||||
|
<DollarSign className="h-4 w-4" />
|
||||||
|
<span data-testid={`text-total-volume-${market.id}`}>
|
||||||
|
{formatCurrency(market.totalVolume)} Vol.
|
||||||
|
</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 className="font-semibold">
|
|
||||||
{formatDate(market.resolutionDate)}
|
|
||||||
</div>
|
|
||||||
<div>결과 발표일</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>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user