hs1 demo: albany template + codex improvements to core code#1128
hs1 demo: albany template + codex improvements to core code#1128bryanreed wants to merge 3 commits intocomponent-genfrom
Conversation
|
| Key | Languages Removed |
|---|---|
atms |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
events
| Key | Languages Removed |
|---|---|
events |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
failedToPasteComponentPermissionDenied
| Key | Languages Removed |
|---|---|
failedToPasteComponentPermissionDenied |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
failedToPasteLayoutPermissionDenied
| Key | Languages Removed |
|---|---|
failedToPasteLayoutPermissionDenied |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields
| Key | Languages Removed |
|---|---|
fields.currentPageLinkLabel |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.directoryListBackgroundColor |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.headingBackgroundColor |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.normalizeLink |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.showCountry |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.showCurrentPagesLinkLabel |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
fields.showRegion |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
kilometer_zero
| Key | Languages Removed |
|---|---|
kilometer_zero |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt nb,nl pl,pt ro,sk sv,tr zh,zh-TW |
mile_zero
| Key | Languages Removed |
|---|---|
mile_zero |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt nb,nl pl,pt ro,sk sv,tr zh,zh-TW |
providerFacilities
| Key | Languages Removed |
|---|---|
providerFacilities |
cs,da de,en en-GB,es et,fi fr,hr hu,it ja,lt lv,nb nl,pl pt,ro sk,sv tr,zh zh-TW |
WalkthroughThis pull request adds support for hours field configuration in the visual editor and implements a complete HS1 Albany template with eleven section components. It includes the new Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/visual-editor/src/utils/resolveComponentData.tsx (1)
275-280:⚠️ Potential issue | 🟠 MajorDon’t key YextEntityField detection off generic
field/constantValuenames alone.With this guard, any literal object that happens to expose a root
fieldorconstantValueproperty is now treated as a binding and routed throughresolveYextEntityField(). That means inputs like{ field: "literal" }will resolve as KG lookups/undefinedinstead of staying literal data. Please use an explicit discriminator for YextEntityField payloads, or normalize saved field configs so they always carry one before broadening this check.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/visual-editor/src/utils/resolveComponentData.tsx` around lines 275 - 280, The type guard isYextEntityField incorrectly treats any object with a top-level "field" or "constantValue" as a YextEntityField, causing plain literals like { field: "literal" } to be routed through resolveYextEntityField; update the guard to require a clear discriminator or a stricter shape before treating something as a YextEntityField (for example, check for a dedicated discriminator property or verify that "field" is an object with the expected keys/type), and then use that stricter guard in resolveComponentData where resolveYextEntityField is called so only genuine YextEntityField payloads are resolved via resolveYextEntityField.
🧹 Nitpick comments (2)
starter/src/templates/dev.tsx (1)
282-296: Consider keeping a Back to Editor action in preview mode.
openPreview()still does same-tab navigation on Line 273, so once this branch hides the toolbar there is no in-app way back to the editor. A single back action would keep the preview clean without forcing users to rely on browser chrome.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@starter/src/templates/dev.tsx` around lines 282 - 296, The preview branch hides the toolbar and leaves no in-app way back to the editor; add a "Back to Editor" action when isPreviewMode is true that restores the editor view instead of relying on browser chrome. Update the component to render a Back button in the preview branch which calls a handler that either toggles the same preview state (e.g., call setIsPreviewMode(false) or a new closePreview function) or navigates programmatically back to the editor (matching how openPreview() works), ensuring the handler name (closePreview or setIsPreviewMode) is used consistently with openPreview and isPreviewMode.starter/src/registry/hs1-albany/components/Hs1AlbanyHeaderSection.tsx (1)
124-133: Consider using unique keys for array items.Using
${item.label}-${item.link}as keys could cause collisions if duplicate label/link combinations exist. While unlikely in practice, using the array index as a fallback or a unique ID would be more robust.💡 Optional: Add index to ensure unique keys
- {props.primaryLinks.map((item) => ( - <li key={`${item.label}-${item.link}`}> + {props.primaryLinks.map((item, index) => ( + <li key={`${item.label}-${item.link}-${index}`}>Apply similarly to
moreLinks(line 143) andpatientEducation.items(line 163).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@starter/src/registry/hs1-albany/components/Hs1AlbanyHeaderSection.tsx` around lines 124 - 133, The list item keys in the Hs1AlbanyHeaderSection component (inside props.primaryLinks.map) use `${item.label}-${item.link}` which can collide; update the key generation to ensure uniqueness by falling back to the array index or a unique id when label+link is not unique (apply the same fix for moreLinks mapping and patientEducation.items mapping), e.g., prefer a unique identifier on the item (id) and if absent append the map index to the key so every <li> key is guaranteed unique.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@starter/src/registry/hs1-albany/.captured-artifact/plan.md`:
- Around line 148-162: The checklist lists generated components and layout as
unfinished, which is misleading; either mark each completed item
(Hs1AlbanyHeaderSection, Hs1AlbanyHeroSection, Hs1AlbanyServicesSection,
Hs1AlbanyWelcomeSection, Hs1AlbanySignupFormSection,
Hs1AlbanyTestimonialsSection, Hs1AlbanyHoursSection, Hs1AlbanyLocationSection,
Hs1AlbanyContactFormSection, Hs1AlbanyFooterSection, Hs1AlbanyCopyrightSection,
registration in ve.config.tsx, and creation of defaultLayout.json) as done, or
replace the TODO checklist with a plain reference list of the added components
and artifacts so the file no longer implies work remains.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyContactFormSection.tsx`:
- Around line 90-123: The form in Hs1AlbanyContactFormSection.tsx is
non-functional and inaccessible: change the button from type="button" to
type="submit", add an onSubmit handler on the form (e.g., handleContactSubmit)
that prevents default, validates fields, and sends data (fetch/axios) or calls a
provided prop; also give each input and the textarea name and required
attributes and add visible <label> elements or aria-label attributes (or
associate labels via htmlFor/id) so the fields are accessible; alternatively, if
no submission is intended, convert the inputs/button into non-interactive text
or disable them and update copy to indicate the form is not functional. Ensure
you edit the form element, the three <input> fields, the <textarea>, and the
Submit <button> in Hs1AlbanyContactFormSection.tsx accordingly.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyFooterSection.tsx`:
- Around line 106-115: In Hs1AlbanyFooterSection, social link buttons rendered
from props.socialLinks currently only output SVG icons (Icon) inside Link,
making them inaccessible; update the Link to include an accessible name by
adding an aria-label={item.label} (or include visually-hidden text with
item.label) on the Link component so screen readers receive the label for each
Icon, keeping the existing key and cta props intact.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyHeroSection.tsx`:
- Around line 138-144: The code computes resolvedHeroImage via
resolveComponentData(props.heroImage, locale, streamDocument) but immediately
discards it and always uses capturedHeroImageUrl; replace that by using the
resolved asset's url (e.g., heroImageUrl = (resolvedHeroImage as
TranslatableAssetImage)?.url ?? capturedHeroImageUrl) and remove the void
resolvedHeroImage; ensure you reference resolvedHeroImage and fall back to
capturedHeroImageUrl so entity-selected images render correctly.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyHoursSection.tsx`:
- Around line 255-263: The desktop rendering in Hs1AlbanyHoursSection.tsx
currently splits item.hours on every " - ", which breaks multi-interval strings
from formatHoursForDay; update the conditional so if item.hours contains a comma
(", ") you render item.hours as-is, otherwise split only the first " - "
occurrence (e.g., find the firstIndexOf " - " and use substring before/after)
when constructing the two parts; reference the item.hours usage in the JSX and
adjust the split logic to use indexOf/substring (or a single split with a limit)
instead of splitting on all " - "s.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyLocationSection.tsx`:
- Around line 133-139: The distance badge in Hs1AlbanyLocationSection currently
renders a hardcoded "--", so either wire it to the real distance value or hide
the badge when no distance exists: locate the Hs1AlbanyLocationSection component
and replace the static "--" text with the actual distance variable (e.g.,
props.distance or computed formattedDistance) and ensure you format it
(round/trim) and append "mi"; alternatively, wrap the entire <div
className="mb-1 flex items-end gap-1"> block in a conditional render (e.g., only
render when distance != null/undefined) so the placeholder never appears if the
data is absent.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanySignupFormSection.tsx`:
- Around line 91-106: The form in Hs1AlbanySignupFormSection uses a plain <form>
with inputs that only have placeholders and a button set to type="button", so it
never submits and lacks accessible labels; change the button in this component
to type="submit" and add an onSubmit handler (e.g., handleSignupSubmit) on the
<form> to process/validate the name/email, or if this is purely demo chrome,
replace the <form> with a non-interactive container (or explicitly mark it as
mock) and keep the CTA as a non-submitting element; additionally, add proper
<label> elements or visible/aria-label attributes for the two inputs
(name/email) and wire them to state or form refs so the submit handler can read
values.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyTestimonialsSection.tsx`:
- Around line 104-133: The component currently only uses props.quotes[0]
(activeQuote) and always renders a single <p>, so additional testimonials and
per-quote typography are ignored; update Hs1AlbanyTestimonialsSection to iterate
over props.quotes (e.g., map) and for each quote call
resolveComponentData(quote.quote.text, locale, streamDocument) to compute
quoteText, render each testimonial block (including the quote mark, text, and
any per-quote typography props from the quote item) instead of the hard-coded
single <p>, and remove or repurpose the activeQuote variable if you keep a
single-view mode; ensure you reference props.quotes, resolveComponentData, and
any per-quote typography fields when implementing the mapping.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyWelcomeSection.tsx`:
- Around line 146-160: The subtitle and body render blocks in
Hs1AlbanyWelcomeSection are using fixed classes/styles so the passed-in
StyledTextProps (subtitle and body) fontSize, fontColor, fontWeight, and
textTransform are ignored; update the subtitle and body render logic to consume
those props: compute style entries (fontSize -> fontSize, fontColor -> color,
fontWeight -> fontWeight, textTransform -> textTransform, plus existing
fontFamily/lineHeight where applicable) and merge them into the inline style
object, and/or compute className fragments from those prop values instead of
hardcoded text sizes/colors; target the JSX elements that reference subtitle and
body in Hs1AlbanyWelcomeSection.tsx and replace the fixed className/style usage
so the StyledTextProps values are applied at render time.
---
Outside diff comments:
In `@packages/visual-editor/src/utils/resolveComponentData.tsx`:
- Around line 275-280: The type guard isYextEntityField incorrectly treats any
object with a top-level "field" or "constantValue" as a YextEntityField, causing
plain literals like { field: "literal" } to be routed through
resolveYextEntityField; update the guard to require a clear discriminator or a
stricter shape before treating something as a YextEntityField (for example,
check for a dedicated discriminator property or verify that "field" is an object
with the expected keys/type), and then use that stricter guard in
resolveComponentData where resolveYextEntityField is called so only genuine
YextEntityField payloads are resolved via resolveYextEntityField.
---
Nitpick comments:
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyHeaderSection.tsx`:
- Around line 124-133: The list item keys in the Hs1AlbanyHeaderSection
component (inside props.primaryLinks.map) use `${item.label}-${item.link}` which
can collide; update the key generation to ensure uniqueness by falling back to
the array index or a unique id when label+link is not unique (apply the same fix
for moreLinks mapping and patientEducation.items mapping), e.g., prefer a unique
identifier on the item (id) and if absent append the map index to the key so
every <li> key is guaranteed unique.
In `@starter/src/templates/dev.tsx`:
- Around line 282-296: The preview branch hides the toolbar and leaves no in-app
way back to the editor; add a "Back to Editor" action when isPreviewMode is true
that restores the editor view instead of relying on browser chrome. Update the
component to render a Back button in the preview branch which calls a handler
that either toggles the same preview state (e.g., call setIsPreviewMode(false)
or a new closePreview function) or navigates programmatically back to the editor
(matching how openPreview() works), ensuring the handler name (closePreview or
setIsPreviewMode) is used consistently with openPreview and isPreviewMode.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 5cd46e32-dd2d-417e-a1ee-53d35a263d57
⛔ Files ignored due to path filters (5)
starter/src/registry/hs1-albany/.captured-artifact/rendered-preview.diff.pngis excluded by!**/*.pngstarter/src/registry/hs1-albany/.captured-artifact/rendered-preview.pngis excluded by!**/*.pngstarter/src/registry/hs1-albany/.captured-artifact/screenshot.pngis excluded by!**/*.pngstarter/src/registry/hs1-albany/assets/hero-crop.pngis excluded by!**/*.pngstarter/src/registry/hs1-albany/assets/map-crop.pngis excluded by!**/*.png
📒 Files selected for processing (25)
packages/visual-editor/src/editor/YextEntityFieldSelector.tsxpackages/visual-editor/src/internal/components/InternalLayoutEditor.tsxpackages/visual-editor/src/internal/puck/constant-value-fields/Hours.tsxpackages/visual-editor/src/internal/puck/ui/UIButtonsToggle.tsxpackages/visual-editor/src/utils/resolveComponentData.test.tsxpackages/visual-editor/src/utils/resolveComponentData.tsxpackages/visual-editor/src/utils/resolveYextEntityField.tsstarter/src/registry/hs1-albany/.captured-artifact/combined.cssstarter/src/registry/hs1-albany/.captured-artifact/manifest.jsonstarter/src/registry/hs1-albany/.captured-artifact/page.htmlstarter/src/registry/hs1-albany/.captured-artifact/plan.mdstarter/src/registry/hs1-albany/components/Hs1AlbanyContactFormSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyCopyrightSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyFooterSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyHeaderSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyHeroSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyHoursSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyLocationSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyServicesSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanySignupFormSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyTestimonialsSection.tsxstarter/src/registry/hs1-albany/components/Hs1AlbanyWelcomeSection.tsxstarter/src/registry/hs1-albany/defaultLayout.jsonstarter/src/templates/dev.tsxstarter/src/ve.config.tsx
| ## Implementation Checklist | ||
|
|
||
| - [ ] `Hs1AlbanyHeaderSection` -> `components/Hs1AlbanyHeaderSection.tsx` | ||
| - [ ] `Hs1AlbanyHeroSection` -> `components/Hs1AlbanyHeroSection.tsx` | ||
| - [ ] `Hs1AlbanyServicesSection` -> `components/Hs1AlbanyServicesSection.tsx` | ||
| - [ ] `Hs1AlbanyWelcomeSection` -> `components/Hs1AlbanyWelcomeSection.tsx` | ||
| - [ ] `Hs1AlbanySignupFormSection` -> `components/Hs1AlbanySignupFormSection.tsx` | ||
| - [ ] `Hs1AlbanyTestimonialsSection` -> `components/Hs1AlbanyTestimonialsSection.tsx` | ||
| - [ ] `Hs1AlbanyHoursSection` -> `components/Hs1AlbanyHoursSection.tsx` | ||
| - [ ] `Hs1AlbanyLocationSection` -> `components/Hs1AlbanyLocationSection.tsx` | ||
| - [ ] `Hs1AlbanyContactFormSection` -> `components/Hs1AlbanyContactFormSection.tsx` | ||
| - [ ] `Hs1AlbanyFooterSection` -> `components/Hs1AlbanyFooterSection.tsx` | ||
| - [ ] `Hs1AlbanyCopyrightSection` -> `components/Hs1AlbanyCopyrightSection.tsx` | ||
| - [ ] Register all generated components in `starter/src/ve.config.tsx` | ||
| - [ ] Generate `starter/src/registry/hs1-albany/defaultLayout.json` in final visual order |
There was a problem hiding this comment.
This checklist will be stale as soon as this PR merges.
The PR already adds these components and the default layout, so committing this section with every box unchecked leaves misleading guidance in the repo. Please either mark the completed items or rewrite this as a reference list instead of a TODO list.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/.captured-artifact/plan.md` around lines 148
- 162, The checklist lists generated components and layout as unfinished, which
is misleading; either mark each completed item (Hs1AlbanyHeaderSection,
Hs1AlbanyHeroSection, Hs1AlbanyServicesSection, Hs1AlbanyWelcomeSection,
Hs1AlbanySignupFormSection, Hs1AlbanyTestimonialsSection, Hs1AlbanyHoursSection,
Hs1AlbanyLocationSection, Hs1AlbanyContactFormSection, Hs1AlbanyFooterSection,
Hs1AlbanyCopyrightSection, registration in ve.config.tsx, and creation of
defaultLayout.json) as done, or replace the TODO checklist with a plain
reference list of the added components and artifacts so the file no longer
implies work remains.
| <form className="grid gap-4 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]"> | ||
| <div className="space-y-4"> | ||
| <input | ||
| className="h-[44px] w-full border border-white/80 bg-transparent px-3 text-[13px] text-white placeholder:text-white/80" | ||
| placeholder="Enter your name (Required)" | ||
| /> | ||
| <input | ||
| className="h-[44px] w-full border border-white/80 bg-transparent px-3 text-[13px] text-white placeholder:text-white/80" | ||
| placeholder="Enter email (Required)" | ||
| /> | ||
| <input | ||
| className="h-[44px] w-full border border-white/80 bg-transparent px-3 text-[13px] text-white placeholder:text-white/80" | ||
| placeholder="(XXX)XXX-XXXX (Required)" | ||
| /> | ||
| </div> | ||
| <textarea | ||
| className="min-h-[164px] w-full border border-white/80 bg-transparent px-3 py-3 text-[13px] text-white placeholder:text-white/80" | ||
| placeholder="Notes to the Doctor" | ||
| /> | ||
| </form> | ||
| <p | ||
| className="mb-0 mt-5 text-center text-[12px] text-white" | ||
| style={{ fontFamily: "Montserrat, Open Sans, sans-serif" }} | ||
| > | ||
| Please do not submit any Protected Health Information (PHI). | ||
| </p> | ||
| <div className="mt-5 text-center"> | ||
| <button | ||
| type="button" | ||
| className="inline-flex h-[44px] min-w-[220px] items-center justify-center border border-white/80 px-8 text-[13px] font-bold uppercase tracking-[0.08em] text-white" | ||
| style={{ fontFamily: "Nunito Sans, Open Sans, sans-serif" }} | ||
| > | ||
| Submit | ||
| </button> |
There was a problem hiding this comment.
This section renders a dead form.
type="button" plus no form action/onSubmit means users cannot actually send anything. The placeholder-only fields also aren't sufficient labels, so the UI is inaccessible if it ships as a real form. Either wire a real submission flow or make the section clearly non-interactive.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyContactFormSection.tsx`
around lines 90 - 123, The form in Hs1AlbanyContactFormSection.tsx is
non-functional and inaccessible: change the button from type="button" to
type="submit", add an onSubmit handler on the form (e.g., handleContactSubmit)
that prevents default, validates fields, and sends data (fetch/axios) or calls a
provided prop; also give each input and the textarea name and required
attributes and add visible <label> elements or aria-label attributes (or
associate labels via htmlFor/id) so the fields are accessible; alternatively, if
no submission is intended, convert the inputs/button into non-interactive text
or disable them and update copy to indicate the form is not functional. Ensure
you edit the form element, the three <input> fields, the <textarea>, and the
Submit <button> in Hs1AlbanyContactFormSection.tsx accordingly.
| {props.socialLinks.map((item) => { | ||
| const Icon = iconMap[item.icon]; | ||
| return ( | ||
| <Link | ||
| key={`${item.label}-${item.link}`} | ||
| cta={{ link: item.link, linkType: "URL" }} | ||
| className="flex h-9 w-9 items-center justify-center rounded-full bg-[#dcb65f] text-white no-underline" | ||
| > | ||
| <Icon /> | ||
| </Link> |
There was a problem hiding this comment.
Icon-only social links need an accessible name.
These links render only SVGs, so assistive tech gets unlabeled controls. Add hidden text or an aria-label from item.label.
Suggested fix
<Link
key={`${item.label}-${item.link}`}
cta={{ link: item.link, linkType: "URL" }}
className="flex h-9 w-9 items-center justify-center rounded-full bg-[`#dcb65f`] text-white no-underline"
>
- <Icon />
+ <Icon aria-hidden="true" />
+ <span className="sr-only">{item.label}</span>
</Link>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {props.socialLinks.map((item) => { | |
| const Icon = iconMap[item.icon]; | |
| return ( | |
| <Link | |
| key={`${item.label}-${item.link}`} | |
| cta={{ link: item.link, linkType: "URL" }} | |
| className="flex h-9 w-9 items-center justify-center rounded-full bg-[#dcb65f] text-white no-underline" | |
| > | |
| <Icon /> | |
| </Link> | |
| {props.socialLinks.map((item) => { | |
| const Icon = iconMap[item.icon]; | |
| return ( | |
| <Link | |
| key={`${item.label}-${item.link}`} | |
| cta={{ link: item.link, linkType: "URL" }} | |
| className="flex h-9 w-9 items-center justify-center rounded-full bg-[`#dcb65f`] text-white no-underline" | |
| > | |
| <Icon aria-hidden="true" /> | |
| <span className="sr-only">{item.label}</span> | |
| </Link> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyFooterSection.tsx` around
lines 106 - 115, In Hs1AlbanyFooterSection, social link buttons rendered from
props.socialLinks currently only output SVG icons (Icon) inside Link, making
them inaccessible; update the Link to include an accessible name by adding an
aria-label={item.label} (or include visually-hidden text with item.label) on the
Link component so screen readers receive the label for each Icon, keeping the
existing key and cta props intact.
| const resolvedHeroImage = resolveComponentData( | ||
| props.heroImage, | ||
| locale, | ||
| streamDocument, | ||
| ); | ||
| void resolvedHeroImage; | ||
| const heroImageUrl = capturedHeroImageUrl; |
There was a problem hiding this comment.
Resolved hero image is discarded — entity-selected images won't render.
The resolvedHeroImage is computed from props.heroImage but immediately voided. The component then uses a hardcoded static asset (capturedHeroImageUrl) instead. This prevents users from seeing their entity-selected or configured hero images.
Based on context snippet 1, resolveComponentData returns a TranslatableAssetImage containing the url property that should be used.
🔧 Proposed fix to use the resolved image
const resolvedHeroImage = resolveComponentData(
props.heroImage,
locale,
streamDocument,
);
- void resolvedHeroImage;
- const heroImageUrl = capturedHeroImageUrl;
+ const heroImageUrl =
+ (resolvedHeroImage as { url?: string } | undefined)?.url ??
+ capturedHeroImageUrl;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const resolvedHeroImage = resolveComponentData( | |
| props.heroImage, | |
| locale, | |
| streamDocument, | |
| ); | |
| void resolvedHeroImage; | |
| const heroImageUrl = capturedHeroImageUrl; | |
| const resolvedHeroImage = resolveComponentData( | |
| props.heroImage, | |
| locale, | |
| streamDocument, | |
| ); | |
| const heroImageUrl = | |
| (resolvedHeroImage as { url?: string } | undefined)?.url ?? | |
| capturedHeroImageUrl; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyHeroSection.tsx` around
lines 138 - 144, The code computes resolvedHeroImage via
resolveComponentData(props.heroImage, locale, streamDocument) but immediately
discards it and always uses capturedHeroImageUrl; replace that by using the
resolved asset's url (e.g., heroImageUrl = (resolvedHeroImage as
TranslatableAssetImage)?.url ?? capturedHeroImageUrl) and remove the void
resolvedHeroImage; ensure you reference resolvedHeroImage and fall back to
capturedHeroImageUrl so entity-selected images render correctly.
| {item.hours.includes(" - ") ? ( | ||
| <> | ||
| {item.hours.split(" - ")[0]} | ||
| <span> - </span> | ||
| {item.hours.split(" - ")[1]} | ||
| </> | ||
| ) : ( | ||
| item.hours | ||
| )} |
There was a problem hiding this comment.
Edge case: Multiple intervals display incorrectly in desktop view.
When formatHoursForDay returns multiple intervals joined with ", " (e.g., "9:00 am - 12:00 pm, 1:00 pm - 5:00 pm"), splitting on " - " produces incorrect segments. The current logic would display "9:00 am" and "12:00 pm, 1:00 pm" instead of the full hours string.
The mobile view (line 286) correctly displays item.hours without splitting.
🔧 Proposed fix to handle multiple intervals
<p
className="mb-0 mt-3 text-[11px] text-[`#4f4e4e`]"
style={{ fontFamily: "Montserrat, Open Sans, sans-serif" }}
>
- {item.hours.includes(" - ") ? (
- <>
- {item.hours.split(" - ")[0]}
- <span> - </span>
- {item.hours.split(" - ")[1]}
- </>
- ) : (
- item.hours
- )}
+ {item.hours}
</p>Alternatively, if line breaking between start/end is needed, split only the first occurrence:
- {item.hours.includes(" - ") ? (
+ {item.hours.includes(" - ") && !item.hours.includes(", ") ? (
<>
{item.hours.split(" - ")[0]}
<span> - </span>
{item.hours.split(" - ")[1]}
</>
) : (
item.hours
)}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {item.hours.includes(" - ") ? ( | |
| <> | |
| {item.hours.split(" - ")[0]} | |
| <span> - </span> | |
| {item.hours.split(" - ")[1]} | |
| </> | |
| ) : ( | |
| item.hours | |
| )} | |
| {item.hours} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyHoursSection.tsx` around
lines 255 - 263, The desktop rendering in Hs1AlbanyHoursSection.tsx currently
splits item.hours on every " - ", which breaks multi-interval strings from
formatHoursForDay; update the conditional so if item.hours contains a comma (",
") you render item.hours as-is, otherwise split only the first " - " occurrence
(e.g., find the firstIndexOf " - " and use substring before/after) when
constructing the two parts; reference the item.hours usage in the JSX and adjust
the split logic to use indexOf/substring (or a single split with a limit)
instead of splitting on all " - "s.
| <div className="mb-1 flex items-end gap-1"> | ||
| <span className="text-[26px] leading-none text-[#7b7b7b]"> | ||
| -- | ||
| </span> | ||
| <span className="text-[15px] font-bold uppercase tracking-[0.08em]"> | ||
| mi | ||
| </span> |
There was a problem hiding this comment.
The distance badge is shipping a placeholder.
Nothing in this component ever replaces --, so the template will always render -- mi. Wire it to real data or remove the badge until that value exists.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyLocationSection.tsx`
around lines 133 - 139, The distance badge in Hs1AlbanyLocationSection currently
renders a hardcoded "--", so either wire it to the real distance value or hide
the badge when no distance exists: locate the Hs1AlbanyLocationSection component
and replace the static "--" text with the actual distance variable (e.g.,
props.distance or computed formattedDistance) and ensure you format it
(round/trim) and append "mi"; alternatively, wrap the entire <div
className="mb-1 flex items-end gap-1"> block in a conditional render (e.g., only
render when distance != null/undefined) so the placeholder never appears if the
data is absent.
| <form className="grid gap-4 md:grid-cols-[1fr_1fr_auto]"> | ||
| <input | ||
| className="h-[44px] border border-white/80 bg-transparent px-3 text-[13px] text-white placeholder:text-white/80" | ||
| placeholder="Enter your name (Required)" | ||
| /> | ||
| <input | ||
| className="h-[44px] border border-white/80 bg-transparent px-3 text-[13px] text-white placeholder:text-white/80" | ||
| placeholder="Enter email (Required)" | ||
| /> | ||
| <button | ||
| type="button" | ||
| className="h-[44px] border border-white/80 px-8 text-[13px] font-bold uppercase tracking-[0.08em] text-white" | ||
| style={{ fontFamily: "Nunito Sans, Open Sans, sans-serif" }} | ||
| > | ||
| Submit | ||
| </button> |
There was a problem hiding this comment.
The signup form can't be submitted.
This repeats the same type="button"/no submit handler pattern, so the CTA never does anything. Because the inputs rely only on placeholders, the published form would also miss proper labels. If this is demo chrome only, render it as a mock instead of a real form.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanySignupFormSection.tsx`
around lines 91 - 106, The form in Hs1AlbanySignupFormSection uses a plain
<form> with inputs that only have placeholders and a button set to
type="button", so it never submits and lacks accessible labels; change the
button in this component to type="submit" and add an onSubmit handler (e.g.,
handleSignupSubmit) on the <form> to process/validate the name/email, or if this
is purely demo chrome, replace the <form> with a non-interactive container (or
explicitly mark it as mock) and keep the CTA as a non-submitting element;
additionally, add proper <label> elements or visible/aria-label attributes for
the two inputs (name/email) and wire them to state or form refs so the submit
handler can read values.
| const activeQuote = props.quotes[0]; | ||
| const quoteText = | ||
| activeQuote && | ||
| resolveComponentData(activeQuote.quote.text, locale, streamDocument); | ||
|
|
||
| return ( | ||
| <section className="bg-[#4f4e4e] px-6 py-12"> | ||
| <div className="mx-auto max-w-[1170px]"> | ||
| <h2 | ||
| className="mb-8 mt-0 text-center text-white" | ||
| style={{ | ||
| fontFamily: "Montserrat, Open Sans, sans-serif", | ||
| fontSize: `${props.heading.fontSize}px`, | ||
| fontWeight: props.heading.fontWeight, | ||
| letterSpacing: "1px", | ||
| textTransform: | ||
| props.heading.textTransform === "normal" | ||
| ? undefined | ||
| : props.heading.textTransform, | ||
| }} | ||
| > | ||
| {heading} | ||
| </h2> | ||
| <div className="mx-auto max-w-[840px] bg-white px-8 py-10 text-center"> | ||
| <div className="mx-auto mb-6 flex h-11 w-11 items-center justify-center rounded-full bg-[#d3a335] text-2xl text-white"> | ||
| “ | ||
| </div> | ||
| <p className="m-0 text-[22px] leading-8 text-[#4a4a4a]"> | ||
| {quoteText} | ||
| </p> |
There was a problem hiding this comment.
Only the first testimonial is ever rendered.
quotes is modeled as an editable array of styled items, but this component always reads props.quotes[0] and prints it inside a hard-coded <p>. Every additional testimonial and all per-quote typography controls are ignored. Either render the array or collapse this to a single quote field so the editor matches runtime behavior.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyTestimonialsSection.tsx`
around lines 104 - 133, The component currently only uses props.quotes[0]
(activeQuote) and always renders a single <p>, so additional testimonials and
per-quote typography are ignored; update Hs1AlbanyTestimonialsSection to iterate
over props.quotes (e.g., map) and for each quote call
resolveComponentData(quote.quote.text, locale, streamDocument) to compute
quoteText, render each testimonial block (including the quote mark, text, and
any per-quote typography props from the quote item) instead of the hard-coded
single <p>, and remove or repurpose the activeQuote variable if you keep a
single-view mode; ensure you reference props.quotes, resolveComponentData, and
any per-quote typography fields when implementing the mapping.
| <p | ||
| className="mb-0 mt-5 text-[22px] text-[#d3a335]" | ||
| style={{ | ||
| fontFamily: "Montserrat, Open Sans, sans-serif", | ||
| lineHeight: "1.4", | ||
| }} | ||
| > | ||
| {subtitle} | ||
| </p> | ||
| <p | ||
| className="mb-0 mt-5 text-[14px] leading-7 text-[#7a7a7a]" | ||
| style={{ fontFamily: "Montserrat, Open Sans, sans-serif" }} | ||
| > | ||
| {body} | ||
| </p> |
There was a problem hiding this comment.
Subtitle and body typography controls aren't wired up.
Both props are declared as StyledTextProps, but this render path never applies their fontSize, fontColor, fontWeight, or textTransform values. Edits to those controls in Puck won't show up until the styles come from props instead of fixed classes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@starter/src/registry/hs1-albany/components/Hs1AlbanyWelcomeSection.tsx`
around lines 146 - 160, The subtitle and body render blocks in
Hs1AlbanyWelcomeSection are using fixed classes/styles so the passed-in
StyledTextProps (subtitle and body) fontSize, fontColor, fontWeight, and
textTransform are ignored; update the subtitle and body render logic to consume
those props: compute style entries (fontSize -> fontSize, fontColor -> color,
fontWeight -> fontWeight, textTransform -> textTransform, plus existing
fontFamily/lineHeight where applicable) and merge them into the inline style
object, and/or compute className fragments from those prop values instead of
hardcoded text sizes/colors; target the JSX elements that reference subtitle and
body in Hs1AlbanyWelcomeSection.tsx and replace the fixed className/style usage
so the StyledTextProps values are applied at render time.
Summary
Verification