Enable navigation to home page via footer logo and filter media outlets by category
Update Footer component to navigate to home page on logo click. Modify MainContent to filter and display media outlets by "People", "Topics", and "Companies" categories, with a two-column layout. Adjust MediaOutlet page to display articles in a two-column layout when not in grid view. 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/IfFFLfD
This commit is contained in:
@ -1,6 +1,9 @@
|
|||||||
import logoWhite from "@assets/logo_white_1759167910147.png";
|
import logoWhite from "@assets/logo_white_1759167910147.png";
|
||||||
|
import { useLocation } from "wouter";
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
|
const [, setLocation] = useLocation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="fixed bottom-0 left-0 right-0 bg-gray-900 border-t border-gray-700 z-40">
|
<footer className="fixed bottom-0 left-0 right-0 bg-gray-900 border-t border-gray-700 z-40">
|
||||||
<div className="max-w-7xl mx-auto px-4 py-4">
|
<div className="max-w-7xl mx-auto px-4 py-4">
|
||||||
@ -10,8 +13,9 @@ export default function Footer() {
|
|||||||
<img
|
<img
|
||||||
src={logoWhite}
|
src={logoWhite}
|
||||||
alt="SAPIENS"
|
alt="SAPIENS"
|
||||||
className="h-5"
|
className="h-5 cursor-pointer hover:opacity-80 transition-opacity"
|
||||||
data-testid="footer-logo"
|
data-testid="footer-logo"
|
||||||
|
onClick={() => setLocation("/")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
|
|||||||
@ -20,6 +20,7 @@ export default function MainContent() {
|
|||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [sortBy, setSortBy] = useState<"alphabetical" | "traffic">("alphabetical");
|
const [sortBy, setSortBy] = useState<"alphabetical" | "traffic">("alphabetical");
|
||||||
const [enlargedImage, setEnlargedImage] = useState<string | null>(null);
|
const [enlargedImage, setEnlargedImage] = useState<string | null>(null);
|
||||||
|
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||||
|
|
||||||
const { data: allOutlets = [], isLoading } = useQuery<MediaOutlet[]>({
|
const { data: allOutlets = [], isLoading } = useQuery<MediaOutlet[]>({
|
||||||
queryKey: ["/api/media-outlets"],
|
queryKey: ["/api/media-outlets"],
|
||||||
@ -170,11 +171,32 @@ export default function MainContent() {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
) : selectedCategory ? (
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<h2 className="text-2xl font-bold text-gray-900 cursor-pointer hover:text-blue-600">
|
||||||
|
{selectedCategory}
|
||||||
|
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory(selectedCategory).length})</span>
|
||||||
|
</h2>
|
||||||
|
<button
|
||||||
|
onClick={() => setSelectedCategory(null)}
|
||||||
|
className="ml-4 text-sm text-blue-600 hover:text-blue-800"
|
||||||
|
>
|
||||||
|
View All Categories
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
{getOutletsByCategory(selectedCategory).map(renderOutletCard)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
{/* People Section */}
|
{/* People Section */}
|
||||||
<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 cursor-pointer hover:text-blue-600 transition-colors"
|
||||||
|
onClick={() => setSelectedCategory("People")}
|
||||||
|
>
|
||||||
People
|
People
|
||||||
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("People").length})</span>
|
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("People").length})</span>
|
||||||
</h2>
|
</h2>
|
||||||
@ -185,7 +207,10 @@ export default function MainContent() {
|
|||||||
|
|
||||||
{/* Topics Section */}
|
{/* Topics Section */}
|
||||||
<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 cursor-pointer hover:text-blue-600 transition-colors"
|
||||||
|
onClick={() => setSelectedCategory("Topics")}
|
||||||
|
>
|
||||||
Topics
|
Topics
|
||||||
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("Topics").length})</span>
|
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("Topics").length})</span>
|
||||||
</h2>
|
</h2>
|
||||||
@ -196,7 +221,10 @@ export default function MainContent() {
|
|||||||
|
|
||||||
{/* Companies Section */}
|
{/* Companies Section */}
|
||||||
<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 cursor-pointer hover:text-blue-600 transition-colors"
|
||||||
|
onClick={() => setSelectedCategory("Companies")}
|
||||||
|
>
|
||||||
Companies
|
Companies
|
||||||
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("Companies").length})</span>
|
<span className="text-gray-400 text-base ml-2">({getOutletsByCategory("Companies").length})</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@ -343,7 +343,7 @@ export default function MediaOutlet() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{articlesLoading ? (
|
{articlesLoading ? (
|
||||||
<div className={`grid gap-4 ${viewMode === "grid" ? "grid-cols-1 md:grid-cols-2 lg:grid-cols-3" : "grid-cols-1"}`}>
|
<div className={`grid gap-4 ${viewMode === "grid" ? "grid-cols-1 md:grid-cols-2 lg:grid-cols-3" : "grid-cols-1 md:grid-cols-2"}`}>
|
||||||
{Array.from({ length: 6 }).map((_, i) => (
|
{Array.from({ length: 6 }).map((_, i) => (
|
||||||
<div key={i} className="bg-white border border-gray-200 rounded-xl p-6 animate-pulse">
|
<div key={i} className="bg-white border border-gray-200 rounded-xl p-6 animate-pulse">
|
||||||
<div className="h-40 bg-gray-200 rounded mb-4"></div>
|
<div className="h-40 bg-gray-200 rounded mb-4"></div>
|
||||||
@ -353,7 +353,7 @@ export default function MediaOutlet() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : articles.length > 0 ? (
|
) : articles.length > 0 ? (
|
||||||
<div className={`grid gap-4 ${viewMode === "grid" ? "grid-cols-1 md:grid-cols-2 lg:grid-cols-3" : "grid-cols-1"}`}>
|
<div className={`grid gap-4 ${viewMode === "grid" ? "grid-cols-1 md:grid-cols-2 lg:grid-cols-3" : "grid-cols-1 md:grid-cols-2"}`}>
|
||||||
{articles.map((article) => (
|
{articles.map((article) => (
|
||||||
<ArticleCard
|
<ArticleCard
|
||||||
key={article.id}
|
key={article.id}
|
||||||
|
|||||||
Reference in New Issue
Block a user