Update
This commit is contained in:
rodič
c0b55c26cd
revize
27099f5929
|
@ -56,7 +56,7 @@
|
|||
</script>
|
||||
|
||||
{#if size === 'big'}
|
||||
<div class="w-64 text-center pb-4">
|
||||
<div class="w-64 text-center pb-4 m-auto">
|
||||
<img src={currentImg} class="w-64 rounded-full m-auto shadow-xl" alt={speaker.name} on:mouseover={mouseOver} on:mouseleave={mouseLeave} />
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -79,7 +79,7 @@
|
|||
|
||||
{#if size === 'semi-small'}
|
||||
<div class="w-10 text-center">
|
||||
<img src={currentImg} class="w-10 rounded-full m-auto" alt="{speaker.name}" />
|
||||
<img src={currentImg} class="w-10 rounded-full m-auto shadow-md" alt="{speaker.name}" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<script>
|
||||
export let event;
|
||||
|
||||
const e = event;
|
||||
|
||||
import Avatar from '$lib/Avatar.svelte';
|
||||
import EventTypeLabel from '$lib/EventTypeLabel.svelte';
|
||||
|
||||
import { bundle, userData } from '$lib/stores.js';
|
||||
|
||||
function speakersMap (arr) {
|
||||
if (!arr) return;
|
||||
return arr.map(sId => {
|
||||
return $bundle.spec.speakers.find(sp => sp.id === sId)
|
||||
})
|
||||
}
|
||||
|
||||
function trackRender (trackId) {
|
||||
const track = $bundle.spec.tracks.find(t => t.id === trackId)
|
||||
return track.shortname || track.name
|
||||
}
|
||||
|
||||
function getParents (e) {
|
||||
return $bundle.spec.events.filter(i => i.parent === e.id)
|
||||
}
|
||||
|
||||
function handleFavorite (el) {
|
||||
const t = el.target.getAttribute('utxo-event-id')
|
||||
userData.update(data => {
|
||||
const fe = data.favoriteEvents
|
||||
let output = null
|
||||
if (fe.includes(t)) {
|
||||
output = Object.assign($userData, { favoriteEvents: fe.filter(f => f !== t) } )
|
||||
} else {
|
||||
fe.push(t)
|
||||
output = Object.assign($userData, { favoriteEvents: fe })
|
||||
}
|
||||
localStorage.setItem('userData', JSON.stringify(output))
|
||||
return output
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="transition-all mb-4 border px-3 py-2 rounded-md shadow {$userData.favoriteEvents.includes(e.id) ? 'bg-yellow-100' : '' }" >
|
||||
<div class="float-right"><i class="fa-star {$userData.favoriteEvents.includes(e.id) ? 'fa-solid' : 'fa-regular'} cursor-pointer" utxo-event-id="{e.id}" on:click={handleFavorite}></i></div>
|
||||
<div class="text-lg font-semibold"><a href="/udalosti/{e.id}">{e.name}</a></div>
|
||||
{#if e.speakers && e.speakers.length > 0}
|
||||
<div class="mt-1 mb-2 flex flex-wrap gap-2">
|
||||
{#each speakersMap(e.speakers) as s}
|
||||
<div class="flex gap-1.5">
|
||||
<Avatar speaker={s} size='extra-small' />
|
||||
<div class="m-auto"><a href="/lide/{s.id}">{s.name}</a></div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="mt-2 text-sm flex flex-wrap gap-2">
|
||||
<div><EventTypeLabel event={e} /></div>
|
||||
<div class="text-sm my-auto">{trackRender(e.track)}</div>
|
||||
<div class="text-xs my-auto">{e.duration}m</div>
|
||||
</div>
|
||||
{#if getParents(e).length > 0}
|
||||
<div class="mt-4 w-auto mb-2">
|
||||
<div class="flex flex-wrap gap-2" cellpadding="5">
|
||||
{#each getParents(e) as pe}
|
||||
<div class="border rounded py-1.5 px-2.5 bg-gray-100 text-sm">
|
||||
<div class="font-bold"><a href="/udalosti/{pe.id}">{pe.name}</a></div>
|
||||
<div class="mt-1">
|
||||
{#if pe.speakers.length === 0}
|
||||
<div>TBA</div>
|
||||
{:else}
|
||||
{#each speakersMap(pe.speakers) as s}
|
||||
<div class="flex gap-1"><Avatar speaker={s} size='micro' /><div><a href="/lide/{s.id}">{s.name}</a></div></div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
|
@ -7,6 +7,7 @@
|
|||
talk: { title: 'Přednáška', style: 'bg-custom-green text-white' },
|
||||
workshop: { title: 'Workshop', style: 'bg-custom-blue text-white' },
|
||||
other: { title: 'Ostatní', style: 'bg-custom-yellow' },
|
||||
lightning: { title: 'Lightning talk', style: 'bg-pink-400' },
|
||||
}
|
||||
|
||||
const current = config[event.type];
|
||||
|
|
|
@ -4,12 +4,18 @@
|
|||
import '../app.css';
|
||||
import api from '$lib/api.js';
|
||||
import { page } from '$app/stores';
|
||||
import { userData } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let bundle = null
|
||||
|
||||
onMount(async () => {
|
||||
bundle = await api.loadBundle($page.url.hostname === 'localhost')
|
||||
|
||||
const userDataLS = localStorage.getItem('userData')
|
||||
if (userDataLS) {
|
||||
userData.set(JSON.parse(userDataLS))
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
<script>
|
||||
import SvelteMarkdown from 'svelte-markdown';
|
||||
|
||||
import Avatar from '$lib/Avatar.svelte';
|
||||
import Event from '$lib/Event.svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { bundle } from '$lib/stores.js';
|
||||
import Avatar from '$lib/Avatar.svelte';
|
||||
|
||||
$: s = $bundle ? $bundle.spec.speakers.find(s => s.id === $page.params.id) : null
|
||||
|
||||
$: events = $bundle.spec.events.filter(ev => ev.speakers && ev.speakers.includes(s.id))
|
||||
|
||||
function trackRender (trackId) {
|
||||
const track = $bundle.spec.tracks.find(t => t.id === trackId)
|
||||
return track.shortname || track.name
|
||||
|
@ -31,7 +34,7 @@
|
|||
<div class="sm:flex gap-10 mt-4">
|
||||
<div><Avatar speaker={s} size="big" /></div>
|
||||
<div class="mt-4 sm:mt-0">
|
||||
<div class="mb-4 text-sm uppercase">Přednášející</div>
|
||||
<div class="mb-4 text-md uppercase">Přednášející</div>
|
||||
<h1 class="text-2xl font-bold">{s.name} {getFlagEmoji(s.country)}</h1>
|
||||
{#if s.bio}
|
||||
<div class="mt-4 text-blue-web italic"><SvelteMarkdown source={s.bio} /></div>
|
||||
|
@ -48,5 +51,17 @@
|
|||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="uppercase mb-4 text-md">Události ({ events.length })</h2>
|
||||
<div>
|
||||
{#if events.length > 0}
|
||||
{#each events as e}
|
||||
<Event event={e} />
|
||||
{/each}
|
||||
{:else}
|
||||
Tento člověk zatím nemá v programu žádnou událost.
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
|
|
|
@ -3,46 +3,8 @@
|
|||
</script>
|
||||
|
||||
<script>
|
||||
import Event from '$lib/Event.svelte';
|
||||
import { bundle, userData } from '$lib/stores.js';
|
||||
import EventTypeLabel from '$lib/EventTypeLabel.svelte';
|
||||
import Avatar from '$lib/Avatar.svelte';
|
||||
|
||||
const userDataLS = localStorage.getItem('userData')
|
||||
if (userDataLS) {
|
||||
userData.set(JSON.parse(userDataLS))
|
||||
}
|
||||
|
||||
function speakersMap (arr) {
|
||||
if (!arr) return;
|
||||
return arr.map(sId => {
|
||||
return $bundle.spec.speakers.find(sp => sp.id === sId)
|
||||
})
|
||||
}
|
||||
|
||||
function trackRender (trackId) {
|
||||
const track = $bundle.spec.tracks.find(t => t.id === trackId)
|
||||
return track.shortname || track.name
|
||||
}
|
||||
|
||||
function getParents (e) {
|
||||
return $bundle.spec.events.filter(i => i.parent === e.id)
|
||||
}
|
||||
|
||||
function handleFavorite (el) {
|
||||
const t = el.target.getAttribute('utxo-event-id')
|
||||
userData.update(data => {
|
||||
const fe = data.favoriteEvents
|
||||
let output = null
|
||||
if (fe.includes(t)) {
|
||||
output = Object.assign($userData, { favoriteEvents: fe.filter(f => f !== t) } )
|
||||
} else {
|
||||
fe.push(t)
|
||||
output = Object.assign($userData, { favoriteEvents: fe })
|
||||
}
|
||||
localStorage.setItem('userData', JSON.stringify(output))
|
||||
return output
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -57,45 +19,7 @@
|
|||
|
||||
<div class="mt-6">
|
||||
{#each $bundle.spec.events.filter(e => !e.parent) as e}
|
||||
<div class="transition-all mb-4 border px-3 py-2 rounded-md shadow {$userData.favoriteEvents.includes(e.id) ? 'bg-yellow-100' : '' }" >
|
||||
<div class="float-right"><i class="fa-star {$userData.favoriteEvents.includes(e.id) ? 'fa-solid' : 'fa-regular'} cursor-pointer" utxo-event-id="{e.id}" on:click={handleFavorite}></i></div>
|
||||
<div class="text-lg font-semibold"><a href="/udalosti/{e.id}">{e.name}</a></div>
|
||||
{#if e.speakers && e.speakers.length > 0}
|
||||
<div class="mt-1 mb-2 flex flex-wrap gap-2">
|
||||
{#each speakersMap(e.speakers) as s}
|
||||
<div class="flex gap-1.5">
|
||||
<Avatar speaker={s} size='extra-small' />
|
||||
<div class="m-auto"><a href="/lide/{s.id}">{s.name}</a></div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="mt-2 text-sm flex flex-wrap gap-2">
|
||||
<div><EventTypeLabel event={e} /></div>
|
||||
<div class="text-sm my-auto">{trackRender(e.track)}</div>
|
||||
<div class="text-xs my-auto">{e.duration}m</div>
|
||||
</div>
|
||||
{#if getParents(e).length > 0}
|
||||
<div class="mt-4 w-auto mb-2">
|
||||
<div class="flex flex-wrap gap-2" cellpadding="5">
|
||||
{#each getParents(e) as pe}
|
||||
<div class="border rounded py-1.5 px-2.5 bg-gray-100 text-sm">
|
||||
<div class="font-bold">{pe.name}</div>
|
||||
<div class="mt-1">
|
||||
{#if pe.speakers.length === 0}
|
||||
<div>TBA</div>
|
||||
{:else}
|
||||
{#each speakersMap(pe.speakers) as s}
|
||||
<div class="flex gap-1"><Avatar speaker={s} size='micro' /><div><a href="/lide/{s.id}">{s.name}</a></div></div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<Event event={e} />
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import SvelteMarkdown from 'svelte-markdown';
|
||||
|
||||
import { page } from '$app/stores';
|
||||
import { bundle } from '$lib/stores.js';
|
||||
import { bundle, userData } from '$lib/stores.js';
|
||||
import EventTypeLabel from '$lib/EventTypeLabel.svelte';
|
||||
import Avatar from '$lib/Avatar.svelte';
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
<section class="relative mx-auto py-10 px-6 max-w-6xl mb-10 text-blue-web">
|
||||
{#if $bundle}
|
||||
<div class="mb-4 flex flex-wrap gap-4">
|
||||
<div class="mb-6 flex flex-wrap gap-4">
|
||||
<div><EventTypeLabel event={e} size="big" /></div>
|
||||
<div class="text-md my-auto">{trackRender(e.track)}</div>
|
||||
<div class="text-sm my-auto">{e.duration}m</div>
|
||||
|
@ -37,7 +37,7 @@
|
|||
{#if e.speakers && e.speakers.length > 0}
|
||||
<div class="mt-4 mb-2 flex flex-wrap gap-4">
|
||||
{#each speakersMap(e.speakers) as s}
|
||||
<div class="flex gap-1.5">
|
||||
<div class="flex gap-2">
|
||||
<Avatar speaker={s} size='semi-small' />
|
||||
<div class="m-auto"><a href="/lide/{s.id}" class="text-xl">{s.name}</a></div>
|
||||
</div>
|
||||
|
|
Načítá se…
Odkázat v novém úkolu