This commit is contained in:
tree 2023-01-29 06:23:27 +01:00
rodič 910da24ed9
revize f555c14865
10 změnil soubory, kde provedl 207 přidání a 49 odebrání

Zobrazit soubor

@ -0,0 +1,39 @@
<script>
export let segments;
export let date;
export let entry;
export let bundle;
export let event = null;
import { format } from 'date-fns';
</script>
<div class="text-2xl">
{#each segments as segment}
<div class="flex flex-wrap mb-2 gap-3 items-center text-gray-800">
<div class="text-xl md:w-32 text-right">{format(new Date(segment.startTime), "HH:mm")} - {format(new Date(segment.endTime), "HH:mm")}</div>
<div class="flex flex-wrap gap-2 items-center mb-6 md:mb-0">
<div><img src={(segment.event || event).logo} class="{event ? 'w-8' : 'w-10'} rounded" /></div>
<div class="">
{#if !event}
<a href="/{entry}/event/{(segment.event || event).id}" class="text-pbw-red hover:underline">{(segment.event || event)[event && event.shortname ? 'shortname' : 'name']}</a>
{:else}
<span class="">{event.shortname || event.name}</span>
{/if}
{#if segment.title}
- {segment.title}
{/if}
</div>
<div class="text-xl">
{#if (segment.venues || event.venues)}
@ {@html ((segment.venues || event.venues).map(vId => {
const place = bundle.places.find(p => p.id === vId)
return `<a href="/${entry}/place/${place.id}" class=\"underline hover:no-underline\">${place.name}</a>`
})).join("<span>, </span>")}
{:else if (segment.event || event).venueName}
@ {(segment.event || event).venueName}
{/if}
</div>
</div>
</div>
{/each}
</div>

Zobrazit soubor

@ -1,10 +1,12 @@
<script>
import { compareAsc, addDays, addMinutes, format } from 'date-fns';
export let bundle;
import { goto } from '$app/navigation';
export let data;
const startDate = "2023-06-02"
const endDate = "2023-06-11"
const segmentMinutes = 60
const bundle = data.bundle
const days = []
let currentDate = startDate
@ -32,36 +34,44 @@
}
}
const events = []
for (const event of bundle.events) {
const defaultTimes = "09:00-18:00"
const [ tstart, tend ] = (event.times || defaultTimes).split('-').map(t => t.trim())
const times = []
for (let i = 0; i < (event.days || 1); i++) {
const time = {
start: addDays(new Date(event.date + "T" + tstart), i),
end: addDays(new Date(event.date + "T" + tend), (tend < tstart ? i+1 : i))
}
for (const day of days) {
for (const segment of segments) {
const sstart = new Date(`${day}T${segment}`)
const send = new Date(addMinutes(sstart, segmentMinutes))
if (compareAsc(sstart, time.end) <= 0 && compareAsc(send, time.start) >= 0) {
//console.log(timelineData[[day, segment].join(';')])
const baseScore = event.attendees ? (event.attendees > 3000 ? 3000 : (event.attendees < 200 ? 200 : event.attendees)) : 0
const target = timelineData[[day, segment].join(';')]
target.score += baseScore || 0
target.events.push(event.id)
}
function updateTimelineEvent(time, eventId, attendees) {
for (const day of days) {
for (const segment of segments) {
const sstart = new Date(`${day}T${segment}`)
const send = new Date(addMinutes(sstart, segmentMinutes))
if (compareAsc(sstart, time.end) < 0 && compareAsc(send, time.start) > 0) {
//console.log(timelineData[[day, segment].join(';')])
const baseScore = attendees ? (attendees > 3000 ? 3000 : (attendees < 200 ? 200 : attendees)) : 0
const target = timelineData[[day, segment].join(';')]
target.score += baseScore || 0
target.events.push(eventId)
}
}
}
events.push({
id: event.id,
tstart,
tend,
times
})
}
const defaultTimes = "09:00-18:00"
for (const event of bundle.events) {
if (event.segments) {
for (const eventSegment of event.segments) {
const [ tstart, tend ] = (eventSegment.times || defaultTimes).split('-')
const time = {
start: new Date(`${eventSegment.date}T${tstart}`),
end: new Date(`${tend <= tstart ? format(addDays(new Date(eventSegment.date),1), 'yyyy-MM-dd') : eventSegment.date}T${tend}`)
}
updateTimelineEvent(time, event.id, eventSegment.ecap || event.attendees)
}
} else {
const [ tstart, tend ] = (event.times || defaultTimes).split('-').map(t => t.trim())
const times = []
for (let i = 0; i < (event.days || 1); i++) {
const time = {
start: addDays(new Date(event.date + "T" + tstart), i),
end: addDays(new Date(event.date + "T" + tend), (tend < tstart ? i+1 : i))
}
updateTimelineEvent(time, event.id, event.attendees)
}
}
}
const segmentsMax = Math.max(...Object.keys(timelineData).map(k => timelineData[k].score))
@ -85,6 +95,14 @@
}
}
}
function makeClick (day, segment, keys) {
const start = new Date(`${day}T${segment}`)
const end = addMinutes(start, segmentMinutes)
//goto(`/${data.params.entry}/events?start=${start.toISOString()}&end=${end.toISOString()}`)
goto(`/${data.params.entry}/day/${day}?start=${start.toISOString()}&end=${end.toISOString()}`)
}
function hiddenSelected() {
selectedSegment = null
}
@ -97,32 +115,32 @@
<div class="w-full mb-10 relative">
{#if selectedSegment}
<div class="absolute top-[74px] w-[300px] border bg-white z-50 py-2 px-4 {selectedSegment ? 'block' : 'hidden'}" style="left: {selectedSegment.event.layerX}px;">
<div class="absolute top-[66px] w-[300px] border bg-white z-50 py-2 px-4 {selectedSegment ? 'block' : 'hidden'}" style="left: {selectedSegment.event.layerX}px;">
<div class="uppercase">{selectedSegment.title}</div>
<div class="text-xl mt-4">
{#each selectedSegment.data.events.map(e => eventDetail(e)) as item}
<div class="h-12">
<div class="h-11">
{#if item.logo}
<img src={item.logo} alt={item.name} class="rounded-lg w-full aspect-square object-cover w-10 inline-block mr-1" />
<img src={item.logo} alt={item.name} class="rounded aspect-square object-cover w-10 inline-block mr-1" />
{/if}
{item.name}
{item.shortname || item.name}
</div>
{/each}
</div>
</div>
{/if}
<div class="flex text-center text-gray-600 text-sm">
<div class="flex text-center text-gray-400 text-sm">
{#each days as day}
<div class="mb-1 uppercase" style="width: {1/(days.length/100)}%;">
{format(new Date(day), 'MMMM d')}
<a href="/23/day/{format(new Date(day), 'yyyy-MM-dd')}"><span class="hidden md:inline-block">{format(new Date(day), 'eee ')}</span> {format(new Date(day), 'd')}</a>
</div>
{/each}
</div>
<div class="w-full border border-gray-600 rounded flex">
{#each days as day}
<div class="h-12 flex flex-grow " style="width: {1/(days.length/100)}%; border-right: 1px solid gray;">
<div class="w-full border border-gray-300 rounded flex">
{#each days as day, i}
<div class="h-10 flex flex-grow hover:bg-pbw-yellow/20" style="width: {1/(days.length/100)}%; {days.length-i > 1 ? "border-right: 1px solid silver;" : ""}">
{#each segments as segment}
<div id="{day}-{segment}" data-events={timelineData[[day, segment].join(";")].events} data-score={timelineData[[day, segment].join(";")].score} class="hover:border hover:border-pbw-red flex-grow" style="width: {1/(segments.length/50)}%; background-color: rgba(255, 120, 120, {timelineData[[day, segment].join(";")].perc}%);" on:mouseenter={makeSelected(day, segment, timelineData[[day, segment].join(";")])} on:mouseleave={hiddenSelected}>
<div id="{day}-{segment}" data-events={timelineData[[day, segment].join(";")].events} data-score={timelineData[[day, segment].join(";")].score} class="hover:border hover:border-pbw-yellow flex-grow cursor-pointer" style="width: {1/(segments.length/50)}%; background-color: rgba(255, 22, 22, {timelineData[[day, segment].join(";")].perc}%);" on:click={makeClick(day, segment, timelineData[[day, segment].join(";")])} on:mouseenter={makeSelected(day, segment, timelineData[[day, segment].join(";")])} on:mouseleave={hiddenSelected}>
</div>
{/each}
</div>

Zobrazit soubor

@ -29,6 +29,7 @@ export const config = {
conference: '#d3e5ee',
meetup: '#fdecc8',
hackathon: '#dad7ed',
expo: '#eee0da'
expo: '#eee0da',
party: '#dbeddb'
}
}

Zobrazit soubor

@ -2,19 +2,19 @@
import { page } from '$app/stores';
import "../app.css";
$: homepage = !$page.params.type
$: homepage = !$page.params.type && !$page.params.date
</script>
{#if homepage}
<div class="bg-slate-100 dark:bg-pbw-dark">
<div class="max-w-7xl mx-auto py-20">
<div class="px-6 xl:px-0 dark:bg-pbw-dark">
<div class="max-w-7xl mx-auto pt-10 pb-6">
<h1 class="text-5xl uppercase font-bold text-pbw-red"><a href="/{$page.params.entry}">Prague Blockchain Week 2023</a></h1>
<div class="text-4xl text-pbw-yellow">June 2-11, 2023</div>
</div>
</div>
{/if}
<div class="pb-24 bg-slate-100 dark:bg-pbw-dark">
<div class="pb-24 dark:bg-pbw-dark">
<slot />
</div>

Zobrazit soubor

@ -2,6 +2,7 @@ import * as dataApi from "$lib/dataApi";
export async function load({ params, url }) {
return {
params,
bundle: await dataApi.load(params.entry, url.hostname),
schema: await dataApi.loadSchema(),
};

Zobrazit soubor

@ -17,7 +17,7 @@
<div class="w-full px-6 xl:mx-0">
<div class="max-w-7xl mx-auto pt-2 md:pt-7">
<TimelineHeatmap bundle={data.bundle} />
<TimelineHeatmap {data} />
<h2 class="text-2xl uppercase font-bold text-gray-500"><a href="/{entry}/events">Conferences & Hackathons</a> ({conferences.length})</h2>
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-6 my-6 text-center text-2xl">

Zobrazit soubor

@ -9,6 +9,9 @@
import EventTypeBadge from '$lib/components/EventTypeBadge.svelte';
import { formatItemDate, bareDomain, getFlagEmoji } from '$lib/utils.js';
import makeBlockie from 'ethereum-blockies-base64';
import TimelineHeatmap from '$lib/components/TimelineHeatmap.svelte';
import { compareAsc, compareDesc, addMinutes } from 'date-fns';
import { writable } from 'svelte/store';
export let data;
@ -17,17 +20,27 @@
$: tc = config.collections[type]
$: items = data.bundle[type]
function processItems(_items) {
function processItems(_items, query = {}) {
if (!_items) return [];
_items = JSON.parse(JSON.stringify(_items))
if (type === 'events') {
_items = _items.sort((x, y) => x.date > y.date ? 1 : -1)
}
if (type === 'events' && query.start && query.end) {
_items = _items.filter(item => {
return item.segments.find(sgm => {
const [ tstart, tend ] = sgm.times.split("-")
return compareAsc(new Date(sgm.startTime), new Date(query.start)) <= 0
&& compareAsc(new Date(sgm.endTime), new Date(query.end)) >= 0
})
// return compareAsc(item.new Date(query.segment) > 0)
})
}
return _items
}
$: processedItems = processItems(items)
$: processedItems = processItems(items) //, Object.fromEntries($page.url.searchParams))
onMount(async () => {
if (!config.collections[$page.params.type]) {
@ -53,8 +66,9 @@
</div>
<div class="flex flex-wrap md:flex-nowrap w-full">
</div>
<TimelineHeatmap {data} />
<h2 class="text-2xl uppercase font-bold text-gray-500">{tc.title} ({processedItems.length})</h2>
<div class="text-xl mt-6 text-gray-500 dark:text-gray-400">
<div class="text-xl mt-6 text-gray-800 dark:text-gray-400">
<table class="w-full table-auto">
<thead>
<tr class="text-left">

Zobrazit soubor

@ -2,11 +2,13 @@
export let data;
import { page } from '$app/stores';
import CollectionList from '$lib/components/CollectionList.svelte';
import CalendarList from '$lib/components/CalendarList.svelte';
import EventTypeBadge from '$lib/components/EventTypeBadge.svelte';
import Footer from '$lib/components/Footer.svelte';
import SvelteMarkdown from 'svelte-markdown';
import { formatItemDate, bareDomain, getFlagEmoji } from '$lib/utils.js';
import { config } from '$lib/pbw';
import { format } from 'date-fns';
const colsDef = Object.fromEntries(Object.keys(config.collections).map(col => { return [ config.collections[col].model, col ]}))
@ -16,6 +18,17 @@
linkedin: { col: x => x.linkedin ? 'https://linkedin.com/in/'+x.linkedin : null }
}
function eventDates(event) {
const dates = []
for (const seg of event.segments) {
const date = format(new Date(seg.startTime), 'yyyy-MM-dd')
if (!dates.includes(date)) {
dates.push(date)
}
}
return dates
}
$: entry = $page.params.entry
$: col = $page.params.type
$: colPlural = colsDef[col]
@ -224,6 +237,17 @@
{/if}
{#if col === "event"}
{#if item.segments}
<h2 class="text-2xl uppercase font-bold mt-10 text-gray-500">Day Schedule</h2>
{#each eventDates(item) as date}
<div class="mb-6">
<h3 class="mt-4 text-xl uppercase text-gray-500"><a href="/{entry}/day/{date}">{format(new Date(date), "EEEE - MMMM d, yyyy")}</a></h3>
<div class="mt-4">
<CalendarList date={date} segments={item.segments.filter(s => s.startTime.match(new RegExp("^"+date)))} entry={entry} bundle={data.bundle} event={item} />
</div>
</div>
{/each}
{/if}
{#if item.venues}
<h2 class="text-2xl uppercase font-bold mt-10 text-gray-500">Venues ({item.venues?.length || 0})</h2>
<div class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 xl:grid-cols-8 mt-4 text-center text-xl">

Zobrazit soubor

@ -0,0 +1,60 @@
<script>
import { page } from '$app/stores';
import TimelineHeatmap from '$lib/components/TimelineHeatmap.svelte';
import CalendarList from '$lib/components/CalendarList.svelte';
import Footer from '$lib/components/Footer.svelte';
import { format, compareAsc } from 'date-fns';
export let data;
function makeSegments (events, date) {
const query = {
start: date+"T00:00",
end: date+"T23:59"
}
let arr = []
for (const ev of events) {
for (const sg of ev.segments) {
if (!(compareAsc(new Date(sg.startTime), new Date(query.end)) <= 0
&& compareAsc(new Date(sg.startTime), new Date(query.start)) >= 0)) {
continue;
}
arr.push({
startTime: sg.startTime,
endTime: sg.endTime,
event: ev,
title: sg.title,
venues: sg.venues || ev.venues || [],
})
}
}
return arr.sort((x, y) => {
return x.start > y.start ? 1 : -1
})
}
$: segments = makeSegments(data.bundle.events, $page.params.date)
</script>
<svelte:head>
<title>{format(new Date($page.params.date), "EEEE MMMM d, yyyy")} | #PBW{$page.params.entry} Inspector</title>
</svelte:head>
<div class="w-full">
<div class="max-w-7xl mx-auto pt-5 md:pt-10">
<div class="mx-4 xl:mx-0">
<div class="flex gap-8 mb-6 md:mb-10">
<h1 class="text-4xl md:text-5xl font-bold text-pbw-red"><a href="/{$page.params.entry}">#PBW23</a><span class="text-pbw-yellow">.days</span></h1>
</div>
</div>
<TimelineHeatmap {data} />
<h2 class="text-4xl font-bold text-gray-600">{format(new Date($page.params.date), "MMMM d, yyyy - EEEE")}</h2>
<div class="mt-10">
<CalendarList date={$page.params.date} segments={segments} entry={$page.params.entry} bundle={data.bundle} />
</div>
<Footer bundle={data.bundle} />
</div>
</div>

Zobrazit soubor

@ -19,5 +19,6 @@ module.exports = {
},
},
},
darkMode: 'class',
plugins: []
};