mirror of
				https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
				synced 2025-10-29 17:15:31 +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
	 Simon Martens
					Simon Martens