update
This commit is contained in:
rodič
72f694a932
revize
56a5af507b
|
@ -39,13 +39,12 @@
|
|||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.markdown ul{
|
||||
.markdown ul {
|
||||
@apply py-4;
|
||||
}
|
||||
.markdown li{
|
||||
.markdown li {
|
||||
list-style-type: disc;
|
||||
@apply pl-2 ml-6;
|
||||
|
||||
}
|
||||
|
||||
.external::after {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import EventTypeBadge from '$lib/components/EventTypeBadge.svelte';
|
||||
import { config } from '$lib/pbw';
|
||||
import { format } from 'date-fns';
|
||||
import { formatInTimeZone } from 'date-fns-tz'
|
||||
import { formatInTimeZone } from 'date-fns-tz';
|
||||
|
||||
export let segments;
|
||||
export let date;
|
||||
|
@ -13,20 +13,21 @@
|
|||
export let event = null;
|
||||
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
const sg = segments[i]
|
||||
const sg = segments[i];
|
||||
if (sg.remote) {
|
||||
const event = bundle.events.find(e => e.id === sg.remote)
|
||||
const event = bundle.events.find((e) => e.id === sg.remote);
|
||||
if (!event || !event.segments) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
const remoteSegments = event.segments.map(rs => Object.assign(rs, {
|
||||
const remoteSegments = event.segments.map((rs) =>
|
||||
Object.assign(rs, {
|
||||
event,
|
||||
remote: true
|
||||
}))
|
||||
segments.splice(i, remoteSegments.length, ...remoteSegments)
|
||||
})
|
||||
);
|
||||
segments.splice(i, remoteSegments.length, ...remoteSegments);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="text-2xl">
|
||||
|
@ -58,12 +59,16 @@
|
|||
<div>
|
||||
{#if !event || segment.remote}
|
||||
{#if (segment.event || event).hidden}
|
||||
{(segment.event || event)[(segment.event || event).shortname ? 'shortname' : 'name']}*
|
||||
{(segment.event || event)[
|
||||
(segment.event || event).shortname ? 'shortname' : 'name'
|
||||
]}*
|
||||
{:else}
|
||||
<a
|
||||
href="/{entry}/{col}/{(segment.event || event).id}"
|
||||
class="text-pbw-red hover:underline"
|
||||
>{(segment.event || event)[(segment.event || event).shortname ? 'shortname' : 'name']}</a
|
||||
>{(segment.event || event)[
|
||||
(segment.event || event).shortname ? 'shortname' : 'name'
|
||||
]}</a
|
||||
>
|
||||
{/if}
|
||||
{:else}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
export let offer = false;
|
||||
export let bundle = null;
|
||||
export let currentItem = null;
|
||||
export let thumb = '300';
|
||||
|
||||
function findObject(it) {
|
||||
if (!bundle) {
|
||||
|
@ -39,7 +40,7 @@
|
|||
<div
|
||||
class="{size === 'small' ? 'p-0.5 lg:p-1' : 'p-1 lg:p-1.5'} {!item.hidden
|
||||
? 'hover:bg-pbw-yellow/20 dark:hover:bg-pbw-white/10'
|
||||
: ''} {(size === 'small' ? 'rounded-lg' : 'rounded-2xl')}"
|
||||
: ''} {size === 'small' ? 'rounded-lg' : 'rounded-2xl'}"
|
||||
>
|
||||
<div class="w-full relative">
|
||||
{#if col === 'benefit'}
|
||||
|
@ -53,10 +54,11 @@
|
|||
<a href={_url(col, item)}>
|
||||
<ItemLogo
|
||||
{item}
|
||||
{thumb}
|
||||
width="w-full"
|
||||
{aspect}
|
||||
{img}
|
||||
rounded={circle ? 'rounded-full' : (size === 'small' ? 'rounded-lg' : 'rounded-2xl')}
|
||||
rounded={circle ? 'rounded-full' : size === 'small' ? 'rounded-lg' : 'rounded-2xl'}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -113,8 +115,9 @@
|
|||
{#if col === 'speaker'}<a href="/{entry}/for-speakers" class="underline hover:no-underline"
|
||||
>Participate as a speaker!</a
|
||||
>{/if}
|
||||
{#if col === 'place'}<a href="https://prgblockweek.com/submit-venue" class="underline hover:no-underline"
|
||||
>Offer your own venue!</a
|
||||
{#if col === 'place'}<a
|
||||
href="https://prgblockweek.com/submit-venue"
|
||||
class="underline hover:no-underline">Offer your own venue!</a
|
||||
>{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,13 +6,18 @@
|
|||
export let width = 'w-10';
|
||||
export let aspect = 'aspect-square';
|
||||
export let rounded = 'rounded';
|
||||
export let thumb = '300';
|
||||
|
||||
if (width.match(/^w-48/)) {
|
||||
thumb = '500';
|
||||
}
|
||||
|
||||
$: blockie = !item[img] && item.hash ? makeBlockie('0x' + item.hash.substr(0, 40)) : null;
|
||||
</script>
|
||||
|
||||
{#if item[img]}
|
||||
<img
|
||||
src={item[img]}
|
||||
src={item[img].replace(/\.([^.]+)$/, `_${thumb}px.webp`)}
|
||||
class="{width} {rounded} {aspect} object-cover dark:bg-white drop-shadow-xl z-10"
|
||||
alt={item.name}
|
||||
/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export const config = {
|
||||
tz: "Europe/Prague",
|
||||
tz: 'Europe/Prague',
|
||||
collections: {
|
||||
places: {
|
||||
title: 'Places',
|
||||
|
|
|
@ -36,16 +36,16 @@ export function getFlagEmoji(str, mapper = true) {
|
|||
return String.fromCodePoint(...codePoints);
|
||||
}
|
||||
|
||||
export function processItemsList (arr) {
|
||||
const out = []
|
||||
const ids = []
|
||||
export function processItemsList(arr) {
|
||||
const out = [];
|
||||
const ids = [];
|
||||
for (const sp of arr) {
|
||||
// filter out duplicates
|
||||
if (ids.includes(sp.id)) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
out.push(sp)
|
||||
ids.push(sp.id)
|
||||
out.push(sp);
|
||||
ids.push(sp.id);
|
||||
}
|
||||
return out
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
return !e.types.find((t) => ['conference', 'hackathon'].includes(t)) && !e.hidden;
|
||||
});
|
||||
|
||||
const speakers = processItemsList(data.bundle.speakers)
|
||||
const speakers = processItemsList(data.bundle.speakers);
|
||||
|
||||
const collections = [
|
||||
{ title: 'Days', value: 10, col: 'schedule' },
|
||||
|
@ -27,7 +27,6 @@
|
|||
//{ title: "Unions", col: "unions" },
|
||||
{ title: 'Benefits', col: 'benefits' }
|
||||
];
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
@ -58,7 +57,7 @@
|
|||
<div
|
||||
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 my-6 text-center text-2xl"
|
||||
>
|
||||
<CollectionList arr={conferences} img="logo" col="event" {entry} offer={true} />
|
||||
<CollectionList arr={conferences} thumb="500" img="logo" col="event" {entry} offer={true} />
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl uppercase font-bold pbw-text-color-secondary">
|
||||
|
@ -67,7 +66,7 @@
|
|||
<div
|
||||
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 my-6 text-center text-2xl"
|
||||
>
|
||||
<CollectionList arr={otherEvents} img="logo" col="event" {entry} />
|
||||
<CollectionList arr={otherEvents} thumb="500" img="logo" col="event" {entry} />
|
||||
</div>
|
||||
<h2 class="text-2xl uppercase font-bold mt-10 pbw-text-color-secondary">
|
||||
<a href="/{entry}/speakers">Speakers</a> ({speakers.length})
|
||||
|
@ -77,7 +76,11 @@
|
|||
class="grid grid-cols-3 sm:grid-cols-3 md:grid-cols-6 xl:grid-cols-8 my-6 text-center text-xl"
|
||||
>
|
||||
<CollectionList
|
||||
arr={processItemsList(speakers.filter((s) => !['cz', 'sk'].includes(s.country)).sort((x, y) => (x.name > y.name ? 1 : -1)))}
|
||||
arr={processItemsList(
|
||||
speakers
|
||||
.filter((s) => !['cz', 'sk'].includes(s.country))
|
||||
.sort((x, y) => (x.name > y.name ? 1 : -1))
|
||||
)}
|
||||
{entry}
|
||||
offer="true"
|
||||
circle="true"
|
||||
|
@ -90,7 +93,11 @@
|
|||
class="grid grid-cols-3 sm:grid-cols-3 md:grid-cols-6 xl:grid-cols-8 my-6 text-center text-xl"
|
||||
>
|
||||
<CollectionList
|
||||
arr={processItemsList(speakers.filter((s) => ['cz', 'sk'].includes(s.country)).sort((x, y) => (x.name > y.name ? 1 : -1)))}
|
||||
arr={processItemsList(
|
||||
speakers
|
||||
.filter((s) => ['cz', 'sk'].includes(s.country))
|
||||
.sort((x, y) => (x.name > y.name ? 1 : -1))
|
||||
)}
|
||||
{entry}
|
||||
offer="true"
|
||||
circle="true"
|
||||
|
@ -102,7 +109,14 @@
|
|||
<div
|
||||
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 my-6 text-center text-2xl"
|
||||
>
|
||||
<CollectionList arr={data.bundle.places} col="place" img="photo" {entry} offer={true} />
|
||||
<CollectionList
|
||||
arr={data.bundle.places}
|
||||
thumb="500"
|
||||
col="place"
|
||||
img="photo"
|
||||
{entry}
|
||||
offer={true}
|
||||
/>
|
||||
</div>
|
||||
{#if data.bundle.benefits}
|
||||
<h2 class="text-2xl uppercase font-bold pbw-text-color-secondary">
|
||||
|
|
|
@ -23,12 +23,11 @@
|
|||
let entry = $page.params.entry;
|
||||
$: type = $page.params.type;
|
||||
$: tc = config.collections[type];
|
||||
$: items = type === 'speakers' ? processItemsList(data.bundle[type]) : data.bundle[type]
|
||||
|
||||
$: items = type === 'speakers' ? processItemsList(data.bundle[type]) : data.bundle[type];
|
||||
|
||||
function processItems(_items, query = {}) {
|
||||
if (!_items) return [];
|
||||
_items = [..._items]
|
||||
_items = [..._items];
|
||||
if (type === 'events') {
|
||||
_items = _items.sort((x, y) => (x.date > y.date ? 1 : -1));
|
||||
}
|
||||
|
@ -45,10 +44,10 @@
|
|||
});
|
||||
}
|
||||
if (['speakers', 'benefits', 'media-partner'].includes(type)) {
|
||||
_items = _items.sort((x, y) => (x.name.toLowerCase() > y.name.toLowerCase() ? 1 : -1))
|
||||
_items = _items.sort((x, y) => (x.name.toLowerCase() > y.name.toLowerCase() ? 1 : -1));
|
||||
}
|
||||
if (type === 'places') {
|
||||
_items = _items.sort((x, y) => (x.capacity > y.capacity ? -1 : 1))
|
||||
_items = _items.sort((x, y) => (x.capacity > y.capacity ? -1 : 1));
|
||||
}
|
||||
|
||||
return _items;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
import { formatItemDate, bareDomain, getFlagEmoji } from '$lib/utils.js';
|
||||
import { config } from '$lib/pbw';
|
||||
import { format } from 'date-fns';
|
||||
import { formatInTimeZone } from 'date-fns-tz'
|
||||
import { formatInTimeZone } from 'date-fns-tz';
|
||||
|
||||
const colsDef = Object.fromEntries(
|
||||
Object.keys(config.collections).map((col) => {
|
||||
|
@ -38,26 +38,28 @@
|
|||
return dates;
|
||||
}
|
||||
|
||||
function enrichItem (it) {
|
||||
if (!it || !it.segments) return it
|
||||
function enrichItem(it) {
|
||||
if (!it || !it.segments) return it;
|
||||
// segments
|
||||
let segments = it.segments
|
||||
let segments = it.segments;
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
const sg = segments[i]
|
||||
const sg = segments[i];
|
||||
if (sg.remote) {
|
||||
const event = data.bundle.events.find(e => e.id === sg.remote)
|
||||
const event = data.bundle.events.find((e) => e.id === sg.remote);
|
||||
if (!event || !event.segments) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
const remoteSegments = event.segments.map(rs => Object.assign(rs, {
|
||||
const remoteSegments = event.segments.map((rs) =>
|
||||
Object.assign(rs, {
|
||||
event,
|
||||
remote: true
|
||||
}))
|
||||
segments.splice(i, remoteSegments.length, ...remoteSegments)
|
||||
})
|
||||
);
|
||||
segments.splice(i, remoteSegments.length, ...remoteSegments);
|
||||
}
|
||||
}
|
||||
it.segments = segments
|
||||
return it
|
||||
it.segments = segments;
|
||||
return it;
|
||||
}
|
||||
|
||||
$: entry = $page.params.entry;
|
||||
|
@ -66,34 +68,45 @@
|
|||
$: item = enrichItem(data.bundle[colPlural].find((e) => e.id === $page.params.slug));
|
||||
$: defs = data.schema ? data.schema.definitions[col] : {};
|
||||
|
||||
function venuesMap (arr, rich = false) {
|
||||
return arr.map((vId) => {
|
||||
function venuesMap(arr, rich = false) {
|
||||
return arr
|
||||
.map((vId) => {
|
||||
const place = data.bundle.places.find((p) => p.id === vId);
|
||||
return rich ? `<a href="/${$page.params.entry}/place/${place.id}" class=\"underline hover:no-underline\">${place.name}</a>` : place.name;
|
||||
return rich
|
||||
? `<a href="/${$page.params.entry}/place/${place.id}" class=\"underline hover:no-underline\">${place.name}</a>`
|
||||
: place.name;
|
||||
})
|
||||
.join(', ')
|
||||
.join(', ');
|
||||
}
|
||||
|
||||
$: itemDescription = col === 'event' ? `${formatItemDate(item, { full: true })} @ ${item.venues ? venuesMap(item.venues) : item.venueName }. ${item.tags ? item.tags.join(', ') : ''}` : null
|
||||
$: itemImage = item[config.collections[colPlural]?.img || 'logo']
|
||||
$: itemDescription =
|
||||
col === 'event'
|
||||
? `${formatItemDate(item, { full: true })} @ ${
|
||||
item.venues ? venuesMap(item.venues) : item.venueName
|
||||
}. ${item.tags ? item.tags.join(', ') : ''}`
|
||||
: null;
|
||||
$: itemImage = item[config.collections[colPlural]?.img || 'logo'];
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{item.name} | #PBW{$page.params.entry}</title>
|
||||
<meta name="description" content={itemDescription}>
|
||||
<meta name="keywords" content={item.tags ? item.tags.join(", ") : ""}>
|
||||
<meta name="description" content={itemDescription} />
|
||||
<meta name="keywords" content={item.tags ? item.tags.join(', ') : ''} />
|
||||
|
||||
{#if item.links?.web}
|
||||
<meta property="og:url" content={item.links.web}>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content={item.links.web} />
|
||||
<meta property="og:type" content="website" />
|
||||
{/if}
|
||||
<meta property="og:title" content={item.name}>
|
||||
<meta property="og:description" content={itemDescription}>
|
||||
<meta property="og:image" content={itemImage}>
|
||||
<meta property="og:title" content={item.name} />
|
||||
<meta property="og:description" content={itemDescription} />
|
||||
<meta property="og:image" content={itemImage} />
|
||||
|
||||
<meta name="twitter:card" content="summary" />
|
||||
{#if item.links?.twitter}
|
||||
<meta name="twitter:site" content="@{item.links.twitter.replace(/https?:\/\/(twitter\.com\/)/g,'')}" />
|
||||
<meta
|
||||
name="twitter:site"
|
||||
content="@{item.links.twitter.replace(/https?:\/\/(twitter\.com\/)/g, '')}"
|
||||
/>
|
||||
{/if}
|
||||
<meta name="twitter:title" content="{item.name} | #PBW{$page.params.entry}" />
|
||||
<meta name="twitter:description" content={itemDescription} />
|
||||
|
@ -370,7 +383,11 @@
|
|||
<div class="mt-4">
|
||||
<CalendarList
|
||||
{date}
|
||||
segments={item.segments.filter((s) => s.remote || formatInTimeZone(new Date(s.startTime), config.tz, 'yyyy-MM-dd') === date)}
|
||||
segments={item.segments.filter(
|
||||
(s) =>
|
||||
s.remote ||
|
||||
formatInTimeZone(new Date(s.startTime), config.tz, 'yyyy-MM-dd') === date
|
||||
)}
|
||||
{entry}
|
||||
bundle={data.bundle}
|
||||
event={item}
|
||||
|
@ -386,7 +403,12 @@
|
|||
<div
|
||||
class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 xl:grid-cols-8 mt-4 text-center text-xl"
|
||||
>
|
||||
<CollectionList arr={item.speakers} bundle={data.bundle} currentItem={item} circle="true" />
|
||||
<CollectionList
|
||||
arr={item.speakers}
|
||||
bundle={data.bundle}
|
||||
currentItem={item}
|
||||
circle="true"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if item.events}
|
||||
|
|
|
@ -45,7 +45,9 @@
|
|||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 pbw-text-color-secondary">Date: <span>{formatItemDate(event, { full: true })}</span></div>
|
||||
<div class="mt-2 pbw-text-color-secondary">
|
||||
Date: <span>{formatItemDate(event, { full: true })}</span>
|
||||
</div>
|
||||
{#if event.cfp.text}
|
||||
<div class="mt-2 pbw-text-color-secondary">{event.cfp.text}</div>
|
||||
{/if}
|
||||
|
|
Načítá se…
Odkázat v novém úkolu