@ -34,6 +34,17 @@ function truncateSummary(text: string, level: number): string {
/** Renders a single news article with its title (linked) and summary. */
const NewsItemCard : Component < { item : NewsItemType ; displayLevel : number } > = ( props ) = > {
const [ expanded , setExpanded ] = createSignal ( false ) ;
const effectiveLevel = ( ) = > expanded ( ) ? 4 : props.displayLevel ;
const isTruncated = ( ) = > {
if ( ! props . item . summary || effectiveLevel ( ) >= 4 ) return false ;
if ( effectiveLevel ( ) === 1 ) return ! ! props . item . summary ;
if ( effectiveLevel ( ) === 2 ) return props . item . summary . length > 160 ;
// level 3
return true ;
} ;
return (
< div class = "bg-white rounded-lg shadow-sm border border-gray-100 p-6 hover:shadow-md transition-shadow" >
< h3 class = "text-lg font-semibold text-indigo-700 mb-2" >
@ -50,11 +61,27 @@ const NewsItemCard: Component<{ item: NewsItemType; displayLevel: number }> = (p
< Show when = { props . item . date } >
< p class = "text-xs text-gray-400 mb-1" > { props . item . date } < / p >
< / Show >
< Show when = { props. displayLevel > 1 && props . item . summary } >
< p class = { ` text-gray-700 leading-relaxed text-sm ${ props . displayLevel < 4 ? 'text-gray-500' : '' } ` } >
{ truncateSummary ( props . item . summary , props. displayLevel ) }
< Show when = { effectiveLevel( ) > 1 && props . item . summary } >
< p class = "text-gray-700 leading-relaxed text-sm" >
{ truncateSummary ( props . item . summary , effectiveLevel( ) ) }
< / p >
< / Show >
< Show when = { props . displayLevel < 4 && ! expanded ( ) && isTruncated ( ) } >
< button
onClick = { ( ) = > setExpanded ( true ) }
class = "mt-2 text-xs text-indigo-600 hover:text-indigo-800 font-medium"
>
Lire la suite & darr ;
< / button >
< / Show >
< Show when = { expanded ( ) && props . displayLevel < 4 } >
< button
onClick = { ( ) = > setExpanded ( false ) }
class = "mt-2 text-xs text-indigo-600 hover:text-indigo-800 font-medium"
>
Reduire & uarr ;
< / button >
< / Show >
< / div >
) ;
} ;