mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-12-16 12:05:30 +00:00
Some serious layout changes
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
<div class="max-w-7xl mx-auto px-8 py-8">
|
||||
<div class="mb-10 2xl:mb-0">
|
||||
<div class="max-w-none mx-auto px-8">
|
||||
<div class="mb-10 2xl:mb-0 sticky top-0 ">
|
||||
{{ template "_header_with_toggle" .model }}
|
||||
</div>
|
||||
|
||||
<!-- Two Column Layout: Scrollspy + Content -->
|
||||
<div class="flex gap-8">
|
||||
{{ template "_scrollspy_layout" .model }}
|
||||
|
||||
<!-- People List - Main Content -->
|
||||
<div class="flex-1 space-y-6 bg-white">
|
||||
<div class="flex-1 space-y-6 bg-white mt-4">
|
||||
{{ range $_, $id := $.model.Sorted }}
|
||||
{{ $a := index $.model.Agents $id }}
|
||||
<div id="author-{{ $id }}" class="p-6 scroll-mt-8 author-section">
|
||||
@@ -17,4 +16,4 @@
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,23 +1,40 @@
|
||||
<div class="max-w-7xl mx-auto px-8 py-8">
|
||||
<div class="mb-10 2xl:mb-0">
|
||||
{{ template "_header_with_toggle" .model }}
|
||||
|
||||
<!-- Alphabet Navigation -->
|
||||
{{ template "_alphabet_nav" .model }}
|
||||
</div>
|
||||
|
||||
<!-- Two Column Layout: Scrollspy + Content -->
|
||||
<div class="max-w-none mx-auto px-8">
|
||||
<!-- Two Column Layout: Header+Scrollspy + Content -->
|
||||
<div class="flex gap-8">
|
||||
<!-- Left Column: Header + Scrollspy -->
|
||||
{{ template "_scrollspy_layout" .model }}
|
||||
|
||||
<!-- Mobile Header (shown on smaller screens) -->
|
||||
<div class="2xl:hidden mb-10 w-full">
|
||||
{{ template "_header_with_toggle" .model }}
|
||||
</div>
|
||||
|
||||
<!-- People List - Main Content -->
|
||||
<div class="flex-1 space-y-6 bg-white">
|
||||
<div class="flex-1 space-y-6 flex flex-col">
|
||||
<!-- Alphabet Navigation -->
|
||||
<div class="mb-6 w-full pt-4">
|
||||
<div class="bg-white px-8 py-4 rounded">
|
||||
<div class="mx-auto flex flex-row flex-wrap gap-x-6 gap-y-3 w-fit items-end leading-none justify-center">
|
||||
{{ range $_, $l := .model.AvailableLetters }}
|
||||
{{ if eq $l (Upper $.model.Search) }}
|
||||
<!-- This is the active letter -->
|
||||
<span class="no-underline leading-none !m-0 !p-0 text-3xl font-bold text-red-600 pointer-events-none" aria-current="true">{{ $l }}</span>
|
||||
{{ else }}
|
||||
<!-- This is an inactive letter -->
|
||||
<a href="/akteure/{{ $l }}" class="no-underline leading-none !m-0 !p-0 text-xl font-medium text-gray-700 hover:text-red-600 transition-colors">{{ $l }}</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<dv class="flex-1 space-y-6 bg-white">
|
||||
{{ range $_, $id := $.model.Sorted }}
|
||||
{{ $a := index $.model.Agents $id }}
|
||||
<div id="author-{{ $id }}" class="p-6 scroll-mt-8 author-section">
|
||||
{{ template "_akteur" $a }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
{{- $sorted := .Sorted -}}
|
||||
|
||||
<div class="hidden 2xl:block w-96 flex-shrink-0">
|
||||
<div class="sticky top-0 max-h-screen bg-white rounded py-4 flex flex-col">
|
||||
<div class="sticky top-0 max-h-screen flex flex-col">
|
||||
<!-- Compact header for 2xl+ screens -->
|
||||
<div class="px-3 pb-4 border-b border-gray-200 mb-4">
|
||||
<div class="px-3 pb-4 border-b border-gray-200 bg-slate-50 rounded-t py-8">
|
||||
{{ if eq .Search "autoren" }}
|
||||
<h2 class="text-2xl font-bold font-serif text-gray-900 mb-1">Autor:innen</h2>
|
||||
<p class="text-base text-gray-600 mb-3">Personen, die Beiträge in der Zeitung verfasst haben</p>
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="flex-1 overflow-y-auto overscroll-contain relative" id="scrollspy-nav">
|
||||
<nav class="flex-1 py-4 overflow-y-auto overscroll-contain relative bg-white rounded-b" id="scrollspy-nav">
|
||||
<!-- Sliding red background element -->
|
||||
<div id="scrollspy-slider" class="absolute bg-red-100 rounded-sm transition-all duration-300 ease-out opacity-0 z-0" style="width: calc(100% - 1.5rem); height: 0; top: 0; left: 0.75rem;"></div>
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
{{- $placeObj := GetPlace $placeRef.Ref -}}
|
||||
{{- if gt (len $placeObj.Names) 0 -}}
|
||||
{{- $placeName := index $placeObj.Names 0 -}}
|
||||
{{- $placeTag = printf "%s <a href=\"/ort/%s\"><span class=\"place-tag inline-block bg-slate-200 text-slate-700 text-xs px-2 py-0.5 rounded-md whitespace-nowrap\">%s</span></a>" $placeTag $placeObj.ID $placeName -}}
|
||||
{{- $placeTag = printf "%s <a href=\"/ort/%s\" class=\"ml-0\"><span class=\"place-tag inline-block bg-slate-200 text-slate-700 text-xs px-2 py-0.5 rounded-md whitespace-nowrap hover:bg-slate-300 hover:text-slate-800 transition-colors duration-150\">%s</span></a>" $placeTag $placeObj.ID $placeName -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -134,7 +134,7 @@
|
||||
{{- /* Author prefix for colon format (place view) */ -}}
|
||||
{{- $colonPrefix := "" -}}
|
||||
{{- if $useColonFormat -}}
|
||||
{{- $colonPrefix = ": " -}}
|
||||
{{- $colonPrefix = ":" -}}
|
||||
{{- else -}}
|
||||
{{- $colonPrefix = " mit " -}}
|
||||
{{- end -}}
|
||||
@@ -561,7 +561,7 @@
|
||||
{{- end -}}
|
||||
{{- if gt (len $authorElements) 0 -}}
|
||||
{{- if $title }}: <em>{{ $title }}</em>{{ end }}{{ if $workTitle }}
|
||||
{{ if $title }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
{{ if and $title (not $categoryFlags.Uebersetzung) }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
<a href="/akteure/{{ $workAuthorID }}" class="author-link text-slate-700 hover:text-slate-900 underline decoration-slate-400 hover:decoration-slate-600">{{ $workAuthorName }}</a>, {{ end }}<em
|
||||
class="work-title"
|
||||
data-short-title="{{ $workTitle }}"
|
||||
@@ -570,7 +570,7 @@
|
||||
{{ end }}
|
||||
{{- else -}}
|
||||
{{- if $title }}<em>{{ $title }}</em>{{ end }}{{ if $workTitle }}
|
||||
{{ if $title }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
{{ if and $title (not $categoryFlags.Uebersetzung) }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
<a href="/akteure/{{ $workAuthorID }}" class="author-link text-slate-700 hover:text-slate-900 underline decoration-slate-400 hover:decoration-slate-600">{{ $workAuthorName }}</a>, {{ end }}<em
|
||||
class="work-title"
|
||||
data-short-title="{{ $workTitle }}"
|
||||
@@ -580,7 +580,7 @@
|
||||
{{- end -}}{{ Safe $placeTag }}
|
||||
{{- else -}}
|
||||
{{ Safe $fortsPrefix }}{{ if $title }}<em>{{ $title }}</em>{{ end }}{{ if $workTitle }}
|
||||
{{ if $title }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
{{ if and $title (not $categoryFlags.Uebersetzung) }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
<a href="/akteure/{{ $workAuthorID }}" class="author-link text-slate-700 hover:text-slate-900 underline decoration-slate-400 hover:decoration-slate-600">{{ $workAuthorName }}</a>, {{ end }}<em
|
||||
class="work-title"
|
||||
data-short-title="{{ $workTitle }}"
|
||||
@@ -590,7 +590,7 @@
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{ Safe $fortsPrefix }}{{ if $title }}<em>{{ $title }}</em>{{ end }}{{ if $workTitle }}
|
||||
{{ if $title }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
{{ if and $title (not $categoryFlags.Uebersetzung) }}, {{ end }}{{ if $categoryFlags.Uebersetzung }}Übersetzung aus:{{ else }}Auszug aus:{{ end }} {{ if $workAuthorName }}
|
||||
<a href="/akteure/{{ $workAuthorID }}" class="author-link text-slate-700 hover:text-slate-900 underline decoration-slate-400 hover:decoration-slate-600">{{ $workAuthorName }}</a>, {{ end }}<em
|
||||
class="work-title"
|
||||
data-short-title="{{ $workTitle }}"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="flex flex-row justify-center gap-4 h-96" id="filter">
|
||||
<div class="p-4 w-full max-w-md flex flex-col h-full">
|
||||
<div class="p-4 w-full max-w-sm flex flex-col h-full">
|
||||
<h3 class="text-lg font-semibold text-slate-800 mb-4 flex items-center gap-2">
|
||||
<i class="ri-calendar-line text-slate-600"></i>
|
||||
Auswahl nach Datum, Nummer od. Seite
|
||||
Nach Datum, Nummer oder Seite
|
||||
</h3>
|
||||
|
||||
<!-- Unified Year Jump Filter -->
|
||||
@@ -54,11 +54,11 @@
|
||||
</year-jump-filter>
|
||||
</div>
|
||||
|
||||
<div class="p-4 w-full max-w-md flex flex-col h-full">
|
||||
<div class="p-4 w-full max-w-sm flex flex-col h-full">
|
||||
<h3 class="text-lg font-semibold text-slate-800 mb-4 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="ri-user-line text-slate-600"></i>
|
||||
Auswahl nach Person
|
||||
Nach Person
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<i class="ri-arrow-right-line"></i>
|
||||
@@ -123,11 +123,11 @@
|
||||
</person-jump-filter>
|
||||
</div>
|
||||
|
||||
<div class="p-4 w-full max-w-md flex flex-col h-full">
|
||||
<div class="p-4 w-full max-w-sm flex flex-col h-full">
|
||||
<h3 class="text-lg font-semibold text-slate-800 mb-4 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="ri-map-pin-line text-slate-600"></i>
|
||||
Auswahl nach Ort
|
||||
Nach Ort
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<i class="ri-arrow-right-line"></i>
|
||||
@@ -169,5 +169,49 @@
|
||||
</div>
|
||||
</place-jump-filter>
|
||||
</div>
|
||||
|
||||
<div class="p-4 w-full max-w-sm flex flex-col h-full">
|
||||
<h3 class="text-lg font-semibold text-slate-800 mb-4 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="ri-price-tag-3-line text-slate-600"></i>
|
||||
Nach Kategorie
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<i class="ri-arrow-right-line"></i>
|
||||
<a href="/kategorie/" class="text-sm text-slate-600 hover:underline">Kategorien</a>
|
||||
</div>
|
||||
</h3>
|
||||
|
||||
<!-- Category Jump Filter -->
|
||||
<category-jump-filter class="flex-1 flex flex-col min-h-0">
|
||||
<div class="space-y-3 flex flex-col h-full">
|
||||
<div class="flex items-center gap-2">
|
||||
<label for="category-search" class="hidden text-sm text-slate-600 w-16">Filter</label>
|
||||
<input
|
||||
type="text"
|
||||
id="category-search"
|
||||
placeholder="Kategorie eingeben..."
|
||||
autocomplete="off"
|
||||
class="flex-1 px-2 py-1 border border-slate-300 rounded text-sm bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 focus:border-blue-400"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-h-0 overflow-y-auto border border-slate-300 rounded bg-white text-sm">
|
||||
<!-- All Categories List -->
|
||||
<div id="all-categories">
|
||||
{{ range $category := .Categories }}
|
||||
<div class="category-item odd:bg-slate-50 even:bg-white">
|
||||
<a href="/kategorie/{{ $category.ID }}" class="block px-2 py-1 hover:bg-blue-50 border-b border-slate-100 last:border-b-0">
|
||||
<span class="category-name font-medium text-slate-800">{{ $category.Name }}</span>
|
||||
<span class="text-xs text-slate-400 ml-2">ab {{ $category.FirstYear }}</span>
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</category-jump-filter>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
101
views/routes/kategorie/list/body.gohtml
Normal file
101
views/routes/kategorie/list/body.gohtml
Normal file
@@ -0,0 +1,101 @@
|
||||
{{- /* Categories list page body */ -}}
|
||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
|
||||
{{- /* Main content */ -}}
|
||||
<div class="lg:col-span-3">
|
||||
{{- /* Categories grid */ -}}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4 mt-6">
|
||||
{{- range $categoryID := .model.Sorted -}}
|
||||
{{- $categoryData := index $.model.Categories $categoryID -}}
|
||||
{{- $category := $categoryData.Category -}}
|
||||
{{- $readable := $categoryData.Readable -}}
|
||||
<div class="bg-white rounded p-4 hover:bg-slate-50 transition-colors duration-200"
|
||||
data-filter-item
|
||||
data-category-name="{{ if $category.Names }}{{ index $category.Names 0 }}{{ else }}{{ $category.ID }}{{ end }}"
|
||||
data-category-description="{{ if $readable.Annotations }}{{ $readable.Annotations | html }}{{ end }}{{ if $readable.Notes }} {{ $readable.Notes | html }}{{ end }}">
|
||||
<div class="mb-3">
|
||||
<h2 class="text-lg font-medium mb-1 text-slate-900">
|
||||
{{ if $category.Names }}{{ index $category.Names 0 }}{{ else }}{{ $category.ID }}{{ end }}
|
||||
</h2>
|
||||
<p class="text-sm text-slate-500">
|
||||
{{ $categoryData.PieceCount }} {{ if eq $categoryData.PieceCount 1 }}Beitrag{{ else }}Beiträge{{ end }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{- /* Show category annotations and notes */ -}}
|
||||
{{- if $readable.AnnotationsHTML -}}
|
||||
<div class="text-sm text-slate-700 mb-2">
|
||||
{{- range $annotation := $readable.AnnotationsHTML -}}
|
||||
{{ $annotation }}
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{- if $readable.NotesHTML -}}
|
||||
<div class="text-sm text-slate-600 italic">
|
||||
{{- range $note := $readable.NotesHTML -}}
|
||||
{{ $note }}
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Available years */ -}}
|
||||
{{- if $categoryData.AvailableYears -}}
|
||||
<div class="mt-3 pt-2 border-t border-slate-100">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{{- range $yearData := $categoryData.AvailableYears -}}
|
||||
<a href="/kategorie/{{ $category.ID }}/{{ $yearData.Year }}"
|
||||
class="inline-block px-2 py-1 text-xs bg-blue-100 text-blue-700 rounded hover:bg-blue-200 hover:text-blue-800 transition-colors duration-150"
|
||||
title="{{ $yearData.PieceCount }} {{ if eq $yearData.PieceCount 1 }}Beitrag{{ else }}Beiträge{{ end }}">
|
||||
{{ $yearData.Year }}
|
||||
</a>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{- /* Sidebar */ -}}
|
||||
<div class="lg:col-span-1 sticky top-0 self-start">
|
||||
<div class="bg-slate-50 p-6 filter-sidebar">
|
||||
<h1 class="text-2xl font-bold text-slate-800 mb-4">Kategorien</h1>
|
||||
|
||||
<p class="text-slate-600 mb-6">
|
||||
Verzeichnis aller Kategorien von Beiträgen in der Königsberger Gelehrten und Politischen Zeitung
|
||||
</p>
|
||||
|
||||
{{- /* Search Filter */ -}}
|
||||
<div class="mb-4">
|
||||
<generic-filter
|
||||
placeholder="Kategorien durchsuchen..."
|
||||
item-selector="[data-filter-item]"
|
||||
search-attributes="data-category-name,data-category-description"
|
||||
count-selector="[data-filter-count]"
|
||||
item-type="Kategorien"
|
||||
item-type-singular="Kategorie">
|
||||
</generic-filter>
|
||||
</div>
|
||||
|
||||
<div class="text-sm text-slate-700 mb-4" data-filter-count>
|
||||
{{ len .model.Categories }} Kategorien
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{- /* Statistics */ -}}
|
||||
<div class="bg-slate-50 border border-slate-200 rounded-lg p-4 mt-4">
|
||||
<div class="text-sm text-slate-700">
|
||||
<p class="mb-2">
|
||||
<span class="font-medium">{{ len .model.Categories }}</span> Kategorien verfügbar
|
||||
</p>
|
||||
{{- $totalPieces := 0 -}}
|
||||
{{- range $categoryData := .model.Categories -}}
|
||||
{{- $totalPieces = add $totalPieces $categoryData.PieceCount -}}
|
||||
{{- end -}}
|
||||
<p>
|
||||
<span class="font-medium">{{ $totalPieces }}</span> Beiträge insgesamt
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
3
views/routes/kategorie/list/head.gohtml
Normal file
3
views/routes/kategorie/list/head.gohtml
Normal file
@@ -0,0 +1,3 @@
|
||||
{{- /* Head template for categories list page */ -}}
|
||||
<title>Kategorien — KGPZ Digital</title>
|
||||
<meta name="description" content="Übersicht aller Kategorien von Beiträgen in der Königsberger Gelehrten und Politischen Zeitung.">
|
||||
153
views/routes/kategorie/pieces/body.gohtml
Normal file
153
views/routes/kategorie/pieces/body.gohtml
Normal file
@@ -0,0 +1,153 @@
|
||||
{{- /* Category pieces page body - matches single place view layout */ -}}
|
||||
<!-- Single Category/Year Detail View -->
|
||||
<div class="max-w-7xl mx-auto px-8 py-8">
|
||||
{{- /* Year Navigation with Back Button - Outside main content box */ -}}
|
||||
{{- if .model.AvailableYears -}}
|
||||
<div class="mb-6 w-full">
|
||||
<div class="bg-white px-8 py-6 rounded">
|
||||
<div class="flex items-center justify-between gap-8">
|
||||
{{- /* Back Navigation */ -}}
|
||||
<div class="flex-shrink-0">
|
||||
<a href="/kategorie/" class="inline-flex items-center hover:text-black text-gray-600 transition-colors text-xl no-underline font-bold">
|
||||
<i class="ri-arrow-left-line mr-1 text-xl font-bold"></i>
|
||||
Kategorien
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{- /* Year Navigation */ -}}
|
||||
<div class="flex flex-row flex-wrap gap-x-6 gap-y-3 items-end leading-none justify-center flex-1">
|
||||
{{- range $yearData := .model.AvailableYears -}}
|
||||
{{- if eq $yearData.Year $.model.Year -}}
|
||||
<!-- This is the active year -->
|
||||
<span class="no-underline leading-none !m-0 !p-0 text-3xl font-bold text-red-600 pointer-events-none" aria-current="true">{{ $yearData.Year }}</span>
|
||||
{{- else -}}
|
||||
<!-- This is an inactive year -->
|
||||
<a href="/kategorie/{{ $.model.Category.ID }}/{{ $yearData.Year }}" class="no-underline leading-none !m-0 !p-0 text-xl font-medium text-gray-700 hover:text-red-600 transition-colors" title="{{ $yearData.PieceCount }} {{ if eq $yearData.PieceCount 1 }}Beitrag{{ else }}Beiträge{{ end }}">{{ $yearData.Year }}</a>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{- else -}}
|
||||
{{- /* Fallback: Just back navigation if no years available */ -}}
|
||||
<div class="mb-6">
|
||||
<div class="bg-white px-8 py-6 rounded">
|
||||
<a href="/kategorie/" class="inline-flex items-center hover:text-black text-gray-600 transition-colors text-xl no-underline font-bold">
|
||||
<i class="ri-arrow-left-line mr-1 text-xl font-bold"></i>
|
||||
Kategorien
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
<div class="bg-white px-6 py-6 rounded w-full lg:min-w-[800px] xl:min-w-[900px]">
|
||||
|
||||
{{- /* Category Header */ -}}
|
||||
<div class="mb-8">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="flex-1">
|
||||
<h1 class="text-3xl font-bold text-slate-800 mb-2">
|
||||
{{ index .model.Category.Names 0 }}
|
||||
</h1>
|
||||
|
||||
{{- /* Category description */ -}}
|
||||
{{- if .model.CategoryReadable.AnnotationsHTML -}}
|
||||
<div class="text-lg text-slate-700 mb-2">
|
||||
{{- range $annotation := .model.CategoryReadable.AnnotationsHTML -}}
|
||||
<div>{{ $annotation }}</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
<p class="text-slate-600">
|
||||
<span class="font-medium">{{ .model.PieceCount }}</span>
|
||||
{{ if eq .model.PieceCount 1 }}Beitrag{{ else }}Beiträge{{ end }}
|
||||
in der Kategorie „{{ index .model.Category.Names 0 }}" aus dem Jahr {{ .model.Year }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{- /* Pieces List */ -}}
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold text-slate-800 mb-4">
|
||||
<i class="ri-newspaper-line mr-2"></i><u class="decoration underline-offset-3">Beiträge</u> ({{ .model.PieceCount }})
|
||||
</h2>
|
||||
|
||||
{{- if .model.Pieces -}}
|
||||
<div class="space-y-6 max-w-[85ch]">
|
||||
<div>
|
||||
<h3 class="text-lg font-bold font-serif text-slate-800 mb-3">{{ .model.Year }}</h3>
|
||||
|
||||
<div class="space-y-1">
|
||||
{{- /* Group pieces by title within the year */ -}}
|
||||
{{- $groupedPieces := dict -}}
|
||||
{{- range $_, $p := .model.Pieces -}}
|
||||
{{- $groupKey := "" -}}
|
||||
{{- if $p.Title -}}
|
||||
{{- $groupKey = index $p.Title 0 -}}
|
||||
{{- else if $p.Incipit -}}
|
||||
{{- $groupKey = index $p.Incipit 0 -}}
|
||||
{{- else -}}
|
||||
{{- $groupKey = printf "untitled-%s" $p.ID -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $existing := index $groupedPieces $groupKey -}}
|
||||
{{- if $existing -}}
|
||||
{{- $groupedPieces = merge $groupedPieces (dict $groupKey (append $existing $p)) -}}
|
||||
{{- else -}}
|
||||
{{- $groupedPieces = merge $groupedPieces (dict $groupKey (slice $p)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range $groupKey, $groupedItems := $groupedPieces -}}
|
||||
<div>
|
||||
<div class="pb-1 text-lg indent-4">
|
||||
{{- /* Use first piece for display text with colon format for places */ -}}
|
||||
{{ template "_unified_piece_entry" (dict "Piece" (index $groupedItems 0) "CurrentActorID" "" "DisplayMode" "place" "ShowPlaceTags" false "UseColonFormat" true "ShowContinuation" false) }}
|
||||
|
||||
{{- /* Show all citations from all pieces in this group inline with commas */ -}}
|
||||
{{ " " }}{{- range $groupIndex, $groupItem := $groupedItems -}}
|
||||
{{- range $issueIndex, $issue := $groupItem.IssueRefs -}}
|
||||
{{- /* Only show citations for the current year */ -}}
|
||||
{{- if eq $issue.When.Year $.model.Year -}}
|
||||
{{- if or (gt $groupIndex 0) (gt $issueIndex 0) }}, {{ end -}}
|
||||
<span class="text-blue-600 hover:text-blue-700 underline decoration-dotted hover:decoration-solid [&>a]:text-blue-600 [&>a:hover]:text-blue-700">{{- template "_citation" $issue -}}</span>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Add "Ganzer Beitrag" link if piece spans multiple issues */ -}}
|
||||
{{- $firstGroupItem := index $groupedItems 0 -}}
|
||||
{{- if gt (len $firstGroupItem.IssueRefs) 1 -}}
|
||||
{{ " " }}<div class="inline-flex items-center gap-1 px-2 py-1 bg-blue-50
|
||||
hover:bg-blue-100 text-blue-700 hover:text-blue-800 border border-blue-200
|
||||
hover:border-blue-300 rounded text-xs font-medium transition-colors duration-200">
|
||||
<i class="ri-file-copy-2-line text-xs"></i>
|
||||
<a href="{{ GetPieceURL $firstGroupItem.ID }}" class="">
|
||||
Ganzer Beitrag
|
||||
</a>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{- else -}}
|
||||
<div class="bg-slate-50 rounded-lg p-8 text-center">
|
||||
<div class="text-slate-500 mb-2">
|
||||
<svg class="w-12 h-12 mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-lg font-medium text-slate-900 mb-2">Keine Beiträge gefunden</h3>
|
||||
<p class="text-slate-600">
|
||||
Für die Kategorie „{{ index .model.Category.Names 0 }}" wurden im Jahr {{ .model.Year }} keine Beiträge gefunden.
|
||||
</p>
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
3
views/routes/kategorie/pieces/head.gohtml
Normal file
3
views/routes/kategorie/pieces/head.gohtml
Normal file
@@ -0,0 +1,3 @@
|
||||
{{- /* Head template for category pieces page */ -}}
|
||||
<title>Kategorie „{{ index .model.Category.Names 0 }}" {{ .model.Year }} — KGPZ Digital</title>
|
||||
<meta name="description" content="Beiträge der Kategorie „{{ index .model.Category.Names 0 | html }}“ aus dem Jahr {{ .model.Year }} in der Königsberger Gelehrten und Politischen Zeitung.">
|
||||
@@ -7,7 +7,7 @@
|
||||
{{ $mainPlaceName = .ID }}
|
||||
{{ end }}
|
||||
{{ $modernName := GetModernPlaceName .Geo $mainPlaceName }}
|
||||
<div class="border border-slate-200 rounded-lg hover:bg-slate-50 transition-colors h-20" data-place-name="{{ $mainPlaceName }}" data-modern-name="{{ $modernName }}">
|
||||
<div class="bg-white rounded hover:bg-slate-50 transition-colors duration-200 h-20" data-place-name="{{ $mainPlaceName }}" data-modern-name="{{ $modernName }}">
|
||||
<a href="/ort/{{ .ID }}" class="block p-4 h-full flex flex-col justify-between">
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="flex-1">
|
||||
|
||||
@@ -1,27 +1,73 @@
|
||||
<!-- Places Overview -->
|
||||
<div class="max-w-7xl mx-auto px-8 py-8">
|
||||
<div class="bg-white px-6 py-6 rounded w-full">
|
||||
<h1 class="text-3xl font-bold text-slate-800 mb-8">Orte</h1>
|
||||
|
||||
<!-- Places List -->
|
||||
{{- /* Places overview page body */ -}}
|
||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
|
||||
{{- /* Main content */ -}}
|
||||
<div class="lg:col-span-3">
|
||||
{{- /* Places grid */ -}}
|
||||
{{ if .model.Places }}
|
||||
<div>
|
||||
<!-- Search Filter -->
|
||||
<places-filter></places-filter>
|
||||
|
||||
<h2 class="text-lg font-semibold text-slate-700 mb-4" data-places-count>
|
||||
Alle Orte ({{ len .model.Places }})
|
||||
</h2>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 lg:min-w-[768px] xl:min-w-[1024px]">
|
||||
{{ range $placeID := .model.Sorted }}
|
||||
{{ $place := index $.model.Places $placeID }}
|
||||
{{ template "_place_card" $place }}
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4 mt-6">
|
||||
{{ range $placeID := .model.Sorted }}
|
||||
{{ $place := index $.model.Places $placeID }}
|
||||
{{ template "_place_card" $place }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<p class="text-slate-500 italic">Keine Orte gefunden.</p>
|
||||
<div class="bg-slate-50 rounded-lg p-8 text-center mt-6">
|
||||
<div class="text-slate-500 mb-2">
|
||||
<svg class="w-12 h-12 mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-lg font-medium text-slate-900 mb-2">Keine Orte gefunden</h3>
|
||||
<p class="text-slate-600">Es wurden keine Orte in der Datenbank gefunden.</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
{{- /* Sidebar */ -}}
|
||||
<div class="lg:col-span-1 sticky top-0 self-start">
|
||||
<div class="bg-slate-50 p-6 filter-sidebar">
|
||||
<h1 class="text-2xl font-bold text-slate-800 mb-4">Orte</h1>
|
||||
|
||||
<p class="text-slate-600 mb-6">
|
||||
Verzeichnis aller in der Zeitung erwähnten Orte und Lokalitäten
|
||||
</p>
|
||||
|
||||
{{- /* Search Filter */ -}}
|
||||
<div class="mb-4">
|
||||
<generic-filter
|
||||
placeholder="Ortsnamen eingeben..."
|
||||
item-selector="[data-place-name]"
|
||||
search-attributes="data-place-name,data-modern-name"
|
||||
count-selector="[data-filter-count]"
|
||||
item-type="Orte"
|
||||
item-type-singular="Ort">
|
||||
</generic-filter>
|
||||
</div>
|
||||
|
||||
<div class="text-sm text-slate-700 mb-4" data-filter-count>
|
||||
Alle Orte ({{ len .model.Places }})
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{- /* Statistics */ -}}
|
||||
<div class="bg-slate-50 border border-slate-200 rounded-lg p-4 mt-4">
|
||||
<div class="text-sm text-slate-700 space-y-2">
|
||||
<div class="flex justify-between">
|
||||
<span>Orte gesamt:</span>
|
||||
<span class="font-medium">{{ len .model.Places }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Beiträge mit Ort:</span>
|
||||
<span class="font-medium">{{ .model.TotalPiecesWithPlaces }}</span>
|
||||
</div>
|
||||
{{- if .model.SelectedPlace -}}
|
||||
<div class="flex justify-between">
|
||||
<span>Beiträge hier:</span>
|
||||
<span class="font-medium">{{ len .model.SelectedPlace.Pieces }}</span>
|
||||
</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user