fix(project-editor): validate footer payment/social links, add footer logo picker
- 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>
This commit is contained in:
@@ -1,15 +1,65 @@
|
||||
@if (bootstrap(); as bootstrap) {
|
||||
<section class="editor-section-card">
|
||||
<h2>{{ 'builder.footer' | translate }}</h2>
|
||||
<app-section-card [title]="'builder.footer' | translate">
|
||||
<div class="editor-grid two">
|
||||
<app-form-field [label]="'builder.companyName' | translate" [hint]="'builder.companyNameDesc' | translate"><app-input [ngModel]="bootstrap.company.companyName" (ngModelChange)="updateCompanyName($event)" /></app-form-field>
|
||||
<app-form-field [label]="'builder.address' | translate" [hint]="'builder.addressDesc' | translate"><app-input [ngModel]="bootstrap.company.address.street || ''" (ngModelChange)="updateAddress($event)" /></app-form-field>
|
||||
<app-form-field [label]="'builder.phone' | translate" [hint]="'builder.phoneDesc' | translate"><app-input [ngModel]="bootstrap.company.contacts.phone || ''" (ngModelChange)="updatePhone($event)" /></app-form-field>
|
||||
<app-form-field [label]="'builder.email' | translate" [hint]="'builder.emailDesc' | translate"><app-input [ngModel]="bootstrap.company.contacts.email" (ngModelChange)="updateEmail($event)" /></app-form-field>
|
||||
<app-form-field class="full" [label]="'builder.copyright' | translate" [hint]="'builder.copyrightDesc' | translate"><app-input [ngModel]="copyrightValue()" (ngModelChange)="updateCopyright($event)" /></app-form-field>
|
||||
<label class="full"><span>{{ 'builder.paymentIcons' | translate }}</span><small class="field-desc">{{ 'builder.paymentIconsDesc' | translate }}</small><textarea rows="4" [ngModel]="paymentIconsValue()" (ngModelChange)="updatePaymentIcons($event)"></textarea></label>
|
||||
<label class="full"><span>{{ 'builder.socialLinks' | translate }}</span><small class="field-desc">{{ 'builder.socialLinksDesc' | translate }}</small><textarea rows="4" [ngModel]="socialLinksValue()" (ngModelChange)="updateSocialLinks($event)"></textarea></label>
|
||||
<app-form-field class="full" [label]="'builder.footerLogo' | translate" [hint]="'builder.footerLogoDesc' | translate">
|
||||
<div class="media-field-row">
|
||||
<app-input [ngModel]="bootstrap.footer?.logoUrl || ''" (ngModelChange)="updateLogo($event)" />
|
||||
<app-button variant="secondary" size="sm" (click)="openLogoPicker()">{{ 'adminCategories.chooseImage' | translate }}</app-button>
|
||||
</div>
|
||||
</app-form-field>
|
||||
|
||||
<div class="full">
|
||||
<label><span>{{ 'builder.paymentIcons' | translate }}</span><small class="field-desc">{{ 'builder.paymentIconsDesc' | translate }}</small></label>
|
||||
<app-key-value-editor
|
||||
[rows]="paymentIconRows()"
|
||||
[addLabel]="'builder.addPaymentIcon' | translate"
|
||||
[removeLabel]="'builder.removePaymentIcon' | translate"
|
||||
[createRow]="createPaymentIconRow"
|
||||
(rowsChange)="onPaymentIconsChange($event)"
|
||||
>
|
||||
<ng-template let-row let-index="index">
|
||||
<div class="media-field-row">
|
||||
<app-input [ngModel]="row.src" (ngModelChange)="updatePaymentIconSrc(index, $event)" [placeholder]="'builder.iconLabel' | translate" />
|
||||
<app-button variant="secondary" size="sm" (click)="openPaymentIconPicker(index)">{{ 'adminCategories.chooseImage' | translate }}</app-button>
|
||||
<app-input [ngModel]="row.alt" (ngModelChange)="updatePaymentIconAlt(index, $event)" [placeholder]="'builder.iconAltLabel' | translate" />
|
||||
</div>
|
||||
</ng-template>
|
||||
</app-key-value-editor>
|
||||
</div>
|
||||
|
||||
<div class="full">
|
||||
<label><span>{{ 'builder.socialLinks' | translate }}</span><small class="field-desc">{{ 'builder.socialLinksDesc' | translate }}</small></label>
|
||||
<app-key-value-editor
|
||||
[rows]="socialLinkRows()"
|
||||
[addLabel]="'builder.addSocialLink' | translate"
|
||||
[removeLabel]="'builder.removeSocialLink' | translate"
|
||||
[createRow]="createSocialLinkRow"
|
||||
(rowsChange)="onSocialLinksChange($event)"
|
||||
>
|
||||
<ng-template let-row let-index="index">
|
||||
<div class="editor-grid two compact">
|
||||
<app-form-field [label]="'builder.socialLinkLabel' | translate">
|
||||
<app-input [ngModel]="row.label" (ngModelChange)="updateSocialLinkLabel(index, $event)" />
|
||||
</app-form-field>
|
||||
<app-form-field
|
||||
[label]="'builder.socialLinkUrl' | translate"
|
||||
[hint]="isValidUrl(row.url) ? ('builder.socialLinkUrlDesc' | translate) : null"
|
||||
[error]="isValidUrl(row.url) ? null : ('builder.invalidUrl' | translate)"
|
||||
>
|
||||
<app-input type="url" [ngModel]="row.url" (ngModelChange)="updateSocialLinkUrl(index, $event)" />
|
||||
</app-form-field>
|
||||
</div>
|
||||
</ng-template>
|
||||
</app-key-value-editor>
|
||||
</div>
|
||||
|
||||
<app-form-field class="full" [label]="'builder.staticPages' | translate" [hint]="'builder.staticPagesFieldDesc' | translate"><app-input [ngModel]="staticPagesValue()" (ngModelChange)="updateStaticPages($event)" /></app-form-field>
|
||||
</div>
|
||||
</section>
|
||||
<app-media-picker [open]="mediaPickerOpen" (selected)="onImagePicked($event)" (closed)="mediaPickerOpen = false" />
|
||||
</app-section-card>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user