This commit is contained in:
tree 2023-04-27 04:53:20 +02:00
rodič 72f694a932
revize 56a5af507b
10 změnil soubory, kde provedl 127 přidání a 78 odebrání

Zobrazit soubor

@ -39,13 +39,12 @@
padding-bottom: 1em; padding-bottom: 1em;
} }
.markdown ul{ .markdown ul {
@apply py-4; @apply py-4;
} }
.markdown li{ .markdown li {
list-style-type: disc; list-style-type: disc;
@apply pl-2 ml-6; @apply pl-2 ml-6;
} }
.external::after { .external::after {

Zobrazit soubor

@ -3,7 +3,7 @@
import EventTypeBadge from '$lib/components/EventTypeBadge.svelte'; import EventTypeBadge from '$lib/components/EventTypeBadge.svelte';
import { config } from '$lib/pbw'; import { config } from '$lib/pbw';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { formatInTimeZone } from 'date-fns-tz' import { formatInTimeZone } from 'date-fns-tz';
export let segments; export let segments;
export let date; export let date;
@ -13,20 +13,21 @@
export let event = null; export let event = null;
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < segments.length; i++) {
const sg = segments[i] const sg = segments[i];
if (sg.remote) { 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) { if (!event || !event.segments) {
continue continue;
} }
const remoteSegments = event.segments.map(rs => Object.assign(rs, { const remoteSegments = event.segments.map((rs) =>
event, Object.assign(rs, {
remote: true event,
})) remote: true
segments.splice(i, remoteSegments.length, ...remoteSegments) })
);
segments.splice(i, remoteSegments.length, ...remoteSegments);
} }
} }
</script> </script>
<div class="text-2xl"> <div class="text-2xl">
@ -58,12 +59,16 @@
<div> <div>
{#if !event || segment.remote} {#if !event || segment.remote}
{#if (segment.event || event).hidden} {#if (segment.event || event).hidden}
{(segment.event || event)[(segment.event || event).shortname ? 'shortname' : 'name']}* {(segment.event || event)[
(segment.event || event).shortname ? 'shortname' : 'name'
]}*
{:else} {:else}
<a <a
href="/{entry}/{col}/{(segment.event || event).id}" href="/{entry}/{col}/{(segment.event || event).id}"
class="text-pbw-red hover:underline" 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} {/if}
{:else} {:else}

Zobrazit soubor

@ -13,6 +13,7 @@
export let offer = false; export let offer = false;
export let bundle = null; export let bundle = null;
export let currentItem = null; export let currentItem = null;
export let thumb = '300';
function findObject(it) { function findObject(it) {
if (!bundle) { if (!bundle) {
@ -39,7 +40,7 @@
<div <div
class="{size === 'small' ? 'p-0.5 lg:p-1' : 'p-1 lg:p-1.5'} {!item.hidden 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' ? '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"> <div class="w-full relative">
{#if col === 'benefit'} {#if col === 'benefit'}
@ -53,10 +54,11 @@
<a href={_url(col, item)}> <a href={_url(col, item)}>
<ItemLogo <ItemLogo
{item} {item}
{thumb}
width="w-full" width="w-full"
{aspect} {aspect}
{img} {img}
rounded={circle ? 'rounded-full' : (size === 'small' ? 'rounded-lg' : 'rounded-2xl')} rounded={circle ? 'rounded-full' : size === 'small' ? 'rounded-lg' : 'rounded-2xl'}
/> />
</a> </a>
</div> </div>
@ -113,9 +115,10 @@
{#if col === 'speaker'}<a href="/{entry}/for-speakers" class="underline hover:no-underline" {#if col === 'speaker'}<a href="/{entry}/for-speakers" class="underline hover:no-underline"
>Participate as a speaker!</a >Participate as a speaker!</a
>{/if} >{/if}
{#if col === 'place'}<a href="https://prgblockweek.com/submit-venue" class="underline hover:no-underline" {#if col === 'place'}<a
>Offer your own venue!</a href="https://prgblockweek.com/submit-venue"
>{/if} class="underline hover:no-underline">Offer your own venue!</a
>{/if}
</div> </div>
</div> </div>
</div> </div>

Zobrazit soubor

@ -6,13 +6,18 @@
export let width = 'w-10'; export let width = 'w-10';
export let aspect = 'aspect-square'; export let aspect = 'aspect-square';
export let rounded = 'rounded'; 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; $: blockie = !item[img] && item.hash ? makeBlockie('0x' + item.hash.substr(0, 40)) : null;
</script> </script>
{#if item[img]} {#if item[img]}
<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" class="{width} {rounded} {aspect} object-cover dark:bg-white drop-shadow-xl z-10"
alt={item.name} alt={item.name}
/> />

Zobrazit soubor

@ -1,5 +1,5 @@
export const config = { export const config = {
tz: "Europe/Prague", tz: 'Europe/Prague',
collections: { collections: {
places: { places: {
title: 'Places', title: 'Places',

Zobrazit soubor

@ -36,16 +36,16 @@ export function getFlagEmoji(str, mapper = true) {
return String.fromCodePoint(...codePoints); return String.fromCodePoint(...codePoints);
} }
export function processItemsList (arr) { export function processItemsList(arr) {
const out = [] const out = [];
const ids = [] const ids = [];
for (const sp of arr) { for (const sp of arr) {
// filter out duplicates // filter out duplicates
if (ids.includes(sp.id)) { if (ids.includes(sp.id)) {
continue continue;
} }
out.push(sp) out.push(sp);
ids.push(sp.id) ids.push(sp.id);
} }
return out return out;
} }

Zobrazit soubor

@ -15,7 +15,7 @@
return !e.types.find((t) => ['conference', 'hackathon'].includes(t)) && !e.hidden; 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 = [ const collections = [
{ title: 'Days', value: 10, col: 'schedule' }, { title: 'Days', value: 10, col: 'schedule' },
@ -27,7 +27,6 @@
//{ title: "Unions", col: "unions" }, //{ title: "Unions", col: "unions" },
{ title: 'Benefits', col: 'benefits' } { title: 'Benefits', col: 'benefits' }
]; ];
</script> </script>
<svelte:head> <svelte:head>
@ -58,7 +57,7 @@
<div <div
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 my-6 text-center text-2xl" 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> </div>
<h2 class="text-2xl uppercase font-bold pbw-text-color-secondary"> <h2 class="text-2xl uppercase font-bold pbw-text-color-secondary">
@ -67,7 +66,7 @@
<div <div
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 my-6 text-center text-2xl" 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> </div>
<h2 class="text-2xl uppercase font-bold mt-10 pbw-text-color-secondary"> <h2 class="text-2xl uppercase font-bold mt-10 pbw-text-color-secondary">
<a href="/{entry}/speakers">Speakers</a> ({speakers.length}) <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" class="grid grid-cols-3 sm:grid-cols-3 md:grid-cols-6 xl:grid-cols-8 my-6 text-center text-xl"
> >
<CollectionList <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} {entry}
offer="true" offer="true"
circle="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" class="grid grid-cols-3 sm:grid-cols-3 md:grid-cols-6 xl:grid-cols-8 my-6 text-center text-xl"
> >
<CollectionList <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} {entry}
offer="true" offer="true"
circle="true" circle="true"
@ -102,7 +109,14 @@
<div <div
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 my-6 text-center text-2xl" 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> </div>
{#if data.bundle.benefits} {#if data.bundle.benefits}
<h2 class="text-2xl uppercase font-bold pbw-text-color-secondary"> <h2 class="text-2xl uppercase font-bold pbw-text-color-secondary">

Zobrazit soubor

@ -23,12 +23,11 @@
let entry = $page.params.entry; let entry = $page.params.entry;
$: type = $page.params.type; $: type = $page.params.type;
$: tc = config.collections[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 = {}) { function processItems(_items, query = {}) {
if (!_items) return []; if (!_items) return [];
_items = [..._items] _items = [..._items];
if (type === 'events') { if (type === 'events') {
_items = _items.sort((x, y) => (x.date > y.date ? 1 : -1)); _items = _items.sort((x, y) => (x.date > y.date ? 1 : -1));
} }
@ -45,10 +44,10 @@
}); });
} }
if (['speakers', 'benefits', 'media-partner'].includes(type)) { 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') { 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; return _items;

Zobrazit soubor

@ -12,7 +12,7 @@
import { formatItemDate, bareDomain, getFlagEmoji } from '$lib/utils.js'; import { formatItemDate, bareDomain, getFlagEmoji } from '$lib/utils.js';
import { config } from '$lib/pbw'; import { config } from '$lib/pbw';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { formatInTimeZone } from 'date-fns-tz' import { formatInTimeZone } from 'date-fns-tz';
const colsDef = Object.fromEntries( const colsDef = Object.fromEntries(
Object.keys(config.collections).map((col) => { Object.keys(config.collections).map((col) => {
@ -38,26 +38,28 @@
return dates; return dates;
} }
function enrichItem (it) { function enrichItem(it) {
if (!it || !it.segments) return it if (!it || !it.segments) return it;
// segments // segments
let segments = it.segments let segments = it.segments;
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < segments.length; i++) {
const sg = segments[i] const sg = segments[i];
if (sg.remote) { 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) { if (!event || !event.segments) {
continue continue;
} }
const remoteSegments = event.segments.map(rs => Object.assign(rs, { const remoteSegments = event.segments.map((rs) =>
event, Object.assign(rs, {
remote: true event,
})) remote: true
segments.splice(i, remoteSegments.length, ...remoteSegments) })
);
segments.splice(i, remoteSegments.length, ...remoteSegments);
} }
} }
it.segments = segments it.segments = segments;
return it return it;
} }
$: entry = $page.params.entry; $: entry = $page.params.entry;
@ -66,38 +68,49 @@
$: item = enrichItem(data.bundle[colPlural].find((e) => e.id === $page.params.slug)); $: item = enrichItem(data.bundle[colPlural].find((e) => e.id === $page.params.slug));
$: defs = data.schema ? data.schema.definitions[col] : {}; $: defs = data.schema ? data.schema.definitions[col] : {};
function venuesMap (arr, rich = false) { function venuesMap(arr, rich = false) {
return arr.map((vId) => { return arr
const place = data.bundle.places.find((p) => p.id === vId); .map((vId) => {
return rich ? `<a href="/${$page.params.entry}/place/${place.id}" class=\"underline hover:no-underline\">${place.name}</a>` : place.name; const place = data.bundle.places.find((p) => p.id === vId);
}) return rich
.join(', ') ? `<a href="/${$page.params.entry}/place/${place.id}" class=\"underline hover:no-underline\">${place.name}</a>`
: place.name;
})
.join(', ');
} }
$: itemDescription = col === 'event' ? `${formatItemDate(item, { full: true })} @ ${item.venues ? venuesMap(item.venues) : item.venueName }. ${item.tags ? item.tags.join(', ') : ''}` : null $: itemDescription =
$: itemImage = item[config.collections[colPlural]?.img || 'logo'] 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> </script>
<svelte:head> <svelte:head>
<title>{item.name} | #PBW{$page.params.entry}</title> <title>{item.name} | #PBW{$page.params.entry}</title>
<meta name="description" content={itemDescription}> <meta name="description" content={itemDescription} />
<meta name="keywords" content={item.tags ? item.tags.join(", ") : ""}> <meta name="keywords" content={item.tags ? item.tags.join(', ') : ''} />
{#if item.links?.web} {#if item.links?.web}
<meta property="og:url" content={item.links.web}> <meta property="og:url" content={item.links.web} />
<meta property="og:type" content="website"> <meta property="og:type" content="website" />
{/if} {/if}
<meta property="og:title" content={item.name}> <meta property="og:title" content={item.name} />
<meta property="og:description" content={itemDescription}> <meta property="og:description" content={itemDescription} />
<meta property="og:image" content={itemImage}> <meta property="og:image" content={itemImage} />
<meta name="twitter:card" content="summary" /> <meta name="twitter:card" content="summary" />
{#if item.links?.twitter} {#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} {/if}
<meta name="twitter:title" content="{item.name} | #PBW{$page.params.entry}" /> <meta name="twitter:title" content="{item.name} | #PBW{$page.params.entry}" />
<meta name="twitter:description" content={itemDescription} /> <meta name="twitter:description" content={itemDescription} />
<meta name="twitter:image" content={itemImage} /> <meta name="twitter:image" content={itemImage} />
</svelte:head> </svelte:head>
<Header path={colsDef[$page.params.type]} type={$page.params.type} /> <Header path={colsDef[$page.params.type]} type={$page.params.type} />
@ -370,7 +383,11 @@
<div class="mt-4"> <div class="mt-4">
<CalendarList <CalendarList
{date} {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} {entry}
bundle={data.bundle} bundle={data.bundle}
event={item} event={item}
@ -386,7 +403,12 @@
<div <div
class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 xl:grid-cols-8 mt-4 text-center text-xl" 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> </div>
{/if} {/if}
{#if item.events} {#if item.events}

Zobrazit soubor

@ -45,7 +45,9 @@
> >
</div> </div>
</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} {#if event.cfp.text}
<div class="mt-2 pbw-text-color-secondary">{event.cfp.text}</div> <div class="mt-2 pbw-text-color-secondary">{event.cfp.text}</div>
{/if} {/if}