mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-10-29 17:15:31 +00:00
Page target navigation
This commit is contained in:
@@ -28,10 +28,11 @@
|
||||
{{ end }}</span
|
||||
>
|
||||
<a
|
||||
href="#page-{{ $page }}"
|
||||
class="page-number-inhalts font-bold text-slate-700 bg-slate-100 px-2 py-1 rounded text-sm transition-colors duration-200 hover:bg-slate-200 no-underline"
|
||||
href="/{{ $model.Year }}/{{ $model.Number.No }}/{{ $page }}"
|
||||
class="page-number-inhalts font-bold text-slate-700 bg-slate-100 px-2 py-1 rounded text-sm transition-colors duration-200 hover:bg-slate-200 no-underline relative"
|
||||
data-page-number="{{ $page }}">
|
||||
<span class="page-label">{{ $page }}</span>
|
||||
{{ template "_page_link_indicator" (dict "pageNumber" $page "targetPage" $.targetPage) }}
|
||||
</a>
|
||||
</div>
|
||||
<button
|
||||
@@ -73,21 +74,38 @@
|
||||
{{ end }}">
|
||||
<span class="text-black text-xs font-bold">{{ add $index 1 }}</span>
|
||||
<span class="w-px h-3 bg-slate-300 mx-1"></span>
|
||||
<span class="{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year $model.Datum.When.Year) -}}
|
||||
text-red-700 pointer-events-none
|
||||
{{ end }}"
|
||||
{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year
|
||||
$model.Datum.When.Year)
|
||||
-}}
|
||||
aria-current="page"
|
||||
{{ end }}>
|
||||
<span
|
||||
class="{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year $model.Datum.When.Year) -}}
|
||||
text-red-700 pointer-events-none
|
||||
{{ end }}"
|
||||
{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year
|
||||
$model.Datum.When.Year)
|
||||
-}}
|
||||
aria-current="page"
|
||||
{{ end }}>
|
||||
{{ template "_citation" $issue }}
|
||||
</span>
|
||||
</div>
|
||||
{{ end }}
|
||||
<!-- Link zum gesamten Beitrag anzeigen -->
|
||||
{{ if and (not $individualPiece.PieceByIssue.IsContinuation) (gt (len $individualPiece.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 $individualPiece.PieceByIssue.Reference.When.Year $individualPiece.PieceByIssue.Reference.Nr $individualPiece.PieceByIssue.Reference.Von }}"
|
||||
class="">
|
||||
Alle
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
@@ -191,21 +209,38 @@
|
||||
{{ end }}">
|
||||
<span class="text-black text-xs font-bold">{{ add $index 1 }}</span>
|
||||
<span class="w-px h-3 bg-slate-300 mx-1"></span>
|
||||
<span class="{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year $model.Datum.When.Year) -}}
|
||||
text-red-700 pointer-events-none
|
||||
{{ end }}"
|
||||
{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year
|
||||
$model.Datum.When.Year)
|
||||
-}}
|
||||
aria-current="page"
|
||||
{{ end }}>
|
||||
<span
|
||||
class="{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year $model.Datum.When.Year) -}}
|
||||
text-red-700 pointer-events-none
|
||||
{{ end }}"
|
||||
{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year
|
||||
$model.Datum.When.Year)
|
||||
-}}
|
||||
aria-current="page"
|
||||
{{ end }}>
|
||||
{{ template "_citation" $issue }}
|
||||
</span>
|
||||
</div>
|
||||
{{ end }}
|
||||
<!-- Link zum gesamten Beitrag anzeigen -->
|
||||
{{ if and (not $individualPiece.PieceByIssue.IsContinuation) (gt (len $individualPiece.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 $individualPiece.PieceByIssue.Reference.When.Year $individualPiece.PieceByIssue.Reference.Nr $individualPiece.PieceByIssue.Reference.Von }}"
|
||||
class="">
|
||||
Alle
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<!-- Historical printing layout grid -->
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{{ template "_historical_layout" (dict "pages" $pages "pageCount" $pageCount "isBeilage" false) }}
|
||||
{{ template "_historical_layout" (dict "pages" $pages "pageCount" $pageCount "isBeilage" false "targetPage" $.targetPage) }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<!-- Historical printing layout grid for Beilage -->
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{{ template "_historical_layout" (dict "pages" $beilagePages "pageCount" $pageCount "isBeilage" true) }}
|
||||
{{ template "_historical_layout" (dict "pages" $beilagePages "pageCount" $pageCount "isBeilage" true "targetPage" $.targetPage) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
@@ -56,50 +56,51 @@
|
||||
{{ $pages := .pages }}
|
||||
{{ $pageCount := .pageCount }}
|
||||
{{ $isBeilage := .isBeilage }}
|
||||
{{ $targetPage := .targetPage }}
|
||||
|
||||
{{ if eq $pageCount 2 }}
|
||||
<!-- 2 pages: [1] [2] -->
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ else if eq $pageCount 4 }}
|
||||
<!-- 4 pages: [1] [_] \n [2] [3] \n [_] [4] -->
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 2) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 2) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 3) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 3) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ else if eq $pageCount 6 }}
|
||||
<!-- 6 pages: [1] [_] \n [2] [3] \n [_] [4] \n [5] [6] -->
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 2) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 2) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 3) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 4) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 5) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 3) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 4) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 5) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ else if eq $pageCount 8 }}
|
||||
<!-- 8 pages: [1] [_] \n [2] [3] \n [4] [5] \n [6] [_] \n [_] [7] \n [8] [_] -->
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 0) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 2) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 3) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 4) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 5) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 1) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 2) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 3) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 4) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 5) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 6) "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 7) "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 6) "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_page" (dict "page" (index $pages 7) "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ template "_render_empty" "" }}
|
||||
{{ else }}
|
||||
<!-- Fallback: side by side layout for other page counts -->
|
||||
{{ range $index, $page := $pages }}
|
||||
{{ if eq (mod $index 2) 0 }}
|
||||
{{ template "_render_page" (dict "page" $page "position" "left" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" $page "position" "left" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ else }}
|
||||
{{ template "_render_page" (dict "page" $page "position" "right" "isBeilage" $isBeilage) }}
|
||||
{{ template "_render_page" (dict "page" $page "position" "right" "isBeilage" $isBeilage "targetPage" $targetPage) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@@ -110,21 +111,18 @@
|
||||
{{ $page := .page }}
|
||||
{{ $position := .position }}
|
||||
{{ $isBeilage := .isBeilage }}
|
||||
{{ $targetPage := .targetPage }}
|
||||
{{ $isLeft := eq $position "left" }}
|
||||
{{ $borderColor := "border-slate-200" }}
|
||||
{{ $hoverColor := "hover:border-slate-300" }}
|
||||
{{ $bgColor := "bg-blue-50" }}
|
||||
{{ $idPrefix := "page" }}
|
||||
{{ $linkPrefix := "" }}
|
||||
|
||||
{{ if $isBeilage }}
|
||||
{{ $borderColor = "border-amber-200" }}
|
||||
{{ $hoverColor = "hover:border-amber-300" }}
|
||||
{{ $bgColor = "bg-amber-50" }}
|
||||
{{ $idPrefix = "beilage-1-page" }}
|
||||
{{ $linkPrefix = "#beilage-1-page-" }}
|
||||
{{ else }}
|
||||
{{ $linkPrefix = "#page-" }}
|
||||
{{ end }}
|
||||
|
||||
<div class="newspaper-page-container" id="{{ $idPrefix }}-{{ $page.PageNumber }}" data-page-container="{{ $page.PageNumber }}"{{ if $isBeilage }} data-beilage="true"{{ end }}>
|
||||
@@ -141,15 +139,17 @@
|
||||
<button onclick="enlargePage(document.querySelector('#{{ $idPrefix }}-{{ $page.PageNumber }} .newspaper-page-image'), {{ $page.PageNumber }}, false)" class="w-6 h-6 bg-purple-100 hover:bg-purple-200 text-purple-700 border border-purple-300 rounded flex items-center justify-center transition-colors duration-200 cursor-pointer" title="Seite {{ $page.PageNumber }} vergrößern">
|
||||
<i class="ri-zoom-in-line text-xs"></i>
|
||||
</button>
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 {{ $bgColor }} px-2 py-1 rounded transition-all duration-300 shadow-sm flex items-center gap-1" data-page="{{ $page.PageNumber }}">
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 {{ $bgColor }} px-2 py-1 rounded transition-all duration-300 shadow-sm flex items-center gap-1 relative" data-page="{{ $page.PageNumber }}">
|
||||
{{ $page.PageNumber }}
|
||||
<i class="ri-file-text-line {{ if $isBeilage }}text-amber-600{{ else }}text-black{{ end }} text-sm scale-x-[-1]"></i>
|
||||
{{ template "_page_link_indicator" (dict "pageNumber" $page.PageNumber "targetPage" $targetPage) }}
|
||||
</span>
|
||||
{{ else }}
|
||||
<!-- Right page: page number then buttons -->
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 {{ $bgColor }} px-2 py-1 rounded transition-all duration-300 shadow-sm flex items-center gap-1" data-page="{{ $page.PageNumber }}">
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 {{ $bgColor }} px-2 py-1 rounded transition-all duration-300 shadow-sm flex items-center gap-1 relative" data-page="{{ $page.PageNumber }}">
|
||||
<i class="ri-file-text-line {{ if $isBeilage }}text-amber-600{{ else }}text-black{{ end }} text-sm"></i>
|
||||
{{ $page.PageNumber }}
|
||||
{{ template "_page_link_indicator" (dict "pageNumber" $page.PageNumber "targetPage" $targetPage) }}
|
||||
</span>
|
||||
<button onclick="copyPagePermalink('{{ $page.PageNumber }}', this{{ if $isBeilage }}, true{{ end }})" class="w-6 h-6 bg-blue-100 hover:bg-blue-200 text-blue-700 border border-blue-300 rounded flex items-center justify-center transition-colors duration-200 cursor-pointer" title="Link zu Seite {{ $page.PageNumber }} kopieren">
|
||||
<i class="ri-share-line text-xs"></i>
|
||||
|
||||
@@ -1 +1,32 @@
|
||||
<title>KGPZ – Ausgabe {{ .model.Number.No }} / {{ .model.Year }}</title>
|
||||
|
||||
<script>
|
||||
// Make template data available to JavaScript
|
||||
window.templateData = {
|
||||
targetPage: {{ if .targetPage }}{{ .targetPage }}{{ else }}0{{ end }}
|
||||
};
|
||||
</script>
|
||||
|
||||
{{ if .targetPage }}
|
||||
<script>
|
||||
// Auto-scroll to target page when page loads
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Wait for newspaper layout to be initialized
|
||||
setTimeout(function() {
|
||||
const targetPage = {{ .targetPage }};
|
||||
const pageContainer = document.querySelector('[data-page-container="' + targetPage + '"]');
|
||||
if (pageContainer) {
|
||||
pageContainer.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
|
||||
// Highlight the page in the Inhaltsverzeichnis
|
||||
if (typeof markCurrentPageInInhaltsverzeichnis === 'function') {
|
||||
markCurrentPageInInhaltsverzeichnis(targetPage);
|
||||
}
|
||||
}
|
||||
}, 500); // Give time for layout initialization
|
||||
});
|
||||
</script>
|
||||
{{ end }}
|
||||
|
||||
@@ -14,6 +14,48 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Page Jump Form -->
|
||||
<div class="mt-8 w-full">
|
||||
<div class="mx-auto max-w-md bg-slate-50 p-6 rounded-lg border border-slate-200">
|
||||
<h3 class="text-lg font-semibold text-slate-800 mb-4 text-center">Direkt zu Seite springen</h3>
|
||||
|
||||
<form hx-post="/jump" hx-swap="outerHTML" class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- Year Selection -->
|
||||
<div>
|
||||
<label for="jump-year" class="block text-sm font-medium text-slate-700 mb-1">Jahr</label>
|
||||
<select id="jump-year" name="year" value="{{ $y }}" class="w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
{{ range $year := .model.AvailableYears }}
|
||||
<option value="{{ $year }}" {{ if eq $year $y }}selected{{ end }}>{{ $year }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
<div id="year-error"></div>
|
||||
</div>
|
||||
|
||||
<!-- Page Input -->
|
||||
<div>
|
||||
<label for="jump-page" class="block text-sm font-medium text-slate-700 mb-1">Seite</label>
|
||||
<input type="number" id="jump-page" name="page" min="1" placeholder="z.B. 42" class="w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<div id="page-error"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<div class="text-center">
|
||||
<button type="submit" class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-md shadow-sm transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
|
||||
<i class="ri-arrow-right-line mr-2"></i>
|
||||
Zur Seite springen
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Instructions -->
|
||||
<div class="mt-4 text-sm text-slate-600 text-center">
|
||||
<p>Geben Sie Jahr und Seitenzahl ein, um direkt zur entsprechenden Ausgabe zu springen.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-11 gap-x-2 gap-y-4 pt-8">
|
||||
{{ range $index, $month := .model.Issues }}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{{- if $issue.Beilage -}}
|
||||
#beilage-{{ $issue.Beilage }}-page-{{ $issue.Von }}
|
||||
{{- else -}}
|
||||
#page-{{ $issue.Von }}
|
||||
/{{ $issue.Von }}
|
||||
{{- end -}}
|
||||
{{- end -}}"
|
||||
class="citation-link text-slate-700 no-underline hover:text-slate-900"
|
||||
@@ -45,7 +45,28 @@ function updateCitationLinks() {
|
||||
|
||||
citationLinks.forEach(link => {
|
||||
const citationUrl = link.getAttribute('data-citation-url');
|
||||
let isCurrentPage = false;
|
||||
|
||||
// Check for exact match
|
||||
if (citationUrl === currentPath) {
|
||||
isCurrentPage = true;
|
||||
} else {
|
||||
// Check if current path is an issue with page number that matches this citation
|
||||
const currentPathMatch = currentPath.match(/^\/(\d{4})\/(\d+)(?:\/(\d+))?$/);
|
||||
const citationUrlMatch = citationUrl.match(/^\/(\d{4})\/(\d+)$/);
|
||||
|
||||
if (currentPathMatch && citationUrlMatch) {
|
||||
const [, currentYear, currentIssue, currentPage] = currentPathMatch;
|
||||
const [, citationYear, citationIssue] = citationUrlMatch;
|
||||
|
||||
// If year and issue match, this citation refers to the current issue
|
||||
if (currentYear === citationYear && currentIssue === citationIssue) {
|
||||
isCurrentPage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isCurrentPage) {
|
||||
// Style as current page: red text, no underline, not clickable
|
||||
link.classList.remove('text-slate-700', 'hover:text-slate-900');
|
||||
link.classList.add('text-red-700', 'pointer-events-none');
|
||||
|
||||
33
views/routes/components/_page_jump_form_error.gohtml
Normal file
33
views/routes/components/_page_jump_form_error.gohtml
Normal file
@@ -0,0 +1,33 @@
|
||||
<form hx-post="/jump" hx-swap="outerHTML" class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- Year Selection -->
|
||||
<div>
|
||||
<label for="jump-year" class="block text-sm font-medium text-slate-700 mb-1">Jahr</label>
|
||||
<select id="jump-year" name="year" class="w-full px-3 py-2 border {{ if .YearError }}border-red-300{{ else }}border-slate-300{{ end }} rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
{{ range $year := .AvailableYears }}
|
||||
<option value="{{ $year }}" {{ if eq $year $.CurrentYear }}selected{{ end }}>{{ $year }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
{{ if .YearError }}
|
||||
<div class="text-red-600 text-sm mt-1">{{ .YearError }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<!-- Page Input -->
|
||||
<div>
|
||||
<label for="jump-page" class="block text-sm font-medium text-slate-700 mb-1">Seite</label>
|
||||
<input type="number" id="jump-page" name="page" min="1" placeholder="z.B. 42" value="{{ .PageValue }}" class="w-full px-3 py-2 border {{ if .PageError }}border-red-300{{ else }}border-slate-300{{ end }} rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
{{ if .PageError }}
|
||||
<div class="text-red-600 text-sm mt-1">{{ .PageError }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<div class="text-center">
|
||||
<button type="submit" class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-md shadow-sm transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
|
||||
<i class="ri-arrow-right-line mr-2"></i>
|
||||
Zur Seite springen
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
17
views/routes/components/_page_link_indicator.gohtml
Normal file
17
views/routes/components/_page_link_indicator.gohtml
Normal file
@@ -0,0 +1,17 @@
|
||||
{{- /*
|
||||
Red dot indicator for directly linked pages
|
||||
Usage: {{ template "_page_link_indicator" (dict "pageNumber" $page "targetPage" $targetPage) }}
|
||||
|
||||
Parameters:
|
||||
- pageNumber (int): The page number being displayed
|
||||
- targetPage (int): The target page from URL (0 if none)
|
||||
|
||||
Shows a red dot with tooltip when pageNumber matches targetPage
|
||||
*/ -}}
|
||||
|
||||
{{ $pageNumber := .pageNumber }}
|
||||
{{ $targetPage := .targetPage }}
|
||||
|
||||
{{ if and $targetPage (eq $pageNumber $targetPage) }}
|
||||
<span class="absolute -top-1 -right-1 w-3 h-3 bg-red-500 rounded-full z-10" title="verlinkte Seite"></span>
|
||||
{{ end }}
|
||||
31
views/routes/piece/body.gohtml
Normal file
31
views/routes/piece/body.gohtml
Normal file
@@ -0,0 +1,31 @@
|
||||
{{ $model := .model }}
|
||||
|
||||
{{ if $model.Images.HasImages }}
|
||||
<!-- Container with proper padding -->
|
||||
<div class="">
|
||||
<!-- Two-column layout for piece view -->
|
||||
<div class="flex flex-col lg:flex-row gap-6 w-full min-h-screen">
|
||||
<!-- Column 1: Table of Contents ONLY -->
|
||||
<div class="lg:w-1/3 xl:w-1/4 flex-shrink-0 bg-slate-50 px-8 py-4">
|
||||
<div class="lg:sticky lg:top-8 lg:overflow-y-auto">
|
||||
{{ template "_piece_inhaltsverzeichnis" . }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column 2: Sequential Page Layout -->
|
||||
<div class="lg:w-2/3 xl:w-3/4 flex-1 py-4">
|
||||
{{ template "_piece_sequential_layout" . }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
<!-- No images fallback -->
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-6">
|
||||
<h2 class="text-xl font-semibold text-yellow-800 mb-2">Keine Bilder verfügbar</h2>
|
||||
<p class="text-yellow-700">
|
||||
Für diesen Beitrag sind derzeit keine Seitenbilder verfügbar.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,61 @@
|
||||
{{ $model := .model }}
|
||||
|
||||
<div class="w-full hyphens-auto">
|
||||
<div class="space-y-4">
|
||||
<!-- Header with icon and type (small) -->
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-text-line text-slate-600"></i>
|
||||
<h3 class="text-sm font-medium text-slate-600">Einzelbeitrag</h3>
|
||||
</div>
|
||||
|
||||
<!-- Main piece entry -->
|
||||
<div class="mb-6">
|
||||
<!-- Get the first page to generate the actual content description -->
|
||||
{{ if $model.ContinuousPages.Pages }}
|
||||
{{ $firstPageNum := index $model.ContinuousPages.Pages 0 }}
|
||||
{{ $firstPageEntries := index $model.ContinuousPages.Items $firstPageNum }}
|
||||
{{ if $firstPageEntries }}
|
||||
{{ $firstPiece := index $firstPageEntries 0 }}
|
||||
<!-- Actual piece content description (larger) -->
|
||||
<div class="mb-3">
|
||||
<div class="text-base font-semibold text-slate-800 leading-snug">
|
||||
{{ template "_inhaltsverzeichnis_eintrag" $firstPiece.PieceByIssue }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<!-- Summary with boxed numbers -->
|
||||
<div class="mb-4">
|
||||
<p class="text-sm text-slate-600">
|
||||
<span class="inline-flex items-center gap-1">
|
||||
<span class="bg-slate-800 text-white px-1.5 py-0.5 rounded text-xs font-bold">{{ $model.TotalPageCount }}</span>
|
||||
Seiten in
|
||||
<span class="bg-slate-800 text-white px-1.5 py-0.5 rounded text-xs font-bold">{{ len $model.IssueContexts }}</span>
|
||||
Ausgaben gefunden:
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Issue and page links with highlighting data attributes -->
|
||||
<div class="space-y-1">
|
||||
{{ range $pageEntry := $model.AllPages }}
|
||||
<!-- Find the issue ref for this page to get date -->
|
||||
{{ range $issueRef := $model.AllIssueRefs }}
|
||||
{{ if and (eq $issueRef.When.Year $pageEntry.IssueYear) (eq $issueRef.Nr $pageEntry.IssueNumber) (le $issueRef.Von $pageEntry.PageNumber) (ge $issueRef.Bis $pageEntry.PageNumber) }}
|
||||
<div class="inhalts-entry issue-link-entry pl-4 border-l-4 border-slate-300 hover:bg-slate-100">
|
||||
<a href="/{{ $pageEntry.IssueYear }}/{{ $pageEntry.IssueNumber }}/{{ $pageEntry.PageNumber }}"
|
||||
class="page-number-inhalts text-slate-700 hover:text-red-700 text-sm hover:underline transition-colors duration-200 bg-blue-50 hover:bg-blue-100 relative"
|
||||
data-page-number="{{ $pageEntry.PageNumber }}">
|
||||
{{ if $issueRef.When.Day }}{{ $issueRef.When.Day }}.{{ end }}{{ if $issueRef.When.Month }}{{ $issueRef.When.Month }}.{{ end }}{{ $issueRef.When.Year }} [Nr. {{ $pageEntry.IssueNumber }}], {{ $pageEntry.PageNumber }}
|
||||
{{ template "_page_link_indicator" (dict "pageNumber" $pageEntry.PageNumber "targetPage" $.targetPage) }}
|
||||
</a>
|
||||
</div>
|
||||
{{ break }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,85 @@
|
||||
{{ $model := .model }}
|
||||
|
||||
<!-- Sequential page layout for piece view -->
|
||||
|
||||
<div class="space-y-8 h-full relative" id="piece-content">
|
||||
{{ if $model.Images.AllPages }}
|
||||
<!-- Two-column newspaper layout -->
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{{ range $pageIndex, $page := $model.Images.AllPages }}
|
||||
{{ $pageEntry := index $model.AllPages $pageIndex }}
|
||||
{{ $issueContext := printf "%d Nr. %d" $pageEntry.IssueYear $pageEntry.IssueNumber }}
|
||||
|
||||
<!-- Page container -->
|
||||
<div class="piece-page-container newspaper-page-container" id="piece-page-{{ $page.PageNumber }}" data-page-container="{{ $page.PageNumber }}">
|
||||
<!-- Page indicator row -->
|
||||
<div class="flex justify-start items-center gap-2 mb-3">
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 bg-blue-50 px-2 py-1 rounded transition-all duration-300 flex items-center gap-1 relative" data-page="{{ $page.PageNumber }}">
|
||||
{{ PageIcon "single" }}
|
||||
{{ $issueContext }}, {{ $page.PageNumber }}
|
||||
{{ template "_page_link_indicator" (dict "pageNumber" $page.PageNumber "targetPage" $.targetPage) }}
|
||||
</span>
|
||||
|
||||
<!-- Action buttons -->
|
||||
<button onclick="copyPagePermalink('{{ $page.PageNumber }}', this)"
|
||||
class="w-6 h-6 bg-blue-100 hover:bg-blue-200 text-blue-700 border border-blue-300 rounded flex items-center justify-center transition-colors duration-200 cursor-pointer"
|
||||
title="Link zu Seite {{ $page.PageNumber }} kopieren">
|
||||
<i class="ri-share-line text-xs"></i>
|
||||
</button>
|
||||
|
||||
<button onclick="generatePageCitation('{{ $page.PageNumber }}', this)"
|
||||
class="w-6 h-6 bg-green-100 hover:bg-green-200 text-green-700 border border-green-300 rounded flex items-center justify-center transition-colors duration-200 cursor-pointer"
|
||||
title="Zitation für Seite {{ $page.PageNumber }} generieren">
|
||||
<i class="ri-file-text-line text-xs"></i>
|
||||
</button>
|
||||
|
||||
<button onclick="enlargePage(document.querySelector('#piece-page-{{ $page.PageNumber }} .piece-page-image'), {{ $page.PageNumber }}, false)"
|
||||
class="w-6 h-6 bg-purple-100 hover:bg-purple-200 text-purple-700 border border-purple-300 rounded flex items-center justify-center transition-colors duration-200 cursor-pointer"
|
||||
title="Seite {{ $page.PageNumber }} vergrößern">
|
||||
<i class="ri-zoom-in-line text-xs"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Page image -->
|
||||
<div class="single-page bg-white p-4 rounded border border-slate-200 hover:border-slate-300 transition-colors duration-200">
|
||||
{{ if $page.Available }}
|
||||
<img src="{{ $page.ImagePath }}"
|
||||
alt="Seite {{ $page.PageNumber }} ({{ $issueContext }})"
|
||||
class="piece-page-image newspaper-page-image cursor-zoom-in rounded-sm hover:scale-[1.02] transition-transform duration-200 w-full"
|
||||
onclick="enlargePage(this, {{ $page.PageNumber }}, false)"
|
||||
data-page="{{ $page.PageNumber }}"
|
||||
loading="lazy" />
|
||||
{{ else }}
|
||||
<div class="bg-slate-100 border border-slate-200 rounded p-8 text-center">
|
||||
<i class="ri-image-line text-4xl text-slate-400 mb-2 block"></i>
|
||||
<p class="text-slate-500">Bild nicht verfügbar</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<!-- No pages available -->
|
||||
<div class="text-center text-slate-500 py-16">
|
||||
<i class="ri-file-list-line text-6xl mb-4 block"></i>
|
||||
<h3 class="text-xl font-semibold mb-2">Keine Seiten verfügbar</h3>
|
||||
<p>Für diesen Beitrag sind derzeit keine Seitenbilder verfügbar.</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<!-- Modal for enlarged view - reuse existing modal -->
|
||||
<div
|
||||
id="pageModal"
|
||||
class="absolute inset-0 bg-black bg-opacity-75 hidden z-50 flex items-center justify-center backdrop-blur-sm"
|
||||
onclick="closeModal()">
|
||||
<div class="relative max-w-full max-h-full p-4">
|
||||
<img id="modalImage" src="" alt="" class="max-w-full max-h-full object-contain rounded-lg" />
|
||||
<button
|
||||
onclick="closeModal()"
|
||||
class="absolute top-2 right-2 text-white bg-slate-800 bg-opacity-80 rounded-full w-10 h-10 flex items-center justify-center hover:bg-opacity-100 transition-all duration-200">
|
||||
<i class="ri-close-line text-xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
32
views/routes/piece/head.gohtml
Normal file
32
views/routes/piece/head.gohtml
Normal file
@@ -0,0 +1,32 @@
|
||||
<title>KGPZ – {{ if .model.Title }}{{ .model.Title }}{{ else }}Beitrag{{ end }} ({{ len .model.IssueContexts }} Teil{{ if gt (len .model.IssueContexts) 1 }}e{{ end }})</title>
|
||||
|
||||
<script>
|
||||
// Make template data available to JavaScript
|
||||
window.templateData = {
|
||||
targetPage: {{ if .targetPage }}{{ .targetPage }}{{ else }}0{{ end }}
|
||||
};
|
||||
</script>
|
||||
|
||||
{{ if .targetPage }}
|
||||
<script>
|
||||
// Auto-scroll to target page when page loads
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Wait for newspaper layout to be initialized
|
||||
setTimeout(function() {
|
||||
const targetPage = {{ .targetPage }};
|
||||
const pageContainer = document.querySelector('[data-page-container="' + targetPage + '"]');
|
||||
if (pageContainer) {
|
||||
pageContainer.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
|
||||
// Highlight the page in the Inhaltsverzeichnis if function exists
|
||||
if (typeof markCurrentPageInInhaltsverzeichnis === 'function') {
|
||||
markCurrentPageInInhaltsverzeichnis(targetPage);
|
||||
}
|
||||
}
|
||||
}, 500); // Give time for layout initialization
|
||||
});
|
||||
</script>
|
||||
{{ end }}
|
||||
Reference in New Issue
Block a user