mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-05 03:02:56 +00:00
dev day #89
This commit is contained in:
@@ -20,7 +20,7 @@ const VideosSection = React.lazy(() => import('../components/home/VideosSection'
|
||||
const MerchSection = React.lazy(() => import('../components/home/MerchSection'));
|
||||
const PollsWidget = React.lazy(() => import('../components/home/PollsWidget'));
|
||||
const GallerySection = React.lazy(() => import('../components/home/GallerySection'));
|
||||
import { getArticles as apiGetArticles, Article as ApiArticle } from '../services/articles';
|
||||
import { getArticles as apiGetArticles, getFeaturedArticles, Article as ApiArticle } from '../services/articles';
|
||||
import { getCompetitionAliasesPublic, CompetitionAlias } from '../services/competitionAliases';
|
||||
import { getUpcomingEvents } from '../services/eventService';
|
||||
const NewsletterSubscribe = React.lazy(() => import('../components/newsletter/NewsletterSubscribe'));
|
||||
@@ -104,7 +104,7 @@ const HomePage: React.FC = () => {
|
||||
// Matches slider auto-centering handled internally by MatchesSlider component
|
||||
|
||||
// API-driven players and sponsors
|
||||
type UiPlayer = { id:number|string; name:string; number?:number; position?:string; image?:string; slug?:string; age?: number; nationality?: string };
|
||||
type UiPlayer = { id:number|string; name:string; number?:number; position?:string; image?:string; slug?:string; age?: number; nationality?: string; active?: boolean };
|
||||
type UiSponsor = { id:number|string; name:string; logo:string; url?:string; tier?: string };
|
||||
type UiBanner = { id:number|string; name:string; image:string; url?:string; placement?:string; width?:number; height?:number };
|
||||
type UiMerch = { id?: number|string; title?: string; image_url: string; url?: string };
|
||||
@@ -412,9 +412,9 @@ const HomePage: React.FC = () => {
|
||||
if (name) setClubName(name);
|
||||
if (logo) setClubLogo(logo);
|
||||
|
||||
// Load players via API
|
||||
// Load players via API (include inactive to show as non-active instead of hiding)
|
||||
try {
|
||||
const apiPlayers: ApiPlayer[] = await apiGetPlayers();
|
||||
const apiPlayers: ApiPlayer[] = await apiGetPlayers({ active: false });
|
||||
const mappedPlayers: UiPlayer[] = (apiPlayers || []).map((p: ApiPlayer) => ({
|
||||
id: p.id,
|
||||
name: [p.first_name, p.last_name].filter(Boolean).join(' '),
|
||||
@@ -422,6 +422,7 @@ const HomePage: React.FC = () => {
|
||||
position: p.position,
|
||||
image: assetUrl(p.image_url) || undefined,
|
||||
nationality: (p as any).nationality,
|
||||
active: Boolean((p as any).is_active),
|
||||
age: (function(iso?: string){
|
||||
if (!iso) return undefined;
|
||||
const d = new Date(iso);
|
||||
@@ -464,10 +465,10 @@ const HomePage: React.FC = () => {
|
||||
setBanners(mappedBanners);
|
||||
} catch {}
|
||||
|
||||
// Load featured articles (homepage primary) via API
|
||||
// Load featured articles (homepage primary) via dedicated endpoint
|
||||
try {
|
||||
const resp = await apiGetArticles({ featured: true, page_size: 3 });
|
||||
const items = (resp?.data || []).map((a: ApiArticle, idx: number) => ({
|
||||
const resp = await getFeaturedArticles({ page_size: 100 });
|
||||
const all = (resp?.data || []).map((a: ApiArticle, idx: number) => ({
|
||||
id: a.id ?? idx + 1,
|
||||
title: a.title,
|
||||
excerpt: (a as any).excerpt || (a.content || '').slice(0, 140),
|
||||
@@ -476,10 +477,11 @@ const HomePage: React.FC = () => {
|
||||
category: 'Aktuality',
|
||||
slug: a.slug,
|
||||
}));
|
||||
setFeatured(items);
|
||||
// Ensure non-featured 'news' excludes featured items
|
||||
// Show only first 3 in hero; exclude only those 3 from the other news list
|
||||
const top3 = all.slice(0, 3);
|
||||
setFeatured(top3);
|
||||
setNews((prev) => {
|
||||
const featuredKeys = new Set(items.map((f) => (f.slug ? `s:${f.slug}` : `i:${f.id}`)));
|
||||
const featuredKeys = new Set(top3.map((f) => (f.slug ? `s:${f.slug}` : `i:${f.id}`)));
|
||||
return (prev || []).filter((n) => !featuredKeys.has(n.slug ? `s:${n.slug}` : `i:${n.id}`));
|
||||
});
|
||||
} catch {}
|
||||
@@ -1064,12 +1066,11 @@ const HomePage: React.FC = () => {
|
||||
</div>
|
||||
<div className="track">
|
||||
{items.map((p)=> (
|
||||
<div key={p.id} className="card">
|
||||
<div key={p.id} className="card" style={{ opacity: p.active === false ? 0.6 : 1 }}>
|
||||
<div className="photo" style={{ backgroundImage: `url(${assetUrl((p as any).image) || '/images/player-placeholder.jpg'})` }} />
|
||||
<div className="name">{p.name}</div>
|
||||
<div className="role">{p.position || 'Hráč'}</div>
|
||||
{typeof p.number !== 'undefined' && <div className="number">#{p.number}</div>}
|
||||
{typeof p.age === 'number' && <div className="age">{p.age} {czYears(p.age)}</div>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -1678,12 +1679,10 @@ const HomePage: React.FC = () => {
|
||||
</div>
|
||||
<div className="scroll-x">
|
||||
{players.map((p) => (
|
||||
<a key={p.id} href={p.slug ? `/players/${p.slug}` : `/players/${p.id}`} className="player-card card">
|
||||
<a key={p.id} href={p.slug ? `/players/${p.slug}` : `/players/${p.id}`} className="player-card card" style={{ opacity: p.active === false ? 0.6 : 1 }}>
|
||||
<div className="photo" style={{ backgroundImage: `url(${assetUrl(p.image) || p.image})` }} />
|
||||
<div className="meta">{typeof p.number !== 'undefined' ? (<><span className="nr">#{p.number}</span> {p.name}</>) : p.name}</div>
|
||||
<div className="pos">{p.position}</div>
|
||||
{p.nationality ? (<div className="nat"><span className="flag" style={{ marginRight: 6 }}>{getCountryFlag(p.nationality)}</span>{translateNationality(p.nationality)}</div>) : null}
|
||||
{typeof p.age === 'number' && <div className="age">{p.age} let</div>}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user