diff --git a/client/src/components/MainContent.tsx b/client/src/components/MainContent.tsx index c26f505..c32a837 100644 --- a/client/src/components/MainContent.tsx +++ b/client/src/components/MainContent.tsx @@ -2,11 +2,12 @@ import { useQuery } from "@tanstack/react-query"; import { Card, CardContent } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Dialog, DialogContent } from "@/components/ui/dialog"; -import type { MediaOutlet } from "@shared/schema"; +import { Badge } from "@/components/ui/badge"; +import type { MediaOutlet, Article } from "@shared/schema"; import { useAuth } from "@/hooks/useAuth"; import Footer from "@/components/Footer"; import { useState } from "react"; -import { ArrowUpDown } from "lucide-react"; +import { ArrowUpDown, Sparkles } from "lucide-react"; import { Link } from "wouter"; const categories = [ @@ -33,6 +34,26 @@ export default function MainContent() { }, }); + // Fetch all articles to count per outlet + const { data: allArticles = [] } = useQuery({ + queryKey: ["/api/articles"], + queryFn: async () => { + const res = await fetch("/api/articles", { + credentials: "include", + }); + if (!res.ok) { + throw new Error(`${res.status}: ${res.statusText}`); + } + return res.json(); + }, + }); + + // Count articles per outlet + const articleCountByOutlet = allArticles.reduce((acc, article) => { + acc[article.mediaOutletId] = (acc[article.mediaOutletId] || 0) + 1; + return acc; + }, {} as Record); + // Group outlets by category and sort const getOutletsByCategory = (category: string) => { const filtered = allOutlets.filter(outlet => @@ -49,53 +70,75 @@ export default function MainContent() { }); }; - const renderOutletCard = (outlet: MediaOutlet) => ( - - -
-
{ - e.stopPropagation(); - if (outlet.imageUrl) { - setEnlargedImage(outlet.imageUrl); - } - }} - data-testid={`image-profile-${outlet.id}`} - > - {outlet.imageUrl ? ( - {outlet.name} - ) : ( -
- - {outlet.name.charAt(0)} - -
- )} + const renderOutletCard = (outlet: MediaOutlet) => { + const articleCount = articleCountByOutlet[outlet.id] || 0; + const hasArticles = articleCount > 0; + + return ( + + {hasArticles && ( +
+ + + NEW +
- -
-

- {outlet.name} -

-

- {outlet.description || "Media Outlet"} -

+ )} + +
+
{ + e.stopPropagation(); + if (outlet.imageUrl) { + setEnlargedImage(outlet.imageUrl); + } + }} + data-testid={`image-profile-${outlet.id}`} + > + {outlet.imageUrl ? ( + {outlet.name} + ) : ( +
+ + {outlet.name.charAt(0)} + +
+ )}
- -
-
- - ); + +
+

+ {outlet.name} + {hasArticles && ( + + ({articleCount}) + + )} +

+

+ {outlet.description || "Media Outlet"} +

+
+ +
+ +
+ ); + }; return (
diff --git a/client/src/index.css b/client/src/index.css index bae345d..98629d1 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -123,6 +123,25 @@ .card-hover { transition: all 0.2s ease-in-out; } + + @keyframes float { + 0%, 100% { + transform: translateY(0px); + } + 50% { + transform: translateY(-8px); + } + } + + .animate-float { + animation: float 3s ease-in-out infinite; + } + + @media (prefers-reduced-motion: reduce) { + .animate-float { + animation: none; + } + } .card-hover:hover { transform: translateY(-2px);