mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
64062af9a1
A Guided Review can now leave Plannotator: as a single self-contained HTML file that renders exactly like the in-app guide, as an encrypted-by-default share link on guides.show, or authored by any agent through the new guide CLI. Highlights: packages/guide-viewer extracted from review-editor at the injection seam (read-only host, no third renderer); guides.show Worker with R2-backed share storage, per-IP rate limiting on creation, delete tokens hashed at rest, and 128-bit ids; portable exports pin the viewer by SRI hash with budget and manifest gates in PR CI and at deploy; two-runtime parity across Bun and Pi verified; v0.27.x saved guides load unchanged. Retention is indefinite by explicit decision, to revisit with the lean sharing refactor. Decision record: adr/decisions/007-portable-guided-reviews-20260815.md
33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
import React from 'react';
|
|
|
|
/**
|
|
* Lightweight section placeholders shown while a guide is generating and
|
|
* while a completed guide is being fetched, so the page reads as "sections
|
|
* are coming" before the virtualized chapter cards take over.
|
|
*/
|
|
export function GuideSectionSkeleton({ count = 3 }: { count?: number }) {
|
|
return (
|
|
<div className="mt-6 space-y-4">
|
|
{Array.from({ length: count }).map((_, i) => (
|
|
<div key={i} className="overflow-hidden rounded-lg border border-border/40 bg-card">
|
|
<div className="md:grid md:grid-cols-[440px_minmax(0,1fr)]">
|
|
<div className="space-y-3 border-b border-border/40 px-6 py-5 md:border-b-0 md:border-r">
|
|
<div className="h-4 w-3/4 animate-pulse rounded bg-muted/40" />
|
|
<div className="h-3 w-28 animate-pulse rounded bg-muted/30" />
|
|
<div className="space-y-2 pt-2">
|
|
<div className="h-3 w-full animate-pulse rounded bg-muted/25" />
|
|
<div className="h-3 w-5/6 animate-pulse rounded bg-muted/25" />
|
|
<div className="h-3 w-2/3 animate-pulse rounded bg-muted/25" />
|
|
</div>
|
|
<div className="h-7 w-full animate-pulse rounded-md bg-muted/20" />
|
|
</div>
|
|
<div className="bg-muted/[0.07] px-4 py-4">
|
|
<div className="h-[200px] animate-pulse rounded-lg bg-muted/20" style={{ animationDelay: `${i * 120}ms` }} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|