Files
backnotprop__plannotator/packages/review-editor/utils/guideIntro.ts
Michael Ramos ed4f2e82fe feat(review): Guided Reviews intro dialog + Guide button discovery hint (#1000)
* feat(review): one-time Guided Reviews intro dialog + Guide button hint

New GuideIntroDialog slots into the announcement chain (look-and-feel ->
guide intro -> review setup, never stacking): a hero screenshot of a
guided review with a brief plain-language description and a mock header
strip pointing at the real Guide button. Shows once per user (cookie),
and only when a Guide button actually exists (hasSearchableFiles) --
skipping the render does not consume the one-shot cookie.

The hero is CDN-hosted at https://plannotator.ai/assets/guided-review.webp
(committed to apps/marketing/public/assets so every marketing deploy
re-ships it past the --delete sync; uploaded to S3 now so it is already
live) instead of growing the single-file bundle; on load failure the
image container hides entirely for a clean text-only dialog.

Independently of the dialog, the header Guide button shimmers
(TextShimmer) with a pulsing dot until the guide is first opened --
acked on ANY open path (button, shortcut, job auto-open), not just the
button click.

* fix(review): guide intro first in the dialog chain, full-width panel

Chain is now guide intro -> look-and-feel -> review setup (was second);
panel widened to max-w-5xl to match the look-and-feel dialog. Intro seen
flag switched to the versioned-cookie pattern so future revisions can
re-show it.

* fix(review): latch guide-intro eligibility at first post-load render

hasSearchableFiles changes on mid-session diff switches; an
empty-to-non-empty switch would pop the intro over work in progress, or
yank an open look-and-feel dialog (its gate reads guideIntroVisible).
Eligibility is now decided once when loading clears -- dialogs only
mount after that, so the latch is always set before they render. A
skipped session keeps the cookie unconsumed. Also corrects AGENTS.md's
chain order (guide intro first).
2026-07-05 09:49:00 -07:00

31 lines
1.1 KiB
TypeScript

import { storage } from '@plannotator/ui/utils/storage';
/**
* One-time gates for the guided-review introduction. Cookie-based, mirroring
* the review-setup gate. Two independent flags: the intro dialog (seen once,
* never again) and the header Guide-button hint (shimmer + dot), which runs
* until the user's first Guide click regardless of how the dialog was
* dismissed.
*/
const INTRO_SEEN_KEY = 'plannotator-guide-intro-seen';
const HINT_ACKED_KEY = 'plannotator-guide-hint-acked';
// Versioned like lookAndFeelAnnouncement's CURRENT_VERSION: bumping re-shows
// the intro after a meaningful revision. v2: full-width layout, first in chain.
const INTRO_VERSION = '2';
export function needsGuideIntro(): boolean {
return storage.getItem(INTRO_SEEN_KEY) !== INTRO_VERSION;
}
export function markGuideIntroSeen(): void {
storage.setItem(INTRO_SEEN_KEY, INTRO_VERSION);
}
export function needsGuideHint(): boolean {
return storage.getItem(HINT_ACKED_KEY) !== 'true';
}
export function markGuideHintSeen(): void {
storage.setItem(HINT_ACKED_KEY, 'true');
}