feat: print-friendly layout + comment count on every post overview
- Hides Header / HeaderOverlay / Footer / TopBanner / Breadcrumbs and the comment accordion when printing. Action toolbar already had `print:hidden`. - Adds @media print rules in app.css: 1.5cm page margins, 11pt body, forced black-on-white, expand link URLs after anchor text inside articles, keep images and headings together at page breaks. - PostCard now renders the count pill whenever a value is known (incl. zero); previously hidden for `count === 0`, so posts whose comments are still pending always looked empty. - Extracts the bulk-fetch helper to `lib/comment-counts.ts` (`fetchCommentCounts` + `postSlugForComments`) and uses it from both `BlogOverview` and `PostOverviewBlock`. Homepage / any page with a post_overview block now shows the badges too — previously only the paginated /posts/* routes did. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+28
-20
@@ -269,35 +269,43 @@
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<Header
|
||||
links={data.headerLinks}
|
||||
socialLinks={data.socialLinks}
|
||||
logoUrl={data.logoUrl}
|
||||
logoSvgHtml={data.logoSvgHtml}
|
||||
translations={data.translations}
|
||||
/>
|
||||
<HeaderOverlay />
|
||||
<div class="print:hidden">
|
||||
<Header
|
||||
links={data.headerLinks}
|
||||
socialLinks={data.socialLinks}
|
||||
logoUrl={data.logoUrl}
|
||||
logoSvgHtml={data.logoSvgHtml}
|
||||
translations={data.translations}
|
||||
/>
|
||||
<HeaderOverlay />
|
||||
</div>
|
||||
|
||||
{#if topBannerData}
|
||||
<TopBanner
|
||||
banner={topBannerData.banner as import('$lib/cms').FullwidthBannerEntry | null}
|
||||
resolvedImages={topBannerData.resolvedImages}
|
||||
responsive={topBannerData.responsive ?? null}
|
||||
focalCss={topBannerData.focalCss ?? null}
|
||||
headline={topBannerData.headline}
|
||||
subheadline={topBannerData.subheadline}
|
||||
/>
|
||||
<div class="print:hidden">
|
||||
<TopBanner
|
||||
banner={topBannerData.banner as import('$lib/cms').FullwidthBannerEntry | null}
|
||||
resolvedImages={topBannerData.resolvedImages}
|
||||
responsive={topBannerData.responsive ?? null}
|
||||
focalCss={topBannerData.focalCss ?? null}
|
||||
headline={topBannerData.headline}
|
||||
subheadline={topBannerData.subheadline}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<main id="main-content" tabindex="-1" class="flex-1 min-h-[60em]">
|
||||
<div class="container-custom pb-12">
|
||||
<main id="main-content" tabindex="-1" class="flex-1 min-h-[60em] print:min-h-0">
|
||||
<div class="container-custom pb-12 print:pb-0">
|
||||
{#if breadcrumbItems.length > 0}
|
||||
<Breadcrumbs items={breadcrumbItems} />
|
||||
<div class="print:hidden">
|
||||
<Breadcrumbs items={breadcrumbItems} />
|
||||
</div>
|
||||
{/if}
|
||||
{@render children()}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer footer={data.footerData} translations={data.translations} />
|
||||
<div class="print:hidden">
|
||||
<Footer footer={data.footerData} translations={data.translations} />
|
||||
</div>
|
||||
</div>
|
||||
</TranslationProvider>
|
||||
|
||||
@@ -165,14 +165,16 @@
|
||||
{/if}
|
||||
|
||||
{#if data.commentPageId}
|
||||
<Accordion
|
||||
id="comments-section"
|
||||
label={t(data.translations, T.post_comments)}
|
||||
lazy
|
||||
class="mt-6"
|
||||
>
|
||||
<div class="p-8 border border-zinc-200 rounded-lg">
|
||||
<Comments pageId={data.commentPageId} />
|
||||
</div>
|
||||
</Accordion>
|
||||
<div class="print:hidden">
|
||||
<Accordion
|
||||
id="comments-section"
|
||||
label={t(data.translations, T.post_comments)}
|
||||
lazy
|
||||
class="mt-6"
|
||||
>
|
||||
<div class="p-8 border border-zinc-200 rounded-lg">
|
||||
<Comments pageId={data.commentPageId} />
|
||||
</div>
|
||||
</Accordion>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user