Workshop Kit · widget reference

Shipped

gbp-card-preview

Live mock of how the operator's Google Business Profile will render in search results — built from whatever MuntinContext has so far. Captures the one GBP-specific field not collected by any other lesson (the primary category, from a 27-item restaurant taxonomy plus an "Other" escape hatch), then renders a card with name, category, today's open/closed status from hours, address, phone, description, photo-count badge, accent color from palette, and a readiness checklist that flags missing fields.

Live demo

Pick a primary category. The card preview updates immediately; the readiness checklist below shows which other fields are still needed. Open the bootcamp lessons (L4 → L7 → L8 → L10) to fill out the other fields and watch the card complete itself.

No config block — primary-category list baked in

Current MuntinContext.gbp Pick a primary category above…

Contract

BehaviorNotes
Reads restaurantProfile.{name,cuisine,address,phone} Name + address + phone shown in the card. Cuisine isn't shown directly (category overrides it for GBP rendering).
Reads hours Computes today's open/closed status with a colored dot + label ("Open · 11:00–22:00" / "Closed today" / "Hours not set").
Reads palette[0] Tints the photo placeholder + the CTA pill. Defaults to teal.
Reads shotList.length Shows a "N photos ready" badge. Readiness goes from missing (0) to partial (1-2) to ready (3+).
Reads gbpDescription Renders below the address, line-clamped to 3 lines (matches the Google search-result truncation).
Reads gbp.primaryCategory Pre-fills the select on remount.
Writes gbp.primaryCategory The id of the selected category, or the operator's free-text when "Other" is chosen.
Live re-render Subscribes to mtn:context-change; any other widget on the page (or the cross-device sync arriving) re-renders the card without remounting.

Markup

<section class="course-widget" data-widget="gbp-card-preview"></section>

No config block. The widget reads what it needs and writes only gbp.primaryCategory.

Accessibility

Why a preview, not a form

The operator already filled out most of these fields elsewhere (name in L1/L5a, address + phone in L10, hours in L10, description in L11a, photos in L9a/b). Asking them to fill the same fields a second time inside L11 is the most common reason operators bounce. The preview reuses the data instead: it shows them how the same context renders in Google's specific surface, points out what's still missing (with deep links back to where it gets filled), and asks them only the question Google asks that nobody else does — which primary category.

Where it ships

The standalone GBP Grader tool grades an actual live profile by URL; this widget previews what the listing should look like before it goes live.

Source

/tools/_shared/workshop/gbp-card-preview.js — ~290 LOC. Exports { tag, contextKeys, mount, serialize }. The 27-entry category taxonomy lives at the top of the file in bilingual EN/ES tables; todayStatus() computes the open/closed pill from hours; readContext() reads MuntinContext fresh on every re-render so external commits (palette changes, new photos selected, etc.) flow through without a remount.

← Back to the Workshop Kit