Add meetup modal

This commit is contained in:
Dennis Reimann
2023-09-28 23:02:02 +02:00
parent 7a6c55f192
commit f3499569c8
11 changed files with 3421 additions and 1564 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -201,7 +201,7 @@ img:-moz-loading {
background-color: var(--color-accent); background-color: var(--color-accent);
text-decoration: none; text-decoration: none;
text-transform: uppercase; text-transform: uppercase;
border-radius: var(--space-m); border-radius: var(--border-radius);
transition-property: color, background; transition-property: color, background;
transition-duration: var(--transition-duration-fast); transition-duration: var(--transition-duration-fast);
@@ -216,7 +216,7 @@ img:-moz-loading {
.podlove-subscribe-button-iframe { .podlove-subscribe-button-iframe {
margin-top: var(--space-m); margin-top: var(--space-m);
border-radius: var(--space-m); border-radius: var(--border-radius);
} }
#podlove-subscribe-popup { #podlove-subscribe-popup {

View File

@@ -127,7 +127,7 @@
background: var(--color-flyout-bg); background: var(--color-flyout-bg);
transition-property: background, position, opacity; transition-property: background, position, opacity;
transition-duration: var(--transition-duration-fast); transition-duration: var(--transition-duration-fast);
border-radius: var(--space-m); border-radius: var(--border-radius);
@media (--up_to_M) { @media (--up_to_M) {
padding-top: 1.4em; padding-top: 1.4em;

82
src/css/base/modal.css Normal file
View File

@@ -0,0 +1,82 @@
.modal {
display: none;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
z-index: 100;
padding-left: var(--wrap-padding-horizontal);
padding-right: var(--wrap-padding-horizontal);
@media (--up_to_M) {
--modal-space: var(--space-l);
}
@media (--M_and_up) {
--modal-space: var(--space-xl);
}
&.modal--visible {
display: flex;
transition-property: opacity;
transition-duration: var(--transition-duration-fast);
}
&.modal--appear {
opacity: 1;
}
&:before {
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--color-overlay-bg);
}
& .modal-close {
position: absolute;
top: var(--modal-space);
right: var(--modal-space);
background: none;
width: 32px;
height: 32px;
padding: 6px;
color: var(--color-neutral-80);
cursor: pointer;
& svg {
display: block;
width: 100%;
height: 100%;
transition-property: background, color;
transition-duration: var(--transition-duration-fast);
}
&:hover {
@media not all and (hover: none) {
color: var(--color-accent);
}
}
}
& .inner {
position: relative;
z-index: 100;
color: var(--color-body-text);
background: var(--color-flyout-bg);
border: 1px solid var(--color-border-light);
border-radius: var(--border-radius);
padding: var(--modal-space);
max-width: 620px;
}
& h2 {
margin: var(--space-xs) var(--space-xxl) var(--space-m) 0;
}
}

View File

@@ -74,6 +74,7 @@
} }
--logo-height: calc((100vw - var(--wrap-padding-horizontal) * 2) / 134 * 12); --logo-height: calc((100vw - var(--wrap-padding-horizontal) * 2) / 134 * 12);
--border-radius: var(--space-m);
} }
@define-mixin dark-theme { @define-mixin dark-theme {

View File

@@ -3,6 +3,7 @@
@import 'base/fonts.css'; @import 'base/fonts.css';
@import 'base/elements.css'; @import 'base/elements.css';
@import 'base/layout.css'; @import 'base/layout.css';
@import 'base/modal.css';
@import 'base/header.css'; @import 'base/header.css';
@import 'base/footer.css'; @import 'base/footer.css';

View File

@@ -54,7 +54,7 @@
& img { & img {
display: block; display: block;
width: 100%; width: 100%;
border-radius: var(--space-m); border-radius: var(--border-radius);
} }
} }
@@ -80,7 +80,7 @@
display: block; display: block;
width: 240px; width: 240px;
height: 240px; height: 240px;
border-radius: var(--space-m); border-radius: var(--border-radius);
margin: var(--space-l) 0; margin: var(--space-l) 0;
} }

View File

