From df46319424dbcfb0bfce6938fc94e55b24e7b254 Mon Sep 17 00:00:00 2001 From: kimjaehyeon0101 <47347352-kimjaehyeon0101@users.noreply.replit.com> Date: Mon, 29 Sep 2025 19:04:38 +0000 Subject: [PATCH] Add media outlet pages with articles and related auction details Integrates new API endpoints for fetching articles and auction data for each media outlet, displaying them on dedicated pages with article listings and auction information. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 069d4324-6c40-4355-955e-c714a50de1ea Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/069d4324-6c40-4355-955e-c714a50de1ea/jvFIdY3 --- client/src/pages/MediaOutlet.tsx | 102 +++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/client/src/pages/MediaOutlet.tsx b/client/src/pages/MediaOutlet.tsx index 66f3b23..201ad90 100644 --- a/client/src/pages/MediaOutlet.tsx +++ b/client/src/pages/MediaOutlet.tsx @@ -1,14 +1,16 @@ import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; -import { useRoute } from "wouter"; +import { useRoute, useLocation } from "wouter"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; +import { Gavel, Clock, TrendingUp } from "lucide-react"; import ArticleCard from "@/components/ArticleCard"; -import type { MediaOutlet, Article } from "@shared/schema"; +import type { MediaOutlet, Article, Auction } from "@shared/schema"; export default function MediaOutlet() { const [, params] = useRoute("/media/:slug"); + const [, setLocation] = useLocation(); const [viewMode, setViewMode] = useState<"grid" | "list">("grid"); const { data: outlet, isLoading: outletLoading } = useQuery({ @@ -17,10 +19,38 @@ export default function MediaOutlet() { }); const { data: articles = [], isLoading: articlesLoading } = useQuery({ - queryKey: ["/api/media-outlets", outlet?.id, "articles"], - enabled: !!outlet?.id + queryKey: ["/api/media-outlets", params?.slug, "articles"], + enabled: !!params?.slug }); + const { data: auction, isLoading: auctionLoading } = useQuery({ + queryKey: ["/api/media-outlets", params?.slug, "auction"], + enabled: !!params?.slug + }); + + const formatCurrency = (amount: string | null) => { + if (!amount) return "₩0"; + return new Intl.NumberFormat('ko-KR', { + style: 'currency', + currency: 'KRW' + }).format(parseFloat(amount)); + }; + + const formatTimeRemaining = (endDate: Date | string) => { + const end = new Date(endDate); + const now = new Date(); + const diff = end.getTime() - now.getTime(); + + if (diff <= 0) return "경매 종료"; + + const days = Math.floor(diff / (1000 * 60 * 60 * 24)); + const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + + if (days > 0) return `${days}일 ${hours}시간 남음`; + if (hours > 0) return `${hours}시간 남음`; + return "1시간 미만 남음"; + }; + if (outletLoading) { return (
@@ -97,7 +127,7 @@ export default function MediaOutlet() {

{outlet.name}

{outlet.description}

-
+
{outlet.category} @@ -107,6 +137,68 @@ export default function MediaOutlet() { ))}
+ + {/* Auction Section */} + {!auctionLoading && auction ? ( + + +
+
+
+ + 관리자 권한 경매 +
+
+ + 현재 최고가: {formatCurrency(auction.currentBid)} +
+
+ + {formatTimeRemaining(auction.endDate)} +
+
+ +
+
+
+ ) : !auctionLoading && !auction ? ( + + +
+
+ + 현재 진행 중인 경매가 없습니다 +
+ +
+
+
+ ) : ( + + +
+
+
+
+
+
+
+
+ )}