Distinguish new media outlets from regular ones within categories
Refactors `getOutletsByCategory` to `getSeparatedOutlets` in `MainContent.tsx`, separating outlets with recent articles (marked as "NEW") from regular ones and improving UI presentation. Replit-Commit-Author: Agent Replit-Commit-Session-Id: aabe2db1-f078-4501-aab5-be145ebc6b9a Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/aabe2db1-f078-4501-aab5-be145ebc6b9a/ETDmxYB
This commit is contained in:
4
.replit
4
.replit
@ -38,6 +38,10 @@ externalPort = 3000
|
|||||||
localPort = 43777
|
localPort = 43777
|
||||||
externalPort = 4200
|
externalPort = 4200
|
||||||
|
|
||||||
|
[[ports]]
|
||||||
|
localPort = 44067
|
||||||
|
externalPort = 5000
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
PORT = "5000"
|
PORT = "5000"
|
||||||
|
|
||||||
|
|||||||
@ -54,20 +54,38 @@ export default function MainContent() {
|
|||||||
return acc;
|
return acc;
|
||||||
}, {} as Record<string, number>);
|
}, {} as Record<string, number>);
|
||||||
|
|
||||||
// Group outlets by category and sort
|
// Group outlets by category and separate NEW outlets from regular ones
|
||||||
const getOutletsByCategory = (category: string) => {
|
const getSeparatedOutlets = (category: string) => {
|
||||||
const filtered = allOutlets.filter(outlet =>
|
const filtered = allOutlets.filter(outlet =>
|
||||||
outlet.category.toLowerCase() === category.toLowerCase()
|
outlet.category.toLowerCase() === category.toLowerCase()
|
||||||
);
|
);
|
||||||
|
|
||||||
return filtered.sort((a, b) => {
|
// Separate outlets with articles (NEW) from those without
|
||||||
|
const newOutlets = filtered.filter(outlet => {
|
||||||
|
const articleCount = articleCountByOutlet[outlet.id] || 0;
|
||||||
|
return articleCount > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const regularOutlets = filtered.filter(outlet => {
|
||||||
|
const articleCount = articleCountByOutlet[outlet.id] || 0;
|
||||||
|
return articleCount === 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort both groups
|
||||||
|
const sortFn = (a: MediaOutlet, b: MediaOutlet) => {
|
||||||
if (sortBy === "alphabetical") {
|
if (sortBy === "alphabetical") {
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
} else {
|
} else {
|
||||||
// Sort by traffic score (descending - highest traffic first)
|
// Sort by traffic score (descending - highest traffic first)
|
||||||
return (b.trafficScore || 0) - (a.trafficScore || 0);
|
return (b.trafficScore || 0) - (a.trafficScore || 0);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
newOutlets: newOutlets.sort(sortFn),
|
||||||
|
regularOutlets: regularOutlets.sort(sortFn),
|
||||||
|
total: filtered.length
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderOutletCard = (outlet: MediaOutlet) => {
|
const renderOutletCard = (outlet: MediaOutlet) => {
|
||||||
@ -199,10 +217,22 @@ export default function MainContent() {
|
|||||||
<div data-testid="section-people">
|
<div data-testid="section-people">
|
||||||
<h2 className="text-xl font-bold text-gray-900 mb-2">
|
<h2 className="text-xl font-bold text-gray-900 mb-2">
|
||||||
People
|
People
|
||||||
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("People").length})</span>
|
<span className="text-gray-400 text-base ml-2">({getSeparatedOutlets("People").total})</span>
|
||||||
</h2>
|
</h2>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{getOutletsByCategory("People").map(renderOutletCard)}
|
{getSeparatedOutlets("People").newOutlets.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-2 mb-3">
|
||||||
|
<Sparkles className="h-4 w-4 text-blue-500" />
|
||||||
|
<h3 className="text-sm font-semibold text-blue-600">NEW</h3>
|
||||||
|
</div>
|
||||||
|
{getSeparatedOutlets("People").newOutlets.map(renderOutletCard)}
|
||||||
|
{getSeparatedOutlets("People").regularOutlets.length > 0 && (
|
||||||
|
<div className="border-t border-gray-200 my-4"></div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{getSeparatedOutlets("People").regularOutlets.map(renderOutletCard)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -210,10 +240,22 @@ export default function MainContent() {
|
|||||||
<div data-testid="section-topics">
|
<div data-testid="section-topics">
|
||||||
<h2 className="text-xl font-bold text-gray-900 mb-2">
|
<h2 className="text-xl font-bold text-gray-900 mb-2">
|
||||||
Topics
|
Topics
|
||||||
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("Topics").length})</span>
|
<span className="text-gray-400 text-base ml-2">({getSeparatedOutlets("Topics").total})</span>
|
||||||
</h2>
|
</h2>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{getOutletsByCategory("Topics").map(renderOutletCard)}
|
{getSeparatedOutlets("Topics").newOutlets.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-2 mb-3">
|
||||||
|
<Sparkles className="h-4 w-4 text-blue-500" />
|
||||||
|
<h3 className="text-sm font-semibold text-blue-600">NEW</h3>
|
||||||
|
</div>
|
||||||
|
{getSeparatedOutlets("Topics").newOutlets.map(renderOutletCard)}
|
||||||
|
{getSeparatedOutlets("Topics").regularOutlets.length > 0 && (
|
||||||
|
<div className="border-t border-gray-200 my-4"></div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{getSeparatedOutlets("Topics").regularOutlets.map(renderOutletCard)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -221,10 +263,22 @@ export default function MainContent() {
|
|||||||
<div data-testid="section-companies">
|
<div data-testid="section-companies">
|
||||||
<h2 className="text-xl font-bold text-gray-900 mb-2">
|
<h2 className="text-xl font-bold text-gray-900 mb-2">
|
||||||
Companies
|
Companies
|
||||||
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("Companies").length})</span>
|
<span className="text-gray-400 text-base ml-2">({getSeparatedOutlets("Companies").total})</span>
|
||||||
</h2>
|
</h2>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{getOutletsByCategory("Companies").map(renderOutletCard)}
|
{getSeparatedOutlets("Companies").newOutlets.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-2 mb-3">
|
||||||
|
<Sparkles className="h-4 w-4 text-blue-500" />
|
||||||
|
<h3 className="text-sm font-semibold text-blue-600">NEW</h3>
|
||||||
|
</div>
|
||||||
|
{getSeparatedOutlets("Companies").newOutlets.map(renderOutletCard)}
|
||||||
|
{getSeparatedOutlets("Companies").regularOutlets.length > 0 && (
|
||||||
|
<div className="border-t border-gray-200 my-4"></div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{getSeparatedOutlets("Companies").regularOutlets.map(renderOutletCard)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user