109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
import { useEffect, useState } from 'preact/hooks'
|
|
import './app.css'
|
|
|
|
const EVENTS = 'https://api.kommunity.com/api/v1/faith-in-tech/events?&page=1'
|
|
|
|
interface Event {
|
|
id: string,
|
|
name: string,
|
|
slug: string,
|
|
detail: string,
|
|
highlight_photo: string,
|
|
latest_users: User[],
|
|
users_count: number,
|
|
start_date: {
|
|
date: Date,
|
|
timezone: {
|
|
timezone_type: number,
|
|
timezone: string,
|
|
}
|
|
}
|
|
venue: {
|
|
name: string;
|
|
}
|
|
}
|
|
interface User {
|
|
id: string,
|
|
name: string,
|
|
username: string,
|
|
avatar: string,
|
|
}
|
|
export function App() {
|
|
const [events, setEvents] = useState([]);
|
|
|
|
useEffect(() => {
|
|
fetch(`${EVENTS}`)
|
|
.then(res => res.json())
|
|
.then(data => setEvents((data && data.data) || []))
|
|
.then(() => {
|
|
events.map((event: Event) => {
|
|
event.slug = `https://kommunity.com/faith-in-tech/events/${event.slug}`
|
|
return event;
|
|
}
|
|
|
|
)
|
|
})
|
|
}, []);
|
|
|
|
return (
|
|
<div>
|
|
<h1 style="text-align:center; font-weight: 200">Example</h1>
|
|
<div class="list">
|
|
{events.map((result: Event) => (
|
|
<Result {...result} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function UserList({ users, slug }: { users: User[], slug: Event['slug'] }) {
|
|
return (
|
|
<div class="user-items">
|
|
{users.map((user) => (
|
|
<a href={`/faith-in-tech/events/${slug}/attendees`} class=""><img src={user.avatar} class="mini-avatar" /></a>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const Result = (result: Event) => (
|
|
<div class="list-item">
|
|
<div class="event-card flex">
|
|
<div class="highlight-image-wrapper"><a href={result.slug} class="">
|
|
<img src={result.highlight_photo} class="highlight-image" /></a>
|
|
</div>
|
|
<div class="w-100">
|
|
<div class="flex _vc _sb"><a href={result.slug} class="event-title">{result.name}</a></div>
|
|
<div class="flex _vc" style="margin-top: 8px;">
|
|
<UserList users={result.latest_users} slug={result.slug} />
|
|
<a href={`/faith-in-tech/events/${result.slug}/attendees`} class="more-members for-event-card">
|
|
{result.users_count} members going
|
|
</a>
|
|
</div>
|
|
<div class="event-content">
|
|
<div class="item-with-icon">
|
|
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-calendar">
|
|
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
|
|
<line x1="16" y1="2" x2="16" y2="6"></line>
|
|
<line x1="8" y1="2" x2="8" y2="6"></line>
|
|
<line x1="3" y1="10" x2="21" y2="10"></line>
|
|
</svg></div>
|
|
<div class="text">
|
|
{new Date(result.start_date.date).toLocaleDateString('en-us', { weekday: "short", year: "numeric", month: "short", day: "numeric", hour: "numeric" })}
|
|
</div>
|
|
</div>
|
|
<div class="item-with-icon">
|
|
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-map-pin">
|
|
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>
|
|
<circle cx="12" cy="10" r="3"></circle>
|
|
</svg></div>
|
|
<div class="text">
|
|
{result.venue.name}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
); |