You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
3.0 KiB
146 lines
3.0 KiB
import { useEffect, useState } from 'preact/hooks' |
|
|
|
const endpoint = 'https://kultar.sout.no/events/' |
|
|
|
const fetch_options = {} |
|
|
|
function Link(props) { |
|
return <a {...props} target="_blank" rel="noopener noreferrer" /> |
|
} |
|
|
|
function Facebook({ event_id }) { |
|
const facebook_event_url = `https://facebook.com/events/${event_id}/` |
|
return ( |
|
<Link href={facebook_event_url} title="Åpne facebookarrangement."> |
|
Mer info |
|
</Link> |
|
) |
|
} |
|
|
|
function Tickets({ ticket_url }) { |
|
return ( |
|
<Link href={ticket_url} title="Kjøp billett hos kultar."> |
|
Kjøp billett |
|
</Link> |
|
) |
|
} |
|
|
|
function Time({ date }) { |
|
const hasTime = date.getHours() === 0 |
|
const time_option = hasTime ? undefined : 'numeric' |
|
const options = { |
|
month: 'long', |
|
weekday: 'long', |
|
day: 'numeric', |
|
hour: time_option, |
|
minute: time_option, |
|
} |
|
return <h4>{new Intl.DateTimeFormat('no', options).format(date)}</h4> |
|
} |
|
|
|
function Location({ location }) { |
|
const { location: area, host } = location |
|
const hasHost = host.length !== 0 |
|
const hasArea = area.length !== 0 |
|
|
|
if (hasHost && hasArea) { |
|
return ( |
|
<p> |
|
{host}, {area}. |
|
</p> |
|
) |
|
} |
|
|
|
if (hasHost) { |
|
return <p>{host}.</p> |
|
} |
|
|
|
if (hasArea) { |
|
return <p>{area}.</p> |
|
} |
|
|
|
return '' |
|
} |
|
|
|
function Links({ event_id, ticket_url }) { |
|
if (ticket_url !== null) { |
|
return ( |
|
<> |
|
<Tickets ticket_url={ticket_url} /> |
|
– |
|
<Facebook event_id={event_id} /> |
|
</> |
|
) |
|
} |
|
|
|
return <Facebook event_id={event_id} /> |
|
} |
|
|
|
function EventImage({ images }) { |
|
const { square = null } = images |
|
return ( |
|
<img |
|
className="event-image" |
|
src={`https://kultar.sout.no/events/${square}`} |
|
/> |
|
) |
|
} |
|
|
|
function EventCard({ event }) { |
|
const { name, location, date, ticket_url, event_id } = event |
|
let { start: start_date } = date |
|
let date_array = [] |
|
|
|
if (start_date !== null && start_date.length > 0) { |
|
date_array = start_date.split('+') |
|
const tz = date_array[1].charAt(1) |
|
start_date = [date_array[0], `0${tz}:00`].join('+') |
|
} |
|
|
|
return ( |
|
<span className="event-card"> |
|
<h3>{name}</h3> |
|
<Time date={new Date(start_date)} /> |
|
<Links ticket_url={ticket_url} event_id={event_id} /> |
|
<Location location={location} /> |
|
</span> |
|
) |
|
} |
|
|
|
function Event({ event }) { |
|
const { images } = event |
|
|
|
return ( |
|
<div className="event"> |
|
<EventImage images={images} /> |
|
<EventCard event={event} /> |
|
</div> |
|
) |
|
} |
|
|
|
export default function Events() { |
|
const [events, setEvents] = useState(null) |
|
|
|
useEffect(async () => { |
|
if (events === null) { |
|
let result = [] |
|
try { |
|
const res = await fetch(endpoint, fetch_options) |
|
result = await res.json() |
|
} catch (error) { |
|
console.error(error) |
|
} |
|
setEvents(result) |
|
} |
|
}, [events]) |
|
|
|
if (events === null) { |
|
return <p>Laster arrangement...</p> |
|
} |
|
|
|
if (events.length <= 0) { |
|
return <p>Det er ingen fremtidige arrangement.</p> |
|
} |
|
|
|
return events.map((event) => <Event event={event} />) |
|
}
|
|
|