import { useMemo } from 'react' ; import type { Event as APIEvent } from '../../../types' ; import { Card } from '../../ui/Card' ; import { Entry } from '../../ui/Entry' ; import { Event } from '../Event' ; const Item = ( props ) : JSX . Element => { const { event , pinned } = props ; const handleClickEvent = ( ) : void => { if ( pinned ) { gtag ( 'event' , 'click_pinned_event' , { event_label : event . name , } ) ; } gtag ( 'event' , 'click_upcoming_event' , { event_label : event . name , } ) ; } ; return ( < Card variant = { pinned ? 'primary' : 'wash' } > < Event event = { event } pinned = { pinned } onClick = { handleClickEvent } / > < /Card>); } ; const sortByPriority = ( pinned ? ) => ( a , b ) : number => { if ( pinned === a . id ) return - 999 ; const deltaT = new Date ( a . start_date ) . valueOf ( ) - new Date ( b . start_date ) . valueOf ( ) ; return Math . max ( - 1 , Math . min ( 1 , deltaT ) ) ; } ; export interface UpcomingEventsProps { readonly id ? : string ; readonly pinnedEventId ? : number ; readonly upcomingEvents ? : readonly APIEvent [ ] ; } export const UpcomingEvents = ( props ) : JSX . Element => { const { id , pinnedEventId } = props ; const upcomingEvents = useMemo ( ( ) => { if ( props . upcomingEvents == null ) return ; return [ ... props . upcomingEvents ] . sort ( sortByPriority ( pinnedEventId ) ) ; } , [ pinnedEventId , props . upcomingEvents ] ) ; return ( < > < h2 id = { id } className = "sr-only" > 今後の配信予定 < /h2> { upcomingEvents ? ( < ul className = "space-y-4" > { upcomingEvents . map ( ( event ) => ( < li key = { event . id } > < Item event = { event } pinned = { pinnedEventId === event . id } / > < /li>))} < /ul>) : (<div className="space-y-4"> { Array . from ( { length : 4 } , ( _ , i ) => ( < Card key = { `placeholder-${ i }` } variant = "wash" > < Entry loading / > < /Card>))} < /div>)} < />); } ;