@@ -88,11 +88,23 @@
font-size: .65rem; font-size: .65rem;
padding: var(--space-xs) var(--space-m); padding: var(--space-xs) var(--space-m);
background: var(--color-overlay-bg); background: var(--color-overlay-bg);
border-radius: var(--space-m); border-radius: var(--border-radius);
} }
} }
} }
#modal-meetupMap {
& #meeptupDetails :last-child {
margin-bottom: 0;
}
& .links {
display: flex;
flex-wrap: wrap;
gap: var(--space-xl);
}
}
#unmapped { #unmapped {
@media (--up_to_L) { @media (--up_to_L) {
display: none; display: none;

View File

@@ -165,7 +165,7 @@
--player-button-margin: var(--space-l); --player-button-margin: var(--space-l);
display: flex; display: flex;
border-radius: var(--space-m); border-radius: var(--border-radius);
overflow: hidden; overflow: hidden;
@media (--up_to_M) { @media (--up_to_M) {

View File

@@ -2,6 +2,12 @@ mixin sprite(id)
svg(role="img" title=id)&attributes(attributes) svg(role="img" title=id)&attributes(attributes)
use(xlink:href=`${assetPath("/img/sprite.svg")}#${id}`) use(xlink:href=`${assetPath("/img/sprite.svg")}#${id}`)
mixin modal(id)
div(id=id).modal&attributes(attributes)
.inner
button.modal-close(type="button" data-modal=id): +sprite("close")
block
mixin categories(current) mixin categories(current)
ul.categories ul.categories
li: a(href="/podcast/" class=(!current && 'current')).alles Alles li: a(href="/podcast/" class=(!current && 'current')).alles Alles
@@ -35,8 +41,11 @@ mixin member(m)
mixin map(id, markers) mixin map(id, markers)
.vectorMap(id=id) .vectorMap(id=id)
+modal(`modal-${id}`): #meeptupDetails
script. script.
const markers = [!{markers}]; const markers = [!{markers}];
const modalId = 'modal-meetupMap';
const $modal = document.getElementById(modalId);
// https://jvectormap.com/documentation/javascript-api/jvm-map/ // https://jvectormap.com/documentation/javascript-api/jvm-map/
new jvm.MultiMap({ new jvm.MultiMap({
container: $(`#!{id}`), container: $(`#!{id}`),
@@ -58,8 +67,34 @@ mixin map(id, markers)
} }
}, },
onMarkerClick(event, index) { onMarkerClick(event, index) {
const marker = markers[index] const m = markers[index]
if (marker.url) window.open(marker.url, '_blank'); const city = m.city ? m.city.trim() : ''
const date = m.event ? new Date(`${m.event.start}Z`) : null
const webUrl = m.url != m.websiteUrl ? m.websiteUrl : null
const twitterUrl = m.twitter ? `https://twitter.com/${m.twitter}` : null
const title = m.name + (city && !m.name.includes(city) ? ` (${city})` : '')
const urlTitle = m.url.includes('t.me/')
? 'Telegram'
: m.url.includes('meetup.com/') ? 'Meetup.com' : 'Website'
const link = (url, title) => url ? `<a href="${url}" target="_blank" rel="nofollow noopener">${title}</a>` : ''
document.getElementById('meeptupDetails').innerHTML = `
<h2>${title}</h2>
<p class="links">
${link(m.portalUrl, 'Portal')}
${link(m.url, urlTitle)}
${link(webUrl, 'Website')}
${link(twitterUrl, 'Twitter')}
</p>` + (m.event ? `
<h3>Nächstes Treffen</h3>
<p class="date">${formatDate(date)}${m.event.location ? ` @ ${m.event.location}` : ''}</p>
${m.event.description ? `<p>${m.event.description.replace('\n', '<br />')}</p>` : ''}
<p class="links">
${link(m.event.portalLink, 'Portal')}
${link(m.event.link, 'Website')}
${link(m.event.nostr_note ? `https://snort.social/e/${m.event.nostr_note}` : null, 'Nostr')}
</p>` : '')
toggleModal(modalId)
} }
}, },
mapUrlByCode(code, multiMap) { mapUrlByCode(code, multiMap) {
@@ -75,6 +110,11 @@ mixin meetupMap()
name: m.name, name: m.name,
latLng: [m.latitude, m.longitude], latLng: [m.latitude, m.longitude],
url: m.url, url: m.url,
city: m.city,
portalUrl: m.portalLink,
websiteUrl: m.websiteUrl,
twitter: m.twitter_username,
event: m.next_event,
style: { style: {
fill: m.name.startsWith('Einundzwanzig') || m.name.includes('Einezwänzg') || m.name.includes('Eenanzwanzeg') || m.name.includes('Yirmibir') ? 'var(--color-accent)' : 'var(--color-neutral-50)' fill: m.name.startsWith('Einundzwanzig') || m.name.includes('Einezwänzg') || m.name.includes('Eenanzwanzeg') || m.name.includes('Yirmibir') ? 'var(--color-accent)' : 'var(--color-neutral-50)'
} }

View File

@@ -1,4 +1,8 @@
const shuffle = arr => { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * i); const temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }; return arr } const shuffle = arr => { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * i); const temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }; return arr }
const formatDate = date => {
const [day, time] = date.toISOString().split('T')
return day.split('-').reverse().join('.') + (time ? ` um ${time.replace(':00.000Z', ' Uhr')}` : '')
}
// Theme Switch // Theme Switch
const COLOR_MODES = ["light", "dark"] const COLOR_MODES = ["light", "dark"]
@@ -38,6 +42,19 @@ const copyToClipboard = (e, text) => {
} }
} }
const toggleModal = modalId => {
const $modal = document.getElementById(modalId)
console.log($modal, modalId)
const isVisible = $modal.classList.contains('modal--visible')
if (isVisible) {
$modal.addEventListener('transitionend', () => { $modal.classList.toggle('modal--visible') }, { once: true })
$modal.classList.toggle('modal--appear')
} else {
$modal.classList.toggle('modal--visible')
window.setTimeout(() => { $modal.classList.toggle('modal--appear') }, 25)
}
}
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
// Topbar // Topbar
if ( if (
@@ -110,6 +127,11 @@ document.addEventListener("DOMContentLoaded", () => {
}) })
}) })
// Modal
document.querySelectorAll('[data-modal]').forEach(modalLink => {
modalLink.addEventListener('click', e => toggleModal(modalLink.dataset.modal))
})
// Map // Map
const map = document.getElementById('map') const map = document.getElementById('map')
const mapImg = document.getElementById('dach') const mapImg = document.getElementById('dach')