mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-10-30 01:25:30 +00:00
Var fixes
This commit is contained in:
@@ -1,38 +1,84 @@
|
||||
{{ $model := .model }}
|
||||
|
||||
{{ if $model.Images.HasImages }}
|
||||
|
||||
{{ $layout := .Request.URL.Query.Get "layout" }}
|
||||
{{ if eq $layout "fullwidth" }}
|
||||
{{ template "_fullwidth_layout" . }}
|
||||
{{ else }}
|
||||
<!-- Default sidebar layout -->
|
||||
<!-- Container with proper padding -->
|
||||
<div class="px-4 lg:px-6 xl:px-8">
|
||||
<!-- Three-column layout -->
|
||||
<div class="flex flex-col lg:flex-row gap-6 w-full min-h-screen mt-8">
|
||||
<!-- Left side: Sticky Inhaltsverzeichnis -->
|
||||
<div class="lg:w-1/3 xl:w-1/4 flex-shrink-0">
|
||||
<!-- Column 1: Sticky Inhaltsverzeichnis -->
|
||||
<div class="lg:w-1/4 xl:w-1/5 flex-shrink-0">
|
||||
<div class="lg:sticky lg:top-12 lg:max-h-[calc(100vh-2rem)] lg:overflow-y-auto">
|
||||
{{ template "_title_nav" . }}
|
||||
{{ template "_inhaltsverzeichnis" . }}
|
||||
<!-- Switch to fullwidth button -->
|
||||
<div class="mt-4">
|
||||
<a href="?layout=fullwidth" class="flex items-center justify-center px-3 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors text-sm">
|
||||
<i class="ri-fullscreen-line mr-1"></i>
|
||||
Vollbild
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right side: Newspaper pages -->
|
||||
<div class="lg:w-2/3 xl:w-3/4 flex-1">
|
||||
<!-- Column 2: Newspaper pages -->
|
||||
<div class="lg:w-3/5 xl:w-3/5 flex-1">
|
||||
{{ template "_newspaper_layout" . }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<!-- Column 3: Navigation buttons -->
|
||||
<div class="w-16 lg:w-20 xl:w-24 flex-shrink-0">
|
||||
<div class="lg:sticky lg:top-12 lg:max-h-[calc(100vh-2rem)]">
|
||||
<div class="space-y-3 flex flex-col items-center px-2 pt-8">
|
||||
<button
|
||||
id="prevPageBtn"
|
||||
onclick="scrollToPreviousPage()"
|
||||
class="w-14 h-10 lg:w-16 lg:h-12 px-2 py-1 bg-gray-200 hover:bg-gray-300 text-gray-700 hover:text-gray-800 border border-gray-300 transition-colors duration-200 flex items-center justify-center cursor-pointer"
|
||||
title="Vorherige Seite"
|
||||
style="display: none;">
|
||||
<i class="ri-arrow-up-line text-lg lg:text-xl"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="nextPageBtn"
|
||||
onclick="scrollToNextPage()"
|
||||
class="w-14 h-10 lg:w-16 lg:h-12 px-2 py-1 bg-gray-200 hover:bg-gray-300 text-gray-700 hover:text-gray-800 border border-gray-300 transition-colors duration-200 flex items-center justify-center cursor-pointer"
|
||||
title="Nächste Seite">
|
||||
<i class="ri-arrow-down-line text-lg lg:text-xl"></i>
|
||||
</button>
|
||||
|
||||
{{ if $model.AdditionalPieces.Pages }}
|
||||
<button
|
||||
id="beilageBtn"
|
||||
onclick="scrollToBeilage()"
|
||||
class="w-14 h-10 lg:w-16 lg:h-12 px-2 py-1 bg-amber-100 hover:bg-amber-200 text-amber-700 hover:text-amber-800 border border-amber-300 transition-colors duration-200 flex items-center justify-center cursor-pointer"
|
||||
title="Zu Beilage">
|
||||
<i class="ri-attachment-line text-lg lg:text-xl"></i>
|
||||
</button>
|
||||
{{ end }}
|
||||
|
||||
<!-- Separator for utility buttons -->
|
||||
<div class="w-full border-t border-gray-200 my-4"></div>
|
||||
|
||||
<!-- Share Link Button -->
|
||||
<button
|
||||
id="shareLinkBtn"
|
||||
onclick="shareCurrentPage()"
|
||||
class="w-14 h-10 lg:w-16 lg:h-12 px-2 py-1 bg-blue-100 hover:bg-blue-200 text-blue-700 hover:text-blue-800 border border-blue-300 transition-colors duration-200 flex items-center justify-center cursor-pointer"
|
||||
title="Link zur aktuellen Seite teilen">
|
||||
<i class="ri-share-line text-lg lg:text-xl"></i>
|
||||
</button>
|
||||
|
||||
<!-- Citation Button -->
|
||||
<button
|
||||
id="citationBtn"
|
||||
onclick="generateCitation()"
|
||||
class="w-14 h-10 lg:w-16 lg:h-12 px-2 py-1 bg-green-100 hover:bg-green-200 text-green-700 hover:text-green-800 border border-green-300 transition-colors duration-200 flex items-center justify-center cursor-pointer"
|
||||
title="Zitation für diese Seite generieren">
|
||||
<i class="ri-file-text-line text-lg lg:text-xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="max-w-4xl">
|
||||
{{ template "_title_nav" . }}
|
||||
{{ template "_inhaltsverzeichnis" . }}
|
||||
</div>
|
||||
<div class="px-4 lg:px-6 xl:px-8">
|
||||
<div class="max-w-4xl">
|
||||
{{ template "_title_nav" . }}
|
||||
{{ template "_inhaltsverzeichnis" . }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
@@ -64,11 +64,20 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
// Get page number from the container
|
||||
const pageImg = entry.target.querySelector('img[data-page]');
|
||||
if (pageImg) {
|
||||
const pageNumber = pageImg.getAttribute('data-page');
|
||||
markCurrentPageInInhaltsverzeichnis(pageNumber);
|
||||
// Check if this is a double-spread container
|
||||
const doubleSpread = entry.target.querySelector('.double-spread');
|
||||
if (doubleSpread) {
|
||||
// Handle double-spread: highlight both pages
|
||||
const pageImages = entry.target.querySelectorAll('img[data-page]');
|
||||
const pageNumbers = Array.from(pageImages).map(img => img.getAttribute('data-page'));
|
||||
markCurrentPagesInInhaltsverzeichnis(pageNumbers);
|
||||
} else {
|
||||
// Handle single page
|
||||
const pageImg = entry.target.querySelector('img[data-page]');
|
||||
if (pageImg) {
|
||||
const pageNumber = pageImg.getAttribute('data-page');
|
||||
markCurrentPageInInhaltsverzeichnis(pageNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// Update current active index
|
||||
@@ -119,17 +128,52 @@ function scrollToBeilage() {
|
||||
}
|
||||
|
||||
function markCurrentPageInInhaltsverzeichnis(pageNumber) {
|
||||
// Reset all entries in Inhaltsverzeichnis
|
||||
document.querySelectorAll('.inhalts-entry').forEach(entry => {
|
||||
entry.classList.remove('bg-red-100', 'border-red-300');
|
||||
entry.classList.add('bg-slate-50');
|
||||
markCurrentPagesInInhaltsverzeichnis([pageNumber]);
|
||||
}
|
||||
|
||||
function markCurrentPagesInInhaltsverzeichnis(pageNumbers) {
|
||||
// Reset all page numbers in Inhaltsverzeichnis
|
||||
document.querySelectorAll('.page-number-inhalts').forEach(pageNum => {
|
||||
pageNum.classList.remove('bg-red-500', 'text-white');
|
||||
pageNum.classList.add('text-slate-700');
|
||||
// Restore original background colors
|
||||
if (pageNum.classList.contains('bg-amber-50')) {
|
||||
// Keep amber background for Beilage pages
|
||||
} else {
|
||||
pageNum.classList.remove('bg-amber-50');
|
||||
pageNum.classList.add('bg-blue-50');
|
||||
}
|
||||
});
|
||||
|
||||
// Find and highlight the current page entry
|
||||
const pageEntry = document.querySelector(`.inhalts-entry[data-page="${pageNumber}"]`);
|
||||
if (pageEntry) {
|
||||
pageEntry.classList.remove('bg-slate-50');
|
||||
pageEntry.classList.add('bg-red-100', 'border-red-300');
|
||||
// Find and highlight the current page numbers
|
||||
const highlightedElements = [];
|
||||
const highlightedRanges = new Set(); // Track which ranges we've already highlighted
|
||||
|
||||
pageNumbers.forEach(pageNumber => {
|
||||
// Look for all entries that should be highlighted for this page
|
||||
const allPageNumbers = document.querySelectorAll('.page-number-inhalts');
|
||||
|
||||
for (const pageNumElement of allPageNumbers) {
|
||||
const startPage = parseInt(pageNumElement.getAttribute('data-page-number'));
|
||||
const endPage = parseInt(pageNumElement.getAttribute('data-end-page'));
|
||||
const rangeKey = `${startPage}-${endPage}`;
|
||||
|
||||
// Check if this page falls within this range
|
||||
if (pageNumber >= startPage && pageNumber <= endPage) {
|
||||
// Only highlight this range once, even if multiple visible pages fall within it
|
||||
if (!highlightedRanges.has(rangeKey)) {
|
||||
pageNumElement.classList.remove('bg-blue-50', 'bg-amber-50', 'text-slate-700');
|
||||
pageNumElement.classList.add('bg-red-500', 'text-white');
|
||||
highlightedElements.push(pageNumElement);
|
||||
highlightedRanges.add(rangeKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-scroll to first highlighted element if it exists
|
||||
if (highlightedElements.length > 0) {
|
||||
scrollToHighlightedPage(highlightedElements[0]);
|
||||
}
|
||||
|
||||
// Also highlight page indicators
|
||||
@@ -138,10 +182,35 @@ function markCurrentPageInInhaltsverzeichnis(pageNumber) {
|
||||
indicator.classList.add('bg-blue-50', 'text-slate-600');
|
||||
});
|
||||
|
||||
const pageIndicator = document.querySelector(`.page-indicator[data-page="${pageNumber}"]`);
|
||||
if (pageIndicator) {
|
||||
pageIndicator.classList.remove('bg-blue-50', 'bg-green-50', 'text-slate-600');
|
||||
pageIndicator.classList.add('bg-red-500', 'text-white');
|
||||
// Highlight page indicators for all current pages
|
||||
pageNumbers.forEach(pageNumber => {
|
||||
const pageIndicator = document.querySelector(`.page-indicator[data-page="${pageNumber}"]`);
|
||||
if (pageIndicator) {
|
||||
pageIndicator.classList.remove('bg-blue-50', 'bg-green-50', 'bg-amber-50', 'text-slate-600');
|
||||
pageIndicator.classList.add('bg-red-500', 'text-white');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function scrollToHighlightedPage(element) {
|
||||
// Check if the element is in a scrollable container
|
||||
const inhaltsContainer = element.closest('.lg\\:overflow-y-auto');
|
||||
if (inhaltsContainer) {
|
||||
// Calculate position
|
||||
const containerRect = inhaltsContainer.getBoundingClientRect();
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
|
||||
// Check if element is not fully visible
|
||||
const isAboveContainer = elementRect.top < containerRect.top;
|
||||
const isBelowContainer = elementRect.bottom > containerRect.bottom;
|
||||
|
||||
if (isAboveContainer || isBelowContainer) {
|
||||
// Scroll to make element visible with some padding
|
||||
element.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,4 +230,117 @@ document.addEventListener('keydown', function(e) {
|
||||
scrollToNextPage();
|
||||
}
|
||||
});
|
||||
|
||||
function shareCurrentPage() {
|
||||
const button = document.getElementById('shareLinkBtn');
|
||||
|
||||
// Get current page information
|
||||
let pageInfo = '';
|
||||
|
||||
// Try to get the currently visible page number from active containers
|
||||
if (window.currentActiveIndex !== undefined && window.currentPageContainers && window.currentPageContainers[window.currentActiveIndex]) {
|
||||
const activeContainer = window.currentPageContainers[window.currentActiveIndex];
|
||||
const pageElement = activeContainer.querySelector('[data-page]');
|
||||
if (pageElement) {
|
||||
const pageNumber = pageElement.getAttribute('data-page');
|
||||
pageInfo = `#page-${pageNumber}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the shareable URL
|
||||
const currentUrl = window.location.origin + window.location.pathname + pageInfo;
|
||||
|
||||
// Try to use Web Share API if available (mobile browsers)
|
||||
if (navigator.share) {
|
||||
navigator.share({
|
||||
title: document.title,
|
||||
url: currentUrl
|
||||
}).catch(err => {
|
||||
console.log('Error sharing:', err);
|
||||
// Fallback to clipboard
|
||||
copyToClipboard(currentUrl, button);
|
||||
});
|
||||
} else {
|
||||
// Fallback: copy to clipboard
|
||||
copyToClipboard(currentUrl, button);
|
||||
}
|
||||
}
|
||||
|
||||
function copyToClipboard(text, button) {
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
// Show temporary notification
|
||||
showNotification('Link kopiert!', 'success', button);
|
||||
}).catch(err => {
|
||||
console.error('Failed to copy:', err);
|
||||
showNotification('Kopieren fehlgeschlagen', 'error', button);
|
||||
});
|
||||
} else {
|
||||
// Fallback for older browsers
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
showNotification('Link kopiert!', 'success', button);
|
||||
} catch (err) {
|
||||
console.error('Fallback copy failed:', err);
|
||||
showNotification('Kopieren fehlgeschlagen', 'error', button);
|
||||
}
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
}
|
||||
|
||||
function generateCitation() {
|
||||
const button = document.getElementById('citationBtn');
|
||||
|
||||
// Get current page and issue information
|
||||
const issueInfo = document.title || 'KGPZ';
|
||||
const currentUrl = window.location.href;
|
||||
|
||||
// Basic citation format (can be expanded later)
|
||||
const currentDate = new Date().toLocaleDateString('de-DE');
|
||||
const citation = `Königsberger Gelehrte und Politische Zeitung (KGPZ). ${issueInfo}. Digital verfügbar unter: ${currentUrl} (Zugriff: ${currentDate}).`;
|
||||
|
||||
// Copy citation to clipboard
|
||||
copyToClipboard(citation, button);
|
||||
}
|
||||
|
||||
function showNotification(message, type = 'success', button) {
|
||||
// Remove any existing notifications
|
||||
const existingNotification = document.getElementById('notification');
|
||||
if (existingNotification) {
|
||||
existingNotification.remove();
|
||||
}
|
||||
|
||||
// Create notification element
|
||||
const notification = document.createElement('div');
|
||||
notification.id = 'notification';
|
||||
notification.className = `fixed px-3 py-2 rounded-md text-white text-sm font-medium z-50 transition-opacity duration-300 ${
|
||||
type === 'success' ? 'bg-green-500' : 'bg-red-500'
|
||||
}`;
|
||||
notification.textContent = message;
|
||||
|
||||
// Position notification next to button if button is provided
|
||||
if (button) {
|
||||
const buttonRect = button.getBoundingClientRect();
|
||||
notification.style.left = `${buttonRect.left - 80}px`; // Position to the left of button
|
||||
notification.style.top = `${buttonRect.top + buttonRect.height / 2 - 20}px`; // Center vertically with button
|
||||
} else {
|
||||
// Fallback to top-right corner
|
||||
notification.className += ' top-4 right-4';
|
||||
}
|
||||
|
||||
// Add to page
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Auto-remove after 3 seconds
|
||||
setTimeout(() => {
|
||||
notification.style.opacity = '0';
|
||||
setTimeout(() => {
|
||||
notification.remove();
|
||||
}, 300);
|
||||
}, 3000);
|
||||
}
|
||||
</script>
|
||||
@@ -12,25 +12,28 @@
|
||||
<div class="mb-4 first:mb-0">
|
||||
<div class="flex items-center gap-2 mb-3 pb-2 border-b border-slate-200">
|
||||
<i class="ri-file-text-line text-blue-600 text-sm"></i>
|
||||
<span class="font-medium text-slate-700 bg-blue-50 px-2 py-1 rounded text-xs">{{ $page }}</span>
|
||||
{{ $pageItems := (index $model.Pieces.Items $page) }}
|
||||
{{ $maxEndPage := $page }}
|
||||
{{ range $groupedPiece := $pageItems }}{{ if gt $groupedPiece.EndPage $maxEndPage }}{{ $maxEndPage = $groupedPiece.EndPage }}{{ end }}{{ end }}
|
||||
<span class="page-number-inhalts font-bold text-slate-700 bg-blue-50 px-2 py-1 rounded text-xs transition-colors duration-200" data-page-number="{{ $page }}" data-end-page="{{ $maxEndPage }}" data-page-range="{{ $page }}-{{ $maxEndPage }}">{{ if ne $page $maxEndPage }}{{ $page }}-{{ $maxEndPage }}{{ else }}{{ $page }}{{ end }}</span>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
{{ range $piece := (index $model.Pieces.Items $page) }}
|
||||
<div class="inhalts-entry py-2 px-3 bg-slate-50 rounded hover:bg-slate-100 transition-colors duration-200" data-page="{{ $page }}">
|
||||
{{ template "_inhaltsverzeichnis_eintrag" $piece }}
|
||||
<div class="space-y-1">
|
||||
{{ range $groupedPiece := (index $model.Pieces.Items $page) }}
|
||||
<div class="inhalts-entry py-1 px-3 bg-slate-50 rounded hover:bg-slate-100 transition-colors duration-200" data-page="{{ $page }}">
|
||||
{{ template "_inhaltsverzeichnis_eintrag" $groupedPiece.PieceByIssue }}
|
||||
|
||||
|
||||
<!-- Links zu anderen Teilen: -->
|
||||
{{ if gt (len $piece.IssueRefs) 1 }}
|
||||
<div class="mt-3 pt-3 border-t border-slate-100">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
{{ if and (not $groupedPiece.PieceByIssue.IsContinuation) (gt (len $groupedPiece.IssueRefs) 1) }}
|
||||
<div class="mt-1 pt-1 border-t border-slate-100">
|
||||
<div class="flex items-center gap-2 mb-0.5">
|
||||
<i class="ri-links-line text-blue-500 text-sm"></i>
|
||||
<span class="text-sm font-medium text-slate-600">{{ len $piece.IssueRefs }} Teile:</span>
|
||||
<span class="text-sm font-medium text-slate-600">{{ len $groupedPiece.IssueRefs }} Teile:</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{{ range $issue := $piece.IssueRefs }}
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{{ range $issue := $groupedPiece.IssueRefs }}
|
||||
<a
|
||||
href="/{{- $issue.When -}}/{{- $issue.Nr -}}"
|
||||
href="/{{- $issue.When -}}/{{- $issue.Nr -}}{{- if $issue.Von -}}{{- if $issue.Beilage -}}#beilage-{{ $issue.Beilage }}-page-{{ $issue.Von }}{{- else -}}#page-{{ $issue.Von }}{{- end -}}{{- end -}}"
|
||||
class="inline-flex items-center gap-1 px-2 py-1 bg-blue-50 text-blue-700 rounded-md text-xs font-medium hover:bg-blue-100 transition-colors duration-150"
|
||||
{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year
|
||||
$model.Datum.When.Year)
|
||||
@@ -67,25 +70,28 @@
|
||||
<div class="mb-4 first:mb-0">
|
||||
<div class="flex items-center gap-2 mb-3 pb-2 border-b border-slate-200">
|
||||
<i class="ri-file-text-line text-amber-600 text-sm"></i>
|
||||
<span class="font-medium text-slate-700 bg-amber-50 px-2 py-1 rounded text-xs">{{ $page }}</span>
|
||||
{{ $pageItems := (index $model.AdditionalPieces.Items $page) }}
|
||||
{{ $maxEndPage := $page }}
|
||||
{{ range $groupedPiece := $pageItems }}{{ if gt $groupedPiece.EndPage $maxEndPage }}{{ $maxEndPage = $groupedPiece.EndPage }}{{ end }}{{ end }}
|
||||
<span class="page-number-inhalts font-bold text-slate-700 bg-amber-50 px-2 py-1 rounded text-xs transition-colors duration-200" data-page-number="{{ $page }}" data-end-page="{{ $maxEndPage }}" data-page-range="{{ $page }}-{{ $maxEndPage }}">{{ if ne $page $maxEndPage }}{{ $page }}-{{ $maxEndPage }}{{ else }}{{ $page }}{{ end }}</span>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
{{ range $piece := (index $model.AdditionalPieces.Items $page) }}
|
||||
{{ range $groupedPiece := (index $model.AdditionalPieces.Items $page) }}
|
||||
<div class="inhalts-entry py-2 px-3 bg-slate-50 rounded hover:bg-slate-100 transition-colors duration-200" data-page="{{ $page }}">
|
||||
{{ template "_inhaltsverzeichnis_eintrag" $piece }}
|
||||
{{ template "_inhaltsverzeichnis_eintrag" $groupedPiece.PieceByIssue }}
|
||||
|
||||
|
||||
<!-- Links zu anderen Teilen: -->
|
||||
{{ if gt (len $piece.IssueRefs) 1 }}
|
||||
<div class="mt-3 pt-3 border-t border-slate-100">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
{{ if and (not $groupedPiece.PieceByIssue.IsContinuation) (gt (len $groupedPiece.IssueRefs) 1) }}
|
||||
<div class="mt-1 pt-1 border-t border-slate-100">
|
||||
<div class="flex items-center gap-2 mb-0.5">
|
||||
<i class="ri-links-line text-blue-500 text-sm"></i>
|
||||
<span class="text-sm font-medium text-slate-600">{{ len $piece.IssueRefs }} Teile:</span>
|
||||
<span class="text-sm font-medium text-slate-600">{{ len $groupedPiece.IssueRefs }} Teile:</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{{ range $issue := $piece.IssueRefs }}
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{{ range $issue := $groupedPiece.IssueRefs }}
|
||||
<a
|
||||
href="/{{- $issue.When -}}/{{- $issue.Nr -}}"
|
||||
href="/{{- $issue.When -}}/{{- $issue.Nr -}}{{- if $issue.Von -}}{{- if $issue.Beilage -}}#beilage-{{ $issue.Beilage }}-page-{{ $issue.Von }}{{- else -}}#page-{{ $issue.Von }}{{- end -}}{{- end -}}"
|
||||
class="inline-flex items-center gap-1 px-2 py-1 bg-blue-50 text-blue-700 rounded-md text-xs font-medium hover:bg-blue-100 transition-colors duration-150"
|
||||
{{- if and (eq $issue.Nr $model.Number.No) (eq $issue.When.Year
|
||||
$model.Datum.When.Year)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{{- $piece := . -}}
|
||||
{{- $fortsPrefix := "" -}}
|
||||
{{- if $piece.IsContinuation -}}{{- $fortsPrefix = "<span class=\"italic text-gray-600\">(Forts.) </span>" -}}{{- end -}}
|
||||
|
||||
<div class="entry-description leading-relaxed mb-2">
|
||||
<div class="entry-description leading-snug mb-1">
|
||||
{{- $hasRezension := false -}}
|
||||
{{- $hasWeltnachrichten := false -}}
|
||||
{{- $hasEinkommendeFremde := false -}}
|
||||
@@ -131,18 +133,18 @@
|
||||
{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}
|
||||
{{- $agent := GetAgent $agentref.Ref -}}
|
||||
{{- if gt (len $agent.Names) 0 -}}
|
||||
<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>{{ if $workTitle }}, Rezension: <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }}, Rezension: <em>{{ $title }}</em>{{ else }}, Rezension{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{ Safe $fortsPrefix }}<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>{{ if $workTitle }}, Rezension: <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }}, Rezension: <em>{{ $title }}</em>{{ else }}, Rezension{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{- $authorFound = true -}}
|
||||
{{- break -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if not $authorFound -}}
|
||||
Rezension{{ if $workTitle }}: <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }}: <em>{{ $title }}</em>{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{ Safe $fortsPrefix }}Rezension{{ if $workTitle }}: <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }}: <em>{{ $title }}</em>{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- else if $hasWeltnachrichten -}}
|
||||
Politische Nachrichten aus aller Welt
|
||||
{{ Safe $fortsPrefix }}Politische Nachrichten aus aller Welt
|
||||
|
||||
{{- else if $hasEinkommendeFremde -}}
|
||||
{{- if $hasLokalnachrichten -}}Lokale Meldungen über einreisende Fremde{{- else if $hasNachruf -}}Nachruf und Einreiseliste{{- else -}}Einreiseliste{{- end -}}{{ if $place }} für {{ $place }}{{ end }}
|
||||
@@ -151,10 +153,10 @@
|
||||
Wechselkurse{{ if $place }} in {{ $place }}{{ end }}
|
||||
|
||||
{{- else if $hasBuecher -}}
|
||||
Bücheranzeigen{{ if $title }}: {{ $title }}{{ end }}
|
||||
Bücheranzeigen{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasLokalanzeigen -}}
|
||||
{{ if $hasNachruf }}Todesanzeige{{ else }}Lokalanzeige{{ end }}{{ if $place }} aus {{ $place }}{{ end }}{{ if $title }}: {{ $title }}{{ end }}
|
||||
{{ if $hasNachruf }}Todesanzeige{{ else }}Lokalanzeige{{ end }}{{ if $place }} aus {{ $place }}{{ end }}{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasLokalnachrichten -}}
|
||||
{{ if $hasLotterie }}Lotterienachrichten{{ else if $hasNachruf }}Nachrufe{{ else if $hasTheaterkritik }}Theaternachrichten{{ else if $hasPanegyrik }}Festlichkeiten{{ else }}Lokalnachrichten{{ end }}{{ if $place }} aus {{ $place }}{{ end }}
|
||||
@@ -165,18 +167,18 @@
|
||||
{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}
|
||||
{{- $agent := GetAgent $agentref.Ref -}}
|
||||
{{- if gt (len $agent.Names) 0 -}}
|
||||
<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, {{ if $hasKommentar }}Gedicht mit Kommentar{{ else if $hasUebersetzung }}Gedichtübersetzung{{ else if $hasGelehrteNachrichten }}Gedicht zu gelehrten Angelegenheiten{{ else }}Gedicht{{ end }}{{ if $title }}: „{{ $title }}"{{ end }}
|
||||
<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, {{ if $hasKommentar }}Gedicht mit Kommentar{{ else if $hasUebersetzung }}Gedichtübersetzung{{ else if $hasGelehrteNachrichten }}Gedicht zu gelehrten Angelegenheiten{{ else }}Gedicht{{ end }}{{ if $title }}: <em>„{{ $title }}"</em>{{ end }}
|
||||
{{- $authorFound = true -}}
|
||||
{{- break -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if not $authorFound -}}
|
||||
{{ if $hasKommentar }}Gedicht mit Kommentar{{ else if $hasUebersetzung }}Gedichtübersetzung{{ else if $hasGelehrteNachrichten }}Gedicht zu gelehrten Angelegenheiten{{ else }}Gedicht{{ end }}{{ if $title }}: „{{ $title }}"{{ end }}
|
||||
{{ if $hasKommentar }}Gedicht mit Kommentar{{ else if $hasUebersetzung }}Gedichtübersetzung{{ else if $hasGelehrteNachrichten }}Gedicht zu gelehrten Angelegenheiten{{ else }}Gedicht{{ end }}{{ if $title }}: <em>„{{ $title }}"</em>{{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- else if $hasVorladung -}}
|
||||
Gerichtliche Vorladung{{ if $place }} in {{ $place }}{{ end }}{{ if $title }}: {{ $title }}{{ end }}
|
||||
Gerichtliche Vorladung{{ if $place }} in {{ $place }}{{ end }}{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasAufsatz -}}
|
||||
{{- $authorFound := false -}}
|
||||
@@ -184,18 +186,18 @@
|
||||
{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}
|
||||
{{- $agent := GetAgent $agentref.Ref -}}
|
||||
{{- if gt (len $agent.Names) 0 -}}
|
||||
<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, {{ if $hasReplik }}Erwiderung{{ else if $hasUebersetzung }}Übersetzung{{ else if $hasNachruf }}Nachruf{{ else if $hasKommentar }}Kommentar{{ else if $hasRezepte }}Rezepte und Anleitungen{{ else }}Aufsatz{{ end }}{{ if $title }}: „{{ $title }}"{{ end }}
|
||||
{{ Safe $fortsPrefix }}<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, {{ if $hasReplik }}Erwiderung{{ else if $hasUebersetzung }}Übersetzung{{ else if $hasNachruf }}Nachruf{{ else if $hasKommentar }}Kommentar{{ else if $hasRezepte }}Rezepte und Anleitungen{{ else }}Aufsatz{{ end }}{{ if $title }}: <em>„{{ $title }}"</em>{{ end }}
|
||||
{{- $authorFound = true -}}
|
||||
{{- break -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if not $authorFound -}}
|
||||
{{ if $hasReplik }}Erwiderung{{ else if $hasUebersetzung }}Übersetzung{{ else if $hasNachruf }}Nachruf{{ else if $hasKommentar }}Kommentar{{ else if $hasRezepte }}Rezepte und Anleitungen{{ else }}Aufsatz{{ end }}{{ if $title }}: „{{ $title }}"{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasReplik }}Erwiderung{{ else if $hasUebersetzung }}Übersetzung{{ else if $hasNachruf }}Nachruf{{ else if $hasKommentar }}Kommentar{{ else if $hasRezepte }}Rezepte und Anleitungen{{ else }}Aufsatz{{ end }}{{ if $title }}: <em>„{{ $title }}"</em>{{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- else if $hasGelehrteNachrichten -}}
|
||||
{{ if $hasTheaterkritik }}Theaterkritik{{ else if $hasKommentar }}Gelehrter Kommentar{{ else }}Gelehrte Nachrichten{{ end }}{{ if $place }} aus {{ $place }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasTheaterkritik }}Theaterkritik{{ else if $hasKommentar }}Gelehrter Kommentar{{ else }}Gelehrte Nachrichten{{ end }}{{ if $place }} aus {{ $place }}{{ end }}
|
||||
|
||||
{{- else if $hasTheaterkritik -}}
|
||||
{{- $authorFound := false -}}
|
||||
@@ -203,33 +205,33 @@
|
||||
{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}
|
||||
{{- $agent := GetAgent $agentref.Ref -}}
|
||||
{{- if gt (len $agent.Names) 0 -}}
|
||||
<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, Theaterkritik{{ if $workTitle }} zu <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }} zu <em>{{ $title }}</em>{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{ Safe $fortsPrefix }}<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, Theaterkritik{{ if $workTitle }} zu <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }} zu <em>{{ $title }}</em>{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{- $authorFound = true -}}
|
||||
{{- break -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if not $authorFound -}}
|
||||
Theaterkritik{{ if $workTitle }} zu <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }} zu <em>{{ $title }}</em>{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{ Safe $fortsPrefix }}Theaterkritik{{ if $workTitle }} zu <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if $title }} zu <em>{{ $title }}</em>{{ end }}{{ if $place }} ({{ $place }}){{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- else if $hasProklamation -}}
|
||||
Amtliche Proklamation{{ if $title }}: {{ $title }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}Amtliche Proklamation{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasIneigenersache -}}
|
||||
{{ if $hasKommentar }}{{ if $hasNachtrag }}Ergänzender Kommentar{{ else }}Redaktioneller Kommentar{{ end }}{{ else if $hasReplik }}Redaktionelle Stellungnahme{{ else }}Anmerkung der Redaktion{{ end }}{{ if $title }}: {{ $title }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasKommentar }}{{ if $hasNachtrag }}Ergänzender Kommentar{{ else }}Redaktioneller Kommentar{{ end }}{{ else if $hasReplik }}Redaktionelle Stellungnahme{{ else }}Anmerkung der Redaktion{{ end }}{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasBrief -}}
|
||||
{{ if $hasNachruf }}Kondolenzbrief{{ else }}Leserbrief{{ end }}{{- $authorFound := false -}}{{- range $agentref := $piece.AgentRefs -}}{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}{{- $agent := GetAgent $agentref.Ref -}}{{- if gt (len $agent.Names) 0 -}} von <a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>{{- $authorFound = true -}}{{- break -}}{{- end -}}{{- end -}}{{- end -}}{{ if $place }} aus {{ $place }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasNachruf }}Kondolenzbrief{{ else }}Leserbrief{{ end }}{{- $authorFound := false -}}{{- range $agentref := $piece.AgentRefs -}}{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}{{- $agent := GetAgent $agentref.Ref -}}{{- if gt (len $agent.Names) 0 -}} von <a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>{{- $authorFound = true -}}{{- break -}}{{- end -}}{{- end -}}{{- end -}}{{ if $place }} aus {{ $place }}{{ end }}
|
||||
|
||||
{{- else if $hasDesertionsliste -}}
|
||||
Desertionsliste{{ if $place }} für {{ $place }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}Desertionsliste{{ if $place }} für {{ $place }}{{ end }}
|
||||
|
||||
{{- else if $hasNotenblatt -}}
|
||||
{{ if $hasNachtrag }}Ergänztes {{ end }}Notenblatt{{ if $title }}: {{ $title }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasNachtrag }}Ergänztes {{ end }}Notenblatt{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasVorlesungsverzeichnis -}}
|
||||
Vorlesungsverzeichnis{{ if $place }} der Universität {{ $place }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}Vorlesungsverzeichnis{{ if $place }} der Universität {{ $place }}{{ end }}
|
||||
|
||||
{{- else if $hasErzaehlung -}}
|
||||
{{- $authorFound := false -}}
|
||||
@@ -237,30 +239,30 @@
|
||||
{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}
|
||||
{{- $agent := GetAgent $agentref.Ref -}}
|
||||
{{- if gt (len $agent.Names) 0 -}}
|
||||
<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, {{ if $hasUebersetzung }}Übersetzung einer Erzählung{{ else }}Erzählung{{ end }}{{ if $title }}: „{{ $title }}"{{ end }}
|
||||
{{ Safe $fortsPrefix }}<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>, {{ if $hasUebersetzung }}Übersetzung einer Erzählung{{ else }}Erzählung{{ end }}{{ if $title }}: <em>„{{ $title }}"</em>{{ end }}
|
||||
{{- $authorFound = true -}}
|
||||
{{- break -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if not $authorFound -}}
|
||||
{{ if $hasUebersetzung }}Übersetzung einer Erzählung{{ else }}Erzählung{{ end }}{{ if $title }}: „{{ $title }}"{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasUebersetzung }}Übersetzung einer Erzählung{{ else }}Erzählung{{ end }}{{ if $title }}: <em>„{{ $title }}"</em>{{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- else if $hasAbbildung -}}
|
||||
{{ if $hasAufsatz }}Illustrierter Aufsatz{{ else }}Abbildung{{ end }}{{ if $title }}: {{ $title }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasAufsatz }}Illustrierter Aufsatz{{ else }}Abbildung{{ end }}{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasKriminalanzeige -}}
|
||||
Kriminalanzeige{{ if $place }} aus {{ $place }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}Kriminalanzeige{{ if $place }} aus {{ $place }}{{ end }}
|
||||
|
||||
{{- else if $hasKorrektur -}}
|
||||
Korrektur{{ if $title }}: {{ $title }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}Korrektur{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasAnzeige -}}
|
||||
{{ if $hasAuszug }}{{ if $hasGedicht }}Gedichtauszug{{ else }}Textauszug{{ end }}{{ else }}Anzeige{{ end }}{{ if $title }}: {{ $title }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $hasAuszug }}{{ if $hasGedicht }}Gedichtauszug{{ else }}Textauszug{{ end }}{{ else }}Anzeige{{ end }}{{ if $title }}: <em>{{ $title }}</em>{{ end }}
|
||||
|
||||
{{- else if $hasAuszug -}}
|
||||
Auszug{{ if $title }}: „{{ $title }}"{{ end }}{{ if $workTitle }} aus <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}Auszug{{ if $title }}: <em>„{{ $title }}"</em>{{ end }}{{ if $workTitle }} aus <em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ end }}
|
||||
|
||||
{{- else -}}
|
||||
{{- $authorFound := false -}}
|
||||
@@ -268,21 +270,23 @@
|
||||
{{- if (or (eq $agentref.Category "") (eq $agentref.Category "autor")) -}}
|
||||
{{- $agent := GetAgent $agentref.Ref -}}
|
||||
{{- if gt (len $agent.Names) 0 -}}
|
||||
<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>{{ if $title }}: {{ $title }}{{ end }}{{ if $workTitle }}{{ if $title }} aus {{ end }}<em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ end }}
|
||||
{{ Safe $fortsPrefix }}<a href="/akteure/{{ $agentref.Ref }}" class="author-link">{{ index $agent.Names 0 }}</a>{{ if $title }}: <em>{{ $title }}</em>{{ end }}{{ if $workTitle }}{{ if $title }} aus {{ end }}<em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ end }}
|
||||
{{- $authorFound = true -}}
|
||||
{{- break -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if not $authorFound -}}
|
||||
{{ if $title }}{{ $title }}{{ end }}{{ if $workTitle }}{{ if $title }} aus {{ end }}<em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if not $title }}Beitrag ohne Titel{{ end }}
|
||||
{{ Safe $fortsPrefix }}{{ if $title }}<em>{{ $title }}</em>{{ end }}{{ if $workTitle }}{{ if $title }} aus {{ end }}<em>{{ $workTitle }}</em>{{ if $workAuthorName }} von <a href="/akteure/{{ $workAuthorID }}" class="author-link">{{ $workAuthorName }}</a>{{ end }}{{ else if not $title }}Beitrag ohne Titel{{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
{{- if not $piece.IsContinuation -}}
|
||||
{{- range $annotation := $piece.AnnotationNote.Annotations -}}
|
||||
<div class="italic text-xs mt-1 text-slate-600">
|
||||
<div class="italic text-sm mt-0.5 text-slate-600">
|
||||
{{ $annotation.Inner.InnerXML }}
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -13,11 +13,11 @@
|
||||
{{ if ge $pageCount 1 }}
|
||||
{{ $firstPage := index $pages 0 }}
|
||||
{{ if $firstPage.Available }}
|
||||
<div class="newspaper-page-container">
|
||||
<div class="newspaper-page-container" id="page-{{ $firstPage.PageNumber }}">
|
||||
<div class="mb-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-image-line text-blue-600"></i>
|
||||
<span class="page-indicator text-sm font-medium text-slate-600 bg-blue-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $firstPage.PageNumber }}">{{ $firstPage.PageNumber }}</span>
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 bg-blue-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $firstPage.PageNumber }}">{{ $firstPage.PageNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-page bg-white p-4 rounded-lg border border-slate-200 hover:border-slate-300 transition-colors duration-200">
|
||||
@@ -37,11 +37,11 @@
|
||||
{{ $middlePage1 := index $pages 1 }}
|
||||
{{ $middlePage2 := index $pages 2 }}
|
||||
{{ if and $middlePage1.Available $middlePage2.Available }}
|
||||
<div class="newspaper-page-container">
|
||||
<div class="newspaper-page-container" id="page-{{ $middlePage1.PageNumber }}-{{ $middlePage2.PageNumber }}">
|
||||
<div class="mb-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-copy-2-line text-green-600"></i>
|
||||
<span class="page-indicator text-sm font-medium text-slate-600 bg-green-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $middlePage1.PageNumber }}">{{ $middlePage1.PageNumber }}-{{ $middlePage2.PageNumber }}</span>
|
||||
<i class="ri-file-copy-2-line text-blue-600"></i>
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 bg-blue-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $middlePage1.PageNumber }}">{{ $middlePage1.PageNumber }}-{{ $middlePage2.PageNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="double-spread bg-white p-4 rounded-lg border border-slate-200 hover:border-slate-300 transition-colors duration-200">
|
||||
@@ -66,11 +66,11 @@
|
||||
{{ if ge $pageCount 4 }}
|
||||
{{ $lastPage := index $pages 3 }}
|
||||
{{ if $lastPage.Available }}
|
||||
<div class="newspaper-page-container">
|
||||
<div class="newspaper-page-container" id="page-{{ $lastPage.PageNumber }}">
|
||||
<div class="mb-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-image-line text-blue-600"></i>
|
||||
<span class="page-indicator text-sm font-medium text-slate-600 bg-blue-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $lastPage.PageNumber }}">{{ $lastPage.PageNumber }}</span>
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 bg-blue-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $lastPage.PageNumber }}">{{ $lastPage.PageNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-page bg-white p-4 rounded-lg border border-slate-200 hover:border-slate-300 transition-colors duration-200">
|
||||
@@ -102,11 +102,11 @@
|
||||
{{ if ge $pageCount 1 }}
|
||||
{{ $firstPage := index $beilagePages 0 }}
|
||||
{{ if $firstPage.Available }}
|
||||
<div class="newspaper-page-container">
|
||||
<div class="newspaper-page-container" id="beilage-{{ $beilageNum }}-page-{{ $firstPage.PageNumber }}">
|
||||
<div class="mb-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-image-line text-amber-600"></i>
|
||||
<span class="text-sm font-medium text-slate-600 bg-amber-50 px-2 py-1 rounded">{{ $firstPage.PageNumber }}</span>
|
||||
<span class="page-indicator page-number-inhalts text-sm font-bold text-slate-600 bg-amber-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $firstPage.PageNumber }}" data-page-number="{{ $firstPage.PageNumber }}">{{ $firstPage.PageNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-page bg-white p-4 rounded-lg border border-amber-200 hover:border-amber-300 transition-colors duration-200">
|
||||
@@ -126,18 +126,25 @@
|
||||
{{ $middlePage1 := index $beilagePages 1 }}
|
||||
{{ $middlePage2 := index $beilagePages 2 }}
|
||||
{{ if and $middlePage1.Available $middlePage2.Available }}
|
||||
<div class="newspaper-page-container">
|
||||
<h4 class="text-sm font-medium mb-2">Beilage {{ $beilageNum }}, Seiten {{ $middlePage1.PageNumber }}-{{ $middlePage2.PageNumber }}</h4>
|
||||
<div class="double-spread">
|
||||
<div class="newspaper-page-container" id="beilage-{{ $beilageNum }}-page-{{ $middlePage1.PageNumber }}-{{ $middlePage2.PageNumber }}">
|
||||
<div class="mb-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-copy-2-line text-amber-600 text-sm"></i>
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 bg-amber-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $middlePage1.PageNumber }}">{{ $middlePage1.PageNumber }}-{{ $middlePage2.PageNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="double-spread bg-white p-4 rounded-lg border border-amber-200 hover:border-amber-300 transition-colors duration-200">
|
||||
<img src="{{ $middlePage1.ImagePath }}"
|
||||
alt="Beilage {{ $beilageNum }}, Seite {{ $middlePage1.PageNumber }}"
|
||||
class="newspaper-page-image cursor-pointer border shadow-md"
|
||||
class="newspaper-page-image cursor-pointer rounded-md hover:scale-[1.02] transition-transform duration-200"
|
||||
onclick="enlargePage(this, {{ $middlePage1.PageNumber }}, true)"
|
||||
data-page="{{ $middlePage1.PageNumber }}"
|
||||
loading="lazy">
|
||||
<img src="{{ $middlePage2.ImagePath }}"
|
||||
alt="Beilage {{ $beilageNum }}, Seite {{ $middlePage2.PageNumber }}"
|
||||
class="newspaper-page-image cursor-pointer border shadow-md"
|
||||
class="newspaper-page-image cursor-pointer rounded-md hover:scale-[1.02] transition-transform duration-200"
|
||||
onclick="enlargePage(this, {{ $middlePage2.PageNumber }}, true)"
|
||||
data-page="{{ $middlePage2.PageNumber }}"
|
||||
loading="lazy">
|
||||
</div>
|
||||
</div>
|
||||
@@ -146,13 +153,19 @@
|
||||
<!-- If only 2 pages, show as spread -->
|
||||
{{ $page2 := index $beilagePages 1 }}
|
||||
{{ if $page2.Available }}
|
||||
<div class="newspaper-page-container">
|
||||
<h4 class="text-sm font-medium mb-2">Beilage {{ $beilageNum }}, Seite {{ $page2.PageNumber }}</h4>
|
||||
<div class="single-page">
|
||||
<div class="newspaper-page-container" id="beilage-{{ $beilageNum }}-page-{{ $page2.PageNumber }}">
|
||||
<div class="mb-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-image-line text-amber-600"></i>
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 bg-amber-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $page2.PageNumber }}">{{ $page2.PageNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-page bg-white p-4 rounded-lg border border-amber-200 hover:border-amber-300 transition-colors duration-200">
|
||||
<img src="{{ $page2.ImagePath }}"
|
||||
alt="Beilage {{ $beilageNum }}, Seite {{ $page2.PageNumber }}"
|
||||
class="newspaper-page-image cursor-pointer border shadow-md"
|
||||
class="newspaper-page-image cursor-pointer rounded-md hover:scale-[1.02] transition-transform duration-200"
|
||||
onclick="enlargePage(this, {{ $page2.PageNumber }}, false)"
|
||||
data-page="{{ $page2.PageNumber }}"
|
||||
loading="lazy">
|
||||
</div>
|
||||
</div>
|
||||
@@ -163,13 +176,19 @@
|
||||
{{ if ge $pageCount 4 }}
|
||||
{{ $lastPage := index $beilagePages 3 }}
|
||||
{{ if $lastPage.Available }}
|
||||
<div class="newspaper-page-container">
|
||||
<h4 class="text-sm font-medium mb-2">Beilage {{ $beilageNum }}, Seite {{ $lastPage.PageNumber }}</h4>
|
||||
<div class="single-page">
|
||||
<div class="newspaper-page-container" id="beilage-{{ $beilageNum }}-page-{{ $lastPage.PageNumber }}">
|
||||
<div class="mb-3">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-image-line text-amber-600"></i>
|
||||
<span class="page-indicator text-sm font-bold text-slate-600 bg-amber-50 px-2 py-1 rounded transition-all duration-300" data-page="{{ $lastPage.PageNumber }}">{{ $lastPage.PageNumber }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-page bg-white p-4 rounded-lg border border-amber-200 hover:border-amber-300 transition-colors duration-200">
|
||||
<img src="{{ $lastPage.ImagePath }}"
|
||||
alt="Beilage {{ $beilageNum }}, Seite {{ $lastPage.PageNumber }}"
|
||||
class="newspaper-page-image cursor-pointer border shadow-md"
|
||||
class="newspaper-page-image cursor-pointer rounded-md hover:scale-[1.02] transition-transform duration-200"
|
||||
onclick="enlargePage(this, {{ $lastPage.PageNumber }}, false)"
|
||||
data-page="{{ $lastPage.PageNumber }}"
|
||||
loading="lazy">
|
||||
</div>
|
||||
</div>
|
||||
@@ -262,23 +281,55 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Simple button hover styles */
|
||||
button#prevPageBtn:hover:not([style*="display: none"]),
|
||||
button#nextPageBtn:hover,
|
||||
button#beilageBtn:hover {
|
||||
background-color: rgb(209 213 219) !important; /* gray-300 */
|
||||
color: rgb(55 65 81) !important; /* gray-700 */
|
||||
}
|
||||
|
||||
button#beilageBtn:hover {
|
||||
background-color: rgb(254 215 170) !important; /* amber-200 */
|
||||
color: rgb(146 64 14) !important; /* amber-800 */
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Initialize page tracking
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Page highlighting state - use window to avoid redeclaration
|
||||
window.highlightObserver = window.highlightObserver || null;
|
||||
|
||||
// Initialize or reinitialize page highlighting - can be called multiple times
|
||||
function initializePageHighlighting() {
|
||||
// Clean up existing observer
|
||||
if (window.highlightObserver) {
|
||||
window.highlightObserver.disconnect();
|
||||
window.highlightObserver = null;
|
||||
}
|
||||
|
||||
// Get all page containers
|
||||
const pageContainers = document.querySelectorAll('.newspaper-page-container');
|
||||
|
||||
// Set up intersection observer for active page tracking
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
window.highlightObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
// Get page number from the container
|
||||
const pageImg = entry.target.querySelector('img[data-page]');
|
||||
if (pageImg) {
|
||||
const pageNumber = pageImg.getAttribute('data-page');
|
||||
markCurrentPageInInhaltsverzeichnis(pageNumber);
|
||||
// Check if this is a double-spread container
|
||||
const doubleSpread = entry.target.querySelector('.double-spread');
|
||||
if (doubleSpread) {
|
||||
// Handle double-spread: highlight both pages
|
||||
const pageImages = entry.target.querySelectorAll('img[data-page]');
|
||||
const pageNumbers = Array.from(pageImages).map(img => img.getAttribute('data-page'));
|
||||
markCurrentPagesInInhaltsverzeichnis(pageNumbers);
|
||||
} else {
|
||||
// Handle single page
|
||||
const pageImg = entry.target.querySelector('img[data-page]');
|
||||
if (pageImg) {
|
||||
const pageNumber = pageImg.getAttribute('data-page');
|
||||
markCurrentPageInInhaltsverzeichnis(pageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -288,34 +339,126 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// Observe all page containers
|
||||
pageContainers.forEach(container => {
|
||||
observer.observe(container);
|
||||
window.highlightObserver.observe(container);
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize highlighting on page load
|
||||
document.addEventListener('DOMContentLoaded', initializePageHighlighting);
|
||||
|
||||
// More comprehensive HTMX event handling for highlighting
|
||||
document.body.addEventListener('htmx:afterSwap', function(event) {
|
||||
console.log('HTMX afterSwap detected, target:', event.detail.target);
|
||||
console.log('Target ID:', event.detail.target.id);
|
||||
console.log('Target classes:', event.detail.target.className);
|
||||
|
||||
// Reinitialize on any content swap that might affect our page
|
||||
setTimeout(() => {
|
||||
console.log('Reinitializing page highlighting...');
|
||||
initializePageHighlighting();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
document.body.addEventListener('htmx:afterSettle', function(event) {
|
||||
console.log('HTMX afterSettle detected');
|
||||
setTimeout(() => {
|
||||
initializePageHighlighting();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
// Also try htmx:load event
|
||||
document.body.addEventListener('htmx:load', function(event) {
|
||||
console.log('HTMX load detected');
|
||||
setTimeout(() => {
|
||||
initializePageHighlighting();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
function markCurrentPageInInhaltsverzeichnis(pageNumber) {
|
||||
// Reset all entries in Inhaltsverzeichnis
|
||||
document.querySelectorAll('.inhalts-entry').forEach(entry => {
|
||||
entry.classList.remove('bg-red-100', 'border-red-300');
|
||||
entry.classList.add('bg-slate-50');
|
||||
markCurrentPagesInInhaltsverzeichnis([pageNumber]);
|
||||
}
|
||||
|
||||
function markCurrentPagesInInhaltsverzeichnis(pageNumbers) {
|
||||
// Reset all page numbers in Inhaltsverzeichnis
|
||||
document.querySelectorAll('.page-number-inhalts').forEach(pageNum => {
|
||||
pageNum.classList.remove('text-red-600', 'font-bold');
|
||||
pageNum.classList.add('text-slate-700', 'font-semibold');
|
||||
// Keep original background colors
|
||||
if (!pageNum.classList.contains('bg-amber-50') && !pageNum.classList.contains('bg-blue-50')) {
|
||||
pageNum.classList.add('bg-blue-50');
|
||||
}
|
||||
});
|
||||
|
||||
// Find and highlight the current page entry
|
||||
const pageEntry = document.querySelector(`.inhalts-entry[data-page="${pageNumber}"]`);
|
||||
if (pageEntry) {
|
||||
pageEntry.classList.remove('bg-slate-50');
|
||||
pageEntry.classList.add('bg-red-100', 'border-red-300');
|
||||
// Find and highlight the current page numbers
|
||||
const highlightedElements = [];
|
||||
const highlightedRanges = new Set(); // Track which ranges we've already highlighted
|
||||
|
||||
pageNumbers.forEach(pageNumber => {
|
||||
// Look for all entries that should be highlighted for this page
|
||||
const allPageNumbers = document.querySelectorAll('.page-number-inhalts');
|
||||
|
||||
for (const pageNumElement of allPageNumbers) {
|
||||
const startPage = parseInt(pageNumElement.getAttribute('data-page-number'));
|
||||
const endPage = parseInt(pageNumElement.getAttribute('data-end-page'));
|
||||
const rangeKey = `${startPage}-${endPage}`;
|
||||
|
||||
// Check if this page falls within this range
|
||||
if (pageNumber >= startPage && pageNumber <= endPage) {
|
||||
// Only highlight this range once, even if multiple visible pages fall within it
|
||||
if (!highlightedRanges.has(rangeKey)) {
|
||||
pageNumElement.classList.remove('text-slate-700');
|
||||
pageNumElement.classList.add('text-red-600', 'font-bold');
|
||||
highlightedElements.push(pageNumElement);
|
||||
highlightedRanges.add(rangeKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-scroll to first highlighted element if it exists
|
||||
if (highlightedElements.length > 0) {
|
||||
scrollToHighlightedPage(highlightedElements[0]);
|
||||
}
|
||||
|
||||
// Also highlight page indicators
|
||||
document.querySelectorAll('.page-indicator').forEach(indicator => {
|
||||
indicator.classList.remove('bg-red-500', 'text-white');
|
||||
indicator.classList.add('bg-blue-50', 'text-slate-600');
|
||||
indicator.classList.remove('text-red-600', 'font-bold');
|
||||
indicator.classList.add('text-slate-600', 'font-semibold');
|
||||
// Keep original backgrounds
|
||||
if (!indicator.classList.contains('bg-amber-50')) {
|
||||
indicator.classList.add('bg-blue-50');
|
||||
}
|
||||
});
|
||||
|
||||
const pageIndicator = document.querySelector(`.page-indicator[data-page="${pageNumber}"]`);
|
||||
if (pageIndicator) {
|
||||
pageIndicator.classList.remove('bg-blue-50', 'bg-green-50', 'text-slate-600');
|
||||
pageIndicator.classList.add('bg-red-500', 'text-white');
|
||||
// Highlight page indicators for all current pages
|
||||
pageNumbers.forEach(pageNumber => {
|
||||
const pageIndicator = document.querySelector(`.page-indicator[data-page="${pageNumber}"]`);
|
||||
if (pageIndicator) {
|
||||
pageIndicator.classList.remove('text-slate-600');
|
||||
pageIndicator.classList.add('text-red-600', 'font-bold');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function scrollToHighlightedPage(element) {
|
||||
// Check if the element is in a scrollable container
|
||||
const inhaltsContainer = element.closest('.lg\\:overflow-y-auto');
|
||||
if (inhaltsContainer) {
|
||||
// Calculate position
|
||||
const containerRect = inhaltsContainer.getBoundingClientRect();
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
|
||||
// Check if element is not fully visible
|
||||
const isAboveContainer = elementRect.top < containerRect.top;
|
||||
const isBelowContainer = elementRect.bottom > containerRect.bottom;
|
||||
|
||||
if (isAboveContainer || isBelowContainer) {
|
||||
// Scroll to make element visible with some padding
|
||||
element.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,4 +486,267 @@ document.addEventListener('keydown', function(e) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
|
||||
// Navigation functions and state management - use window to avoid redeclaration
|
||||
window.currentPageContainers = window.currentPageContainers || [];
|
||||
window.currentActiveIndex = window.currentActiveIndex || 0;
|
||||
window.pageObserver = window.pageObserver || null;
|
||||
|
||||
// Initialize or reinitialize page tracking - can be called multiple times
|
||||
function initializePageTracking() {
|
||||
// Clean up existing observer
|
||||
if (window.pageObserver) {
|
||||
window.pageObserver.disconnect();
|
||||
window.pageObserver = null;
|
||||
}
|
||||
|
||||
// Reset state
|
||||
window.currentPageContainers = Array.from(document.querySelectorAll('.newspaper-page-container'));
|
||||
window.currentActiveIndex = 0;
|
||||
updateButtonStates();
|
||||
|
||||
// Set up new observer
|
||||
const existingObserver = document.querySelector('.newspaper-page-container');
|
||||
if (existingObserver) {
|
||||
let visibleContainers = new Set();
|
||||
|
||||
window.pageObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
const containerIndex = window.currentPageContainers.indexOf(entry.target);
|
||||
if (containerIndex !== -1) {
|
||||
if (entry.isIntersecting) {
|
||||
visibleContainers.add(containerIndex);
|
||||
} else {
|
||||
visibleContainers.delete(containerIndex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update currentActiveIndex to the first (topmost) visible container
|
||||
if (visibleContainers.size > 0) {
|
||||
const sortedVisible = Array.from(visibleContainers).sort((a, b) => a - b);
|
||||
const newActiveIndex = sortedVisible[0];
|
||||
if (newActiveIndex !== window.currentActiveIndex) {
|
||||
window.currentActiveIndex = newActiveIndex;
|
||||
updateButtonStates();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
rootMargin: '-20% 0px -70% 0px'
|
||||
});
|
||||
|
||||
window.currentPageContainers.forEach(container => {
|
||||
window.pageObserver.observe(container);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
document.addEventListener('DOMContentLoaded', initializePageTracking);
|
||||
|
||||
// More comprehensive HTMX event handling for navigation tracking
|
||||
document.body.addEventListener('htmx:afterSwap', function(event) {
|
||||
console.log('HTMX afterSwap for navigation tracking');
|
||||
setTimeout(() => {
|
||||
console.log('Reinitializing page tracking...');
|
||||
initializePageTracking();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
document.body.addEventListener('htmx:afterSettle', function(event) {
|
||||
console.log('HTMX afterSettle for navigation tracking');
|
||||
setTimeout(() => {
|
||||
initializePageTracking();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
document.body.addEventListener('htmx:load', function(event) {
|
||||
console.log('HTMX load for navigation tracking');
|
||||
setTimeout(() => {
|
||||
initializePageTracking();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
function scrollToPreviousPage() {
|
||||
if (window.currentActiveIndex > 0) {
|
||||
// Move to previous container that's not currently visible
|
||||
let targetIndex = window.currentActiveIndex - 1;
|
||||
|
||||
// Ensure we go to the previous non-visible container
|
||||
window.currentActiveIndex = targetIndex;
|
||||
window.currentPageContainers[window.currentActiveIndex].scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
|
||||
// Update button states after a brief delay to let intersection observer catch up
|
||||
setTimeout(() => {
|
||||
updateButtonStates();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToNextPage() {
|
||||
if (window.currentActiveIndex < window.currentPageContainers.length - 1) {
|
||||
// Move to next container that's not currently visible
|
||||
let targetIndex = window.currentActiveIndex + 1;
|
||||
|
||||
// Ensure we go to the next non-visible container
|
||||
window.currentActiveIndex = targetIndex;
|
||||
window.currentPageContainers[window.currentActiveIndex].scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
|
||||
// Update button states after a brief delay to let intersection observer catch up
|
||||
setTimeout(() => {
|
||||
updateButtonStates();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToBeilage() {
|
||||
// Find the first beilage container
|
||||
const beilageContainer = document.querySelector('[class*="border-t-2 border-amber-200"]');
|
||||
if (beilageContainer) {
|
||||
beilageContainer.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateButtonStates() {
|
||||
const prevBtn = document.getElementById('prevPageBtn');
|
||||
const nextBtn = document.getElementById('nextPageBtn');
|
||||
|
||||
if (prevBtn) {
|
||||
if (window.currentActiveIndex <= 0) {
|
||||
prevBtn.style.display = 'none';
|
||||
} else {
|
||||
prevBtn.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
if (nextBtn) {
|
||||
if (window.currentActiveIndex >= window.currentPageContainers.length - 1) {
|
||||
nextBtn.style.display = 'none';
|
||||
} else {
|
||||
nextBtn.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function shareCurrentPage() {
|
||||
const button = document.getElementById('shareLinkBtn');
|
||||
|
||||
// Get current page information
|
||||
let pageInfo = '';
|
||||
|
||||
// Try to get the currently visible page number from active containers
|
||||
if (window.currentActiveIndex !== undefined && window.currentPageContainers && window.currentPageContainers[window.currentActiveIndex]) {
|
||||
const activeContainer = window.currentPageContainers[window.currentActiveIndex];
|
||||
const pageElement = activeContainer.querySelector('[data-page]');
|
||||
if (pageElement) {
|
||||
const pageNumber = pageElement.getAttribute('data-page');
|
||||
pageInfo = `#page-${pageNumber}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the shareable URL
|
||||
const currentUrl = window.location.origin + window.location.pathname + pageInfo;
|
||||
|
||||
// Try to use Web Share API if available (mobile browsers)
|
||||
if (navigator.share) {
|
||||
navigator.share({
|
||||
title: document.title,
|
||||
url: currentUrl
|
||||
}).catch(err => {
|
||||
console.log('Error sharing:', err);
|
||||
// Fallback to clipboard
|
||||
copyToClipboard(currentUrl, button);
|
||||
});
|
||||
} else {
|
||||
// Fallback: copy to clipboard
|
||||
copyToClipboard(currentUrl, button);
|
||||
}
|
||||
}
|
||||
|
||||
function copyToClipboard(text, button) {
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
// Show temporary notification
|
||||
showNotification('Link kopiert!', 'success', button);
|
||||
}).catch(err => {
|
||||
console.error('Failed to copy:', err);
|
||||
showNotification('Kopieren fehlgeschlagen', 'error', button);
|
||||
});
|
||||
} else {
|
||||
// Fallback for older browsers
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
showNotification('Link kopiert!', 'success', button);
|
||||
} catch (err) {
|
||||
console.error('Fallback copy failed:', err);
|
||||
showNotification('Kopieren fehlgeschlagen', 'error', button);
|
||||
}
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
}
|
||||
|
||||
function generateCitation() {
|
||||
const button = document.getElementById('citationBtn');
|
||||
|
||||
// Get current page and issue information
|
||||
const issueInfo = document.title || 'KGPZ';
|
||||
const currentUrl = window.location.href;
|
||||
|
||||
// Basic citation format (can be expanded later)
|
||||
const currentDate = new Date().toLocaleDateString('de-DE');
|
||||
const citation = `Königsberger Gelehrte und Politische Zeitung (KGPZ). ${issueInfo}. Digital verfügbar unter: ${currentUrl} (Zugriff: ${currentDate}).`;
|
||||
|
||||
// Copy citation to clipboard
|
||||
copyToClipboard(citation, button);
|
||||
}
|
||||
|
||||
function showNotification(message, type = 'success', button) {
|
||||
// Remove any existing notifications
|
||||
const existingNotification = document.getElementById('notification');
|
||||
if (existingNotification) {
|
||||
existingNotification.remove();
|
||||
}
|
||||
|
||||
// Create notification element
|
||||
const notification = document.createElement('div');
|
||||
notification.id = 'notification';
|
||||
notification.className = `fixed px-3 py-2 rounded-md text-white text-sm font-medium z-50 transition-opacity duration-300 ${
|
||||
type === 'success' ? 'bg-green-500' : 'bg-red-500'
|
||||
}`;
|
||||
notification.textContent = message;
|
||||
|
||||
// Position notification next to button if button is provided
|
||||
if (button) {
|
||||
const buttonRect = button.getBoundingClientRect();
|
||||
notification.style.left = `${buttonRect.left - 80}px`; // Position to the left of button
|
||||
notification.style.top = `${buttonRect.top + buttonRect.height / 2 - 20}px`; // Center vertically with button
|
||||
} else {
|
||||
// Fallback to top-right corner
|
||||
notification.className += ' top-4 right-4';
|
||||
}
|
||||
|
||||
// Add to page
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Auto-remove after 3 seconds
|
||||
setTimeout(() => {
|
||||
notification.style.opacity = '0';
|
||||
setTimeout(() => {
|
||||
notification.remove();
|
||||
}, 300);
|
||||
}, 3000);
|
||||
}
|
||||
</script>
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="flex flex-wrap gap-1 mt-1">
|
||||
{{ range $_, $p := $workPieces }}
|
||||
{{ range $_, $issue := $p.Item.IssueRefs }}
|
||||
<a href="/{{ $issue.When }}/{{ $issue.Nr }}" class="inline-block bg-green-50 hover:bg-green-100 text-green-700 hover:text-green-800 px-2 py-1 rounded text-sm transition-colors">
|
||||
<a href="/{{ $issue.When }}/{{ $issue.Nr }}{{ if $issue.Von }}{{ if $issue.Beilage }}#beilage-{{ $issue.Beilage }}-page-{{ $issue.Von }}{{ else }}#page-{{ $issue.Von }}{{ end }}{{ end }}" class="inline-block bg-green-50 hover:bg-green-100 text-green-700 hover:text-green-800 px-2 py-1 rounded text-sm transition-colors">
|
||||
{{ $issue.Nr }}/{{ $issue.When }}{{ if $issue.Von }} [S. {{ $issue.Von }}{{ if $issue.Bis }}-{{ $issue.Bis }}{{ end }}]{{ end }}
|
||||
</a>
|
||||
{{ end }}
|
||||
@@ -87,7 +87,7 @@
|
||||
<div class="flex flex-wrap gap-1 mt-1">
|
||||
{{ range $_, $p := $pieces }}
|
||||
{{ range $_, $issue := $p.Item.IssueRefs }}
|
||||
<a href="/{{ $issue.When }}/{{ $issue.Nr }}" class="inline-block bg-green-50 hover:bg-green-100 text-green-700 hover:text-green-800 px-2 py-1 rounded text-sm transition-colors">
|
||||
<a href="/{{ $issue.When }}/{{ $issue.Nr }}{{ if $issue.Von }}{{ if $issue.Beilage }}#beilage-{{ $issue.Beilage }}-page-{{ $issue.Von }}{{ else }}#page-{{ $issue.Von }}{{ end }}{{ end }}" class="inline-block bg-green-50 hover:bg-green-100 text-green-700 hover:text-green-800 px-2 py-1 rounded text-sm transition-colors">
|
||||
{{ $issue.Nr }}/{{ $issue.When }}{{ if $issue.Von }} [S. {{ $issue.Von }}{{ if $issue.Bis }}-{{ $issue.Bis }}{{ end }}]{{ end }}
|
||||
</a>
|
||||
{{ end }}
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
{{ range $_, $p := $pieces }}
|
||||
{{- range $_, $i := $p.Item.IssueRefs -}}
|
||||
<div>
|
||||
<a href="/{{ $i.When }}/{{ $i.Nr }}">{{ $i.Nr }}/{{ $i.When }}</a>
|
||||
<a href="/{{ $i.When }}/{{ $i.Nr }}{{ if $i.Von }}{{ if $i.Beilage }}#beilage-{{ $i.Beilage }}-page-{{ $i.Von }}{{ else }}#page-{{ $i.Von }}{{ end }}{{ end }}">{{ $i.Nr }}/{{ $i.When }}</a>
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
Reference in New Issue
Block a user