Update article page to display the correct media outlet header

Modify the Article page component to dynamically fetch and display the header information of the associated media outlet, including its logo and name, by introducing a new API call to retrieve MediaOutlet data.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9a264234-c5d7-4dcc-adf3-a954b149b30d
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/9a264234-c5d7-4dcc-adf3-a954b149b30d/uCJPlBt
This commit is contained in:
kimjaehyeon0101
2025-10-15 05:08:23 +00:00
parent 1c7483b12e
commit 1c859e461c
2 changed files with 68 additions and 19 deletions

View File

@ -50,6 +50,10 @@ externalPort = 3000
localPort = 43777 localPort = 43777
externalPort = 4200 externalPort = 4200
[[ports]]
localPort = 45921
externalPort = 6800
[env] [env]
PORT = "5000" PORT = "5000"

View File

@ -5,16 +5,18 @@ import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { TrendingUp, TrendingDown, DollarSign, Clock } from "lucide-react"; import { TrendingUp, TrendingDown, DollarSign, Clock, IdCard } from "lucide-react";
import { useToast } from "@/hooks/use-toast"; import { useToast } from "@/hooks/use-toast";
import { apiRequest, queryClient } from "@/lib/queryClient"; import { apiRequest, queryClient } from "@/lib/queryClient";
import Footer from "@/components/Footer"; import Footer from "@/components/Footer";
import type { Article, PredictionMarket } from "@shared/schema"; import { useAuth } from "@/hooks/useAuth";
import type { Article, PredictionMarket, MediaOutlet } from "@shared/schema";
export default function Article() { export default function Article() {
const [, params] = useRoute("/articles/:slug"); const [, params] = useRoute("/articles/:slug");
const [, setLocation] = useLocation(); const [, setLocation] = useLocation();
const { toast } = useToast(); const { toast } = useToast();
const { user } = useAuth();
const [betAmounts, setBetAmounts] = useState<Record<string, string>>({}); const [betAmounts, setBetAmounts] = useState<Record<string, string>>({});
const { data: article, isLoading: articleLoading } = useQuery<Article>({ const { data: article, isLoading: articleLoading } = useQuery<Article>({
@ -22,6 +24,11 @@ export default function Article() {
enabled: !!params?.slug enabled: !!params?.slug
}); });
const { data: outlet, isLoading: outletLoading } = useQuery<MediaOutlet>({
queryKey: ["/api/media-outlets", article?.mediaOutletId],
enabled: !!article?.mediaOutletId
});
const { data: markets = [], isLoading: marketsLoading } = useQuery<PredictionMarket[]>({ const { data: markets = [], isLoading: marketsLoading } = useQuery<PredictionMarket[]>({
queryKey: ["/api/articles", params?.slug, "markets"], queryKey: ["/api/articles", params?.slug, "markets"],
enabled: !!params?.slug enabled: !!params?.slug
@ -106,20 +113,17 @@ export default function Article() {
return parts; return parts;
}; };
if (articleLoading) { if (articleLoading || outletLoading) {
return ( return (
<div className="min-h-screen bg-gray-50"> <div className="min-h-screen bg-gray-50">
<header className="bg-white border-b border-gray-200 sticky top-0 z-50"> <header className="bg-white border-b border-gray-200 sticky top-0 z-50">
<div className="max-w-7xl mx-auto px-6 py-4"> <div className="max-w-7xl mx-auto px-6 py-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center"> <div className="flex items-center space-x-4">
<img <div className="animate-pulse flex space-x-3">
src="/attached_assets/logo_black_1759181850935.png" <div className="rounded-full bg-gray-300 h-10 w-10"></div>
alt="SAPIENS" <div className="h-5 bg-gray-300 rounded w-24"></div>
className="h-5 w-auto cursor-pointer" </div>
data-testid="logo-sapiens"
onClick={() => setLocation("/")}
/>
</div> </div>
</div> </div>
</div> </div>
@ -158,14 +162,55 @@ export default function Article() {
<header className="bg-white border-b border-gray-200 sticky top-0 z-50"> <header className="bg-white border-b border-gray-200 sticky top-0 z-50">
<div className="max-w-7xl mx-auto px-6 py-4"> <div className="max-w-7xl mx-auto px-6 py-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center"> <div className="flex items-center space-x-4">
<img {outlet?.imageUrl ? (
src="/attached_assets/logo_black_1759181850935.png" <img
alt="SAPIENS" src={outlet.imageUrl}
className="h-5 w-auto cursor-pointer" alt={outlet.name}
data-testid="logo-sapiens" className="w-10 h-10 rounded-full object-cover cursor-pointer"
onClick={() => setLocation("/")} onClick={() => setLocation(`/media/${outlet.slug}`)}
/> data-testid="img-outlet-profile"
/>
) : (
<div
className="w-10 h-10 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center cursor-pointer"
onClick={() => outlet && setLocation(`/media/${outlet.slug}`)}
data-testid="img-outlet-profile-fallback"
>
<span className="text-white font-bold text-lg">
{outlet?.name.charAt(0)}
</span>
</div>
)}
<div className="flex items-center space-x-3 cursor-pointer hover:opacity-80 transition-opacity" onClick={() => setLocation("/")}>
<img
src="/attached_assets/logo_black_1759162717640.png"
alt="SAPIENS"
className="h-5 w-auto"
data-testid="logo-sapiens"
/>
{outlet && (
<div className="flex items-center space-x-2">
<span className="text-base font-bold text-gray-900" data-testid="text-outlet-name-header">
{outlet.name}
</span>
<Button
variant="outline"
size="sm"
onClick={(e) => {
e.stopPropagation();
setLocation(`/media/${outlet.slug}/report`);
}}
className="h-6 px-2 flex items-center gap-1 text-xs border-gray-300 hover:bg-gray-100"
aria-label="View complete profile"
data-testid="button-profile"
>
<IdCard className="h-3 w-3" />
<span>About</span>
</Button>
</div>
)}
</div>
</div> </div>
</div> </div>
</div> </div>