e434ee3620
Route /termin/[slug] -> /kalender/termin/[slug] verschoben, alte URL 302-redirect (QR-Codes/geteilte Links bleiben gueltig). Breadcrumb 3-stufig (Start > Kalender > Titel). QR-/Detail-/OG-Links auf neuen Pfad. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
64 lines
2.2 KiB
Svelte
64 lines
2.2 KiB
Svelte
<script lang="ts">
|
||
/**
|
||
* Datums-Kachel für Kalender-Einträge.
|
||
*
|
||
* - Einzeltermin: Wochentag · großer Tag · Monat
|
||
* - Mehrtägig: Wochentag-Range · Tag-Range · Monat
|
||
* (gleiche Höhe, Box wächst nur in der Breite)
|
||
*
|
||
* Bewusst feste rem-Schriftgrößen + `size-*` (mobil etwas kleiner als
|
||
* Desktop). Keine fluid/calc-Skalierung → kein Overflow, identisch
|
||
* berechenbar auf allen Geräten.
|
||
*/
|
||
let {
|
||
start,
|
||
end = null,
|
||
multiDay = false,
|
||
}: { start: Date; end?: Date | null; multiDay?: boolean } = $props();
|
||
|
||
const isRange = $derived(multiDay && !!end);
|
||
|
||
const weekday = (d: Date) =>
|
||
d.toLocaleDateString("de-DE", { weekday: "short" }).replace(/\.$/, "");
|
||
const month = (d: Date) =>
|
||
d.toLocaleDateString("de-DE", { month: "short" });
|
||
|
||
// YYYY-MM-DD aus lokalen Feldern (kein UTC-Shift) für <time datetime>.
|
||
const isoDate = (d: Date) =>
|
||
`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
||
|
||
const fullDate = (d: Date) =>
|
||
d.toLocaleDateString("de-DE", {
|
||
weekday: "long",
|
||
day: "numeric",
|
||
month: "long",
|
||
year: "numeric",
|
||
});
|
||
|
||
const ariaLabel = $derived(
|
||
isRange && end
|
||
? `${fullDate(start)} bis ${fullDate(end)}`
|
||
: fullDate(start),
|
||
);
|
||
</script>
|
||
|
||
<time
|
||
datetime={isoDate(start)}
|
||
aria-label={ariaLabel}
|
||
class="shrink-0 select-none aspect-square size-18 rounded-sm rounded-br-4xl bg-wald-200 text-wald-500 flex justify-center items-center shadow"
|
||
>
|
||
<div class="text-center font-black leading-normal">
|
||
<div class="text-[10px] uppercase tracking-wider">
|
||
{#if isRange && end}{weekday(start)}–{weekday(end)}{:else}{weekday(
|
||
start,
|
||
)}{/if}
|
||
</div>
|
||
<div class="text-[20px] leading-5">
|
||
{#if isRange && end}{start.getDate()}–{end.getDate()}{:else}{start.getDate()}{/if}
|
||
</div>
|
||
<div class="text-[10px] uppercase tracking-wider">
|
||
{month(start)}
|
||
</div>
|
||
</div>
|
||
</time>
|