Replace every PrimeIcons pi-* usage across the builder: overview page
(back link, next-step arrow, section cards, readiness checklist,
quick links), sidebar nav (group/section status dots), main layout
(back/home/menu/help icons), brand + homepage overview panels
(checklist ok/pending dots, contrast warning), footer/homepage/widgets
section editors (drag handles, move up/down, duplicate, remove), and
the HTML editor toolbar (list/link/image/table/divider/code/embed).
Notable correctness fix: PrimeIcons reused pi-bars for both the
hamburger menu toggle AND every drag handle - two different meanings
sharing one icon (exactly the kind of icon collision the audit calls
out). Added a dedicated 'grip' icon (GripVertical) for drag handles so
menu and drag-to-reorder are visually distinct.
Added a global .spin utility (icon-registry has no built-in spinner
animation) for the one loading-spinner icon in the builder overview
checklist.
All icon-bearing fields (BuilderGroup.icon, BlockCatalogEntry.icon,
WIDGET_ICONS, STATUS_ICON, HtmlEditorToolbarCommand.icon, etc.) are
now typed AppIconName instead of string.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
P0 user feedback: footer static pages were comma-separated text; no way to add extra phones/emails for different countries.
- New FooterColumnConfig/FooterLinkConfig model (footer-config.model.ts): columns of links, each link pointing at an existing static page (resolved by key, so it survives route renames) or a custom URL
- Footer Builder UI: add/remove columns and links, per-link toggle between 'existing page' (dropdown of real static pages) and 'custom URL', drag-and-drop reordering of both columns and links via @angular/cdk/drag-drop (same primitive already used by the homepage section builder)
- Wired FooterResolverService (the service the real storefront footer actually renders through) to read footer.columns as the primary source when present - without this the builder would have saved data nobody ever displayed. Falls back to the existing legacy static-page auto-grouping when no columns are configured, so existing sites are unaffected
- CompanyContactConfig gains additionalPhones/additionalEmails (primary phone/email field unchanged) with add/remove UI for country-specific support lines
- Old comma-separated staticPageKeys input removed from the UI; field kept on the model as deprecated/read-compat only
- New builder.* i18n keys (en/ru/hy); fixed an accidental duplicate-key collision with pre-existing navigation-section addLink/removeLink keys during the rename pass
- Verified in browser: added column, added link, switched link source page->custom, added phone number - all reactive and error-free
Real gaps, not fabricated: isValidEmail existed in primitives.ts but was
never called anywhere; social-link URL check only lived as a per-row
template hint (never blocked publish or set the nav badge); payment icons
with only src or only alt set were silently accepted.
- invalid-contact-email: company.contacts.email must be a valid email (error)
- invalid-social-link-url: footer.socialLinks entries need a valid http(s) URL (warning)
- incomplete-payment-icon: a payment icon needs both src and alt, or neither (warning)
Wired into footer-section via the existing fieldError() pattern. Header has
no equivalent gap today (every header field is a bool/enum, always valid by
construction) so nothing was added there.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- header-section: raw checkboxes -> app-toggle, wrap in SectionCard
- footer-section: replace unvalidated pipe-delimited textareas for payment
icons/social links with KeyValueEditor + MediaPickerComponent, add missing
footer logo picker, validate social link URLs (http/https), wrap in SectionCard
- i18n: add footer logo / key-value-editor labels and URL validation message
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Applied app-input/app-form-field/app-button to 9 of 11 Project Editor
sections: general, branding, theme, footer, homepage, widgets, languages,
navigation, preview. header and features sections were left unchanged -
they contain only checkboxes and selects, and no Checkbox/Select primitive
exists yet.
Theme section's 8 color pickers stay native <input type=color> (app-input's
type union doesn't include 'color') but are now wrapped in app-form-field
for consistent label/hint treatment. Added app-form-field.full grid-column
rule to section.shared.scss (shared by all 11 sections) alongside the
existing label.full rule, since the custom element doesn't match that
selector.
Production build green, arch:check passes.
Wires up the remaining editor sections (theme, header, footer, homepage,
widgets, features, languages, navigation) with the description text and
dropdown UX started for General/Branding:
- Every enum-backed field is now a <select> with a description per option,
not free text: theme.mode, the new site-wide layout.type (previously had
no editor at all - added to the Theme section, and added to that
section's reset-scope), homepage section layout.strategy, and
catalog.navigationMode (also previously unedited, added to Features).
- Every other field (colors, header toggles, footer contact/company fields,
widget props, feature flags, language add, nav link label/url/visible)
gets a one-line plain-language description under its label via the new
*Desc i18n keys (en/ru/hy) prepared earlier.
- Genuinely open text (widget layout variant strings, JSON props) stays
free text, description-only, per the existing widgetLayoutDesc/widgetJsonDesc
wording - not force-fit into a dropdown.
Verified: tsc --noEmit and ng build both clean.