chore: concerts + fix modals

This commit is contained in:
Cory Dransfeldt 2024-11-17 16:38:19 -08:00
parent 3345c170fc
commit 463a26defc
No known key found for this signature in database
5 changed files with 144 additions and 27 deletions

View file

@ -1,8 +1,25 @@
---
const { content } = Astro.props;
---
import { md } from "@utils/helpers/general.js";
import { IconCircleX, IconInfoCircle } from "@tabler/icons-react";
<div class="modal">
<button class="close">Close</button>
<div class="content">{content}</div>
</div>
const { content, id } = Astro.props;
---
<>
<input
class="modal-input"
id={id}
type="checkbox"
tabindex="0"
/>
<label class="modal-toggle" for={id}>
<IconInfoCircle size={24} />
</label>
<div class="modal-wrapper">
<div class="modal-body">
<label class="modal-close" for={id}>
<IconCircleX size={24} />
</label>
<div set:html={md(content)}></div>
</div>
</div>
</>

View file

@ -1,5 +1,7 @@
---
import { DateTime } from "luxon";
import Layout from "@layouts/Layout.astro";
import Modal from "@components/blocks/Modal.astro";
import ToggleContent from "@components/utils/ToggleContent.astro";
import AssociatedMedia from "@components/blocks/AssociatedMedia.astro";
import {
@ -107,7 +109,6 @@ const playLabel = artist.total_plays === 1 ? "play" : "plays";
</>
)
}
{
artist.concerts && (
<>
@ -115,28 +116,38 @@ const playLabel = artist.total_plays === 1 ? "play" : "plays";
<IconDeviceSpeaker size={18} /> I've seen this artist live!
</p>
<ul>
{artist.concerts.map((concert) => {
const venue =
concert.venue_latitude && concert.venue_longitude
? `<a href="https://www.openstreetmap.org/?mlat=${concert.venue_latitude}&mlon=${concert.venue_longitude}#map=18/${concert.venue_latitude}/${concert.venue_longitude}">${concert.venue_name_short}</a>`
: concert.venue_name_short;
return (
<li>
On{" "}
<strong class="highlight-text">
{concert.date.toLocaleString(DateTime.DATE_MED)}
</strong>
{venue && <> at {venue}</>}
{concert.notes && <span> — {concert.notes}</span>}
</li>
);
})}
{artist.concerts.map((concert, index) => (
<li key={index}>
On{" "}
<strong class="highlight-text">{DateTime.fromISO(concert.date).toLocaleString(DateTime.DATE_MED)}</strong>
{concert.venue_name_short && (
<>
{" "}
at{" "}
{concert.venue_latitude && concert.venue_longitude ? (
<a
href={`https://www.openstreetmap.org/?mlat=${concert.venue_latitude}&mlon=${concert.venue_longitude}#map=18/${concert.venue_latitude}/${concert.venue_longitude}`}
>{concert.venue_name_short}</a>
) : (
<span>{concert.venue_name_short}</span>
)}
</>
)}
{concert.notes && (
<>
{" "}
<Modal
id={`modal-${index}`}
content={`### Notes\n${concert.notes}`}
/>
</>
)}
</li>
))}
</ul>
</>
)
}
{
artist.albums && (
<>

View file

@ -0,0 +1,87 @@
---
import Layout from "@layouts/Layout.astro";
import Paginator from "@components/nav/Paginator.astro";
import Modal from "@components/blocks/Modal.astro";
import { fetchConcerts } from "@utils/data/concerts.js";
import { fetchGlobalData } from "@utils/data/global/index.js";
import { DateTime } from "luxon";
export const prerender = true;
const { globals } = await fetchGlobalData(Astro);
const concerts = await fetchConcerts();
const title = "Concerts";
const description =
"These are concerts I've attended (not all of them — just the ones I could remember or glean from emails, photo metadata et al). I've been to at least " +
concerts.length +
" shows.";
const pageSize = 30;
const currentPage = parseInt(Astro.url.searchParams.get("page") || "1", 10);
const totalPages = Math.ceil(concerts.length / pageSize);
const paginatedConcerts = concerts.slice(
(currentPage - 1) * pageSize,
currentPage * pageSize
);
const pagination = {
currentPage,
totalPages,
hasPrevious: currentPage > 1,
hasNext: currentPage < totalPages,
previousPage: currentPage > 1 ? `/concerts?page=${currentPage - 1}` : null,
nextPage: currentPage < totalPages ? `/concerts?page=${currentPage + 1}` : null,
pages: Array.from({ length: totalPages }, (_, index) => ({
number: index + 1,
href: `/concerts?page=${index + 1}`,
})),
};
---
<Layout
pageTitle={title}
description={description}
currentUrl={Astro.url.pathname}
>
{currentPage === 1 && (
<>
<h2 class="page-title">{title}</h2>
<p>These are concerts I've attended (not all of them — just the ones I could remember or glean from emails, photo metadata et al). I've been to at least <strong class="highlight-text">{concerts.length}</strong> shows.</p>
<hr />
</>
)}
<ul class="concert-list">
{paginatedConcerts.map((concert) => (
<li>
{concert.artist.url ? (
<a href={concert.artist.url}>{concert.artist.name}</a>
) : (
<span>{concert.artist.name}</span>
)}{" "}
on{" "}
<strong class="highlight-text">{DateTime.fromISO(concert.date).toLocaleString(DateTime.DATE_FULL)}</strong>
{concert.venue?.name && (
<>
{" at "}
{concert.venue.latitude && concert.venue.longitude ? (
<a
href={`https://www.openstreetmap.org/?mlat=${concert.venue.latitude}&mlon=${concert.venue.longitude}#map=18/${concert.venue.latitude}/${concert.venue.longitude}`}
>{concert.venue.name_short || concert.venue.name}</a>
) : (
<span>{concert.venue.name_short || concert.venue.name}</span>
)}
</>
)}
{concert.notes && (
<Modal
id={`modal-${concert.id}`}
icon="info-circle"
content={`### Notes\n${concert.notes}`}
/>
)}
</li>
))}
</ul>
<Paginator pagination={pagination} />
</Layout>

View file

@ -435,12 +435,12 @@ td:first-of-type,
main {
flex: 1 1 0%;
margin: 0 auto;
}
main,
footer {
width: 80%;
margin: var(--sizing-3xl) auto 0;
@media screen and (min-width: 768px) {
max-width: 768px;
@ -448,6 +448,8 @@ footer {
}
footer {
margin: var(--sizing-3xl) auto 0;
& nav {
&.social,
&.sub-pages {

View file

@ -6,7 +6,7 @@ const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
let cachedConcerts = null;
export async function fetchConcertsData() {
export async function fetchConcerts() {
if (import.meta.env.MODE === "development" && cachedConcerts)
return cachedConcerts;